KVM: arm64: Initialize trap register values in hyp in pKVM
Handle the initialization of trap registers at the hypervisor in
pKVM, even for non-protected guests. The host is not trusted with
the values of the trap registers, regardless of the VM type.
Therefore, when switching between the host and the guests, only
flush the HCR_EL2 TWI and TWE bits. The host is allowed to
configure these for opportunistic scheduling, as neither affects
the protection of VMs or the hypervisor.
Reported-by: Will Deacon <will@kernel.org>
Fixes: 814ad8f96e
("KVM: arm64: Drop trapping of PAuth instructions/keys")
Signed-off-by: Fuad Tabba <tabba@google.com>
Link: https://lore.kernel.org/r/20241018074833.2563674-5-tabba@google.com
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
This commit is contained in:
parent
cb0c272ace
commit
b56680de9c
2 changed files with 38 additions and 1 deletions
|
@ -105,8 +105,10 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||||
|
|
||||||
hyp_vcpu->vcpu.arch.hw_mmu = host_vcpu->arch.hw_mmu;
|
hyp_vcpu->vcpu.arch.hw_mmu = host_vcpu->arch.hw_mmu;
|
||||||
|
|
||||||
hyp_vcpu->vcpu.arch.hcr_el2 = host_vcpu->arch.hcr_el2;
|
|
||||||
hyp_vcpu->vcpu.arch.mdcr_el2 = host_vcpu->arch.mdcr_el2;
|
hyp_vcpu->vcpu.arch.mdcr_el2 = host_vcpu->arch.mdcr_el2;
|
||||||
|
hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE);
|
||||||
|
hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) &
|
||||||
|
(HCR_TWI | HCR_TWE);
|
||||||
|
|
||||||
hyp_vcpu->vcpu.arch.iflags = host_vcpu->arch.iflags;
|
hyp_vcpu->vcpu.arch.iflags = host_vcpu->arch.iflags;
|
||||||
|
|
||||||
|
|
|
@ -204,11 +204,46 @@ static void pvm_init_trap_regs(struct kvm_vcpu *vcpu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
|
||||||
|
{
|
||||||
|
vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
|
||||||
|
|
||||||
|
if (has_hvhe())
|
||||||
|
vcpu->arch.hcr_el2 |= HCR_E2H;
|
||||||
|
|
||||||
|
if (cpus_have_final_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_final_cap(ARM64_HAS_STAGE2_FWB))
|
||||||
|
vcpu->arch.hcr_el2 |= HCR_FWB;
|
||||||
|
|
||||||
|
if (cpus_have_final_cap(ARM64_HAS_EVT) &&
|
||||||
|
!cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE))
|
||||||
|
vcpu->arch.hcr_el2 |= HCR_TID4;
|
||||||
|
else
|
||||||
|
vcpu->arch.hcr_el2 |= HCR_TID2;
|
||||||
|
|
||||||
|
if (vcpu_has_ptrauth(vcpu))
|
||||||
|
vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize trap register values in protected mode.
|
* Initialize trap register values in protected mode.
|
||||||
*/
|
*/
|
||||||
static void pkvm_vcpu_init_traps(struct kvm_vcpu *vcpu)
|
static void pkvm_vcpu_init_traps(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
|
vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
|
||||||
|
vcpu->arch.mdcr_el2 = 0;
|
||||||
|
|
||||||
|
pkvm_vcpu_reset_hcr(vcpu);
|
||||||
|
|
||||||
|
if ((!vcpu_is_protected(vcpu)))
|
||||||
|
return;
|
||||||
|
|
||||||
pvm_init_trap_regs(vcpu);
|
pvm_init_trap_regs(vcpu);
|
||||||
pvm_init_traps_aa64pfr0(vcpu);
|
pvm_init_traps_aa64pfr0(vcpu);
|
||||||
pvm_init_traps_aa64pfr1(vcpu);
|
pvm_init_traps_aa64pfr1(vcpu);
|
||||||
|
|
Loading…
Add table
Reference in a new issue