|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 16/38] arm/p2m: Add HVMOP_altp2m_set_domain_state
The HVMOP_altp2m_set_domain_state allows to activate altp2m on a
specific domain. This commit adopts the x86
HVMOP_altp2m_set_domain_state implementation.
Signed-off-by: Sergej Proskurin <proskurin@xxxxxxxxxxxxx>
---
Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>
Cc: Julien Grall <julien.grall@xxxxxxx>
---
v2: Dynamically allocate memory for altp2m views only when needed.
Move altp2m related helpers to altp2m.c.
p2m_flush_tlb is made publicly accessible.
v3: Cosmetic fixes.
Removed call to "p2m_alloc_table" in "altp2m_init_helper" as the
entire p2m allocation is now done within the function
"p2m_init_one". The same applies to the call of the function
"p2m_flush_tlb" from "p2m_init_one".
Removed the "altp2m_enabled" check in HVMOP_altp2m_set_domain_state
case as it has been moved in front of the switch statement in
"do_altp2m_op".
Changed the order of setting the new altp2m state (depending on
setting/resetting the state) in HVMOP_altp2m_set_domain_state case.
Removed the call to altp2m_vcpu_reset from altp2m_vcpu_initialise,
as the p2midx is set right after the call to 0, representing the
default view.
Moved the define "vcpu_altp2m" from domain.h to altp2m.h to avoid
defining altp2m-related functionality in multiple files. Also renamed
"vcpu_altp2m" to "altp2m_vcpu".
Declared the function "p2m_flush_tlb" as static, as it is not called
from altp2m.h anymore.
Exported the function "altp2m_get_altp2m" in altp2m.h.
Exchanged the check "altp2m_vttbr[idx] == INVALID_VTTBR" for
"altp2m_p2m[idx] == NULL" in "altp2m_init_by_id".
Set the field p2m->access_required to false by default.
---
xen/arch/arm/altp2m.c | 102 +++++++++++++++++++++++++++++++++++++++++++
xen/arch/arm/hvm.c | 34 ++++++++++++++-
xen/include/asm-arm/altp2m.h | 14 ++++++
xen/include/asm-arm/domain.h | 7 +++
xen/include/asm-arm/p2m.h | 5 +++
5 files changed, 161 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/altp2m.c b/xen/arch/arm/altp2m.c
index 02cffd7..02a52ec 100644
--- a/xen/arch/arm/altp2m.c
+++ b/xen/arch/arm/altp2m.c
@@ -20,6 +20,108 @@
#include <asm/p2m.h>
#include <asm/altp2m.h>
+struct p2m_domain *altp2m_get_altp2m(struct vcpu *v)
+{
+ unsigned int index = altp2m_vcpu(v).p2midx;
+
+ if ( index == INVALID_ALTP2M )
+ return NULL;
+
+ BUG_ON(index >= MAX_ALTP2M);
+
+ return v->domain->arch.altp2m_p2m[index];
+}
+
+static void altp2m_vcpu_reset(struct vcpu *v)
+{
+ struct altp2mvcpu *av = &altp2m_vcpu(v);
+
+ av->p2midx = INVALID_ALTP2M;
+}
+
+void altp2m_vcpu_initialise(struct vcpu *v)
+{
+ if ( v != current )
+ vcpu_pause(v);
+
+ altp2m_vcpu(v).p2midx = 0;
+ atomic_inc(&altp2m_get_altp2m(v)->active_vcpus);
+
+ if ( v != current )
+ vcpu_unpause(v);
+}
+
+void altp2m_vcpu_destroy(struct vcpu *v)
+{
+ struct p2m_domain *p2m;
+
+ if ( v != current )
+ vcpu_pause(v);
+
+ if ( (p2m = altp2m_get_altp2m(v)) )
+ atomic_dec(&p2m->active_vcpus);
+
+ altp2m_vcpu_reset(v);
+
+ if ( v != current )
+ vcpu_unpause(v);
+}
+
+static int altp2m_init_helper(struct domain *d, unsigned int idx)
+{
+ int rc;
+ struct p2m_domain *p2m = d->arch.altp2m_p2m[idx];
+
+ ASSERT(p2m == NULL);
+
+ /* Allocate a new, zeroed altp2m view. */
+ p2m = xzalloc(struct p2m_domain);
+ if ( p2m == NULL)
+ {
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ p2m->p2m_class = p2m_alternate;
+
+ /* Initialize the new altp2m view. */
+ rc = p2m_init_one(d, p2m);
+ if ( rc )
+ goto err;
+
+ p2m->access_required = false;
+ _atomic_set(&p2m->active_vcpus, 0);
+
+ d->arch.altp2m_p2m[idx] = p2m;
+
+ return rc;
+
+err:
+ if ( p2m )
+ xfree(p2m);
+
+ d->arch.altp2m_p2m[idx] = NULL;
+
+ return rc;
+}
+
+int altp2m_init_by_id(struct domain *d, unsigned int idx)
+{
+ int rc = -EINVAL;
+
+ if ( idx >= MAX_ALTP2M )
+ return rc;
+
+ altp2m_lock(d);
+
+ if ( d->arch.altp2m_p2m[idx] == NULL )
+ rc = altp2m_init_helper(d, idx);
+
+ altp2m_unlock(d);
+
+ return rc;
+}
+
int altp2m_init(struct domain *d)
{
unsigned int i;
diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c
index 180154e..c69da36 100644
--- a/xen/arch/arm/hvm.c
+++ b/xen/arch/arm/hvm.c
@@ -83,8 +83,40 @@ static int do_altp2m_op(XEN_GUEST_HANDLE_PARAM(void) arg)
break;
case HVMOP_altp2m_set_domain_state:
- rc = -EOPNOTSUPP;
+ {
+ struct vcpu *v;
+ bool_t ostate, nstate;
+
+ ostate = d->arch.altp2m_active;
+ nstate = !!a.u.domain_state.state;
+
+ /* If the alternate p2m state has changed, handle appropriately */
+ if ( (nstate != ostate) &&
+ (ostate || !(rc = altp2m_init_by_id(d, 0))) )
+ {
+ for_each_vcpu( d, v )
+ {
+ if ( !ostate )
+ {
+ altp2m_vcpu_initialise(v);
+ d->arch.altp2m_active = nstate;
+ }
+ else
+ {
+ d->arch.altp2m_active = nstate;
+ altp2m_vcpu_destroy(v);
+ }
+ }
+
+ /*
+ * The altp2m_active state has been deactivated. It is now safe to
+ * flush all altp2m views -- including altp2m[0].
+ */
+ if ( ostate )
+ altp2m_flush(d);
+ }
break;
+ }
case HVMOP_altp2m_vcpu_enable_notify:
rc = -EOPNOTSUPP;
diff --git a/xen/include/asm-arm/altp2m.h b/xen/include/asm-arm/altp2m.h
index 4c15b75..f604ffd 100644
--- a/xen/include/asm-arm/altp2m.h
+++ b/xen/include/asm-arm/altp2m.h
@@ -22,6 +22,10 @@
#include <xen/sched.h>
+#define INVALID_ALTP2M 0xffff
+
+#define altp2m_vcpu(v) ((v)->arch.avcpu)
+
#define altp2m_lock(d) spin_lock(&(d)->arch.altp2m_lock)
#define altp2m_unlock(d) spin_unlock(&(d)->arch.altp2m_lock)
@@ -42,6 +46,16 @@ static inline uint16_t altp2m_vcpu_idx(const struct vcpu *v)
int altp2m_init(struct domain *d);
void altp2m_teardown(struct domain *d);
+void altp2m_vcpu_initialise(struct vcpu *v);
+void altp2m_vcpu_destroy(struct vcpu *v);
+
+/* Get current alternate p2m table. */
+struct p2m_domain *altp2m_get_altp2m(struct vcpu *v);
+
+/* Make a specific alternate p2m valid. */
+int altp2m_init_by_id(struct domain *d,
+ unsigned int idx);
+
/* Flush all the alternate p2m's for a domain. */
void altp2m_flush(struct domain *d);
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index a4e4762..99aa3bc 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -137,6 +137,10 @@ struct arch_domain
struct p2m_domain *altp2m_p2m[MAX_ALTP2M];
} __cacheline_aligned;
+struct altp2mvcpu {
+ uint16_t p2midx; /* alternate p2m index */
+};
+
struct arch_vcpu
{
struct {
@@ -266,6 +270,9 @@ struct arch_vcpu
struct vtimer phys_timer;
struct vtimer virt_timer;
bool_t vtimer_initialized;
+
+ /* Alternate p2m context */
+ struct altp2mvcpu avcpu;
} __cacheline_aligned;
void vcpu_show_execution_state(struct vcpu *);
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index de0c90a..978125a 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -9,6 +9,8 @@
#include <xen/p2m-common.h>
#include <public/memory.h>
+#include <asm/atomic.h>
+
#define MAX_ALTP2M 10 /* ARM might contain an arbitrary number of
altp2m views. */
#define paddr_bits PADDR_BITS
@@ -102,6 +104,9 @@ struct p2m_domain {
*/
struct radix_tree_root mem_access_settings;
+ /* Alternate p2m: count of vcpu's currently using this p2m. */
+ atomic_t active_vcpus;
+
/* Choose between: host/alternate. */
p2m_class_t p2m_class;
--
2.9.0
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |