From: David Brazdil <dbrazdil@google.com>
To: Marc Zyngier <maz@kernel.org>, Will Deacon <will@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
James Morse <james.morse@arm.com>,
Julien Thierry <julien.thierry.kdev@gmail.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: android-kvm@google.com, linux-kernel@vger.kernel.org,
kernel-team@android.com, kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 09/15] arm64: kvm: Split hyp/debug-sr.c to VHE/nVHE
Date: Thu, 18 Jun 2020 13:25:31 +0100 [thread overview]
Message-ID: <20200618122537.9625-10-dbrazdil@google.com> (raw)
In-Reply-To: <20200618122537.9625-1-dbrazdil@google.com>
This patch is part of a series which builds KVM's non-VHE hyp code separately
from VHE and the rest of the kernel.
debug-sr.c contains KVM's code for context-switching debug registers, with some
parts shared between VHE/nVHE. These common routines are moved to debug-sr.h,
VHE-specific code is left in debug-sr.c and nVHE-specific code is moved to
nvhe/debug-sr.c.
Functions are slightly refactored to move code hidden behind `has_vhe()` checks
to the corresponding .c files.
Signed-off-by: David Brazdil <dbrazdil@google.com>
---
arch/arm64/kernel/image-vars.h | 3 -
arch/arm64/kvm/hyp/debug-sr.c | 210 +----------------------------
arch/arm64/kvm/hyp/debug-sr.h | 172 +++++++++++++++++++++++
arch/arm64/kvm/hyp/nvhe/Makefile | 2 +-
arch/arm64/kvm/hyp/nvhe/debug-sr.c | 77 +++++++++++
5 files changed, 256 insertions(+), 208 deletions(-)
create mode 100644 arch/arm64/kvm/hyp/debug-sr.h
create mode 100644 arch/arm64/kvm/hyp/nvhe/debug-sr.c
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 855f9718d6d9..8096e6f1f2bf 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -61,8 +61,6 @@ __efistub__ctype = _ctype;
* memory mappings.
*/
-__kvm_nvhe___debug_switch_to_guest = __debug_switch_to_guest;
-__kvm_nvhe___debug_switch_to_host = __debug_switch_to_host;
__kvm_nvhe___fpsimd_restore_state = __fpsimd_restore_state;
__kvm_nvhe___fpsimd_save_state = __fpsimd_save_state;
__kvm_nvhe___guest_enter = __guest_enter;
@@ -71,7 +69,6 @@ __kvm_nvhe___hyp_panic_string = __hyp_panic_string;
__kvm_nvhe___hyp_stub_vectors = __hyp_stub_vectors;
__kvm_nvhe___icache_flags = __icache_flags;
__kvm_nvhe___kvm_enable_ssbs = __kvm_enable_ssbs;
-__kvm_nvhe___kvm_get_mdcr_el2 = __kvm_get_mdcr_el2;
__kvm_nvhe___kvm_timer_set_cntvoff = __kvm_timer_set_cntvoff;
__kvm_nvhe___sysreg32_restore_state = __sysreg32_restore_state;
__kvm_nvhe___sysreg32_save_state = __sysreg32_save_state;
diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
index e95af204fec7..28c0a54cda2a 100644
--- a/arch/arm64/kvm/hyp/debug-sr.c
+++ b/arch/arm64/kvm/hyp/debug-sr.c
@@ -4,221 +4,23 @@
* Author: Marc Zyngier <marc.zyngier@arm.com>
*/
-#include <linux/compiler.h>
#include <linux/kvm_host.h>
-#include <asm/debug-monitors.h>
-#include <asm/kvm_asm.h>
#include <asm/kvm_hyp.h>
-#include <asm/kvm_mmu.h>
-#define read_debug(r,n) read_sysreg(r##n##_el1)
-#define write_debug(v,r,n) write_sysreg(v, r##n##_el1)
+#include "debug-sr.h"
-#define save_debug(ptr,reg,nr) \
- switch (nr) { \
- case 15: ptr[15] = read_debug(reg, 15); \
- /* Fall through */ \
- case 14: ptr[14] = read_debug(reg, 14); \
- /* Fall through */ \
- case 13: ptr[13] = read_debug(reg, 13); \
- /* Fall through */ \
- case 12: ptr[12] = read_debug(reg, 12); \
- /* Fall through */ \
- case 11: ptr[11] = read_debug(reg, 11); \
- /* Fall through */ \
- case 10: ptr[10] = read_debug(reg, 10); \
- /* Fall through */ \
- case 9: ptr[9] = read_debug(reg, 9); \
- /* Fall through */ \
- case 8: ptr[8] = read_debug(reg, 8); \
- /* Fall through */ \
- case 7: ptr[7] = read_debug(reg, 7); \
- /* Fall through */ \
- case 6: ptr[6] = read_debug(reg, 6); \
- /* Fall through */ \
- case 5: ptr[5] = read_debug(reg, 5); \
- /* Fall through */ \
- case 4: ptr[4] = read_debug(reg, 4); \
- /* Fall through */ \
- case 3: ptr[3] = read_debug(reg, 3); \
- /* Fall through */ \
- case 2: ptr[2] = read_debug(reg, 2); \
- /* Fall through */ \
- case 1: ptr[1] = read_debug(reg, 1); \
- /* Fall through */ \
- default: ptr[0] = read_debug(reg, 0); \
- }
-
-#define restore_debug(ptr,reg,nr) \
- switch (nr) { \
- case 15: write_debug(ptr[15], reg, 15); \
- /* Fall through */ \
- case 14: write_debug(ptr[14], reg, 14); \
- /* Fall through */ \
- case 13: write_debug(ptr[13], reg, 13); \
- /* Fall through */ \
- case 12: write_debug(ptr[12], reg, 12); \
- /* Fall through */ \
- case 11: write_debug(ptr[11], reg, 11); \
- /* Fall through */ \
- case 10: write_debug(ptr[10], reg, 10); \
- /* Fall through */ \
- case 9: write_debug(ptr[9], reg, 9); \
- /* Fall through */ \
- case 8: write_debug(ptr[8], reg, 8); \
- /* Fall through */ \
- case 7: write_debug(ptr[7], reg, 7); \
- /* Fall through */ \
- case 6: write_debug(ptr[6], reg, 6); \
- /* Fall through */ \
- case 5: write_debug(ptr[5], reg, 5); \
- /* Fall through */ \
- case 4: write_debug(ptr[4], reg, 4); \
- /* Fall through */ \
- case 3: write_debug(ptr[3], reg, 3); \
- /* Fall through */ \
- case 2: write_debug(ptr[2], reg, 2); \
- /* Fall through */ \
- case 1: write_debug(ptr[1], reg, 1); \
- /* Fall through */ \
- default: write_debug(ptr[0], reg, 0); \
- }
-
-static void __hyp_text __debug_save_spe_nvhe(u64 *pmscr_el1)
-{
- u64 reg;
-
- /* Clear pmscr in case of early return */
- *pmscr_el1 = 0;
-
- /* SPE present on this CPU? */
- if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
- ID_AA64DFR0_PMSVER_SHIFT))
- return;
-
- /* Yes; is it owned by EL3? */
- reg = read_sysreg_s(SYS_PMBIDR_EL1);
- if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT))
- return;
-
- /* No; is the host actually using the thing? */
- reg = read_sysreg_s(SYS_PMBLIMITR_EL1);
- if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)))
- return;
-
- /* Yes; save the control register and disable data generation */
- *pmscr_el1 = read_sysreg_s(SYS_PMSCR_EL1);
- write_sysreg_s(0, SYS_PMSCR_EL1);
- isb();
-
- /* Now drain all buffered data to memory */
- psb_csync();
- dsb(nsh);
-}
-
-static void __hyp_text __debug_restore_spe_nvhe(u64 pmscr_el1)
-{
- if (!pmscr_el1)
- return;
-
- /* The host page table is installed, but not yet synchronised */
- isb();
-
- /* Re-enable data generation */
- write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
-}
-
-static void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
- struct kvm_guest_debug_arch *dbg,
- struct kvm_cpu_context *ctxt)
-{
- u64 aa64dfr0;
- int brps, wrps;
-
- aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
- brps = (aa64dfr0 >> 12) & 0xf;
- wrps = (aa64dfr0 >> 20) & 0xf;
-
- save_debug(dbg->dbg_bcr, dbgbcr, brps);
- save_debug(dbg->dbg_bvr, dbgbvr, brps);
- save_debug(dbg->dbg_wcr, dbgwcr, wrps);
- save_debug(dbg->dbg_wvr, dbgwvr, wrps);
-
- ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
-}
-
-static void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
- struct kvm_guest_debug_arch *dbg,
- struct kvm_cpu_context *ctxt)
+void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
{
- u64 aa64dfr0;
- int brps, wrps;
-
- aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
-
- brps = (aa64dfr0 >> 12) & 0xf;
- wrps = (aa64dfr0 >> 20) & 0xf;
-
- restore_debug(dbg->dbg_bcr, dbgbcr, brps);
- restore_debug(dbg->dbg_bvr, dbgbvr, brps);
- restore_debug(dbg->dbg_wcr, dbgwcr, wrps);
- restore_debug(dbg->dbg_wvr, dbgwvr, wrps);
-
- write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
+ __debug_switch_to_guest_common(vcpu);
}
-void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
+void __debug_switch_to_host(struct kvm_vcpu *vcpu)
{
- struct kvm_cpu_context *host_ctxt;
- struct kvm_cpu_context *guest_ctxt;
- struct kvm_guest_debug_arch *host_dbg;
- struct kvm_guest_debug_arch *guest_dbg;
-
- /*
- * Non-VHE: Disable and flush SPE data generation
- * VHE: The vcpu can run, but it can't hide.
- */
- if (!has_vhe())
- __debug_save_spe_nvhe(&vcpu->arch.host_debug_state.pmscr_el1);
-
- if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
- return;
-
- host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
- guest_ctxt = &vcpu->arch.ctxt;
- host_dbg = &vcpu->arch.host_debug_state.regs;
- guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
-
- __debug_save_state(vcpu, host_dbg, host_ctxt);
- __debug_restore_state(vcpu, guest_dbg, guest_ctxt);
-}
-
-void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
-{
- struct kvm_cpu_context *host_ctxt;
- struct kvm_cpu_context *guest_ctxt;
- struct kvm_guest_debug_arch *host_dbg;
- struct kvm_guest_debug_arch *guest_dbg;
-
- if (!has_vhe())
- __debug_restore_spe_nvhe(vcpu->arch.host_debug_state.pmscr_el1);
-
- if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
- return;
-
- host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
- guest_ctxt = &vcpu->arch.ctxt;
- host_dbg = &vcpu->arch.host_debug_state.regs;
- guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
-
- __debug_save_state(vcpu, guest_dbg, guest_ctxt);
- __debug_restore_state(vcpu, host_dbg, host_ctxt);
-
- vcpu->arch.flags &= ~KVM_ARM64_DEBUG_DIRTY;
+ __debug_switch_to_host_common(vcpu);
}
-u32 __hyp_text __kvm_get_mdcr_el2(void)
+u32 __kvm_get_mdcr_el2(void)
{
return read_sysreg(mdcr_el2);
}
diff --git a/arch/arm64/kvm/hyp/debug-sr.h b/arch/arm64/kvm/hyp/debug-sr.h
new file mode 100644
index 000000000000..62b5deeb301d
--- /dev/null
+++ b/arch/arm64/kvm/hyp/debug-sr.h
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ */
+
+#ifndef __ARM64_KVM_HYP_DEBUG_SR_H__
+#define __ARM64_KVM_HYP_DEBUG_SR_H__
+
+#include <linux/compiler.h>
+#include <linux/kvm_host.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+#include <asm/kvm_mmu.h>
+
+#define read_debug(r,n) read_sysreg(r##n##_el1)
+#define write_debug(v,r,n) write_sysreg(v, r##n##_el1)
+
+#define save_debug(ptr,reg,nr) \
+ switch (nr) { \
+ case 15: ptr[15] = read_debug(reg, 15); \
+ /* Fall through */ \
+ case 14: ptr[14] = read_debug(reg, 14); \
+ /* Fall through */ \
+ case 13: ptr[13] = read_debug(reg, 13); \
+ /* Fall through */ \
+ case 12: ptr[12] = read_debug(reg, 12); \
+ /* Fall through */ \
+ case 11: ptr[11] = read_debug(reg, 11); \
+ /* Fall through */ \
+ case 10: ptr[10] = read_debug(reg, 10); \
+ /* Fall through */ \
+ case 9: ptr[9] = read_debug(reg, 9); \
+ /* Fall through */ \
+ case 8: ptr[8] = read_debug(reg, 8); \
+ /* Fall through */ \
+ case 7: ptr[7] = read_debug(reg, 7); \
+ /* Fall through */ \
+ case 6: ptr[6] = read_debug(reg, 6); \
+ /* Fall through */ \
+ case 5: ptr[5] = read_debug(reg, 5); \
+ /* Fall through */ \
+ case 4: ptr[4] = read_debug(reg, 4); \
+ /* Fall through */ \
+ case 3: ptr[3] = read_debug(reg, 3); \
+ /* Fall through */ \
+ case 2: ptr[2] = read_debug(reg, 2); \
+ /* Fall through */ \
+ case 1: ptr[1] = read_debug(reg, 1); \
+ /* Fall through */ \
+ default: ptr[0] = read_debug(reg, 0); \
+ }
+
+#define restore_debug(ptr,reg,nr) \
+ switch (nr) { \
+ case 15: write_debug(ptr[15], reg, 15); \
+ /* Fall through */ \
+ case 14: write_debug(ptr[14], reg, 14); \
+ /* Fall through */ \
+ case 13: write_debug(ptr[13], reg, 13); \
+ /* Fall through */ \
+ case 12: write_debug(ptr[12], reg, 12); \
+ /* Fall through */ \
+ case 11: write_debug(ptr[11], reg, 11); \
+ /* Fall through */ \
+ case 10: write_debug(ptr[10], reg, 10); \
+ /* Fall through */ \
+ case 9: write_debug(ptr[9], reg, 9); \
+ /* Fall through */ \
+ case 8: write_debug(ptr[8], reg, 8); \
+ /* Fall through */ \
+ case 7: write_debug(ptr[7], reg, 7); \
+ /* Fall through */ \
+ case 6: write_debug(ptr[6], reg, 6); \
+ /* Fall through */ \
+ case 5: write_debug(ptr[5], reg, 5); \
+ /* Fall through */ \
+ case 4: write_debug(ptr[4], reg, 4); \
+ /* Fall through */ \
+ case 3: write_debug(ptr[3], reg, 3); \
+ /* Fall through */ \
+ case 2: write_debug(ptr[2], reg, 2); \
+ /* Fall through */ \
+ case 1: write_debug(ptr[1], reg, 1); \
+ /* Fall through */ \
+ default: write_debug(ptr[0], reg, 0); \
+ }
+
+static inline void __hyp_text
+__debug_save_state(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt)
+{
+ u64 aa64dfr0;
+ int brps, wrps;
+
+ aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
+ brps = (aa64dfr0 >> 12) & 0xf;
+ wrps = (aa64dfr0 >> 20) & 0xf;
+
+ save_debug(dbg->dbg_bcr, dbgbcr, brps);
+ save_debug(dbg->dbg_bvr, dbgbvr, brps);
+ save_debug(dbg->dbg_wcr, dbgwcr, wrps);
+ save_debug(dbg->dbg_wvr, dbgwvr, wrps);
+
+ ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
+}
+
+static inline void __hyp_text
+__debug_restore_state(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt)
+{
+ u64 aa64dfr0;
+ int brps, wrps;
+
+ aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
+
+ brps = (aa64dfr0 >> 12) & 0xf;
+ wrps = (aa64dfr0 >> 20) & 0xf;
+
+ restore_debug(dbg->dbg_bcr, dbgbcr, brps);
+ restore_debug(dbg->dbg_bvr, dbgbvr, brps);
+ restore_debug(dbg->dbg_wcr, dbgwcr, wrps);
+ restore_debug(dbg->dbg_wvr, dbgwvr, wrps);
+
+ write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
+}
+
+static inline void __hyp_text
+__debug_switch_to_guest_common(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_cpu_context *guest_ctxt;
+ struct kvm_guest_debug_arch *host_dbg;
+ struct kvm_guest_debug_arch *guest_dbg;
+
+ if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
+ return;
+
+ host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
+ guest_ctxt = &vcpu->arch.ctxt;
+ host_dbg = &vcpu->arch.host_debug_state.regs;
+ guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
+
+ __debug_save_state(vcpu, host_dbg, host_ctxt);
+ __debug_restore_state(vcpu, guest_dbg, guest_ctxt);
+}
+
+static inline void __hyp_text
+__debug_switch_to_host_common(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_cpu_context *guest_ctxt;
+ struct kvm_guest_debug_arch *host_dbg;
+ struct kvm_guest_debug_arch *guest_dbg;
+
+ if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
+ return;
+
+ host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
+ guest_ctxt = &vcpu->arch.ctxt;
+ host_dbg = &vcpu->arch.host_debug_state.regs;
+ guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
+
+ __debug_save_state(vcpu, guest_dbg, guest_ctxt);
+ __debug_restore_state(vcpu, host_dbg, host_ctxt);
+
+ vcpu->arch.flags &= ~KVM_ARM64_DEBUG_DIRTY;
+}
+
+#endif /* __ARM64_KVM_HYP_DEBUG_SR_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 336b1bf64ceb..95a06786bf26 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -7,7 +7,7 @@ asflags-y := -D__KVM_NVHE_HYPERVISOR__
ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -fno-stack-protector \
-DDISABLE_BRANCH_PROFILING $(DISABLE_STACKLEAK_PLUGIN)
-obj-y := switch.o tlb.o hyp-init.o ../hyp-entry.o
+obj-y := debug-sr.o switch.o tlb.o hyp-init.o ../hyp-entry.o
obj-y := $(patsubst %.o,%.hyp.o,$(obj-y))
extra-y := $(patsubst %.hyp.o,%.hyp.tmp.o,$(obj-y))
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
new file mode 100644
index 000000000000..b3752cfdcf3d
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ */
+
+#include <linux/compiler.h>
+#include <linux/kvm_host.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+#include <asm/kvm_mmu.h>
+
+#include "../debug-sr.h"
+
+static void __hyp_text __debug_save_spe(u64 *pmscr_el1)
+{
+ u64 reg;
+
+ /* Clear pmscr in case of early return */
+ *pmscr_el1 = 0;
+
+ /* SPE present on this CPU? */
+ if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
+ ID_AA64DFR0_PMSVER_SHIFT))
+ return;
+
+ /* Yes; is it owned by EL3? */
+ reg = read_sysreg_s(SYS_PMBIDR_EL1);
+ if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT))
+ return;
+
+ /* No; is the host actually using the thing? */
+ reg = read_sysreg_s(SYS_PMBLIMITR_EL1);
+ if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)))
+ return;
+
+ /* Yes; save the control register and disable data generation */
+ *pmscr_el1 = read_sysreg_s(SYS_PMSCR_EL1);
+ write_sysreg_s(0, SYS_PMSCR_EL1);
+ isb();
+
+ /* Now drain all buffered data to memory */
+ psb_csync();
+ dsb(nsh);
+}
+
+static void __hyp_text __debug_restore_spe(u64 pmscr_el1)
+{
+ if (!pmscr_el1)
+ return;
+
+ /* The host page table is installed, but not yet synchronised */
+ isb();
+
+ /* Re-enable data generation */
+ write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
+}
+
+void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
+{
+ /* Disable and flush SPE data generation */
+ __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
+ __debug_switch_to_guest_common(vcpu);
+}
+
+void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
+{
+ __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
+ __debug_switch_to_host_common(vcpu);
+}
+
+u32 __hyp_text __kvm_get_mdcr_el2(void)
+{
+ return read_sysreg(mdcr_el2);
+}
--
2.27.0
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
WARNING: multiple messages have this Message-ID (diff)
From: David Brazdil <dbrazdil@google.com>
To: Marc Zyngier <maz@kernel.org>, Will Deacon <will@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
James Morse <james.morse@arm.com>,
Julien Thierry <julien.thierry.kdev@gmail.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: android-kvm@google.com, linux-kernel@vger.kernel.org,
David Brazdil <dbrazdil@google.com>,
kernel-team@android.com, kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 09/15] arm64: kvm: Split hyp/debug-sr.c to VHE/nVHE
Date: Thu, 18 Jun 2020 13:25:31 +0100 [thread overview]
Message-ID: <20200618122537.9625-10-dbrazdil@google.com> (raw)
In-Reply-To: <20200618122537.9625-1-dbrazdil@google.com>
This patch is part of a series which builds KVM's non-VHE hyp code separately
from VHE and the rest of the kernel.
debug-sr.c contains KVM's code for context-switching debug registers, with some
parts shared between VHE/nVHE. These common routines are moved to debug-sr.h,
VHE-specific code is left in debug-sr.c and nVHE-specific code is moved to
nvhe/debug-sr.c.
Functions are slightly refactored to move code hidden behind `has_vhe()` checks
to the corresponding .c files.
Signed-off-by: David Brazdil <dbrazdil@google.com>
---
arch/arm64/kernel/image-vars.h | 3 -
arch/arm64/kvm/hyp/debug-sr.c | 210 +----------------------------
arch/arm64/kvm/hyp/debug-sr.h | 172 +++++++++++++++++++++++
arch/arm64/kvm/hyp/nvhe/Makefile | 2 +-
arch/arm64/kvm/hyp/nvhe/debug-sr.c | 77 +++++++++++
5 files changed, 256 insertions(+), 208 deletions(-)
create mode 100644 arch/arm64/kvm/hyp/debug-sr.h
create mode 100644 arch/arm64/kvm/hyp/nvhe/debug-sr.c
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 855f9718d6d9..8096e6f1f2bf 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -61,8 +61,6 @@ __efistub__ctype = _ctype;
* memory mappings.
*/
-__kvm_nvhe___debug_switch_to_guest = __debug_switch_to_guest;
-__kvm_nvhe___debug_switch_to_host = __debug_switch_to_host;
__kvm_nvhe___fpsimd_restore_state = __fpsimd_restore_state;
__kvm_nvhe___fpsimd_save_state = __fpsimd_save_state;
__kvm_nvhe___guest_enter = __guest_enter;
@@ -71,7 +69,6 @@ __kvm_nvhe___hyp_panic_string = __hyp_panic_string;
__kvm_nvhe___hyp_stub_vectors = __hyp_stub_vectors;
__kvm_nvhe___icache_flags = __icache_flags;
__kvm_nvhe___kvm_enable_ssbs = __kvm_enable_ssbs;
-__kvm_nvhe___kvm_get_mdcr_el2 = __kvm_get_mdcr_el2;
__kvm_nvhe___kvm_timer_set_cntvoff = __kvm_timer_set_cntvoff;
__kvm_nvhe___sysreg32_restore_state = __sysreg32_restore_state;
__kvm_nvhe___sysreg32_save_state = __sysreg32_save_state;
diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
index e95af204fec7..28c0a54cda2a 100644
--- a/arch/arm64/kvm/hyp/debug-sr.c
+++ b/arch/arm64/kvm/hyp/debug-sr.c
@@ -4,221 +4,23 @@
* Author: Marc Zyngier <marc.zyngier@arm.com>
*/
-#include <linux/compiler.h>
#include <linux/kvm_host.h>
-#include <asm/debug-monitors.h>
-#include <asm/kvm_asm.h>
#include <asm/kvm_hyp.h>
-#include <asm/kvm_mmu.h>
-#define read_debug(r,n) read_sysreg(r##n##_el1)
-#define write_debug(v,r,n) write_sysreg(v, r##n##_el1)
+#include "debug-sr.h"
-#define save_debug(ptr,reg,nr) \
- switch (nr) { \
- case 15: ptr[15] = read_debug(reg, 15); \
- /* Fall through */ \
- case 14: ptr[14] = read_debug(reg, 14); \
- /* Fall through */ \
- case 13: ptr[13] = read_debug(reg, 13); \
- /* Fall through */ \
- case 12: ptr[12] = read_debug(reg, 12); \
- /* Fall through */ \
- case 11: ptr[11] = read_debug(reg, 11); \
- /* Fall through */ \
- case 10: ptr[10] = read_debug(reg, 10); \
- /* Fall through */ \
- case 9: ptr[9] = read_debug(reg, 9); \
- /* Fall through */ \
- case 8: ptr[8] = read_debug(reg, 8); \
- /* Fall through */ \
- case 7: ptr[7] = read_debug(reg, 7); \
- /* Fall through */ \
- case 6: ptr[6] = read_debug(reg, 6); \
- /* Fall through */ \
- case 5: ptr[5] = read_debug(reg, 5); \
- /* Fall through */ \
- case 4: ptr[4] = read_debug(reg, 4); \
- /* Fall through */ \
- case 3: ptr[3] = read_debug(reg, 3); \
- /* Fall through */ \
- case 2: ptr[2] = read_debug(reg, 2); \
- /* Fall through */ \
- case 1: ptr[1] = read_debug(reg, 1); \
- /* Fall through */ \
- default: ptr[0] = read_debug(reg, 0); \
- }
-
-#define restore_debug(ptr,reg,nr) \
- switch (nr) { \
- case 15: write_debug(ptr[15], reg, 15); \
- /* Fall through */ \
- case 14: write_debug(ptr[14], reg, 14); \
- /* Fall through */ \
- case 13: write_debug(ptr[13], reg, 13); \
- /* Fall through */ \
- case 12: write_debug(ptr[12], reg, 12); \
- /* Fall through */ \
- case 11: write_debug(ptr[11], reg, 11); \
- /* Fall through */ \
- case 10: write_debug(ptr[10], reg, 10); \
- /* Fall through */ \
- case 9: write_debug(ptr[9], reg, 9); \
- /* Fall through */ \
- case 8: write_debug(ptr[8], reg, 8); \
- /* Fall through */ \
- case 7: write_debug(ptr[7], reg, 7); \
- /* Fall through */ \
- case 6: write_debug(ptr[6], reg, 6); \
- /* Fall through */ \
- case 5: write_debug(ptr[5], reg, 5); \
- /* Fall through */ \
- case 4: write_debug(ptr[4], reg, 4); \
- /* Fall through */ \
- case 3: write_debug(ptr[3], reg, 3); \
- /* Fall through */ \
- case 2: write_debug(ptr[2], reg, 2); \
- /* Fall through */ \
- case 1: write_debug(ptr[1], reg, 1); \
- /* Fall through */ \
- default: write_debug(ptr[0], reg, 0); \
- }
-
-static void __hyp_text __debug_save_spe_nvhe(u64 *pmscr_el1)
-{
- u64 reg;
-
- /* Clear pmscr in case of early return */
- *pmscr_el1 = 0;
-
- /* SPE present on this CPU? */
- if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
- ID_AA64DFR0_PMSVER_SHIFT))
- return;
-
- /* Yes; is it owned by EL3? */
- reg = read_sysreg_s(SYS_PMBIDR_EL1);
- if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT))
- return;
-
- /* No; is the host actually using the thing? */
- reg = read_sysreg_s(SYS_PMBLIMITR_EL1);
- if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)))
- return;
-
- /* Yes; save the control register and disable data generation */
- *pmscr_el1 = read_sysreg_s(SYS_PMSCR_EL1);
- write_sysreg_s(0, SYS_PMSCR_EL1);
- isb();
-
- /* Now drain all buffered data to memory */
- psb_csync();
- dsb(nsh);
-}
-
-static void __hyp_text __debug_restore_spe_nvhe(u64 pmscr_el1)
-{
- if (!pmscr_el1)
- return;
-
- /* The host page table is installed, but not yet synchronised */
- isb();
-
- /* Re-enable data generation */
- write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
-}
-
-static void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
- struct kvm_guest_debug_arch *dbg,
- struct kvm_cpu_context *ctxt)
-{
- u64 aa64dfr0;
- int brps, wrps;
-
- aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
- brps = (aa64dfr0 >> 12) & 0xf;
- wrps = (aa64dfr0 >> 20) & 0xf;
-
- save_debug(dbg->dbg_bcr, dbgbcr, brps);
- save_debug(dbg->dbg_bvr, dbgbvr, brps);
- save_debug(dbg->dbg_wcr, dbgwcr, wrps);
- save_debug(dbg->dbg_wvr, dbgwvr, wrps);
-
- ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
-}
-
-static void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
- struct kvm_guest_debug_arch *dbg,
- struct kvm_cpu_context *ctxt)
+void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
{
- u64 aa64dfr0;
- int brps, wrps;
-
- aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
-
- brps = (aa64dfr0 >> 12) & 0xf;
- wrps = (aa64dfr0 >> 20) & 0xf;
-
- restore_debug(dbg->dbg_bcr, dbgbcr, brps);
- restore_debug(dbg->dbg_bvr, dbgbvr, brps);
- restore_debug(dbg->dbg_wcr, dbgwcr, wrps);
- restore_debug(dbg->dbg_wvr, dbgwvr, wrps);
-
- write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
+ __debug_switch_to_guest_common(vcpu);
}
-void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
+void __debug_switch_to_host(struct kvm_vcpu *vcpu)
{
- struct kvm_cpu_context *host_ctxt;
- struct kvm_cpu_context *guest_ctxt;
- struct kvm_guest_debug_arch *host_dbg;
- struct kvm_guest_debug_arch *guest_dbg;
-
- /*
- * Non-VHE: Disable and flush SPE data generation
- * VHE: The vcpu can run, but it can't hide.
- */
- if (!has_vhe())
- __debug_save_spe_nvhe(&vcpu->arch.host_debug_state.pmscr_el1);
-
- if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
- return;
-
- host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
- guest_ctxt = &vcpu->arch.ctxt;
- host_dbg = &vcpu->arch.host_debug_state.regs;
- guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
-
- __debug_save_state(vcpu, host_dbg, host_ctxt);
- __debug_restore_state(vcpu, guest_dbg, guest_ctxt);
-}
-
-void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
-{
- struct kvm_cpu_context *host_ctxt;
- struct kvm_cpu_context *guest_ctxt;
- struct kvm_guest_debug_arch *host_dbg;
- struct kvm_guest_debug_arch *guest_dbg;
-
- if (!has_vhe())
- __debug_restore_spe_nvhe(vcpu->arch.host_debug_state.pmscr_el1);
-
- if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
- return;
-
- host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
- guest_ctxt = &vcpu->arch.ctxt;
- host_dbg = &vcpu->arch.host_debug_state.regs;
- guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
-
- __debug_save_state(vcpu, guest_dbg, guest_ctxt);
- __debug_restore_state(vcpu, host_dbg, host_ctxt);
-
- vcpu->arch.flags &= ~KVM_ARM64_DEBUG_DIRTY;
+ __debug_switch_to_host_common(vcpu);
}
-u32 __hyp_text __kvm_get_mdcr_el2(void)
+u32 __kvm_get_mdcr_el2(void)
{
return read_sysreg(mdcr_el2);
}
diff --git a/arch/arm64/kvm/hyp/debug-sr.h b/arch/arm64/kvm/hyp/debug-sr.h
new file mode 100644
index 000000000000..62b5deeb301d
--- /dev/null
+++ b/arch/arm64/kvm/hyp/debug-sr.h
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ */
+
+#ifndef __ARM64_KVM_HYP_DEBUG_SR_H__
+#define __ARM64_KVM_HYP_DEBUG_SR_H__
+
+#include <linux/compiler.h>
+#include <linux/kvm_host.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+#include <asm/kvm_mmu.h>
+
+#define read_debug(r,n) read_sysreg(r##n##_el1)
+#define write_debug(v,r,n) write_sysreg(v, r##n##_el1)
+
+#define save_debug(ptr,reg,nr) \
+ switch (nr) { \
+ case 15: ptr[15] = read_debug(reg, 15); \
+ /* Fall through */ \
+ case 14: ptr[14] = read_debug(reg, 14); \
+ /* Fall through */ \
+ case 13: ptr[13] = read_debug(reg, 13); \
+ /* Fall through */ \
+ case 12: ptr[12] = read_debug(reg, 12); \
+ /* Fall through */ \
+ case 11: ptr[11] = read_debug(reg, 11); \
+ /* Fall through */ \
+ case 10: ptr[10] = read_debug(reg, 10); \
+ /* Fall through */ \
+ case 9: ptr[9] = read_debug(reg, 9); \
+ /* Fall through */ \
+ case 8: ptr[8] = read_debug(reg, 8); \
+ /* Fall through */ \
+ case 7: ptr[7] = read_debug(reg, 7); \
+ /* Fall through */ \
+ case 6: ptr[6] = read_debug(reg, 6); \
+ /* Fall through */ \
+ case 5: ptr[5] = read_debug(reg, 5); \
+ /* Fall through */ \
+ case 4: ptr[4] = read_debug(reg, 4); \
+ /* Fall through */ \
+ case 3: ptr[3] = read_debug(reg, 3); \
+ /* Fall through */ \
+ case 2: ptr[2] = read_debug(reg, 2); \
+ /* Fall through */ \
+ case 1: ptr[1] = read_debug(reg, 1); \
+ /* Fall through */ \
+ default: ptr[0] = read_debug(reg, 0); \
+ }
+
+#define restore_debug(ptr,reg,nr) \
+ switch (nr) { \
+ case 15: write_debug(ptr[15], reg, 15); \
+ /* Fall through */ \
+ case 14: write_debug(ptr[14], reg, 14); \
+ /* Fall through */ \
+ case 13: write_debug(ptr[13], reg, 13); \
+ /* Fall through */ \
+ case 12: write_debug(ptr[12], reg, 12); \
+ /* Fall through */ \
+ case 11: write_debug(ptr[11], reg, 11); \
+ /* Fall through */ \
+ case 10: write_debug(ptr[10], reg, 10); \
+ /* Fall through */ \
+ case 9: write_debug(ptr[9], reg, 9); \
+ /* Fall through */ \
+ case 8: write_debug(ptr[8], reg, 8); \
+ /* Fall through */ \
+ case 7: write_debug(ptr[7], reg, 7); \
+ /* Fall through */ \
+ case 6: write_debug(ptr[6], reg, 6); \
+ /* Fall through */ \
+ case 5: write_debug(ptr[5], reg, 5); \
+ /* Fall through */ \
+ case 4: write_debug(ptr[4], reg, 4); \
+ /* Fall through */ \
+ case 3: write_debug(ptr[3], reg, 3); \
+ /* Fall through */ \
+ case 2: write_debug(ptr[2], reg, 2); \
+ /* Fall through */ \
+ case 1: write_debug(ptr[1], reg, 1); \
+ /* Fall through */ \
+ default: write_debug(ptr[0], reg, 0); \
+ }
+
+static inline void __hyp_text
+__debug_save_state(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt)
+{
+ u64 aa64dfr0;
+ int brps, wrps;
+
+ aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
+ brps = (aa64dfr0 >> 12) & 0xf;
+ wrps = (aa64dfr0 >> 20) & 0xf;
+
+ save_debug(dbg->dbg_bcr, dbgbcr, brps);
+ save_debug(dbg->dbg_bvr, dbgbvr, brps);
+ save_debug(dbg->dbg_wcr, dbgwcr, wrps);
+ save_debug(dbg->dbg_wvr, dbgwvr, wrps);
+
+ ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
+}
+
+static inline void __hyp_text
+__debug_restore_state(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt)
+{
+ u64 aa64dfr0;
+ int brps, wrps;
+
+ aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
+
+ brps = (aa64dfr0 >> 12) & 0xf;
+ wrps = (aa64dfr0 >> 20) & 0xf;
+
+ restore_debug(dbg->dbg_bcr, dbgbcr, brps);
+ restore_debug(dbg->dbg_bvr, dbgbvr, brps);
+ restore_debug(dbg->dbg_wcr, dbgwcr, wrps);
+ restore_debug(dbg->dbg_wvr, dbgwvr, wrps);
+
+ write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
+}
+
+static inline void __hyp_text
+__debug_switch_to_guest_common(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_cpu_context *guest_ctxt;
+ struct kvm_guest_debug_arch *host_dbg;
+ struct kvm_guest_debug_arch *guest_dbg;
+
+ if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
+ return;
+
+ host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
+ guest_ctxt = &vcpu->arch.ctxt;
+ host_dbg = &vcpu->arch.host_debug_state.regs;
+ guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
+
+ __debug_save_state(vcpu, host_dbg, host_ctxt);
+ __debug_restore_state(vcpu, guest_dbg, guest_ctxt);
+}
+
+static inline void __hyp_text
+__debug_switch_to_host_common(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_cpu_context *guest_ctxt;
+ struct kvm_guest_debug_arch *host_dbg;
+ struct kvm_guest_debug_arch *guest_dbg;
+
+ if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
+ return;
+
+ host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
+ guest_ctxt = &vcpu->arch.ctxt;
+ host_dbg = &vcpu->arch.host_debug_state.regs;
+ guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
+
+ __debug_save_state(vcpu, guest_dbg, guest_ctxt);
+ __debug_restore_state(vcpu, host_dbg, host_ctxt);
+
+ vcpu->arch.flags &= ~KVM_ARM64_DEBUG_DIRTY;
+}
+
+#endif /* __ARM64_KVM_HYP_DEBUG_SR_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 336b1bf64ceb..95a06786bf26 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -7,7 +7,7 @@ asflags-y := -D__KVM_NVHE_HYPERVISOR__
ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -fno-stack-protector \
-DDISABLE_BRANCH_PROFILING $(DISABLE_STACKLEAK_PLUGIN)
-obj-y := switch.o tlb.o hyp-init.o ../hyp-entry.o
+obj-y := debug-sr.o switch.o tlb.o hyp-init.o ../hyp-entry.o
obj-y := $(patsubst %.o,%.hyp.o,$(obj-y))
extra-y := $(patsubst %.hyp.o,%.hyp.tmp.o,$(obj-y))
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
new file mode 100644
index 000000000000..b3752cfdcf3d
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ */
+
+#include <linux/compiler.h>
+#include <linux/kvm_host.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+#include <asm/kvm_mmu.h>
+
+#include "../debug-sr.h"
+
+static void __hyp_text __debug_save_spe(u64 *pmscr_el1)
+{
+ u64 reg;
+
+ /* Clear pmscr in case of early return */
+ *pmscr_el1 = 0;
+
+ /* SPE present on this CPU? */
+ if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
+ ID_AA64DFR0_PMSVER_SHIFT))
+ return;
+
+ /* Yes; is it owned by EL3? */
+ reg = read_sysreg_s(SYS_PMBIDR_EL1);
+ if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT))
+ return;
+
+ /* No; is the host actually using the thing? */
+ reg = read_sysreg_s(SYS_PMBLIMITR_EL1);
+ if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)))
+ return;
+
+ /* Yes; save the control register and disable data generation */
+ *pmscr_el1 = read_sysreg_s(SYS_PMSCR_EL1);
+ write_sysreg_s(0, SYS_PMSCR_EL1);
+ isb();
+
+ /* Now drain all buffered data to memory */
+ psb_csync();
+ dsb(nsh);
+}
+
+static void __hyp_text __debug_restore_spe(u64 pmscr_el1)
+{
+ if (!pmscr_el1)
+ return;
+
+ /* The host page table is installed, but not yet synchronised */
+ isb();
+
+ /* Re-enable data generation */
+ write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
+}
+
+void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
+{
+ /* Disable and flush SPE data generation */
+ __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
+ __debug_switch_to_guest_common(vcpu);
+}
+
+void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
+{
+ __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
+ __debug_switch_to_host_common(vcpu);
+}
+
+u32 __hyp_text __kvm_get_mdcr_el2(void)
+{
+ return read_sysreg(mdcr_el2);
+}
--
2.27.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: David Brazdil <dbrazdil@google.com>
To: Marc Zyngier <maz@kernel.org>, Will Deacon <will@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
James Morse <james.morse@arm.com>,
Julien Thierry <julien.thierry.kdev@gmail.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, android-kvm@google.com,
kernel-team@android.com, David Brazdil <dbrazdil@google.com>
Subject: [PATCH v3 09/15] arm64: kvm: Split hyp/debug-sr.c to VHE/nVHE
Date: Thu, 18 Jun 2020 13:25:31 +0100 [thread overview]
Message-ID: <20200618122537.9625-10-dbrazdil@google.com> (raw)
In-Reply-To: <20200618122537.9625-1-dbrazdil@google.com>
This patch is part of a series which builds KVM's non-VHE hyp code separately
from VHE and the rest of the kernel.
debug-sr.c contains KVM's code for context-switching debug registers, with some
parts shared between VHE/nVHE. These common routines are moved to debug-sr.h,
VHE-specific code is left in debug-sr.c and nVHE-specific code is moved to
nvhe/debug-sr.c.
Functions are slightly refactored to move code hidden behind `has_vhe()` checks
to the corresponding .c files.
Signed-off-by: David Brazdil <dbrazdil@google.com>
---
arch/arm64/kernel/image-vars.h | 3 -
arch/arm64/kvm/hyp/debug-sr.c | 210 +----------------------------
arch/arm64/kvm/hyp/debug-sr.h | 172 +++++++++++++++++++++++
arch/arm64/kvm/hyp/nvhe/Makefile | 2 +-
arch/arm64/kvm/hyp/nvhe/debug-sr.c | 77 +++++++++++
5 files changed, 256 insertions(+), 208 deletions(-)
create mode 100644 arch/arm64/kvm/hyp/debug-sr.h
create mode 100644 arch/arm64/kvm/hyp/nvhe/debug-sr.c
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 855f9718d6d9..8096e6f1f2bf 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -61,8 +61,6 @@ __efistub__ctype = _ctype;
* memory mappings.
*/
-__kvm_nvhe___debug_switch_to_guest = __debug_switch_to_guest;
-__kvm_nvhe___debug_switch_to_host = __debug_switch_to_host;
__kvm_nvhe___fpsimd_restore_state = __fpsimd_restore_state;
__kvm_nvhe___fpsimd_save_state = __fpsimd_save_state;
__kvm_nvhe___guest_enter = __guest_enter;
@@ -71,7 +69,6 @@ __kvm_nvhe___hyp_panic_string = __hyp_panic_string;
__kvm_nvhe___hyp_stub_vectors = __hyp_stub_vectors;
__kvm_nvhe___icache_flags = __icache_flags;
__kvm_nvhe___kvm_enable_ssbs = __kvm_enable_ssbs;
-__kvm_nvhe___kvm_get_mdcr_el2 = __kvm_get_mdcr_el2;
__kvm_nvhe___kvm_timer_set_cntvoff = __kvm_timer_set_cntvoff;
__kvm_nvhe___sysreg32_restore_state = __sysreg32_restore_state;
__kvm_nvhe___sysreg32_save_state = __sysreg32_save_state;
diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
index e95af204fec7..28c0a54cda2a 100644
--- a/arch/arm64/kvm/hyp/debug-sr.c
+++ b/arch/arm64/kvm/hyp/debug-sr.c
@@ -4,221 +4,23 @@
* Author: Marc Zyngier <marc.zyngier@arm.com>
*/
-#include <linux/compiler.h>
#include <linux/kvm_host.h>
-#include <asm/debug-monitors.h>
-#include <asm/kvm_asm.h>
#include <asm/kvm_hyp.h>
-#include <asm/kvm_mmu.h>
-#define read_debug(r,n) read_sysreg(r##n##_el1)
-#define write_debug(v,r,n) write_sysreg(v, r##n##_el1)
+#include "debug-sr.h"
-#define save_debug(ptr,reg,nr) \
- switch (nr) { \
- case 15: ptr[15] = read_debug(reg, 15); \
- /* Fall through */ \
- case 14: ptr[14] = read_debug(reg, 14); \
- /* Fall through */ \
- case 13: ptr[13] = read_debug(reg, 13); \
- /* Fall through */ \
- case 12: ptr[12] = read_debug(reg, 12); \
- /* Fall through */ \
- case 11: ptr[11] = read_debug(reg, 11); \
- /* Fall through */ \
- case 10: ptr[10] = read_debug(reg, 10); \
- /* Fall through */ \
- case 9: ptr[9] = read_debug(reg, 9); \
- /* Fall through */ \
- case 8: ptr[8] = read_debug(reg, 8); \
- /* Fall through */ \
- case 7: ptr[7] = read_debug(reg, 7); \
- /* Fall through */ \
- case 6: ptr[6] = read_debug(reg, 6); \
- /* Fall through */ \
- case 5: ptr[5] = read_debug(reg, 5); \
- /* Fall through */ \
- case 4: ptr[4] = read_debug(reg, 4); \
- /* Fall through */ \
- case 3: ptr[3] = read_debug(reg, 3); \
- /* Fall through */ \
- case 2: ptr[2] = read_debug(reg, 2); \
- /* Fall through */ \
- case 1: ptr[1] = read_debug(reg, 1); \
- /* Fall through */ \
- default: ptr[0] = read_debug(reg, 0); \
- }
-
-#define restore_debug(ptr,reg,nr) \
- switch (nr) { \
- case 15: write_debug(ptr[15], reg, 15); \
- /* Fall through */ \
- case 14: write_debug(ptr[14], reg, 14); \
- /* Fall through */ \
- case 13: write_debug(ptr[13], reg, 13); \
- /* Fall through */ \
- case 12: write_debug(ptr[12], reg, 12); \
- /* Fall through */ \
- case 11: write_debug(ptr[11], reg, 11); \
- /* Fall through */ \
- case 10: write_debug(ptr[10], reg, 10); \
- /* Fall through */ \
- case 9: write_debug(ptr[9], reg, 9); \
- /* Fall through */ \
- case 8: write_debug(ptr[8], reg, 8); \
- /* Fall through */ \
- case 7: write_debug(ptr[7], reg, 7); \
- /* Fall through */ \
- case 6: write_debug(ptr[6], reg, 6); \
- /* Fall through */ \
- case 5: write_debug(ptr[5], reg, 5); \
- /* Fall through */ \
- case 4: write_debug(ptr[4], reg, 4); \
- /* Fall through */ \
- case 3: write_debug(ptr[3], reg, 3); \
- /* Fall through */ \
- case 2: write_debug(ptr[2], reg, 2); \
- /* Fall through */ \
- case 1: write_debug(ptr[1], reg, 1); \
- /* Fall through */ \
- default: write_debug(ptr[0], reg, 0); \
- }
-
-static void __hyp_text __debug_save_spe_nvhe(u64 *pmscr_el1)
-{
- u64 reg;
-
- /* Clear pmscr in case of early return */
- *pmscr_el1 = 0;
-
- /* SPE present on this CPU? */
- if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
- ID_AA64DFR0_PMSVER_SHIFT))
- return;
-
- /* Yes; is it owned by EL3? */
- reg = read_sysreg_s(SYS_PMBIDR_EL1);
- if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT))
- return;
-
- /* No; is the host actually using the thing? */
- reg = read_sysreg_s(SYS_PMBLIMITR_EL1);
- if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)))
- return;
-
- /* Yes; save the control register and disable data generation */
- *pmscr_el1 = read_sysreg_s(SYS_PMSCR_EL1);
- write_sysreg_s(0, SYS_PMSCR_EL1);
- isb();
-
- /* Now drain all buffered data to memory */
- psb_csync();
- dsb(nsh);
-}
-
-static void __hyp_text __debug_restore_spe_nvhe(u64 pmscr_el1)
-{
- if (!pmscr_el1)
- return;
-
- /* The host page table is installed, but not yet synchronised */
- isb();
-
- /* Re-enable data generation */
- write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
-}
-
-static void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
- struct kvm_guest_debug_arch *dbg,
- struct kvm_cpu_context *ctxt)
-{
- u64 aa64dfr0;
- int brps, wrps;
-
- aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
- brps = (aa64dfr0 >> 12) & 0xf;
- wrps = (aa64dfr0 >> 20) & 0xf;
-
- save_debug(dbg->dbg_bcr, dbgbcr, brps);
- save_debug(dbg->dbg_bvr, dbgbvr, brps);
- save_debug(dbg->dbg_wcr, dbgwcr, wrps);
- save_debug(dbg->dbg_wvr, dbgwvr, wrps);
-
- ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
-}
-
-static void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
- struct kvm_guest_debug_arch *dbg,
- struct kvm_cpu_context *ctxt)
+void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
{
- u64 aa64dfr0;
- int brps, wrps;
-
- aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
-
- brps = (aa64dfr0 >> 12) & 0xf;
- wrps = (aa64dfr0 >> 20) & 0xf;
-
- restore_debug(dbg->dbg_bcr, dbgbcr, brps);
- restore_debug(dbg->dbg_bvr, dbgbvr, brps);
- restore_debug(dbg->dbg_wcr, dbgwcr, wrps);
- restore_debug(dbg->dbg_wvr, dbgwvr, wrps);
-
- write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
+ __debug_switch_to_guest_common(vcpu);
}
-void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
+void __debug_switch_to_host(struct kvm_vcpu *vcpu)
{
- struct kvm_cpu_context *host_ctxt;
- struct kvm_cpu_context *guest_ctxt;
- struct kvm_guest_debug_arch *host_dbg;
- struct kvm_guest_debug_arch *guest_dbg;
-
- /*
- * Non-VHE: Disable and flush SPE data generation
- * VHE: The vcpu can run, but it can't hide.
- */
- if (!has_vhe())
- __debug_save_spe_nvhe(&vcpu->arch.host_debug_state.pmscr_el1);
-
- if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
- return;
-
- host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
- guest_ctxt = &vcpu->arch.ctxt;
- host_dbg = &vcpu->arch.host_debug_state.regs;
- guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
-
- __debug_save_state(vcpu, host_dbg, host_ctxt);
- __debug_restore_state(vcpu, guest_dbg, guest_ctxt);
-}
-
-void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
-{
- struct kvm_cpu_context *host_ctxt;
- struct kvm_cpu_context *guest_ctxt;
- struct kvm_guest_debug_arch *host_dbg;
- struct kvm_guest_debug_arch *guest_dbg;
-
- if (!has_vhe())
- __debug_restore_spe_nvhe(vcpu->arch.host_debug_state.pmscr_el1);
-
- if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
- return;
-
- host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
- guest_ctxt = &vcpu->arch.ctxt;
- host_dbg = &vcpu->arch.host_debug_state.regs;
- guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
-
- __debug_save_state(vcpu, guest_dbg, guest_ctxt);
- __debug_restore_state(vcpu, host_dbg, host_ctxt);
-
- vcpu->arch.flags &= ~KVM_ARM64_DEBUG_DIRTY;
+ __debug_switch_to_host_common(vcpu);
}
-u32 __hyp_text __kvm_get_mdcr_el2(void)
+u32 __kvm_get_mdcr_el2(void)
{
return read_sysreg(mdcr_el2);
}
diff --git a/arch/arm64/kvm/hyp/debug-sr.h b/arch/arm64/kvm/hyp/debug-sr.h
new file mode 100644
index 000000000000..62b5deeb301d
--- /dev/null
+++ b/arch/arm64/kvm/hyp/debug-sr.h
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ */
+
+#ifndef __ARM64_KVM_HYP_DEBUG_SR_H__
+#define __ARM64_KVM_HYP_DEBUG_SR_H__
+
+#include <linux/compiler.h>
+#include <linux/kvm_host.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+#include <asm/kvm_mmu.h>
+
+#define read_debug(r,n) read_sysreg(r##n##_el1)
+#define write_debug(v,r,n) write_sysreg(v, r##n##_el1)
+
+#define save_debug(ptr,reg,nr) \
+ switch (nr) { \
+ case 15: ptr[15] = read_debug(reg, 15); \
+ /* Fall through */ \
+ case 14: ptr[14] = read_debug(reg, 14); \
+ /* Fall through */ \
+ case 13: ptr[13] = read_debug(reg, 13); \
+ /* Fall through */ \
+ case 12: ptr[12] = read_debug(reg, 12); \
+ /* Fall through */ \
+ case 11: ptr[11] = read_debug(reg, 11); \
+ /* Fall through */ \
+ case 10: ptr[10] = read_debug(reg, 10); \
+ /* Fall through */ \
+ case 9: ptr[9] = read_debug(reg, 9); \
+ /* Fall through */ \
+ case 8: ptr[8] = read_debug(reg, 8); \
+ /* Fall through */ \
+ case 7: ptr[7] = read_debug(reg, 7); \
+ /* Fall through */ \
+ case 6: ptr[6] = read_debug(reg, 6); \
+ /* Fall through */ \
+ case 5: ptr[5] = read_debug(reg, 5); \
+ /* Fall through */ \
+ case 4: ptr[4] = read_debug(reg, 4); \
+ /* Fall through */ \
+ case 3: ptr[3] = read_debug(reg, 3); \
+ /* Fall through */ \
+ case 2: ptr[2] = read_debug(reg, 2); \
+ /* Fall through */ \
+ case 1: ptr[1] = read_debug(reg, 1); \
+ /* Fall through */ \
+ default: ptr[0] = read_debug(reg, 0); \
+ }
+
+#define restore_debug(ptr,reg,nr) \
+ switch (nr) { \
+ case 15: write_debug(ptr[15], reg, 15); \
+ /* Fall through */ \
+ case 14: write_debug(ptr[14], reg, 14); \
+ /* Fall through */ \
+ case 13: write_debug(ptr[13], reg, 13); \
+ /* Fall through */ \
+ case 12: write_debug(ptr[12], reg, 12); \
+ /* Fall through */ \
+ case 11: write_debug(ptr[11], reg, 11); \
+ /* Fall through */ \
+ case 10: write_debug(ptr[10], reg, 10); \
+ /* Fall through */ \
+ case 9: write_debug(ptr[9], reg, 9); \
+ /* Fall through */ \
+ case 8: write_debug(ptr[8], reg, 8); \
+ /* Fall through */ \
+ case 7: write_debug(ptr[7], reg, 7); \
+ /* Fall through */ \
+ case 6: write_debug(ptr[6], reg, 6); \
+ /* Fall through */ \
+ case 5: write_debug(ptr[5], reg, 5); \
+ /* Fall through */ \
+ case 4: write_debug(ptr[4], reg, 4); \
+ /* Fall through */ \
+ case 3: write_debug(ptr[3], reg, 3); \
+ /* Fall through */ \
+ case 2: write_debug(ptr[2], reg, 2); \
+ /* Fall through */ \
+ case 1: write_debug(ptr[1], reg, 1); \
+ /* Fall through */ \
+ default: write_debug(ptr[0], reg, 0); \
+ }
+
+static inline void __hyp_text
+__debug_save_state(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt)
+{
+ u64 aa64dfr0;
+ int brps, wrps;
+
+ aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
+ brps = (aa64dfr0 >> 12) & 0xf;
+ wrps = (aa64dfr0 >> 20) & 0xf;
+
+ save_debug(dbg->dbg_bcr, dbgbcr, brps);
+ save_debug(dbg->dbg_bvr, dbgbvr, brps);
+ save_debug(dbg->dbg_wcr, dbgwcr, wrps);
+ save_debug(dbg->dbg_wvr, dbgwvr, wrps);
+
+ ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
+}
+
+static inline void __hyp_text
+__debug_restore_state(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *dbg,
+ struct kvm_cpu_context *ctxt)
+{
+ u64 aa64dfr0;
+ int brps, wrps;
+
+ aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
+
+ brps = (aa64dfr0 >> 12) & 0xf;
+ wrps = (aa64dfr0 >> 20) & 0xf;
+
+ restore_debug(dbg->dbg_bcr, dbgbcr, brps);
+ restore_debug(dbg->dbg_bvr, dbgbvr, brps);
+ restore_debug(dbg->dbg_wcr, dbgwcr, wrps);
+ restore_debug(dbg->dbg_wvr, dbgwvr, wrps);
+
+ write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
+}
+
+static inline void __hyp_text
+__debug_switch_to_guest_common(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_cpu_context *guest_ctxt;
+ struct kvm_guest_debug_arch *host_dbg;
+ struct kvm_guest_debug_arch *guest_dbg;
+
+ if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
+ return;
+
+ host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
+ guest_ctxt = &vcpu->arch.ctxt;
+ host_dbg = &vcpu->arch.host_debug_state.regs;
+ guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
+
+ __debug_save_state(vcpu, host_dbg, host_ctxt);
+ __debug_restore_state(vcpu, guest_dbg, guest_ctxt);
+}
+
+static inline void __hyp_text
+__debug_switch_to_host_common(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *host_ctxt;
+ struct kvm_cpu_context *guest_ctxt;
+ struct kvm_guest_debug_arch *host_dbg;
+ struct kvm_guest_debug_arch *guest_dbg;
+
+ if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY))
+ return;
+
+ host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt;
+ guest_ctxt = &vcpu->arch.ctxt;
+ host_dbg = &vcpu->arch.host_debug_state.regs;
+ guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
+
+ __debug_save_state(vcpu, guest_dbg, guest_ctxt);
+ __debug_restore_state(vcpu, host_dbg, host_ctxt);
+
+ vcpu->arch.flags &= ~KVM_ARM64_DEBUG_DIRTY;
+}
+
+#endif /* __ARM64_KVM_HYP_DEBUG_SR_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 336b1bf64ceb..95a06786bf26 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -7,7 +7,7 @@ asflags-y := -D__KVM_NVHE_HYPERVISOR__
ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -fno-stack-protector \
-DDISABLE_BRANCH_PROFILING $(DISABLE_STACKLEAK_PLUGIN)
-obj-y := switch.o tlb.o hyp-init.o ../hyp-entry.o
+obj-y := debug-sr.o switch.o tlb.o hyp-init.o ../hyp-entry.o
obj-y := $(patsubst %.o,%.hyp.o,$(obj-y))
extra-y := $(patsubst %.hyp.o,%.hyp.tmp.o,$(obj-y))
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
new file mode 100644
index 000000000000..b3752cfdcf3d
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ */
+
+#include <linux/compiler.h>
+#include <linux/kvm_host.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_hyp.h>
+#include <asm/kvm_mmu.h>
+
+#include "../debug-sr.h"
+
+static void __hyp_text __debug_save_spe(u64 *pmscr_el1)
+{
+ u64 reg;
+
+ /* Clear pmscr in case of early return */
+ *pmscr_el1 = 0;
+
+ /* SPE present on this CPU? */
+ if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
+ ID_AA64DFR0_PMSVER_SHIFT))
+ return;
+
+ /* Yes; is it owned by EL3? */
+ reg = read_sysreg_s(SYS_PMBIDR_EL1);
+ if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT))
+ return;
+
+ /* No; is the host actually using the thing? */
+ reg = read_sysreg_s(SYS_PMBLIMITR_EL1);
+ if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)))
+ return;
+
+ /* Yes; save the control register and disable data generation */
+ *pmscr_el1 = read_sysreg_s(SYS_PMSCR_EL1);
+ write_sysreg_s(0, SYS_PMSCR_EL1);
+ isb();
+
+ /* Now drain all buffered data to memory */
+ psb_csync();
+ dsb(nsh);
+}
+
+static void __hyp_text __debug_restore_spe(u64 pmscr_el1)
+{
+ if (!pmscr_el1)
+ return;
+
+ /* The host page table is installed, but not yet synchronised */
+ isb();
+
+ /* Re-enable data generation */
+ write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
+}
+
+void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
+{
+ /* Disable and flush SPE data generation */
+ __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
+ __debug_switch_to_guest_common(vcpu);
+}
+
+void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
+{
+ __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
+ __debug_switch_to_host_common(vcpu);
+}
+
+u32 __hyp_text __kvm_get_mdcr_el2(void)
+{
+ return read_sysreg(mdcr_el2);
+}
--
2.27.0
next prev parent reply other threads:[~2020-06-18 12:26 UTC|newest]
Thread overview: 110+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-18 12:25 [PATCH v3 00/15] Split off nVHE hyp code David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 01/15] arm64: kvm: Fix symbol dependency in __hyp_call_panic_nvhe David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 02/15] arm64: kvm: Move __smccc_workaround_1_smc to .rodata David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 13:57 ` Marc Zyngier
2020-06-18 13:57 ` Marc Zyngier
2020-06-18 13:57 ` Marc Zyngier
2020-06-19 9:51 ` David Brazdil
2020-06-19 9:51 ` David Brazdil
2020-06-19 9:51 ` David Brazdil
2020-06-19 10:06 ` Marc Zyngier
2020-06-19 10:06 ` Marc Zyngier
2020-06-19 10:06 ` Marc Zyngier
2020-06-18 12:25 ` [PATCH v3 03/15] arm64: kvm: Add build rules for separate nVHE object files David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 16:34 ` Marc Zyngier
2020-06-18 16:34 ` Marc Zyngier
2020-06-18 16:34 ` Marc Zyngier
2020-06-19 12:11 ` David Brazdil
2020-06-19 12:11 ` David Brazdil
2020-06-19 12:11 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 04/15] arm64: kvm: Handle calls to prefixed hyp functions David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 16:51 ` Marc Zyngier
2020-06-18 16:51 ` Marc Zyngier
2020-06-18 16:51 ` Marc Zyngier
2020-06-18 17:04 ` kernel test robot
2020-06-18 17:04 ` kernel test robot
2020-06-18 12:25 ` [PATCH v3 05/15] arm64: kvm: Build hyp-entry.S separately for VHE/nVHE David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 17:17 ` Marc Zyngier
2020-06-18 17:17 ` Marc Zyngier
2020-06-18 17:17 ` Marc Zyngier
2020-06-22 10:20 ` David Brazdil
2020-06-22 10:20 ` David Brazdil
2020-06-25 8:12 ` Marc Zyngier
2020-06-25 8:12 ` Marc Zyngier
2020-06-25 8:12 ` Marc Zyngier
2020-06-25 11:53 ` David Brazdil
2020-06-25 11:53 ` David Brazdil
2020-06-25 11:53 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 06/15] arm64: kvm: Move hyp-init.S to nVHE David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 07/15] arm64: kvm: Split hyp/tlb.c to VHE/nVHE David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-19 8:28 ` Marc Zyngier
2020-06-19 8:28 ` Marc Zyngier
2020-06-19 8:28 ` Marc Zyngier
2020-06-18 12:25 ` [PATCH v3 08/15] arm64: kvm: Split hyp/switch.c " David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 19:52 ` kernel test robot
2020-06-18 19:52 ` kernel test robot
2020-06-18 19:52 ` kernel test robot
2020-06-18 19:52 ` kernel test robot
2020-06-25 5:03 ` kernel test robot
2020-06-25 5:03 ` kernel test robot
2020-06-25 5:03 ` kernel test robot
2020-06-25 5:03 ` kernel test robot
2020-06-25 8:16 ` Marc Zyngier
2020-06-25 8:16 ` Marc Zyngier
2020-06-25 8:16 ` Marc Zyngier
2020-06-25 8:16 ` Marc Zyngier
2020-06-25 8:34 ` Will Deacon
2020-06-25 8:34 ` Will Deacon
2020-06-25 8:34 ` Will Deacon
2020-06-25 8:34 ` Will Deacon
2020-06-25 18:26 ` Nick Desaulniers
2020-06-25 18:26 ` Nick Desaulniers
2020-06-25 18:26 ` Nick Desaulniers
2020-06-25 18:26 ` Nick Desaulniers
2020-06-25 16:37 ` Luc Van Oostenryck
2020-06-25 16:37 ` Luc Van Oostenryck
2020-06-25 16:37 ` Luc Van Oostenryck
2020-06-25 16:37 ` Luc Van Oostenryck
2020-06-25 17:55 ` Ard Biesheuvel
2020-06-25 17:55 ` Ard Biesheuvel
2020-06-25 17:55 ` Ard Biesheuvel
2020-06-25 17:55 ` Ard Biesheuvel
2020-06-18 12:25 ` David Brazdil [this message]
2020-06-18 12:25 ` [PATCH v3 09/15] arm64: kvm: Split hyp/debug-sr.c " David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 10/15] arm64: kvm: Split hyp/sysreg-sr.c " David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 11/15] arm64: kvm: Split hyp/timer-sr.c " David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 12/15] arm64: kvm: Compile remaining hyp/ files for both VHE/nVHE David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 13/15] arm64: kvm: Add comments around __kvm_nvhe_ symbol aliases David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 14/15] arm64: kvm: Remove __hyp_text macro, use build rules instead David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` [PATCH v3 15/15] arm64: kvm: Lift instrumentation restrictions on VHE David Brazdil
2020-06-18 12:25 ` David Brazdil
2020-06-18 12:25 ` David Brazdil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200618122537.9625-10-dbrazdil@google.com \
--to=dbrazdil@google.com \
--cc=android-kvm@google.com \
--cc=catalin.marinas@arm.com \
--cc=james.morse@arm.com \
--cc=julien.thierry.kdev@gmail.com \
--cc=kernel-team@android.com \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.