[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 08/13] x86/altp2m: add control of suppress_ve.
The existing ept_set_entry() and ept_get_entry() routines are extended to optionally set/get suppress_ve and renamed. New ept_set_entry() and ept_get_entry() routines are provided as wrappers, where set preserves suppress_ve for an existing entry and sets it for a new entry. Additional function pointers are added to p2m_domain to allow direct access to the extended routines. Signed-off-by: Ed White <edmund.h.white@xxxxxxxxx> --- xen/arch/x86/mm/p2m-ept.c | 40 +++++++++++++++++++++++++++++++++------- xen/include/asm-x86/p2m.h | 13 +++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index 4111795..bcb9381 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -650,14 +650,15 @@ bool_t ept_handle_misconfig(uint64_t gpa) } /* - * ept_set_entry() computes 'need_modify_vtd_table' for itself, + * _ept_set_entry() computes 'need_modify_vtd_table' for itself, * by observing whether any gfn->mfn translations are modified. * * Returns: 0 for success, -errno for failure */ static int -ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, - unsigned int order, p2m_type_t p2mt, p2m_access_t p2ma) +_ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, + unsigned int order, p2m_type_t p2mt, p2m_access_t p2ma, + int sve) { ept_entry_t *table, *ept_entry = NULL; unsigned long gfn_remainder = gfn; @@ -803,7 +804,11 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, ept_p2m_type_to_flags(p2m, &new_entry, p2mt, p2ma); } - new_entry.suppress_ve = 1; + if ( sve != -1 ) + new_entry.suppress_ve = !!sve; + else + new_entry.suppress_ve = is_epte_valid(&old_entry) ? + old_entry.suppress_ve : 1; rc = atomic_write_ept_entry(ept_entry, new_entry, target); if ( unlikely(rc) ) @@ -848,10 +853,18 @@ out: return rc; } +static int +ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, + unsigned int order, p2m_type_t p2mt, p2m_access_t p2ma) +{ + return _ept_set_entry(p2m, gfn, mfn, order, p2mt, p2ma, -1); +} + /* Read ept p2m entries */ -static mfn_t ept_get_entry(struct p2m_domain *p2m, - unsigned long gfn, p2m_type_t *t, p2m_access_t* a, - p2m_query_t q, unsigned int *page_order) +static mfn_t _ept_get_entry(struct p2m_domain *p2m, + unsigned long gfn, p2m_type_t *t, p2m_access_t* a, + p2m_query_t q, unsigned int *page_order, + bool_t *sve) { ept_entry_t *table = map_domain_page(pagetable_get_pfn(p2m_get_pagetable(p2m))); unsigned long gfn_remainder = gfn; @@ -865,6 +878,8 @@ static mfn_t ept_get_entry(struct p2m_domain *p2m, *t = p2m_mmio_dm; *a = p2m_access_n; + if ( sve ) + *sve = 1; /* This pfn is higher than the highest the p2m map currently holds */ if ( gfn > p2m->max_mapped_pfn ) @@ -930,6 +945,8 @@ static mfn_t ept_get_entry(struct p2m_domain *p2m, else *t = ept_entry->sa_p2mt; *a = ept_entry->access; + if ( sve ) + *sve = ept_entry->suppress_ve; mfn = _mfn(ept_entry->mfn); if ( i ) @@ -953,6 +970,13 @@ out: return mfn; } +static mfn_t ept_get_entry(struct p2m_domain *p2m, + unsigned long gfn, p2m_type_t *t, p2m_access_t* a, + p2m_query_t q, unsigned int *page_order) +{ + return _ept_get_entry(p2m, gfn, t, a, q, page_order, NULL); +} + void ept_walk_table(struct domain *d, unsigned long gfn) { struct p2m_domain *p2m = p2m_get_hostp2m(d); @@ -1131,6 +1155,8 @@ int ept_p2m_init(struct p2m_domain *p2m) p2m->set_entry = ept_set_entry; p2m->get_entry = ept_get_entry; + p2m->set_entry_full = _ept_set_entry; + p2m->get_entry_full = _ept_get_entry; p2m->change_entry_type_global = ept_change_entry_type_global; p2m->change_entry_type_range = ept_change_entry_type_range; p2m->memory_type_changed = ept_memory_type_changed; diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 079a298..bf5e5cb 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -237,6 +237,19 @@ struct p2m_domain { p2m_access_t *p2ma, p2m_query_t q, unsigned int *page_order); + int (*set_entry_full)(struct p2m_domain *p2m, + unsigned long gfn, + mfn_t mfn, unsigned int page_order, + p2m_type_t p2mt, + p2m_access_t p2ma, + int sve); + mfn_t (*get_entry_full)(struct p2m_domain *p2m, + unsigned long gfn, + p2m_type_t *p2mt, + p2m_access_t *p2ma, + p2m_query_t q, + unsigned int *page_order, + bool_t *sve); void (*enable_hardware_log_dirty)(struct p2m_domain *p2m); void (*disable_hardware_log_dirty)(struct p2m_domain *p2m); void (*flush_hardware_cached_dirty)(struct p2m_domain *p2m); -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |