mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
ANDROID: KVM: arm64: Fix initializing traps in protected mode
The values of the trapping registers for protected VMs should be computed from the ground up, and not depend on potentially preexisting values. Moreover, non-protected VMs should not be restricted in protected mode in the same manner as protected VMs. Signed-off-by: Fuad Tabba <tabba@google.com> Signed-off-by: Will Deacon <willdeacon@google.com> Bug: 233587962 Change-Id: I689c6d48e8ebb533a86b78ebd6e1a1416cb8729b
This commit is contained in:
@@ -168,34 +168,49 @@ static void pvm_init_traps_aa64mmfr1(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
static void pvm_init_trap_regs(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
const u64 hcr_trap_feat_regs = HCR_TID3;
|
||||
const u64 hcr_trap_impdef = HCR_TACR | HCR_TIDCP | HCR_TID1;
|
||||
|
||||
/*
|
||||
* Always trap:
|
||||
* - Feature id registers: to control features exposed to guests
|
||||
* - Implementation-defined features
|
||||
*/
|
||||
vcpu->arch.hcr_el2 |= hcr_trap_feat_regs | hcr_trap_impdef;
|
||||
vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS |
|
||||
HCR_TID3 | HCR_TACR | HCR_TIDCP | HCR_TID1;
|
||||
|
||||
/* Clear res0 and set res1 bits to trap potential new features. */
|
||||
vcpu->arch.hcr_el2 &= ~(HCR_RES0);
|
||||
vcpu->arch.mdcr_el2 &= ~(MDCR_EL2_RES0);
|
||||
vcpu->arch.cptr_el2 |= CPTR_NVHE_EL2_RES1;
|
||||
vcpu->arch.cptr_el2 &= ~(CPTR_NVHE_EL2_RES0);
|
||||
if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
|
||||
/* route synchronous external abort exceptions to EL2 */
|
||||
vcpu->arch.hcr_el2 |= HCR_TEA;
|
||||
/* trap error record accesses */
|
||||
vcpu->arch.hcr_el2 |= HCR_TERR;
|
||||
}
|
||||
|
||||
if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
|
||||
vcpu->arch.hcr_el2 |= HCR_FWB;
|
||||
|
||||
if (cpus_have_const_cap(ARM64_MISMATCHED_CACHE_TYPE))
|
||||
vcpu->arch.hcr_el2 |= HCR_TID2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize trap register values for protected VMs.
|
||||
*/
|
||||
static void pkvm_vcpu_init_traps(struct kvm_vcpu *vcpu)
|
||||
static void pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
{
|
||||
pvm_init_trap_regs(vcpu);
|
||||
pvm_init_traps_aa64pfr0(vcpu);
|
||||
pvm_init_traps_aa64pfr1(vcpu);
|
||||
pvm_init_traps_aa64dfr0(vcpu);
|
||||
pvm_init_traps_aa64mmfr0(vcpu);
|
||||
pvm_init_traps_aa64mmfr1(vcpu);
|
||||
hyp_vcpu->vcpu.arch.cptr_el2 = CPTR_EL2_DEFAULT;
|
||||
hyp_vcpu->vcpu.arch.mdcr_el2 = 0;
|
||||
|
||||
if (!pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
|
||||
u64 hcr = READ_ONCE(hyp_vcpu->host_vcpu->arch.hcr_el2);
|
||||
|
||||
hyp_vcpu->vcpu.arch.hcr_el2 = HCR_GUEST_FLAGS | hcr;
|
||||
return;
|
||||
}
|
||||
|
||||
pvm_init_trap_regs(&hyp_vcpu->vcpu);
|
||||
pvm_init_traps_aa64pfr0(&hyp_vcpu->vcpu);
|
||||
pvm_init_traps_aa64pfr1(&hyp_vcpu->vcpu);
|
||||
pvm_init_traps_aa64dfr0(&hyp_vcpu->vcpu);
|
||||
pvm_init_traps_aa64mmfr0(&hyp_vcpu->vcpu);
|
||||
pvm_init_traps_aa64mmfr1(&hyp_vcpu->vcpu);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -349,7 +364,7 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
|
||||
hyp_vcpu->vcpu.arch.hw_mmu = &hyp_vm->kvm.arch.mmu;
|
||||
hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags);
|
||||
|
||||
pkvm_vcpu_init_traps(&hyp_vcpu->vcpu);
|
||||
pkvm_vcpu_init_traps(hyp_vcpu);
|
||||
done:
|
||||
if (ret)
|
||||
unpin_host_vcpu(host_vcpu);
|
||||
|
||||
Reference in New Issue
Block a user