2011-05-03 19:51:18 +02:00
|
|
|
# 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>
|
|
|
|
|
2012-08-10 23:38:41 +02:00
|
|
|
--- a/xen/arch/x86/mm.c
|
|
|
|
+++ b/xen/arch/x86/mm.c
|
|
|
|
@@ -1847,16 +1847,16 @@ static int mod_l2_entry(l2_pgentry_t *pl
|
2011-05-03 19:51:18 +02:00
|
|
|
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 )
|
|
|
|
{
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -1864,32 +1864,33 @@ static int mod_l2_entry(l2_pgentry_t *pl
|
2011-05-03 19:51:18 +02:00
|
|
|
{
|
|
|
|
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);
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3369,7 +3370,7 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
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;
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3436,7 +3437,6 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cmd = req.ptr & (sizeof(l1_pgentry_t)-1);
|
|
|
|
- okay = 0;
|
|
|
|
|
|
|
|
switch ( cmd )
|
|
|
|
{
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3453,6 +3453,7 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
rc = xsm_mmu_normal_update(d, pg_owner, req.val);
|
|
|
|
if ( rc )
|
|
|
|
break;
|
|
|
|
+ rc = -EINVAL;
|
|
|
|
|
|
|
|
req.ptr -= cmd;
|
|
|
|
gmfn = req.ptr >> PAGE_SHIFT;
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3523,7 +3524,6 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
rc = mod_l1_entry(va, l1e, mfn,
|
|
|
|
cmd == MMU_PT_UPDATE_PRESERVE_AD, v,
|
|
|
|
pg_owner);
|
|
|
|
- okay = !rc;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PGT_l2_page_table:
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3547,13 +3547,12 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
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:
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3577,13 +3576,11 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
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
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3609,20 +3606,18 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
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);
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3632,8 +3627,8 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3654,17 +3649,18 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
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);
|
|
|
|
|
2012-08-10 23:38:41 +02:00
|
|
|
@@ -3674,15 +3670,11 @@ int do_mmu_update(
|
2011-05-03 19:51:18 +02:00
|
|
|
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);
|
|
|
|
}
|