# HG changeset patch # User kaf24@firebug.cl.cam.ac.uk # Date 1125680528 0 # Node ID ec11c5cca195bd6a671a9813d4610d8847e01eee # Parent 7c2afbad0188ac64feb0f4122c7b262bc640c014 Fix preemption-check race in memory_op hypercall. Signed-off-by: Keir Fraser diff -r 7c2afbad0188 -r ec11c5cca195 xen/common/memory.c --- a/xen/common/memory.c Fri Sep 02 16:51:55 2005 +0000 +++ b/xen/common/memory.c Fri Sep 02 17:02:08 2005 +0000 @@ -25,7 +25,8 @@ increase_reservation( unsigned long *extent_list, unsigned int nr_extents, unsigned int extent_order, - unsigned int flags) + unsigned int flags, + int *preempted) { struct pfn_info *page; unsigned long i; @@ -43,7 +44,10 @@ increase_reservation( for ( i = 0; i < nr_extents; i++ ) { if ( hypercall_preempt_check() ) + { + *preempted = 1; return i; + } if ( unlikely((page = alloc_domheap_pages( d, extent_order, flags)) == NULL) ) @@ -67,7 +71,8 @@ decrease_reservation( unsigned long *extent_list, unsigned int nr_extents, unsigned int extent_order, - unsigned int flags) + unsigned int flags, + int *preempted) { struct pfn_info *page; unsigned long i, j, mpfn; @@ -78,7 +83,10 @@ decrease_reservation( for ( i = 0; i < nr_extents; i++ ) { if ( hypercall_preempt_check() ) + { + *preempted = 1; return i; + } if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) ) return i; @@ -124,7 +132,7 @@ decrease_reservation( long do_memory_op(int cmd, void *arg) { struct domain *d; - int rc, start_extent, op, flags = 0; + int rc, start_extent, op, flags = 0, preempted = 0; struct xen_memory_reservation reservation; op = cmd & ((1 << START_EXTENT_SHIFT) - 1); @@ -165,19 +173,18 @@ long do_memory_op(int cmd, void *arg) reservation.extent_start, reservation.nr_extents, reservation.extent_order, - flags); + flags, + &preempted); if ( unlikely(reservation.domid != DOMID_SELF) ) put_domain(d); rc += start_extent; - if ( (rc != reservation.nr_extents) && hypercall_preempt_check() ) + if ( preempted ) return hypercall2_create_continuation( - __HYPERVISOR_memory_op, - op | (rc << START_EXTENT_SHIFT), - arg); - + __HYPERVISOR_memory_op, op | (rc << START_EXTENT_SHIFT), arg); + break; case XENMEM_maximum_ram_page: