Add the per-domain and per-vCPU state needed before Realm objects are created: Realm state, RMI feature snapshots, REC bookkeeping and RecRun lifetime.
Signed-off-by: Koichiro Den <[email protected]> --- xen/arch/arm/cca/Makefile | 1 + xen/arch/arm/cca/state.c | 68 +++++++++++++++++++++++++++++++ xen/arch/arm/domain.c | 14 +++++++ xen/arch/arm/include/asm/cca.h | 42 +++++++++++++++++++ xen/arch/arm/include/asm/domain.h | 16 ++++++++ 5 files changed, 141 insertions(+) create mode 100644 xen/arch/arm/cca/state.c create mode 100644 xen/arch/arm/include/asm/cca.h diff --git a/xen/arch/arm/cca/Makefile b/xen/arch/arm/cca/Makefile index 9c351f901dfd..aaa04e3b914b 100644 --- a/xen/arch/arm/cca/Makefile +++ b/xen/arch/arm/cca/Makefile @@ -1 +1,2 @@ obj-y += rmi.o +obj-y += state.o diff --git a/xen/arch/arm/cca/state.c b/xen/arch/arm/cca/state.c new file mode 100644 index 000000000000..a47d9cd7b6fd --- /dev/null +++ b/xen/arch/arm/cca/state.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <xen/lib.h> +#include <xen/mm.h> +#include <xen/sched.h> + +#include <asm/cca.h> + +#include "rmi.h" + +static void arm_cca_reset_domain_state(struct domain *d) +{ + d->arch.cca.realm_active = false; + d->arch.cca.rd = INVALID_PADDR; + d->arch.cca.rmi_features0 = 0; + d->arch.cca.rmi_features1 = 0; +} + +static void arm_cca_reset_vcpu_state(struct vcpu *v) +{ + v->arch.cca.rec = INVALID_PADDR; + v->arch.cca.run = NULL; + v->arch.cca.run_pa = INVALID_PADDR; +} + +void arm_cca_domain_init(struct domain *d) +{ + arm_cca_reset_domain_state(d); +} + +void arm_cca_domain_destroy(struct domain *d) +{ + arm_cca_reset_domain_state(d); +} + +void arm_cca_vcpu_init(struct vcpu *v) +{ + arm_cca_reset_vcpu_state(v); +} + +void arm_cca_vcpu_destroy(struct vcpu *v) +{ + if ( v->arch.cca.run ) + arm_cca_free_rec_run(v->arch.cca.run); + + arm_cca_reset_vcpu_state(v); +} + +void *arm_cca_alloc_rec_run(void) +{ + void *run; + + BUILD_BUG_ON(sizeof(struct arm_cca_rmi_rec_run) != + ARM_CCA_RMI_REC_RUN_SIZE); + + run = alloc_xenheap_page(); + if ( run == NULL ) + return NULL; + + clear_page(run); + + return run; +} + +void arm_cca_free_rec_run(void *run) +{ + free_xenheap_page(run); +} diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 26380a807cad..4b6115491c59 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -482,6 +482,10 @@ int arch_vcpu_create(struct vcpu *v) v->arch.saved_context.sp = (register_t)v->arch.cpu_info; v->arch.saved_context.pc = (register_t)continue_new_vcpu; +#ifdef CONFIG_ARM_CCA + arm_cca_vcpu_init(v); +#endif + /* Idle VCPUs don't need the rest of this setup */ if ( is_idle_vcpu(v) ) return rc; @@ -526,6 +530,9 @@ fail: void arch_vcpu_destroy(struct vcpu *v) { +#ifdef CONFIG_ARM_CCA + arm_cca_vcpu_destroy(v); +#endif if ( is_sve_domain(v->domain) ) sve_context_free(v); vcpu_timer_destroy(v); @@ -642,6 +649,10 @@ int arch_domain_create(struct domain *d, BUILD_BUG_ON(GUEST_MAX_VCPUS < MAX_VIRT_CPUS); +#ifdef CONFIG_ARM_CCA + arm_cca_domain_init(d); +#endif + #ifdef CONFIG_IOREQ_SERVER ioreq_domain_init(d); #endif @@ -786,6 +797,9 @@ void arch_domain_destroy(struct domain *d) { resume_ctx_reset(&d->arch.resume_ctx); +#ifdef CONFIG_ARM_CCA + arm_cca_domain_destroy(d); +#endif tee_free_domain_ctx(d); /* IOMMU page table is shared with P2M, always call * iommu_domain_destroy() before p2m_final_teardown(). diff --git a/xen/arch/arm/include/asm/cca.h b/xen/arch/arm/include/asm/cca.h new file mode 100644 index 000000000000..1be43327119e --- /dev/null +++ b/xen/arch/arm/include/asm/cca.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef ARM_CCA_H +#define ARM_CCA_H + +#include <xen/types.h> + +/* + * Keep the public ARM CCA arch header independent from the internal RMI ABI + * definitions that live under arch/arm/cca/. + * + * DEN0137 2.0-bet1 - B3.99 RecAuxCount caps the implementation-defined + * number of REC auxiliary granules. REC_CREATE gets them through SRO + * donation. + */ +#define ARM_CCA_MAX_REC_AUX 16U + +struct domain; +struct vcpu; + +struct arm_cca_domain_state { + bool realm_active; + paddr_t rd; + unsigned long rmi_features0; + unsigned long rmi_features1; +}; + +struct arm_cca_vcpu_state { + paddr_t rec; + void *run; + paddr_t run_pa; +}; + +void arm_cca_domain_init(struct domain *d); +void arm_cca_domain_destroy(struct domain *d); + +void arm_cca_vcpu_init(struct vcpu *v); +void arm_cca_vcpu_destroy(struct vcpu *v); + +void *arm_cca_alloc_rec_run(void); +void arm_cca_free_rec_run(void *run); + +#endif /* ARM_CCA_H */ diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/domain.h index 46a5cdc0c800..25230c18d16b 100644 --- a/xen/arch/arm/include/asm/domain.h +++ b/xen/arch/arm/include/asm/domain.h @@ -3,6 +3,7 @@ #include <xen/cache.h> #include <xen/timer.h> +#include <asm/cca.h> #include <asm/page.h> #include <asm/p2m.h> #include <asm/suspend.h> @@ -96,6 +97,9 @@ struct arch_domain /* ARM SCI driver's specific data */ void *sci_data; #endif +#ifdef CONFIG_ARM_CCA + struct arm_cca_domain_state cca; +#endif struct resume_info resume_ctx; } __cacheline_aligned; @@ -207,6 +211,10 @@ struct arch_vcpu /* Timer registers */ register_t cntkctl; +#ifdef CONFIG_ARM_CCA + struct arm_cca_vcpu_state cca; +#endif + struct vtimer phys_timer; struct vtimer virt_timer; bool vtimer_initialized; @@ -224,6 +232,14 @@ struct arch_vcpu void vcpu_show_registers(struct vcpu *v); void vcpu_switch_to_aarch64_mode(struct vcpu *v); +#ifdef CONFIG_ARM_CCA +#define is_domain_realm(d) ((d)->arch.cca.realm_active) +#define is_vcpu_realm(v) is_domain_realm((v)->domain) +#else +#define is_domain_realm(d) ({ (void)(d); false; }) +#define is_vcpu_realm(v) ({ (void)(v); false; }) +#endif + /* * Due to the restriction of GICv3, the number of vCPUs in AFF0 is * limited to 16, thus only the first 4 bits of AFF0 are legal. We will -- 2.51.0
