Memory sharing: better handling of ENOMEM while unsharing
authorTim Deegan <tim@xen.org>
Thu, 15 Mar 2012 11:12:44 +0000 (11:12 +0000)
committerTim Deegan <tim@xen.org>
Thu, 15 Mar 2012 11:12:44 +0000 (11:12 +0000)
commit0806e3965914990286b62c120e95f09e4962152c
tree2c7da2078ca2aec05371fffde8c56d11ddbefdb6
parent9ccfacd4706c785434848b9b31701945eceefe0f
Memory sharing: better handling of ENOMEM while unsharing

If unsharing fails with ENOMEM, we were:
 - leaving the list of gfns backed by the shared page in an inconsistent state
 - cycling forever on the hap page fault handler.
 - Attempting to produce a mem event (which could sleep on a wait queue)
   while holding locks.
 - Not checking, for all callers, that unshare could have indeed failed.

Fix bugs above, and sanitize callers to place a ring event in an unlocked
context, or without requiring to go to sleep on a wait queue.

A note on the rationale for unshare error handling:
 1. Unshare can only fail with ENOMEM. Any other error conditions BUG_ON()
 2. We notify a potential dom0 helper through a mem_event ring. But we
    allow the notification to not go to sleep. If the event ring is full
    of ENOMEM warnings, then the helper will already have been kicked enough.
 3. We cannot "just" go to sleep until the unshare is resolved, because we
    might be buried deep into locks (e.g. something -> copy_to_user ->
    __hvm_copy)
 4. So, we make sure we:
    4.1. return an error
    4.2. do not corrupt memory shared with other guests
    4.3. do not corrupt memory private to the current guest
    4.4. do not corrupt the hypervisor memory sharing meta data
    4.5. let the guest deal with the error, if propagation will reach that far

Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
Acked-by: Tim Deegan <tim@xen.org>
Committed-by: Tim Deegan <tim@xen.org>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/mm.c
xen/arch/x86/mm/mem_sharing.c
xen/arch/x86/mm/p2m.c
xen/common/grant_table.c
xen/common/memory.c
xen/include/asm-x86/mem_sharing.h