|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V5 2/3] x86/mm: allocate logdirty_ranges for altp2ms
This patch is a pre-requisite for the one fixing VGA logdirty
freezes when using altp2m. It only concerns itself with the
ranges allocation / deallocation / initialization part. While
touching the code, I've switched global_logdirty from bool_t
to bool.
Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
---
CC: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
CC: Jan Beulich <jbeulich@xxxxxxxx>
CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CC: Wei Liu <wei.liu2@xxxxxxxxxx>
---
Changes since V4:
- Always call p2m_free_logdirty() in p2m_free_one() (previously
the call was gated on hap_enabled(p2m->domain) && cpu_has_vmx).
---
xen/arch/x86/mm/p2m.c | 74 ++++++++++++++++++++++++++++++++++++-----------
xen/include/asm-x86/p2m.h | 2 +-
2 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 42b9ef4..69536c1 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -59,6 +59,28 @@ static void p2m_nestedp2m_init(struct p2m_domain *p2m)
#endif
}
+static int p2m_init_logdirty(struct p2m_domain *p2m)
+{
+ if ( p2m->logdirty_ranges )
+ return 0;
+
+ p2m->logdirty_ranges = rangeset_new(p2m->domain, "log-dirty",
+ RANGESETF_prettyprint_hex);
+ if ( !p2m->logdirty_ranges )
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void p2m_free_logdirty(struct p2m_domain *p2m)
+{
+ if ( !p2m->logdirty_ranges )
+ return;
+
+ rangeset_destroy(p2m->logdirty_ranges);
+ p2m->logdirty_ranges = NULL;
+}
+
/* Init the datastructures for later use by the p2m code */
static int p2m_initialise(struct domain *d, struct p2m_domain *p2m)
{
@@ -107,6 +129,7 @@ free_p2m:
static void p2m_free_one(struct p2m_domain *p2m)
{
+ p2m_free_logdirty(p2m);
if ( hap_enabled(p2m->domain) && cpu_has_vmx )
ept_p2m_uninit(p2m);
free_cpumask_var(p2m->dirty_cpumask);
@@ -116,19 +139,19 @@ static void p2m_free_one(struct p2m_domain *p2m)
static int p2m_init_hostp2m(struct domain *d)
{
struct p2m_domain *p2m = p2m_init_one(d);
+ int rc;
- if ( p2m )
- {
- p2m->logdirty_ranges = rangeset_new(d, "log-dirty",
- RANGESETF_prettyprint_hex);
- if ( p2m->logdirty_ranges )
- {
- d->arch.p2m = p2m;
- return 0;
- }
+ if ( !p2m )
+ return -ENOMEM;
+
+ rc = p2m_init_logdirty(p2m);
+
+ if ( !rc )
+ d->arch.p2m = p2m;
+ else
p2m_free_one(p2m);
- }
- return -ENOMEM;
+
+ return rc;
}
static void p2m_teardown_hostp2m(struct domain *d)
@@ -138,7 +161,6 @@ static void p2m_teardown_hostp2m(struct domain *d)
if ( p2m )
{
- rangeset_destroy(p2m->logdirty_ranges);
p2m_free_one(p2m);
d->arch.p2m = NULL;
}
@@ -2279,6 +2301,18 @@ void p2m_flush_altp2m(struct domain *d)
altp2m_list_unlock(d);
}
+static int p2m_init_altp2m_logdirty(struct p2m_domain *p2m)
+{
+ struct p2m_domain *hostp2m = p2m_get_hostp2m(p2m->domain);
+ int rc = p2m_init_logdirty(p2m);
+
+ if ( rc )
+ return rc;
+
+ /* The following is really just a rangeset copy. */
+ return rangeset_merge(p2m->logdirty_ranges, hostp2m->logdirty_ranges);
+}
+
int p2m_init_altp2m_by_id(struct domain *d, unsigned int idx)
{
int rc = -EINVAL;
@@ -2290,8 +2324,9 @@ int p2m_init_altp2m_by_id(struct domain *d, unsigned int
idx)
if ( d->arch.altp2m_eptp[idx] == mfn_x(INVALID_MFN) )
{
- p2m_init_altp2m_ept(d, idx);
- rc = 0;
+ rc = p2m_init_altp2m_logdirty(d->arch.altp2m_p2m[idx]);
+ if ( !rc )
+ p2m_init_altp2m_ept(d, idx);
}
altp2m_list_unlock(d);
@@ -2310,9 +2345,13 @@ int p2m_init_next_altp2m(struct domain *d, uint16_t *idx)
if ( d->arch.altp2m_eptp[i] != mfn_x(INVALID_MFN) )
continue;
- p2m_init_altp2m_ept(d, i);
- *idx = i;
- rc = 0;
+ rc = p2m_init_altp2m_logdirty(d->arch.altp2m_p2m[i]);
+
+ if ( !rc )
+ {
+ p2m_init_altp2m_ept(d, i);
+ *idx = i;
+ }
break;
}
@@ -2341,6 +2380,7 @@ int p2m_destroy_altp2m_by_id(struct domain *d, unsigned
int idx)
{
p2m_flush_table(d->arch.altp2m_p2m[idx]);
/* Uninit and reinit ept to force TLB shootdown */
+ p2m_free_logdirty(d->arch.altp2m_p2m[idx]);
ept_p2m_uninit(d->arch.altp2m_p2m[idx]);
ept_p2m_init(d->arch.altp2m_p2m[idx]);
d->arch.altp2m_eptp[idx] = mfn_x(INVALID_MFN);
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index ac33f50..c7f5710 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -222,7 +222,7 @@ struct p2m_domain {
struct rangeset *logdirty_ranges;
/* Host p2m: Global log-dirty mode enabled for the domain. */
- bool_t global_logdirty;
+ bool global_logdirty;
/* Host p2m: when this flag is set, don't flush all the nested-p2m
* tables on every host-p2m change. The setter of this flag
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |