mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
ANDROID: KVM: arm64: Monitor Debug support for non-protected guests
Add monitor debug support for non-protected guests in protected mode. Save and restore the monitor debug state when running a non-protected guest, and propagate the monitor debug configuration of non-protected vcpus from the host. This patch assumes that the hyp vcpu debug iflags are kept in sync with the host. Bug: 228011917 Signed-off-by: Fuad Tabba <tabba@google.com> Change-Id: Ie525693a6a6f236e388b16a1af297403e729057f Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
committed by
Quentin Perret
parent
b34bc46188
commit
0a1f3a1f7b
@@ -491,6 +491,57 @@ static void __flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
__copy_vcpu_state(hyp_vcpu->host_vcpu, &hyp_vcpu->vcpu);
|
||||
}
|
||||
|
||||
static void flush_debug_state(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
|
||||
struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
|
||||
u64 mdcr_el2 = READ_ONCE(host_vcpu->arch.mdcr_el2);
|
||||
|
||||
/*
|
||||
* Propagate the monitor debug configuration of the vcpu from host.
|
||||
* Preserve HPMN, which is set-up by some knowledgeable bootcode.
|
||||
* Ensure that MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK are clear,
|
||||
* as guests should not be able to access profiling and trace buffers.
|
||||
* Ensure that RES0 bits are clear.
|
||||
*/
|
||||
mdcr_el2 &= ~(MDCR_EL2_RES0 |
|
||||
MDCR_EL2_HPMN_MASK |
|
||||
(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT) |
|
||||
(MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT));
|
||||
vcpu->arch.mdcr_el2 = read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK;
|
||||
vcpu->arch.mdcr_el2 |= mdcr_el2;
|
||||
|
||||
vcpu->arch.pmu = host_vcpu->arch.pmu;
|
||||
vcpu->guest_debug = READ_ONCE(host_vcpu->guest_debug);
|
||||
|
||||
if (!kvm_vcpu_needs_debug_regs(vcpu))
|
||||
return;
|
||||
|
||||
__vcpu_save_guest_debug_regs(vcpu);
|
||||
|
||||
/* Switch debug_ptr to the external_debug_state if done by the host. */
|
||||
if (kern_hyp_va(READ_ONCE(host_vcpu->arch.debug_ptr)) ==
|
||||
&host_vcpu->arch.external_debug_state)
|
||||
vcpu->arch.debug_ptr = &host_vcpu->arch.external_debug_state;
|
||||
|
||||
/* Propagate any special handling for single step from host. */
|
||||
vcpu_write_sys_reg(vcpu, vcpu_read_sys_reg(host_vcpu, MDSCR_EL1),
|
||||
MDSCR_EL1);
|
||||
*vcpu_cpsr(vcpu) = *vcpu_cpsr(host_vcpu);
|
||||
}
|
||||
|
||||
static void sync_debug_state(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
|
||||
struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
|
||||
|
||||
if (!kvm_vcpu_needs_debug_regs(vcpu))
|
||||
return;
|
||||
|
||||
__vcpu_restore_guest_debug_regs(vcpu);
|
||||
vcpu->arch.debug_ptr = &host_vcpu->arch.vcpu_debug_state;
|
||||
}
|
||||
|
||||
static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
{
|
||||
struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
|
||||
@@ -510,11 +561,10 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
|
||||
__flush_hyp_vcpu(hyp_vcpu);
|
||||
|
||||
hyp_vcpu->vcpu.arch.iflags = READ_ONCE(host_vcpu->arch.iflags);
|
||||
flush_debug_state(hyp_vcpu);
|
||||
|
||||
hyp_vcpu->vcpu.arch.hcr_el2 = HCR_GUEST_FLAGS & ~(HCR_RW | HCR_TWI | HCR_TWE);
|
||||
hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2);
|
||||
|
||||
hyp_vcpu->vcpu.arch.mdcr_el2 = host_vcpu->arch.mdcr_el2;
|
||||
hyp_vcpu->vcpu.arch.debug_ptr = kern_hyp_va(host_vcpu->arch.debug_ptr);
|
||||
}
|
||||
|
||||
hyp_vcpu->vcpu.arch.vsesr_el2 = host_vcpu->arch.vsesr_el2;
|
||||
@@ -551,6 +601,9 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu, u32 exit_reason)
|
||||
hyp_entry_exit_handler_fn ec_handler;
|
||||
u8 esr_ec;
|
||||
|
||||
if (!pkvm_hyp_vcpu_is_protected(hyp_vcpu))
|
||||
sync_debug_state(hyp_vcpu);
|
||||
|
||||
/*
|
||||
* Don't sync the vcpu GPR/sysreg state after a run. Instead,
|
||||
* leave it in the hyp vCPU until someone actually requires it.
|
||||
|
||||
@@ -495,6 +495,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);
|
||||
hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
|
||||
hyp_vcpu->vcpu.arch.debug_ptr = &host_vcpu->arch.vcpu_debug_state;
|
||||
|
||||
pkvm_vcpu_init_features_from_host(hyp_vcpu);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user