From: Marc Zyngier <marc.zyngier@arm.com>
To: stable@vger.kernel.org
Cc: Will Deacon <will.deacon@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Mark Rutland <mark.rutland@arm.com>,
Christoffer Dall <christoffer.dall@arm.com>
Subject: [PATCH 04/23] KVM: arm64: Change hyp_panic()s dependency on tpidr_el2
Date: Fri, 20 Jul 2018 10:56:15 +0100 [thread overview]
Message-ID: <20180720095634.2173-5-marc.zyngier@arm.com> (raw)
In-Reply-To: <20180720095634.2173-1-marc.zyngier@arm.com>
From: James Morse <james.morse@arm.com>
Commit c97e166e54b662717d20ec2e36761758d2b6a7c2 upstream.
Make tpidr_el2 a cpu-offset for per-cpu variables in the same way the
host uses tpidr_el1. This lets tpidr_el{1,2} have the same value, and
on VHE they can be the same register.
KVM calls hyp_panic() when anything unexpected happens. This may occur
while a guest owns the EL1 registers. KVM stashes the vcpu pointer in
tpidr_el2, which it uses to find the host context in order to restore
the host EL1 registers before parachuting into the host's panic().
The host context is a struct kvm_cpu_context allocated in the per-cpu
area, and mapped to hyp. Given the per-cpu offset for this CPU, this is
easy to find. Change hyp_panic() to take a pointer to the
struct kvm_cpu_context. Wrap these calls with an asm function that
retrieves the struct kvm_cpu_context from the host's per-cpu area.
Copy the per-cpu offset from the hosts tpidr_el1 into tpidr_el2 during
kvm init. (Later patches will make this unnecessary for VHE hosts)
We print out the vcpu pointer as part of the panic message. Add a back
reference to the 'running vcpu' in the host cpu context to preserve this.
Signed-off-by: James Morse <james.morse@arm.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/kvm_host.h | 2 ++
arch/arm64/kvm/hyp/hyp-entry.S | 12 ++++++++++++
arch/arm64/kvm/hyp/s2-setup.c | 3 +++
arch/arm64/kvm/hyp/switch.c | 25 +++++++++++++------------
4 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2abb4493f4f6..04631b0efbd6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -197,6 +197,8 @@ struct kvm_cpu_context {
u64 sys_regs[NR_SYS_REGS];
u32 copro[NR_COPRO_REGS];
};
+
+ struct kvm_vcpu *__hyp_running_vcpu;
};
typedef struct kvm_cpu_context kvm_cpu_context_t;
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index acd75c905084..f1b48ab02cd5 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -173,6 +173,18 @@ ENTRY(__hyp_do_panic)
eret
ENDPROC(__hyp_do_panic)
+ENTRY(__hyp_panic)
+ /*
+ * '=kvm_host_cpu_state' is a host VA from the constant pool, it may
+ * not be accessible by this address from EL2, hyp_panic() converts
+ * it with kern_hyp_va() before use.
+ */
+ ldr x0, =kvm_host_cpu_state
+ mrs x1, tpidr_el2
+ add x0, x0, x1
+ b hyp_panic
+ENDPROC(__hyp_panic)
+
.macro invalid_vector label, target = __hyp_panic
.align 2
\label:
diff --git a/arch/arm64/kvm/hyp/s2-setup.c b/arch/arm64/kvm/hyp/s2-setup.c
index b81f4091c909..eb401dbb285e 100644
--- a/arch/arm64/kvm/hyp/s2-setup.c
+++ b/arch/arm64/kvm/hyp/s2-setup.c
@@ -84,5 +84,8 @@ u32 __hyp_text __init_stage2_translation(void)
write_sysreg(val, vtcr_el2);
+ /* copy tpidr_el1 into tpidr_el2 for use by HYP */
+ write_sysreg(read_sysreg(tpidr_el1), tpidr_el2);
+
return parange;
}
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index c49d09387192..c8c918302153 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -275,9 +275,9 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
u64 exit_code;
vcpu = kern_hyp_va(vcpu);
- write_sysreg(vcpu, tpidr_el2);
host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+ host_ctxt->__hyp_running_vcpu = vcpu;
guest_ctxt = &vcpu->arch.ctxt;
__sysreg_save_host_state(host_ctxt);
@@ -364,7 +364,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n";
-static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par)
+static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par,
+ struct kvm_vcpu *vcpu)
{
unsigned long str_va;
@@ -378,35 +379,35 @@ static void __hyp_text __hyp_call_panic_nvhe(u64 spsr, u64 elr, u64 par)
__hyp_do_panic(str_va,
spsr, elr,
read_sysreg(esr_el2), read_sysreg_el2(far),
- read_sysreg(hpfar_el2), par,
- (void *)read_sysreg(tpidr_el2));
+ read_sysreg(hpfar_el2), par, vcpu);
}
-static void __hyp_text __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par)
+static void __hyp_text __hyp_call_panic_vhe(u64 spsr, u64 elr, u64 par,
+ struct kvm_vcpu *vcpu)
{
panic(__hyp_panic_string,
spsr, elr,
read_sysreg_el2(esr), read_sysreg_el2(far),
- read_sysreg(hpfar_el2), par,
- (void *)read_sysreg(tpidr_el2));
+ read_sysreg(hpfar_el2), par, vcpu);
}
static hyp_alternate_select(__hyp_call_panic,
__hyp_call_panic_nvhe, __hyp_call_panic_vhe,
ARM64_HAS_VIRT_HOST_EXTN);
-void __hyp_text __noreturn __hyp_panic(void)
+void __hyp_text __noreturn hyp_panic(struct kvm_cpu_context *__host_ctxt)
{
+ struct kvm_vcpu *vcpu = NULL;
+
u64 spsr = read_sysreg_el2(spsr);
u64 elr = read_sysreg_el2(elr);
u64 par = read_sysreg(par_el1);
if (read_sysreg(vttbr_el2)) {
- struct kvm_vcpu *vcpu;
struct kvm_cpu_context *host_ctxt;
- vcpu = (struct kvm_vcpu *)read_sysreg(tpidr_el2);
- host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
+ host_ctxt = kern_hyp_va(__host_ctxt);
+ vcpu = host_ctxt->__hyp_running_vcpu;
__timer_save_state(vcpu);
__deactivate_traps(vcpu);
__deactivate_vm(vcpu);
@@ -414,7 +415,7 @@ void __hyp_text __noreturn __hyp_panic(void)
}
/* Call panic for real */
- __hyp_call_panic()(spsr, elr, par);
+ __hyp_call_panic()(spsr, elr, par, vcpu);
unreachable();
}
--
2.18.0
next prev parent reply other threads:[~2018-07-20 10:44 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-20 9:56 [PATCH 00/23] arm64: 4.9 backport of the SSBD mitigation patches Marc Zyngier
2018-07-20 9:56 ` [PATCH 01/23] arm64: assembler: introduce ldr_this_cpu Marc Zyngier
2018-07-20 9:56 ` [PATCH 02/23] KVM: arm64: Store vcpu on the stack during __guest_enter() Marc Zyngier
2018-07-20 9:56 ` [PATCH 03/23] KVM: arm/arm64: Convert kvm_host_cpu_state to a static per-cpu allocation Marc Zyngier
2018-07-20 9:56 ` Marc Zyngier [this message]
2018-07-20 9:56 ` [PATCH 05/23] arm64: alternatives: use tpidr_el2 on VHE hosts Marc Zyngier
2018-07-20 9:56 ` [PATCH 06/23] KVM: arm64: Stop save/restoring host tpidr_el1 on VHE Marc Zyngier
2018-07-20 9:56 ` [PATCH 07/23] arm64: alternatives: Add dynamic patching feature Marc Zyngier
2018-07-20 9:56 ` [PATCH 08/23] KVM: arm/arm64: Do not use kern_hyp_va() with kvm_vgic_global_state Marc Zyngier
2018-07-20 9:56 ` [PATCH 09/23] KVM: arm64: Avoid storing the vcpu pointer on the stack Marc Zyngier
2018-07-20 9:56 ` [PATCH 10/23] arm/arm64: smccc: Add SMCCC-specific return codes Marc Zyngier
2018-07-20 9:56 ` [PATCH 11/23] arm64: Call ARCH_WORKAROUND_2 on transitions between EL0 and EL1 Marc Zyngier
2018-07-20 9:56 ` [PATCH 12/23] arm64: Add per-cpu infrastructure to call ARCH_WORKAROUND_2 Marc Zyngier
2018-07-20 9:56 ` [PATCH 13/23] arm64: Add ARCH_WORKAROUND_2 probing Marc Zyngier
2018-07-20 9:56 ` [PATCH 14/23] arm64: Add 'ssbd' command-line option Marc Zyngier
2018-07-20 9:56 ` [PATCH 15/23] arm64: ssbd: Add global mitigation state accessor Marc Zyngier
2018-07-20 9:56 ` [PATCH 16/23] arm64: ssbd: Skip apply_ssbd if not using dynamic mitigation Marc Zyngier
2018-07-20 9:56 ` [PATCH 17/23] arm64: ssbd: Restore mitigation status on CPU resume Marc Zyngier
2018-07-20 9:56 ` [PATCH 18/23] arm64: ssbd: Introduce thread flag to control userspace mitigation Marc Zyngier
2018-07-20 9:56 ` [PATCH 19/23] arm64: ssbd: Add prctl interface for per-thread mitigation Marc Zyngier
2018-07-20 9:56 ` [PATCH 20/23] arm64: KVM: Add HYP per-cpu accessors Marc Zyngier
2018-07-20 9:56 ` [PATCH 21/23] arm64: KVM: Add ARCH_WORKAROUND_2 support for guests Marc Zyngier
2018-07-20 9:56 ` [PATCH 22/23] arm64: KVM: Handle guest's ARCH_WORKAROUND_2 requests Marc Zyngier
2018-07-20 9:56 ` [PATCH 23/23] arm64: KVM: Add ARCH_WORKAROUND_2 discovery through ARCH_FEATURES_FUNC_ID Marc Zyngier
2018-07-20 10:43 ` [PATCH 00/23] arm64: 4.9 backport of the SSBD mitigation patches Greg KH
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=20180720095634.2173-5-marc.zyngier@arm.com \
--to=marc.zyngier@arm.com \
--cc=catalin.marinas@arm.com \
--cc=christoffer.dall@arm.com \
--cc=mark.rutland@arm.com \
--cc=stable@vger.kernel.org \
--cc=will.deacon@arm.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).