arm: Generalise vcpu fields saved when inactive

Different microarchitectures & configurations save different sets of
VCPU registers when the current VCPU is not active. This generalises the
handling of these cases such that each microarchitecture defines which
regisers are managed in this fashion.

Fixes regression introduced in 454dfd897f

Signed-off-by: Curtis Millar <curtis.millar@data61.csiro.au>
This commit is contained in:
Curtis Millar 2020-12-11 10:28:13 +11:00
parent c381c7e14c
commit 93ab2543d9
No known key found for this signature in database
GPG key ID: 836B6EBF7E3C490A
3 changed files with 28 additions and 36 deletions

View file

@ -850,6 +850,15 @@ static inline bool_t armv_handleVCPUFault(word_t hsr)
return false;
}
static inline bool_t vcpu_reg_saved_when_disabled(word_t field)
{
switch (field) {
case seL4_VCPUReg_SCTLR:
return true;
default:
return false;
}
}
#endif /* End of CONFIG_ARM_HYPERVISOR_SUPPORT */

View file

@ -660,6 +660,19 @@ static inline bool_t armv_handleVCPUFault(word_t hsr)
return false;
}
static inline bool_t vcpu_reg_saved_when_disabled(word_t field)
{
switch (field) {
case seL4_VCPUReg_SCTLR:
#ifdef CONFIG_HAVE_FPU
case seL4_VCPUReg_CPACR:
#endif
return true;
default:
return false;
}
}
#endif /* End of CONFIG_ARM_HYPERVISOR_SUPPORT */

View file

@ -58,24 +58,9 @@ static void vcpu_save(vcpu_t *vcpu, bool_t active)
static word_t readVCPUReg(vcpu_t *vcpu, word_t field)
{
if (likely(ARCH_NODE_STATE(armHSCurVCPU) == vcpu)) {
switch (field) {
case seL4_VCPUReg_SCTLR:
/* The SCTLR value is switched to/from hardware when we enable/disable
* the vcpu, not when we switch vcpus */
if (ARCH_NODE_STATE(armHSVCPUActive)) {
return getSCTLR();
} else {
return vcpu_read_reg(vcpu, field);
}
#ifdef CONFIG_HAVE_FPU
case seL4_VCPUReg_CPACR:
if (ARCH_NODE_STATE(armHSVCPUActive)) {
return vcpu_hw_read_reg(field);
} else {
return vcpu_read_reg(vcpu, field);
}
#endif
default:
if (vcpu_reg_saved_when_disabled(field) && !ARCH_NODE_STATE(armHSVCPUActive)) {
return vcpu_read_reg(vcpu, field);
} else {
return vcpu_hw_read_reg(field);
}
} else {
@ -86,24 +71,9 @@ static word_t readVCPUReg(vcpu_t *vcpu, word_t field)
static void writeVCPUReg(vcpu_t *vcpu, word_t field, word_t value)
{
if (likely(ARCH_NODE_STATE(armHSCurVCPU) == vcpu)) {
switch (field) {
case seL4_VCPUReg_SCTLR:
if (ARCH_NODE_STATE(armHSVCPUActive)) {
setSCTLR(value);
} else {
vcpu_write_reg(vcpu, field, value);
}
break;
#ifdef CONFIG_HAVE_FPU
case seL4_VCPUReg_CPACR:
if (ARCH_NODE_STATE(armHSVCPUActive)) {
vcpu_hw_write_reg(field, value);
} else {
vcpu_write_reg(vcpu, field, value);
}
break;
#endif
default:
if (vcpu_reg_saved_when_disabled(field) && !ARCH_NODE_STATE(armHSVCPUActive)) {
vcpu_write_reg(vcpu, field, value);
} else {
vcpu_hw_write_reg(field, value);
}
} else {