# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1299687446 0
# Node ID d428fa67abaa0db20b915a697f1d5ba16e554185
# Parent  82b5f8d12903e140f957ae8d13d66e44be076b05
x86: make mod_l2_entry() return a proper error code

... so that finally all mod_lN_entry() functions behave identically,
allowing some cleanup in do_mmu_update() (which no longer needs to
track both an okay status and an error code).

Signed-off-by: Jan Beulich <jbeulich@novell.com>

Index: xen-4.1.5-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.1.5-testing.orig/xen/arch/x86/mm.c
+++ xen-4.1.5-testing/xen/arch/x86/mm.c
@@ -1861,16 +1861,16 @@ static int mod_l2_entry(l2_pgentry_t *pl
     struct domain *d = vcpu->domain;
     struct page_info *l2pg = mfn_to_page(pfn);
     unsigned long type = l2pg->u.inuse.type_info;
-    int rc = 1;
+    int rc = 0;
 
     if ( unlikely(!is_guest_l2_slot(d, type, pgentry_ptr_to_slot(pl2e))) )
     {
         MEM_LOG("Illegal L2 update attempt in Xen-private area %p", pl2e);
-        return 0;
+        return -EPERM;
     }
 
     if ( unlikely(__copy_from_user(&ol2e, pl2e, sizeof(ol2e)) != 0) )
-        return 0;
+        return -EFAULT;
 
     if ( l2e_get_flags(nl2e) & _PAGE_PRESENT )
     {
@@ -1878,32 +1878,33 @@ static int mod_l2_entry(l2_pgentry_t *pl
         {
             MEM_LOG("Bad L2 flags %x",
                     l2e_get_flags(nl2e) & L2_DISALLOW_MASK);
-            return 0;
+            return -EINVAL;
         }
 
         /* Fast path for identical mapping and presence. */
         if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT) )
         {
             adjust_guest_l2e(nl2e, d);
-            rc = UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu, preserve_ad);
-            return rc;
+            if ( UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu, preserve_ad) )
+                return 0;
+            return -EBUSY;
         }
 
-        if ( unlikely(get_page_from_l2e(nl2e, pfn, d) < 0) )
-            return 0;
+        if ( unlikely((rc = get_page_from_l2e(nl2e, pfn, d)) < 0) )
+            return rc;
 
         adjust_guest_l2e(nl2e, d);
         if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu,
                                     preserve_ad)) )
         {
             ol2e = nl2e;
-            rc = 0;
+            rc = -EBUSY;
         }
     }
     else if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu,
                                      preserve_ad)) )
     {
-        return 0;
+        return -EBUSY;
     }
 
     put_page_from_l2e(ol2e, pfn);
@@ -3383,7 +3384,7 @@ long do_mmu_update(
     void *va;
     unsigned long gpfn, gmfn, mfn;
     struct page_info *page;
-    int rc = 0, okay = 1, i = 0;
+    int rc = 0, i = 0;
     unsigned int cmd, done = 0, pt_dom;
     struct vcpu *v = current;
     struct domain *d = v->domain, *pt_owner = d, *pg_owner;
@@ -3450,7 +3451,6 @@ long do_mmu_update(
         }
 
         cmd = req.ptr & (sizeof(l1_pgentry_t)-1);
-        okay = 0;
 
         switch ( cmd )
         {
@@ -3467,6 +3467,7 @@ long do_mmu_update(
             rc = xsm_mmu_normal_update(d, pg_owner, req.val);
             if ( rc )
                 break;
+            rc = -EINVAL;
 
             req.ptr -= cmd;
             gmfn = req.ptr >> PAGE_SHIFT;
@@ -3537,7 +3538,6 @@ long do_mmu_update(
                     rc = mod_l1_entry(va, l1e, mfn,
                                       cmd == MMU_PT_UPDATE_PRESERVE_AD, v,
                                       pg_owner);
-                    okay = !rc;
                 }
                 break;
                 case PGT_l2_page_table:
@@ -3561,13 +3561,12 @@ long do_mmu_update(
                     else if ( p2m_ram_shared == l2e_p2mt )
                     {
                         MEM_LOG("Unexpected attempt to map shared page.\n");
-                        rc = -EINVAL;
                         break;
                     }
 
 
-                    okay = mod_l2_entry(va, l2e, mfn,
-                                        cmd == MMU_PT_UPDATE_PRESERVE_AD, v);
+                    rc = mod_l2_entry(va, l2e, mfn,
+                                      cmd == MMU_PT_UPDATE_PRESERVE_AD, v);
                 }
                 break;
                 case PGT_l3_page_table:
@@ -3591,13 +3590,11 @@ long do_mmu_update(
                     else if ( p2m_ram_shared == l3e_p2mt )
                     {
                         MEM_LOG("Unexpected attempt to map shared page.\n");
-                        rc = -EINVAL;
                         break;
                     }
 
                     rc = mod_l3_entry(va, l3e, mfn,
                                       cmd == MMU_PT_UPDATE_PRESERVE_AD, 1, v);
-                    okay = !rc;
                 }
                 break;
 #if CONFIG_PAGING_LEVELS >= 4
@@ -3623,20 +3620,18 @@ long do_mmu_update(
                     else if ( p2m_ram_shared == l4e_p2mt )
                     {
                         MEM_LOG("Unexpected attempt to map shared page.\n");
-                        rc = -EINVAL;
                         break;
                     }
 
                     rc = mod_l4_entry(va, l4e, mfn,
                                       cmd == MMU_PT_UPDATE_PRESERVE_AD, 1, v);
-                    okay = !rc;
                 }
                 break;
 #endif
                 case PGT_writable_page:
                     perfc_incr(writable_mmu_updates);
-                    okay = paging_write_guest_entry(
-                        v, va, req.val, _mfn(mfn));
+                    if ( paging_write_guest_entry(v, va, req.val, _mfn(mfn)) )
+                        rc = 0;
                     break;
                 }
                 page_unlock(page);
@@ -3646,8 +3641,8 @@ long do_mmu_update(
             else if ( get_page_type(page, PGT_writable_page) )
             {
                 perfc_incr(writable_mmu_updates);
-                okay = paging_write_guest_entry(
-                    v, va, req.val, _mfn(mfn));
+                if ( paging_write_guest_entry(v, va, req.val, _mfn(mfn)) )
+                    rc = 0;
                 put_page_type(page);
             }
 
@@ -3668,17 +3663,18 @@ long do_mmu_update(
             if ( unlikely(!get_page_from_pagenr(mfn, pg_owner)) )
             {
                 MEM_LOG("Could not get page for mach->phys update");
+                rc = -EINVAL;
                 break;
             }
 
             if ( unlikely(paging_mode_translate(pg_owner)) )
             {
                 MEM_LOG("Mach-phys update on auto-translate guest");
+                rc = -EINVAL;
                 break;
             }
 
             set_gpfn_from_mfn(mfn, gpfn);
-            okay = 1;
 
             paging_mark_dirty(pg_owner, mfn);
 
@@ -3688,15 +3684,11 @@ long do_mmu_update(
         default:
             MEM_LOG("Invalid page update command %x", cmd);
             rc = -ENOSYS;
-            okay = 0;
             break;
         }
 
-        if ( unlikely(!okay) )
-        {
-            rc = rc ? rc : -EINVAL;
+        if ( unlikely(rc) )
             break;
-        }
 
         guest_handle_add_offset(ureqs, 1);
     }
