Signed-off-by: Sergej Proskurin <prosku...@sec.in.tum.de> --- Cc: Stefano Stabellini <sstabell...@kernel.org> Cc: Julien Grall <julien.gr...@arm.com> --- v3: Extended the function "altp2m_switch_domain_altp2m_by_id" so that if the guest domain indirectly calles this function, the current vcpu also changes the altp2m view without performing an explicit context switch.
Exchanged the check "altp2m_vttbr[idx] == INVALID_VTTBR" for "altp2m_p2m[idx] == NULL" in "altp2m_switch_domain_altp2m_by_id". v4: ARM supports an external-only interface to the altp2m subsystem, i.e, the guest does not have access to altp2m. Thus, we don't have to consider that the current vcpu will not switch its context in the function "p2m_restore_state". For this reason, we do not check for whether we are working on the current vcpu in the function altp2m_switch_domain_altp2m_by_id. If the current guest access restriction to the altp2m subsystem should change in the future, we have to update VTTBR_EL2 directly. Cosmetic fixes. --- xen/arch/arm/altp2m.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/hvm.c | 2 +- xen/include/asm-arm/altp2m.h | 4 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/altp2m.c b/xen/arch/arm/altp2m.c index 1128e1af16..9a2cf5a018 100644 --- a/xen/arch/arm/altp2m.c +++ b/xen/arch/arm/altp2m.c @@ -32,6 +32,51 @@ struct p2m_domain *altp2m_get_altp2m(struct vcpu *v) return v->domain->arch.altp2m_p2m[idx]; } +int altp2m_switch_domain_altp2m_by_id(struct domain *d, unsigned int idx) +{ + struct vcpu *v; + int rc = -EINVAL; + + if ( idx >= MAX_ALTP2M ) + return rc; + + domain_pause_except_self(d); + + altp2m_lock(d); + + if ( d->arch.altp2m_p2m[idx] != NULL ) + { + for_each_vcpu( d, v ) + { + if ( idx == v->arch.ap2m_idx ) + continue; + + atomic_dec(&altp2m_get_altp2m(v)->active_vcpus); + v->arch.ap2m_idx = idx; + atomic_inc(&altp2m_get_altp2m(v)->active_vcpus); + + /* + * ARM supports an external-only interface to the altp2m subsystem, + * i.e, the guest does not have access to altp2m. Thus, we don't + * have to consider that the current vcpu will not switch its + * context in the function "p2m_restore_state". + * + * XXX: If the current guest access restriction to the altp2m + * subsystem should change in the future, we have to update + * VTTBR_EL2 directly. + */ + } + + rc = 0; + } + + altp2m_unlock(d); + + domain_unpause_except_self(d); + + return rc; +} + static void altp2m_vcpu_reset(struct vcpu *v) { v->arch.ap2m_idx = INVALID_ALTP2M; diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c index 4bf2f28a1a..9bddc7e17e 100644 --- a/xen/arch/arm/hvm.c +++ b/xen/arch/arm/hvm.c @@ -135,7 +135,7 @@ static int do_altp2m_op(XEN_GUEST_HANDLE_PARAM(void) arg) break; case HVMOP_altp2m_switch_p2m: - rc = -EOPNOTSUPP; + rc = altp2m_switch_domain_altp2m_by_id(d, a.u.view.view); break; case HVMOP_altp2m_set_mem_access: diff --git a/xen/include/asm-arm/altp2m.h b/xen/include/asm-arm/altp2m.h index 778c6c4f12..d59f704489 100644 --- a/xen/include/asm-arm/altp2m.h +++ b/xen/include/asm-arm/altp2m.h @@ -49,6 +49,10 @@ void altp2m_vcpu_destroy(struct vcpu *v); /* Get current alternate p2m table. */ struct p2m_domain *altp2m_get_altp2m(struct vcpu *v); +/* Switch alternate p2m for entire domain */ +int altp2m_switch_domain_altp2m_by_id(struct domain *d, + unsigned int idx); + /* Make a specific alternate p2m valid. */ int altp2m_init_by_id(struct domain *d, unsigned int idx); -- 2.13.3 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel