[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 12/14] xen: vmx: Support for clear EPT SPP write Protect bit
From: Zhang Yi Z <yi.z.zhang@xxxxxxxxxxxxxxx> This is a implement of clear the Write protect bit. EPT SPP Write Protect bit will remove when we set all the 32 sub-pages is writeable. We should also update the EPT page frame w bit as the whole page is writeable. Signed-off-by: Zhang Yi Z <yi.z.zhang@xxxxxxxxx> --- xen/arch/x86/mm/mem_access.c | 12 +++++++++--- xen/arch/x86/mm/p2m-ept.c | 17 +++++++++++++---- xen/include/asm-x86/p2m.h | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c index fdedc4a..fddb6e3 100644 --- a/xen/arch/x86/mm/mem_access.c +++ b/xen/arch/x86/mm/mem_access.c @@ -466,7 +466,7 @@ int p2m_get_mem_access(struct domain *d, gfn_t gfn, xenmem_access_t *access) return _p2m_get_mem_access(p2m, gfn, access); } -int p2m_set_mem_spp_wp(struct domain *d, gfn_t gfn) +int p2m_set_mem_spp_wp(struct domain *d, gfn_t gfn, bool spp, bool w) { struct p2m_domain *p2m = p2m_get_hostp2m(d); mfn_t mfn; @@ -482,8 +482,9 @@ int p2m_set_mem_spp_wp(struct domain *d, gfn_t gfn) rc = -1; goto unlock_exit; } + if ( p2m->update_ept_spp_wp ) - rc = p2m->update_ept_spp_wp(p2m, gfn_l); + rc = p2m->update_ept_spp_wp(p2m, gfn_l, spp, w); unlock_exit: p2m_unlock(p2m); @@ -528,7 +529,12 @@ int p2m_set_spp_page_st(struct domain *d, gfn_t gfn, uint32_t access_map) int p2m_set_subpage(struct domain *d, gfn_t gfn, uint32_t access_map) { int ret; - ret = p2m_set_mem_spp_wp(d, gfn); + bool w, spp = 0; + + w = !~access_map; + spp = !w; + printk("SPP: Set subpage spp=%d, is write:%d\n", spp, w); + ret = p2m_set_mem_spp_wp(d, gfn, spp, w); if ( ret < 0 ) { printk("SPP: Set subpage ept wp failed!! %x\n", ret); diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index 065beb9..55c3ded 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -46,6 +46,11 @@ static inline bool_t is_epte_valid(ept_entry_t *e) return ((e->epte & ~(1ul << 63)) != 0 && e->sa_p2mt != p2m_invalid); } +static inline bool_t is_epte_spp_wp(ept_entry_t *e) +{ + return ( e->spp && !(e->w) && (e->access == p2m_access_spp) ); +} + /* returns : 0 for success, -errno otherwise */ static int atomic_write_ept_entry(ept_entry_t *entryptr, ept_entry_t new, int level) @@ -725,7 +730,7 @@ bool_t ept_handle_misconfig(uint64_t gpa) } static int -ept_spp_update_wp(struct p2m_domain *p2m, unsigned long gfn) +ept_spp_update_wp(struct p2m_domain *p2m, unsigned long gfn, bool spp, bool w) { ept_entry_t *table, *ept_entry = NULL; unsigned long gfn_remainder = gfn; @@ -754,12 +759,16 @@ ept_spp_update_wp(struct p2m_domain *p2m, unsigned long gfn) goto out; } + if ( is_epte_spp_wp(ept_entry) && spp ) + goto sync_out; + new_entry = atomic_read_ept_entry(ept_entry); - new_entry.spp = 1; - new_entry.w = 0; - new_entry.access = p2m_access_spp; + new_entry.spp = spp; + new_entry.w = w; + new_entry.access = spp? p2m_access_spp:p2m_access_n; write_atomic(&(ept_entry->epte), new_entry.epte); +sync_out: ept_sync_domain(p2m); rc = 0; out: diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index b94ebb2..36d1cc9 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -267,7 +267,7 @@ struct p2m_domain { l1_pgentry_t new, unsigned int level); long (*audit_p2m)(struct p2m_domain *p2m); int (*update_ept_spp_wp)(struct p2m_domain *p2m, - unsigned long gfn); + unsigned long gfn, bool spp, bool w); int (*spp_set_entry)(struct p2m_domain *p2m, unsigned long gfn, u64 access); -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |