xen/xsm: Fix xsm_mmu_* and xsm_update_va_mapping hooks
RFC PATCH 1/1 xen/xsm: Fix xsm_mmu_* and xsm_update_va_mapping hooks
This isn't targeted at 4.1 given the freeze, but is instead just a RFC. This is an attempt to properly fix the hypervisor crash previously described in
http://marc.info/?l=xen-devel&m=128396289707362&w=2
In looking into this issue, I think the proper fix is to move the xsm_mmu_* and xsm_update_va_mapping hook calls later in the callers, after more validation has been performed and the page_info struct is readily available, and pass the page_info to the hooks. This patch moves the xsm_mmu_normal_update, xsm_mmu_machphys_update and xsm_update_va_mapping hook calls accordingly, and updates their interfaces and hook function implementations. This appears to resolve the crashes for me. However, as I am not overly familiar with this area of code, I'd appreciate any feedback or suggestions for improvement. Thanks.
---
xen/arch/x86/mm.c | 30 ++++++++++++++++++------------ xen/include/xsm/xsm.h | 28 +++++++++++++++------------- xen/xsm/dummy.c | 11 ++++++----- xen/xsm/flask/hooks.c | 41 ++++++++--------------------------------- 4 files changed, 47 insertions(+), 63 deletions(-)
xen/arch/x86/mm.c +18 -12
@@ -3416,10 +3416,6 @@ {p2m_type_t p2mt; - rc =xsm_mmu_normal_update (d, pg_owner, req.val); -if ( rc ) -break ; - req.ptr -= cmd; gmfn = req.ptr >>PAGE_SHIFT ; mfn =mfn_x (gfn_to_mfn (p2m_get_hostp2m (pt_owner), gmfn, &p2mt));
@@ -3445,6 +3441,13 @@ (unsigned long)(req.ptr & ~PAGE_MASK)); page =mfn_to_page (mfn); + rc =xsm_mmu_normal_update (d, req.val, page); +if ( rc ) { +unmap_domain_page_with_cache (va, &mapcache); +put_page (page); +break ; + } +if (page_lock (page) ) { switch ( page->u.inuse.type_info & PGT_type_mask )
@@ -3612,10 +3615,6 @@ mfn = req.ptr >>PAGE_SHIFT ; gpfn = req.val; - rc =xsm_mmu_machphys_update (d, mfn); -if ( rc ) -break ; -if (unlikely (!get_page_from_pagenr (mfn, pg_owner)) ) {MEM_LOG ("Could not get page for mach->phys update" );
@@ -3628,6 +3627,10 @@break ; } + rc =xsm_mmu_machphys_update (d,mfn_to_page (mfn)); +if ( rc ) +break ; +set_gpfn_from_mfn (mfn, gpfn); okay =1 ;
@@ -4247,10 +4250,6 @@perfc_incr (calls_to_update_va); - rc =xsm_update_va_mapping (d, pg_owner, val); -if ( rc ) -return rc; - rc = -EINVAL ; pl1e =guest_map_l1e (v, va, &gl1mfn);if (unlikely (!pl1e || !get_page_from_pagenr (gl1mfn, d)) )
@@ -4270,6 +4269,13 @@ goto out; } + rc =xsm_update_va_mapping (d, val, gl1pg); +if ( rc ) { +page_unlock (gl1pg); +put_page (gl1pg); + goto out; + } + rc =mod_l1_entry (pl1e, val, gl1mfn,0 , v, pg_owner) ?0 : -EINVAL ;page_unlock (gl1pg);
xen/include/xsm/xsm.h +15 -13
@@ -136,11 +136,12 @@int (*getidletime) (void );int (*machine_memory_map) (void );int (*domain_memory_map) (struct domain *d); -int (*mmu_normal_update) (struct domain *d,struct domain *f, -intpte_t fpte); -int (*mmu_machphys_update) (struct domain *d,unsigned long mfn); -int (*update_va_mapping) (struct domain *d,struct domain *f, -l1_pgentry_t pte); +int (*mmu_normal_update) (struct domain *d, +intpte_t fpte,struct page_info *page); +int (*mmu_machphys_update) (struct domain *d,struct page_info *page); +int (*update_va_mapping) (struct domain *d, +l1_pgentry_t pte, +struct page_info *page);int (*add_to_physmap) (struct domain *d1,struct domain *d2);int (*sendtrigger) (struct domain *d);int (*test_assign_device) (uint32_t machine_bdf);
@@ -567,21 +568,22 @@return xsm_call (domain_memory_map (d)); } -static inline int xsm_mmu_normal_update (struct domain *d,struct domain *f, -intpte_t fpte) +static inline int xsm_mmu_normal_update (struct domain *d, +intpte_t fpte,struct page_info *page) { -return xsm_call (mmu_normal_update (d, f, fpte)); +return xsm_call (mmu_normal_update (d, fpte, page)); } -static inline int xsm_mmu_machphys_update (struct domain *d,unsigned long mfn) +static inline int xsm_mmu_machphys_update (struct domain *d,struct page_info *page) { -return xsm_call (mmu_machphys_update (d, mfn)); +return xsm_call (mmu_machphys_update (d, page)); } -static inline int xsm_update_va_mapping (struct domain *d,struct domain *f, -l1_pgentry_t pte) +static inline int xsm_update_va_mapping (struct domain *d, +l1_pgentry_t pte, +struct page_info *page) { -return xsm_call (update_va_mapping (d, f, pte)); +return xsm_call (update_va_mapping (d, pte, page)); }static inline int xsm_add_to_physmap (struct domain *d1,struct domain *d2)
xen/xsm/dummy.c +6 -5
@@ -405,19 +405,20 @@return 0 ; } -static int dummy_mmu_normal_update (struct domain *d,struct domain *f, -intpte_t fpte) +static int dummy_mmu_normal_update (struct domain *d, +intpte_t fpte,struct page_info *page) {return 0 ; } -static int dummy_mmu_machphys_update (struct domain *d,unsigned long mfn) +static int dummy_mmu_machphys_update (struct domain *d,struct page_info *page) {return 0 ; } -static int dummy_update_va_mapping (struct domain *d,struct domain *f, -l1_pgentry_t pte) +static int dummy_update_va_mapping (struct domain *d, +l1_pgentry_t pte, +struct page_info *page) {return 0 ; }
xen/xsm/flask/hooks.c +8 -33
88 lines not on this page · raw message
Signature · 2 lines
Stephen Smalley National Security Agency