hv: Transfer ACTLR_EL1 (not just EL2) to secondaries

Also capture config at cpu0 guest entry time, to make sure we don't
carry over guest changes to EL1 regs after that.

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2021-09-24 10:57:27 +09:00
parent 3a4b2870a8
commit 2736f0dd07

View file

@ -29,6 +29,24 @@ bool hv_started_cpus[MAX_CPUS];
u32 hv_cpus_in_guest;
u64 hv_saved_sp[MAX_CPUS];
struct hv_secondary_info_t {
uint64_t hcr;
uint64_t hacr;
uint64_t vtcr, vttbr;
uint64_t mdcr;
uint64_t mdscr;
uint64_t amx_ctl;
uint64_t apvmkeylo, apvmkeyhi, apsts;
uint64_t actlr_el2;
uint64_t actlr_el1;
uint64_t cnthctl;
uint64_t sprr_config;
uint64_t gxf_config;
};
static struct hv_secondary_info_t hv_secondary_info;
void hv_init(void)
{
pcie_shutdown();
@ -79,6 +97,22 @@ void hv_start(void *entry, u64 regs[4])
if (gxf_enabled())
gl2_call(hv_set_gxf_vbar, 0, 0, 0, 0);
hv_secondary_info.hcr = mrs(HCR_EL2);
hv_secondary_info.hacr = mrs(HACR_EL2);
hv_secondary_info.vtcr = mrs(VTCR_EL2);
hv_secondary_info.vttbr = mrs(VTTBR_EL2);
hv_secondary_info.mdcr = mrs(MDCR_EL2);
hv_secondary_info.mdscr = mrs(MDSCR_EL1);
hv_secondary_info.amx_ctl = mrs(SYS_IMP_APL_AMX_CTL_EL2);
hv_secondary_info.apvmkeylo = mrs(SYS_IMP_APL_APVMKEYLO_EL2);
hv_secondary_info.apvmkeyhi = mrs(SYS_IMP_APL_APVMKEYHI_EL2);
hv_secondary_info.apsts = mrs(SYS_IMP_APL_APSTS_EL12);
hv_secondary_info.actlr_el2 = mrs(ACTLR_EL2);
hv_secondary_info.actlr_el1 = mrs(SYS_IMP_APL_ACTLR_EL12);
hv_secondary_info.cnthctl = mrs(CNTHCTL_EL2);
hv_secondary_info.sprr_config = mrs(SYS_IMP_APL_SPRR_CONFIG_EL1);
hv_secondary_info.gxf_config = mrs(SYS_IMP_APL_GXF_CONFIG_EL1);
hv_arm_tick();
hv_want_cpu = -1;
hv_cpus_in_guest = 1;
@ -107,20 +141,6 @@ void hv_start(void *entry, u64 regs[4])
spin_unlock(&bhl);
}
struct hv_secondary_info_t {
uint64_t hcr;
uint64_t hacr;
uint64_t vtcr, vttbr;
uint64_t mdcr;
uint64_t mdscr;
uint64_t amx_ctl;
uint64_t apvmkeylo, apvmkeyhi, apsts;
uint64_t actlr;
uint64_t cnthctl;
uint64_t sprr_config;
uint64_t gxf_config;
};
static void hv_init_secondary(struct hv_secondary_info_t *info)
{
gxf_init();
@ -137,7 +157,8 @@ static void hv_init_secondary(struct hv_secondary_info_t *info)
msr(SYS_IMP_APL_APVMKEYLO_EL2, info->apvmkeylo);
msr(SYS_IMP_APL_APVMKEYHI_EL2, info->apvmkeyhi);
msr(SYS_IMP_APL_APSTS_EL12, info->apsts);
msr(ACTLR_EL2, info->actlr);
msr(ACTLR_EL2, info->actlr_el2);
msr(SYS_IMP_APL_ACTLR_EL12, info->actlr_el1);
msr(CNTHCTL_EL2, info->cnthctl);
msr(SYS_IMP_APL_SPRR_CONFIG_EL1, info->sprr_config);
msr(SYS_IMP_APL_GXF_CONFIG_EL1, info->gxf_config);
@ -167,26 +188,9 @@ void hv_start_secondary(int cpu, void *entry, u64 regs[4])
printf("HV: Initializing secondary %d\n", cpu);
iodev_console_flush();
struct hv_secondary_info_t info = {
.hcr = mrs(HCR_EL2),
.hacr = mrs(HACR_EL2),
.vtcr = mrs(VTCR_EL2),
.vttbr = mrs(VTTBR_EL2),
.mdcr = mrs(MDCR_EL2),
.mdscr = mrs(MDSCR_EL1),
.amx_ctl = mrs(SYS_IMP_APL_AMX_CTL_EL2),
.apvmkeylo = mrs(SYS_IMP_APL_APVMKEYLO_EL2),
.apvmkeyhi = mrs(SYS_IMP_APL_APVMKEYHI_EL2),
.apsts = mrs(SYS_IMP_APL_APSTS_EL12),
.actlr = mrs(ACTLR_EL2),
.cnthctl = mrs(CNTHCTL_EL2),
.sprr_config = mrs(SYS_IMP_APL_SPRR_CONFIG_EL1),
.gxf_config = mrs(SYS_IMP_APL_GXF_CONFIG_EL1),
};
mmu_init_secondary(cpu);
iodev_console_flush();
smp_call4(cpu, hv_init_secondary, (u64)&info, 0, 0, 0);
smp_call4(cpu, hv_init_secondary, (u64)&hv_secondary_info, 0, 0, 0);
smp_wait(cpu);
iodev_console_flush();