]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
x86: make hypercall preemption checks consistent
authorJan Beulich <jbeulich@suse.com>
Thu, 13 Mar 2014 13:27:51 +0000 (14:27 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 13 Mar 2014 13:27:51 +0000 (14:27 +0100)
- never preempt on the first iteration (ensure forward progress)
- never preempt on the last iteration (pointless/wasteful)

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Tim Deegan <tim@xen.org>
Acked-by: Keir Fraser <keir@xen.org>
xen/arch/x86/mm.c
xen/arch/x86/mm/hap/hap.c
xen/arch/x86/mm/p2m-pod.c
xen/arch/x86/mm/shadow/common.c
xen/arch/x86/traps.c
xen/arch/x86/x86_64/compat/traps.c

index 172c68c282565209596c17ea804ebeb560edd522..fdc5ed3ffeaca2d116ae99477b0492c4812f49aa 100644 (file)
@@ -2934,7 +2934,7 @@ long do_mmuext_op(
 
     for ( i = 0; i < count; i++ )
     {
-        if ( curr->arch.old_guest_table || hypercall_preempt_check() )
+        if ( curr->arch.old_guest_table || (i && hypercall_preempt_check()) )
         {
             rc = -EAGAIN;
             break;
@@ -3481,7 +3481,7 @@ long do_mmu_update(
 
     for ( i = 0; i < count; i++ )
     {
-        if ( curr->arch.old_guest_table || hypercall_preempt_check() )
+        if ( curr->arch.old_guest_table || (i && hypercall_preempt_check()) )
         {
             rc = -EAGAIN;
             break;
index 5f756366aa3e9c2825133054160d78e55cc5693d..b8c5422a146d63a3238d0dc5fe2260b235351095 100644 (file)
@@ -326,7 +326,7 @@ hap_set_allocation(struct domain *d, unsigned int pages, int *preempted)
     else
         pages -= d->arch.paging.hap.p2m_pages;
 
-    while ( d->arch.paging.hap.total_pages != pages )
+    for ( ; ; )
     {
         if ( d->arch.paging.hap.total_pages < pages )
         {
@@ -355,6 +355,8 @@ hap_set_allocation(struct domain *d, unsigned int pages, int *preempted)
             d->arch.paging.hap.total_pages--;
             free_domheap_page(pg);
         }
+        else
+            break;
 
         /* Check to see if we need to yield and try again */
         if ( preempted && hypercall_preempt_check() )
index 81645c4d90b2fa0f41a9f0dc2723a9a5b06bcef0..d14565d8eefa49839886e195fefd7cd991745c26 100644 (file)
@@ -242,7 +242,8 @@ p2m_pod_set_cache_target(struct p2m_domain *p2m, unsigned long pod_target, int p
 
         p2m_pod_cache_add(p2m, page, order);
 
-        if ( hypercall_preempt_check() && preemptible )
+        if ( preemptible && pod_target != p2m->pod.count &&
+             hypercall_preempt_check() )
         {
             ret = -EAGAIN;
             goto out;
@@ -286,7 +287,8 @@ p2m_pod_set_cache_target(struct p2m_domain *p2m, unsigned long pod_target, int p
 
             put_page(page+i);
 
-            if ( hypercall_preempt_check() && preemptible )
+            if ( preemptible && pod_target != p2m->pod.count &&
+                 hypercall_preempt_check() )
             {
                 ret = -EAGAIN;
                 goto out;
index 6eb781e45c121663325140e358aa0ccef826a9f2..517b5f178e5251812d98f50d2feee5f9ad12628f 100644 (file)
@@ -1672,7 +1672,7 @@ static unsigned int sh_set_allocation(struct domain *d,
     SHADOW_PRINTK("current %i target %i\n", 
                    d->arch.paging.shadow.total_pages, pages);
 
-    while ( d->arch.paging.shadow.total_pages != pages ) 
+    for ( ; ; )
     {
         if ( d->arch.paging.shadow.total_pages < pages ) 
         {
@@ -1707,6 +1707,8 @@ static unsigned int sh_set_allocation(struct domain *d,
             d->arch.paging.shadow.total_pages--;
             free_domheap_page(sp);
         }
+        else
+            break;
 
         /* Check to see if we need to yield and try again */
         if ( preempted && hypercall_preempt_check() )
index c4623178dd0065634157c48c075426d8aaa240e4..ed4ae2d1fe544427e062d00c7d186433ad724d80 100644 (file)
@@ -3596,13 +3596,6 @@ long do_set_trap_table(XEN_GUEST_HANDLE_PARAM(const_trap_info_t) traps)
 
     for ( ; ; )
     {
-        if ( hypercall_preempt_check() )
-        {
-            rc = hypercall_create_continuation(
-                __HYPERVISOR_set_trap_table, "h", traps);
-            break;
-        }
-
         if ( copy_from_guest(&cur, traps, 1) )
         {
             rc = -EFAULT;
@@ -3623,6 +3616,13 @@ long do_set_trap_table(XEN_GUEST_HANDLE_PARAM(const_trap_info_t) traps)
             init_int80_direct_trap(curr);
 
         guest_handle_add_offset(traps, 1);
+
+        if ( hypercall_preempt_check() )
+        {
+            rc = hypercall_create_continuation(
+                __HYPERVISOR_set_trap_table, "h", traps);
+            break;
+        }
     }
 
     return rc;
index 21a82b91eb7322cb7bf26fdd0ff7bfca8fc27670..5f0ea0a3984c321fc648a24ad0c59a1216104049 100644 (file)
@@ -329,13 +329,6 @@ int compat_set_trap_table(XEN_GUEST_HANDLE(trap_info_compat_t) traps)
 
     for ( ; ; )
     {
-        if ( hypercall_preempt_check() )
-        {
-            rc = hypercall_create_continuation(
-                __HYPERVISOR_set_trap_table, "h", traps);
-            break;
-        }
-
         if ( copy_from_guest(&cur, traps, 1) )
         {
             rc = -EFAULT;
@@ -353,6 +346,13 @@ int compat_set_trap_table(XEN_GUEST_HANDLE(trap_info_compat_t) traps)
             init_int80_direct_trap(current);
 
         guest_handle_add_offset(traps, 1);
+
+        if ( hypercall_preempt_check() )
+        {
+            rc = hypercall_create_continuation(
+                __HYPERVISOR_set_trap_table, "h", traps);
+            break;
+        }
     }
 
     return rc;