162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Debug and Guest Debug support 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015 - Linaro Ltd 662306a36Sopenharmony_ci * Author: Alex Bennée <alex.bennee@linaro.org> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/kvm_host.h> 1062306a36Sopenharmony_ci#include <linux/hw_breakpoint.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <asm/debug-monitors.h> 1362306a36Sopenharmony_ci#include <asm/kvm_asm.h> 1462306a36Sopenharmony_ci#include <asm/kvm_arm.h> 1562306a36Sopenharmony_ci#include <asm/kvm_emulate.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "trace.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* These are the bits of MDSCR_EL1 we may manipulate */ 2062306a36Sopenharmony_ci#define MDSCR_EL1_DEBUG_MASK (DBG_MDSCR_SS | \ 2162306a36Sopenharmony_ci DBG_MDSCR_KDE | \ 2262306a36Sopenharmony_ci DBG_MDSCR_MDE) 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic DEFINE_PER_CPU(u64, mdcr_el2); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/** 2762306a36Sopenharmony_ci * save/restore_guest_debug_regs 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * For some debug operations we need to tweak some guest registers. As 3062306a36Sopenharmony_ci * a result we need to save the state of those registers before we 3162306a36Sopenharmony_ci * make those modifications. 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled 3462306a36Sopenharmony_ci * after we have restored the preserved value to the main context. 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * When single-step is enabled by userspace, we tweak PSTATE.SS on every 3762306a36Sopenharmony_ci * guest entry. Preserve PSTATE.SS so we can restore the original value 3862306a36Sopenharmony_ci * for the vcpu after the single-step is disabled. 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_cistatic void save_guest_debug_regs(struct kvm_vcpu *vcpu) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci u64 val = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci vcpu->arch.guest_debug_preserved.mdscr_el1 = val; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci trace_kvm_arm_set_dreg32("Saved MDSCR_EL1", 4762306a36Sopenharmony_ci vcpu->arch.guest_debug_preserved.mdscr_el1); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci vcpu->arch.guest_debug_preserved.pstate_ss = 5062306a36Sopenharmony_ci (*vcpu_cpsr(vcpu) & DBG_SPSR_SS); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cistatic void restore_guest_debug_regs(struct kvm_vcpu *vcpu) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci u64 val = vcpu->arch.guest_debug_preserved.mdscr_el1; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci vcpu_write_sys_reg(vcpu, val, MDSCR_EL1); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci trace_kvm_arm_set_dreg32("Restored MDSCR_EL1", 6062306a36Sopenharmony_ci vcpu_read_sys_reg(vcpu, MDSCR_EL1)); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci if (vcpu->arch.guest_debug_preserved.pstate_ss) 6362306a36Sopenharmony_ci *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; 6462306a36Sopenharmony_ci else 6562306a36Sopenharmony_ci *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/** 6962306a36Sopenharmony_ci * kvm_arm_init_debug - grab what we need for debug 7062306a36Sopenharmony_ci * 7162306a36Sopenharmony_ci * Currently the sole task of this function is to retrieve the initial 7262306a36Sopenharmony_ci * value of mdcr_el2 so we can preserve MDCR_EL2.HPMN which has 7362306a36Sopenharmony_ci * presumably been set-up by some knowledgeable bootcode. 7462306a36Sopenharmony_ci * 7562306a36Sopenharmony_ci * It is called once per-cpu during CPU hyp initialisation. 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_civoid kvm_arm_init_debug(void) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci __this_cpu_write(mdcr_el2, kvm_call_hyp_ret(__kvm_get_mdcr_el2)); 8162306a36Sopenharmony_ci} 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci/** 8462306a36Sopenharmony_ci * kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * @vcpu: the vcpu pointer 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * This ensures we will trap access to: 8962306a36Sopenharmony_ci * - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR) 9062306a36Sopenharmony_ci * - Debug ROM Address (MDCR_EL2_TDRA) 9162306a36Sopenharmony_ci * - OS related registers (MDCR_EL2_TDOSA) 9262306a36Sopenharmony_ci * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) 9362306a36Sopenharmony_ci * - Self-hosted Trace Filter controls (MDCR_EL2_TTRF) 9462306a36Sopenharmony_ci * - Self-hosted Trace (MDCR_EL2_TTRF/MDCR_EL2_E2TB) 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_cistatic void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci /* 9962306a36Sopenharmony_ci * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK 10062306a36Sopenharmony_ci * to disable guest access to the profiling and trace buffers 10162306a36Sopenharmony_ci */ 10262306a36Sopenharmony_ci vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; 10362306a36Sopenharmony_ci vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | 10462306a36Sopenharmony_ci MDCR_EL2_TPMS | 10562306a36Sopenharmony_ci MDCR_EL2_TTRF | 10662306a36Sopenharmony_ci MDCR_EL2_TPMCR | 10762306a36Sopenharmony_ci MDCR_EL2_TDRA | 10862306a36Sopenharmony_ci MDCR_EL2_TDOSA); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /* Is the VM being debugged by userspace? */ 11162306a36Sopenharmony_ci if (vcpu->guest_debug) 11262306a36Sopenharmony_ci /* Route all software debug exceptions to EL2 */ 11362306a36Sopenharmony_ci vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci /* 11662306a36Sopenharmony_ci * Trap debug register access when one of the following is true: 11762306a36Sopenharmony_ci * - Userspace is using the hardware to debug the guest 11862306a36Sopenharmony_ci * (KVM_GUESTDBG_USE_HW is set). 11962306a36Sopenharmony_ci * - The guest is not using debug (DEBUG_DIRTY clear). 12062306a36Sopenharmony_ci * - The guest has enabled the OS Lock (debug exceptions are blocked). 12162306a36Sopenharmony_ci */ 12262306a36Sopenharmony_ci if ((vcpu->guest_debug & KVM_GUESTDBG_USE_HW) || 12362306a36Sopenharmony_ci !vcpu_get_flag(vcpu, DEBUG_DIRTY) || 12462306a36Sopenharmony_ci kvm_vcpu_os_lock_enabled(vcpu)) 12562306a36Sopenharmony_ci vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2); 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/** 13162306a36Sopenharmony_ci * kvm_arm_vcpu_init_debug - setup vcpu debug traps 13262306a36Sopenharmony_ci * 13362306a36Sopenharmony_ci * @vcpu: the vcpu pointer 13462306a36Sopenharmony_ci * 13562306a36Sopenharmony_ci * Set vcpu initial mdcr_el2 value. 13662306a36Sopenharmony_ci */ 13762306a36Sopenharmony_civoid kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci preempt_disable(); 14062306a36Sopenharmony_ci kvm_arm_setup_mdcr_el2(vcpu); 14162306a36Sopenharmony_ci preempt_enable(); 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/** 14562306a36Sopenharmony_ci * kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_civoid kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state; 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/** 15462306a36Sopenharmony_ci * kvm_arm_setup_debug - set up debug related stuff 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * @vcpu: the vcpu pointer 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * This is called before each entry into the hypervisor to setup any 15962306a36Sopenharmony_ci * debug related registers. 16062306a36Sopenharmony_ci * 16162306a36Sopenharmony_ci * Additionally, KVM only traps guest accesses to the debug registers if 16262306a36Sopenharmony_ci * the guest is not actively using them (see the DEBUG_DIRTY 16362306a36Sopenharmony_ci * flag on vcpu->arch.iflags). Since the guest must not interfere 16462306a36Sopenharmony_ci * with the hardware state when debugging the guest, we must ensure that 16562306a36Sopenharmony_ci * trapping is enabled whenever we are debugging the guest using the 16662306a36Sopenharmony_ci * debug registers. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_civoid kvm_arm_setup_debug(struct kvm_vcpu *vcpu) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci kvm_arm_setup_mdcr_el2(vcpu); 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* Check if we need to use the debug registers. */ 17862306a36Sopenharmony_ci if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) { 17962306a36Sopenharmony_ci /* Save guest debug state */ 18062306a36Sopenharmony_ci save_guest_debug_regs(vcpu); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* 18362306a36Sopenharmony_ci * Single Step (ARM ARM D2.12.3 The software step state 18462306a36Sopenharmony_ci * machine) 18562306a36Sopenharmony_ci * 18662306a36Sopenharmony_ci * If we are doing Single Step we need to manipulate 18762306a36Sopenharmony_ci * the guest's MDSCR_EL1.SS and PSTATE.SS. Once the 18862306a36Sopenharmony_ci * step has occurred the hypervisor will trap the 18962306a36Sopenharmony_ci * debug exception and we return to userspace. 19062306a36Sopenharmony_ci * 19162306a36Sopenharmony_ci * If the guest attempts to single step its userspace 19262306a36Sopenharmony_ci * we would have to deal with a trapped exception 19362306a36Sopenharmony_ci * while in the guest kernel. Because this would be 19462306a36Sopenharmony_ci * hard to unwind we suppress the guest's ability to 19562306a36Sopenharmony_ci * do so by masking MDSCR_EL.SS. 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * This confuses guest debuggers which use 19862306a36Sopenharmony_ci * single-step behind the scenes but everything 19962306a36Sopenharmony_ci * returns to normal once the host is no longer 20062306a36Sopenharmony_ci * debugging the system. 20162306a36Sopenharmony_ci */ 20262306a36Sopenharmony_ci if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { 20362306a36Sopenharmony_ci /* 20462306a36Sopenharmony_ci * If the software step state at the last guest exit 20562306a36Sopenharmony_ci * was Active-pending, we don't set DBG_SPSR_SS so 20662306a36Sopenharmony_ci * that the state is maintained (to not run another 20762306a36Sopenharmony_ci * single-step until the pending Software Step 20862306a36Sopenharmony_ci * exception is taken). 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_ci if (!vcpu_get_flag(vcpu, DBG_SS_ACTIVE_PENDING)) 21162306a36Sopenharmony_ci *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; 21262306a36Sopenharmony_ci else 21362306a36Sopenharmony_ci *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 21662306a36Sopenharmony_ci mdscr |= DBG_MDSCR_SS; 21762306a36Sopenharmony_ci vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 21862306a36Sopenharmony_ci } else { 21962306a36Sopenharmony_ci mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 22062306a36Sopenharmony_ci mdscr &= ~DBG_MDSCR_SS; 22162306a36Sopenharmony_ci vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 22262306a36Sopenharmony_ci } 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu)); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci /* 22762306a36Sopenharmony_ci * HW Breakpoints and watchpoints 22862306a36Sopenharmony_ci * 22962306a36Sopenharmony_ci * We simply switch the debug_ptr to point to our new 23062306a36Sopenharmony_ci * external_debug_state which has been populated by the 23162306a36Sopenharmony_ci * debug ioctl. The existing DEBUG_DIRTY mechanism ensures 23262306a36Sopenharmony_ci * the registers are updated on the world switch. 23362306a36Sopenharmony_ci */ 23462306a36Sopenharmony_ci if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { 23562306a36Sopenharmony_ci /* Enable breakpoints/watchpoints */ 23662306a36Sopenharmony_ci mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 23762306a36Sopenharmony_ci mdscr |= DBG_MDSCR_MDE; 23862306a36Sopenharmony_ci vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state; 24162306a36Sopenharmony_ci vcpu_set_flag(vcpu, DEBUG_DIRTY); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci trace_kvm_arm_set_regset("BKPTS", get_num_brps(), 24462306a36Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_bcr[0], 24562306a36Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_bvr[0]); 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), 24862306a36Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_wcr[0], 24962306a36Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_wvr[0]); 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci /* 25262306a36Sopenharmony_ci * The OS Lock blocks debug exceptions in all ELs when it is 25362306a36Sopenharmony_ci * enabled. If the guest has enabled the OS Lock, constrain its 25462306a36Sopenharmony_ci * effects to the guest. Emulate the behavior by clearing 25562306a36Sopenharmony_ci * MDSCR_EL1.MDE. In so doing, we ensure that host debug 25662306a36Sopenharmony_ci * exceptions are unaffected by guest configuration of the OS 25762306a36Sopenharmony_ci * Lock. 25862306a36Sopenharmony_ci */ 25962306a36Sopenharmony_ci } else if (kvm_vcpu_os_lock_enabled(vcpu)) { 26062306a36Sopenharmony_ci mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 26162306a36Sopenharmony_ci mdscr &= ~DBG_MDSCR_MDE; 26262306a36Sopenharmony_ci vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 26362306a36Sopenharmony_ci } 26462306a36Sopenharmony_ci } 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci BUG_ON(!vcpu->guest_debug && 26762306a36Sopenharmony_ci vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci /* If KDE or MDE are set, perform a full save/restore cycle. */ 27062306a36Sopenharmony_ci if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE)) 27162306a36Sopenharmony_ci vcpu_set_flag(vcpu, DEBUG_DIRTY); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci /* Write mdcr_el2 changes since vcpu_load on VHE systems */ 27462306a36Sopenharmony_ci if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2) 27562306a36Sopenharmony_ci write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1)); 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_civoid kvm_arm_clear_debug(struct kvm_vcpu *vcpu) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci trace_kvm_arm_clear_debug(vcpu->guest_debug); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci /* 28562306a36Sopenharmony_ci * Restore the guest's debug registers if we were using them. 28662306a36Sopenharmony_ci */ 28762306a36Sopenharmony_ci if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) { 28862306a36Sopenharmony_ci if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { 28962306a36Sopenharmony_ci if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS)) 29062306a36Sopenharmony_ci /* 29162306a36Sopenharmony_ci * Mark the vcpu as ACTIVE_PENDING 29262306a36Sopenharmony_ci * until Software Step exception is taken. 29362306a36Sopenharmony_ci */ 29462306a36Sopenharmony_ci vcpu_set_flag(vcpu, DBG_SS_ACTIVE_PENDING); 29562306a36Sopenharmony_ci } 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci restore_guest_debug_regs(vcpu); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci /* 30062306a36Sopenharmony_ci * If we were using HW debug we need to restore the 30162306a36Sopenharmony_ci * debug_ptr to the guest debug state. 30262306a36Sopenharmony_ci */ 30362306a36Sopenharmony_ci if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { 30462306a36Sopenharmony_ci kvm_arm_reset_debug_ptr(vcpu); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci trace_kvm_arm_set_regset("BKPTS", get_num_brps(), 30762306a36Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_bcr[0], 30862306a36Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_bvr[0]); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), 31162306a36Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_wcr[0], 31262306a36Sopenharmony_ci &vcpu->arch.debug_ptr->dbg_wvr[0]); 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci } 31562306a36Sopenharmony_ci} 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_civoid kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu) 31862306a36Sopenharmony_ci{ 31962306a36Sopenharmony_ci u64 dfr0; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci /* For VHE, there is nothing to do */ 32262306a36Sopenharmony_ci if (has_vhe()) 32362306a36Sopenharmony_ci return; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci dfr0 = read_sysreg(id_aa64dfr0_el1); 32662306a36Sopenharmony_ci /* 32762306a36Sopenharmony_ci * If SPE is present on this CPU and is available at current EL, 32862306a36Sopenharmony_ci * we may need to check if the host state needs to be saved. 32962306a36Sopenharmony_ci */ 33062306a36Sopenharmony_ci if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_PMSVer_SHIFT) && 33162306a36Sopenharmony_ci !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(PMBIDR_EL1_P_SHIFT))) 33262306a36Sopenharmony_ci vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci /* Check if we have TRBE implemented and available at the host */ 33562306a36Sopenharmony_ci if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) && 33662306a36Sopenharmony_ci !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P)) 33762306a36Sopenharmony_ci vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE); 33862306a36Sopenharmony_ci} 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_civoid kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu) 34162306a36Sopenharmony_ci{ 34262306a36Sopenharmony_ci vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE); 34362306a36Sopenharmony_ci vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE); 34462306a36Sopenharmony_ci} 345