|
[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 |