[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 05/18] arm/altp2m: 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. The function p2m_flush_altp2m is currently implemented in form of a stub. Signed-off-by: Sergej Proskurin <proskurin@xxxxxxxxxxxxx> --- Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx> Cc: Julien Grall <julien.grall@xxxxxxx> --- xen/arch/arm/Makefile | 1 + xen/arch/arm/altp2m.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/hvm.c | 30 ++++++++++++++++++- xen/arch/arm/p2m.c | 46 ++++++++++++++++++++++++++++++ xen/include/asm-arm/altp2m.h | 20 ++----------- xen/include/asm-arm/domain.h | 9 ++++++ xen/include/asm-arm/p2m.h | 19 +++++++++++++ 7 files changed, 175 insertions(+), 18 deletions(-) create mode 100644 xen/arch/arm/altp2m.c diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 9e38da3..abd6f1a 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -41,6 +41,7 @@ obj-y += decode.o obj-y += processor.o obj-y += smc.o obj-$(CONFIG_LIVEPATCH) += livepatch.o +obj-y += altp2m.o #obj-bin-y += ....o diff --git a/xen/arch/arm/altp2m.c b/xen/arch/arm/altp2m.c new file mode 100644 index 0000000..1d2505f --- /dev/null +++ b/xen/arch/arm/altp2m.c @@ -0,0 +1,68 @@ +/* + * arch/arm/altp2m.c + * + * Alternate p2m + * Copyright (c) 2016 Sergej Proskurin <proskurin@xxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; If not, see <http://www.gnu.org/licenses/>. + */ + +#include <asm/p2m.h> +#include <asm/altp2m.h> +#include <asm/hvm/hvm.h> + +void altp2m_vcpu_reset(struct vcpu *v) +{ + struct altp2mvcpu *av = &vcpu_altp2m(v); + + av->p2midx = INVALID_ALTP2M; +} + +void altp2m_vcpu_initialise(struct vcpu *v) +{ + if ( v != current ) + vcpu_pause(v); + + altp2m_vcpu_reset(v); + vcpu_altp2m(v).p2midx = 0; + atomic_inc(&p2m_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 = p2m_get_altp2m(v)) ) + atomic_dec(&p2m->active_vcpus); + + altp2m_vcpu_reset(v); + + if ( v != current ) + vcpu_unpause(v); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c index 8e8e0f7..cb90a55 100644 --- a/xen/arch/arm/hvm.c +++ b/xen/arch/arm/hvm.c @@ -104,8 +104,36 @@ 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; + + if ( !d->arch.hvm_domain.params[HVM_PARAM_ALTP2M] ) + { + rc = -EINVAL; + break; + } + + ostate = d->arch.altp2m_active; + d->arch.altp2m_active = !!a.u.domain_state.state; + + /* If the alternate p2m state has changed, handle appropriately */ + if ( d->arch.altp2m_active != ostate && + (ostate || !(rc = p2m_init_altp2m_by_id(d, 0))) ) + { + for_each_vcpu( d, v ) + { + if ( !ostate ) + altp2m_vcpu_initialise(v); + else + altp2m_vcpu_destroy(v); + } + + if ( ostate ) + p2m_flush_altp2m(d); + } break; + } case HVMOP_altp2m_vcpu_enable_notify: rc = -EOPNOTSUPP; diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index e72ca7a..4a745fd 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -2064,6 +2064,52 @@ int p2m_get_mem_access(struct domain *d, gfn_t gfn, return ret; } +struct p2m_domain *p2m_get_altp2m(struct vcpu *v) +{ + unsigned int index = vcpu_altp2m(v).p2midx; + + if ( index == INVALID_ALTP2M ) + return NULL; + + BUG_ON(index >= MAX_ALTP2M); + + return v->domain->arch.altp2m_p2m[index]; +} + +static void p2m_init_altp2m_helper(struct domain *d, unsigned int i) +{ + struct p2m_domain *p2m = d->arch.altp2m_p2m[i]; + struct vttbr_data *vttbr = &p2m->vttbr; + + p2m->lowest_mapped_gfn = INVALID_GFN; + p2m->max_mapped_gfn = 0; + + vttbr->vttbr_baddr = page_to_maddr(p2m->root); + vttbr->vttbr_vmid = p2m->vmid; + + d->arch.altp2m_vttbr[i] = vttbr->vttbr; +} + +int p2m_init_altp2m_by_id(struct domain *d, unsigned int idx) +{ + int rc = -EINVAL; + + if ( idx >= MAX_ALTP2M ) + return rc; + + altp2m_lock(d); + + if ( d->arch.altp2m_vttbr[idx] == INVALID_MFN ) + { + p2m_init_altp2m_helper(d, idx); + rc = 0; + } + + altp2m_unlock(d); + + return rc; +} + /* * Local variables: * mode: C diff --git a/xen/include/asm-arm/altp2m.h b/xen/include/asm-arm/altp2m.h index 16ae9d6..ec4aa09 100644 --- a/xen/include/asm-arm/altp2m.h +++ b/xen/include/asm-arm/altp2m.h @@ -36,22 +36,8 @@ static inline uint16_t altp2m_vcpu_idx(const struct vcpu *v) return 0; } -static inline void altp2m_vcpu_initialise(struct vcpu *v) -{ - /* Not implemented on ARM, should not be reached. */ - BUG(); -} - -static inline void altp2m_vcpu_destroy(struct vcpu *v) -{ - /* Not implemented on ARM, should not be reached. */ - BUG(); -} - -static inline void altp2m_vcpu_reset(struct vcpu *v) -{ - /* Not implemented on ARM, should not be reached. */ - BUG(); -} +void altp2m_vcpu_initialise(struct vcpu *v); +void altp2m_vcpu_destroy(struct vcpu *v); +void altp2m_vcpu_reset(struct vcpu *v); #endif /* __ASM_ARM_ALTP2M_H */ diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 6b9770f..8bcd618 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -138,6 +138,12 @@ struct arch_domain uint64_t altp2m_vttbr[MAX_ALTP2M]; } __cacheline_aligned; +struct altp2mvcpu { + uint16_t p2midx; /* alternate p2m index */ +}; + +#define vcpu_altp2m(v) ((v)->arch.avcpu) + struct arch_vcpu { struct { @@ -267,6 +273,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 a78d547..8ee78e0 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -121,6 +121,25 @@ void p2m_altp2m_check(struct vcpu *v, uint16_t idx) /* Not supported on ARM. */ } +/* + * Alternate p2m: shadow p2m tables used for alternate memory views. + */ + +#define altp2m_lock(d) spin_lock(&(d)->arch.altp2m_lock) +#define altp2m_unlock(d) spin_unlock(&(d)->arch.altp2m_lock) + +/* Get current alternate p2m table */ +struct p2m_domain *p2m_get_altp2m(struct vcpu *v); + +/* Flush all the alternate p2m's for a domain */ +static inline void p2m_flush_altp2m(struct domain *d) +{ + /* Not supported on ARM. */ +} + +/* Make a specific alternate p2m valid */ +int p2m_init_altp2m_by_id(struct domain *d, unsigned int idx); + #define p2m_is_foreign(_t) ((_t) == p2m_map_foreign) #define p2m_is_ram(_t) ((_t) == p2m_ram_rw || (_t) == p2m_ram_ro) -- 2.8.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |