From: Andrew Scull <ascull@google.com>
To: kvmarm@lists.cs.columbia.edu
Cc: linux-arm-kernel@lists.infradead.org, kernel-team@android.com,
maz@kernel.org, Sudeep Holla <sudeep.holla@arm.com>,
catalin.marinas@arm.com, will@kernel.org
Subject: [PATCH v2 17/20] KVM: arm64: nVHE: Migrate hyp interface to SMCCC
Date: Thu, 20 Aug 2020 11:34:43 +0100 [thread overview]
Message-ID: <20200820103446.959000-18-ascull@google.com> (raw)
In-Reply-To: <20200820103446.959000-1-ascull@google.com>
Rather than passing arbitrary function pointers to run at hyp, define
and equivalent set of SMCCC functions.
Since the SMCCC functions are strongly tied to the original function
prototypes, it is not expected for the host to ever call an invalid ID
but a warning is raised if this does ever occur.
As __kvm_vcpu_run is used for every switch between the host and a guest,
it is explicitly singled out to be identified before the other function
IDs to improve the performance of the hot path.
Signed-off-by: Andrew Scull <ascull@google.com>
Signed-off-by: David Brazdil <dbrazdil@google.com>
---
arch/arm64/include/asm/kvm_asm.h | 24 ++++++
arch/arm64/include/asm/kvm_host.h | 25 ++++---
arch/arm64/kvm/arm.c | 2 +-
arch/arm64/kvm/hyp.S | 24 ++----
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 113 +++++++++++++++++++++++++----
5 files changed, 145 insertions(+), 43 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 358262d4546e..57db148686ee 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -38,6 +38,30 @@
#define __SMCCC_WORKAROUND_1_SMC_SZ 36
+#define KVM_HOST_SMCCC_ID(id) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_STANDARD_HYP, \
+ (id))
+
+#define KVM_HOST_SMCCC_FUNC(name) KVM_HOST_SMCCC_ID(__KVM_HOST_SMCCC_FUNC_##name)
+
+#define __KVM_HOST_SMCCC_FUNC___kvm_hyp_init 0
+#define __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context 1
+#define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa 2
+#define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid 3
+#define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_local_vmid 4
+#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff 5
+#define __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run 6
+#define __KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs 7
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_get_ich_vtr_el2 8
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_read_vmcr 9
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_write_vmcr 10
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_init_lrs 11
+#define __KVM_HOST_SMCCC_FUNC___kvm_get_mdcr_el2 12
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs 13
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs 14
+
#ifndef __ASSEMBLY__
#include <linux/mm.h>
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ec1a80796999..a2ab4933e211 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -11,6 +11,7 @@
#ifndef __ARM64_KVM_HOST_H__
#define __ARM64_KVM_HOST_H__
+#include <linux/arm-smccc.h>
#include <linux/bitmap.h>
#include <linux/types.h>
#include <linux/jump_label.h>
@@ -479,18 +480,20 @@ int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
void kvm_arm_halt_guest(struct kvm *kvm);
void kvm_arm_resume_guest(struct kvm *kvm);
-u64 __kvm_call_hyp(void *hypfn, ...);
+u64 __kvm_call_hyp_init(phys_addr_t pgd_ptr,
+ unsigned long hyp_stack_ptr,
+ unsigned long vector_ptr,
+ unsigned long tpidr_el2);
-#define kvm_call_hyp_nvhe(f, ...) \
- do { \
- DECLARE_KVM_NVHE_SYM(f); \
- __kvm_call_hyp(kvm_ksym_ref_nvhe(f), ##__VA_ARGS__); \
- } while(0)
-
-#define kvm_call_hyp_nvhe_ret(f, ...) \
+#define kvm_call_hyp_nvhe(f, ...) \
({ \
- DECLARE_KVM_NVHE_SYM(f); \
- __kvm_call_hyp(kvm_ksym_ref_nvhe(f), ##__VA_ARGS__); \
+ struct arm_smccc_res res; \
+ \
+ arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(f), \
+ ##__VA_ARGS__, &res); \
+ WARN_ON(res.a0 != SMCCC_RET_SUCCESS); \
+ \
+ res.a1; \
})
/*
@@ -516,7 +519,7 @@ u64 __kvm_call_hyp(void *hypfn, ...);
ret = f(__VA_ARGS__); \
isb(); \
} else { \
- ret = kvm_call_hyp_nvhe_ret(f, ##__VA_ARGS__); \
+ ret = kvm_call_hyp_nvhe(f, ##__VA_ARGS__); \
} \
\
ret; \
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 3f5d00167674..661fdae8ea3f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1288,7 +1288,7 @@ static void cpu_init_hyp_mode(void)
* cpus_have_const_cap() wrapper.
*/
BUG_ON(!system_capabilities_finalized());
- __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr, tpidr_el2);
+ __kvm_call_hyp_init(pgd_ptr, hyp_stack_ptr, vector_ptr, tpidr_el2);
/*
* Disabling SSBD on a non-VHE system requires us to enable SSBS
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 3c79a1124af2..12aa426f7559 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -11,24 +11,12 @@
#include <asm/cpufeature.h>
/*
- * u64 __kvm_call_hyp(void *hypfn, ...);
- *
- * This is not really a variadic function in the classic C-way and care must
- * be taken when calling this to ensure parameters are passed in registers
- * only, since the stack will change between the caller and the callee.
- *
- * Call the function with the first argument containing a pointer to the
- * function you wish to call in Hyp mode, and subsequent arguments will be
- * passed as x0, x1, and x2 (a maximum of 3 arguments in addition to the
- * function pointer can be passed). The function being called must be mapped
- * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are
- * passed in x0.
- *
- * A function pointer with a value less than 0xfff has a special meaning,
- * and is used to implement hyp stubs in the same way as in
- * arch/arm64/kernel/hyp_stub.S.
+ * u64 __kvm_call_hyp_init(phys_addr_t pgd_ptr,
+ * unsigned long hyp_stack_ptr,
+ * unsigned long vector_ptr,
+ * unsigned long tpidr_el2);
*/
-SYM_FUNC_START(__kvm_call_hyp)
+SYM_FUNC_START(__kvm_call_hyp_init)
hvc #0
ret
-SYM_FUNC_END(__kvm_call_hyp)
+SYM_FUNC_END(__kvm_call_hyp_init)
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index c8938e09f585..13093df70c87 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -12,24 +12,111 @@
#include <asm/kvm_hyp.h>
#include <asm/kvm_mmu.h>
-typedef unsigned long (*hypcall_fn_t)
- (unsigned long, unsigned long, unsigned long);
+#include <kvm/arm_hypercalls.h>
+
+static void handle_host_hcall(unsigned long func_id,
+ struct kvm_cpu_context *host_ctxt)
+{
+ unsigned long ret = 0;
+
+ /*
+ * __kvm_vcpu_run is a hot path of the context switch so identify it
+ * quickly before searching through the other functions IDs.
+ */
+ if (func_id == KVM_HOST_SMCCC_FUNC(__kvm_vcpu_run)) {
+ struct kvm_vcpu *vcpu =
+ (struct kvm_vcpu *)host_ctxt->regs.regs[1];
+
+ ret = __kvm_vcpu_run(vcpu);
+ goto out;
+ }
+
+ switch (func_id) {
+ case KVM_HOST_SMCCC_FUNC(__kvm_flush_vm_context):
+ __kvm_flush_vm_context();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_vmid_ipa): {
+ struct kvm_s2_mmu *mmu =
+ (struct kvm_s2_mmu *)host_ctxt->regs.regs[1];
+ phys_addr_t ipa = host_ctxt->regs.regs[2];
+ int level = host_ctxt->regs.regs[3];
+
+ __kvm_tlb_flush_vmid_ipa(mmu, ipa, level);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_vmid): {
+ struct kvm_s2_mmu *mmu =
+ (struct kvm_s2_mmu *)host_ctxt->regs.regs[1];
+
+ __kvm_tlb_flush_vmid(mmu);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_local_vmid): {
+ struct kvm_s2_mmu *mmu =
+ (struct kvm_s2_mmu *)host_ctxt->regs.regs[1];
+
+ __kvm_tlb_flush_local_vmid(mmu);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__kvm_timer_set_cntvoff): {
+ u64 cntvoff = host_ctxt->regs.regs[1];
+
+ __kvm_timer_set_cntvoff(cntvoff);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__kvm_enable_ssbs):
+ __kvm_enable_ssbs();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_get_ich_vtr_el2):
+ ret = __vgic_v3_get_ich_vtr_el2();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_read_vmcr):
+ ret = __vgic_v3_read_vmcr();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_write_vmcr): {
+ u32 vmcr = host_ctxt->regs.regs[1];
+
+ __vgic_v3_write_vmcr(vmcr);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_init_lrs):
+ __vgic_v3_init_lrs();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__kvm_get_mdcr_el2):
+ ret = __kvm_get_mdcr_el2();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_save_aprs): {
+ struct vgic_v3_cpu_if *cpu_if =
+ (struct vgic_v3_cpu_if *)host_ctxt->regs.regs[1];
+
+ __vgic_v3_save_aprs(cpu_if);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_restore_aprs): {
+ struct vgic_v3_cpu_if *cpu_if =
+ (struct vgic_v3_cpu_if *)host_ctxt->regs.regs[1];
+
+ __vgic_v3_restore_aprs(cpu_if);
+ break;
+ }
+ default:
+ /* Invalid host HVC. */
+ host_ctxt->regs.regs[0] = SMCCC_RET_NOT_SUPPORTED;
+ return;
+ }
+
+out:
+ host_ctxt->regs.regs[0] = SMCCC_RET_SUCCESS;
+ host_ctxt->regs.regs[1] = ret;
+}
void handle_trap(struct kvm_cpu_context *host_ctxt) {
u64 esr = read_sysreg_el2(SYS_ESR);
- hypcall_fn_t func;
- unsigned long ret;
+ unsigned long func_id;
if (ESR_ELx_EC(esr) != ESR_ELx_EC_HVC64)
hyp_panic();
- /*
- * __kvm_call_hyp takes a pointer in the host address space and
- * up to three arguments.
- */
- func = (hypcall_fn_t)kern_hyp_va(host_ctxt->regs.regs[0]);
- ret = func(host_ctxt->regs.regs[1],
- host_ctxt->regs.regs[2],
- host_ctxt->regs.regs[3]);
- host_ctxt->regs.regs[0] = ret;
+ func_id = host_ctxt->regs.regs[0];
+ handle_host_hcall(func_id, host_ctxt);
}
--
2.28.0.220.ged08abb693-goog
_______________________________________________
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: Andrew Scull <ascull@google.com>
To: kvmarm@lists.cs.columbia.edu
Cc: linux-arm-kernel@lists.infradead.org, kernel-team@android.com,
suzuki.poulose@arm.com, maz@kernel.org,
Sudeep Holla <sudeep.holla@arm.com>,
james.morse@arm.com, Andrew Scull <ascull@google.com>,
catalin.marinas@arm.com, David Brazdil <dbrazdil@google.com>,
will@kernel.org, julien.thierry.kdev@gmail.com
Subject: [PATCH v2 17/20] KVM: arm64: nVHE: Migrate hyp interface to SMCCC
Date: Thu, 20 Aug 2020 11:34:43 +0100 [thread overview]
Message-ID: <20200820103446.959000-18-ascull@google.com> (raw)
In-Reply-To: <20200820103446.959000-1-ascull@google.com>
Rather than passing arbitrary function pointers to run at hyp, define
and equivalent set of SMCCC functions.
Since the SMCCC functions are strongly tied to the original function
prototypes, it is not expected for the host to ever call an invalid ID
but a warning is raised if this does ever occur.
As __kvm_vcpu_run is used for every switch between the host and a guest,
it is explicitly singled out to be identified before the other function
IDs to improve the performance of the hot path.
Signed-off-by: Andrew Scull <ascull@google.com>
Signed-off-by: David Brazdil <dbrazdil@google.com>
---
arch/arm64/include/asm/kvm_asm.h | 24 ++++++
arch/arm64/include/asm/kvm_host.h | 25 ++++---
arch/arm64/kvm/arm.c | 2 +-
arch/arm64/kvm/hyp.S | 24 ++----
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 113 +++++++++++++++++++++++++----
5 files changed, 145 insertions(+), 43 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 358262d4546e..57db148686ee 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -38,6 +38,30 @@
#define __SMCCC_WORKAROUND_1_SMC_SZ 36
+#define KVM_HOST_SMCCC_ID(id) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_STANDARD_HYP, \
+ (id))
+
+#define KVM_HOST_SMCCC_FUNC(name) KVM_HOST_SMCCC_ID(__KVM_HOST_SMCCC_FUNC_##name)
+
+#define __KVM_HOST_SMCCC_FUNC___kvm_hyp_init 0
+#define __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context 1
+#define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa 2
+#define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid 3
+#define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_local_vmid 4
+#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff 5
+#define __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run 6
+#define __KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs 7
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_get_ich_vtr_el2 8
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_read_vmcr 9
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_write_vmcr 10
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_init_lrs 11
+#define __KVM_HOST_SMCCC_FUNC___kvm_get_mdcr_el2 12
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs 13
+#define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs 14
+
#ifndef __ASSEMBLY__
#include <linux/mm.h>
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ec1a80796999..a2ab4933e211 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -11,6 +11,7 @@
#ifndef __ARM64_KVM_HOST_H__
#define __ARM64_KVM_HOST_H__
+#include <linux/arm-smccc.h>
#include <linux/bitmap.h>
#include <linux/types.h>
#include <linux/jump_label.h>
@@ -479,18 +480,20 @@ int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
void kvm_arm_halt_guest(struct kvm *kvm);
void kvm_arm_resume_guest(struct kvm *kvm);
-u64 __kvm_call_hyp(void *hypfn, ...);
+u64 __kvm_call_hyp_init(phys_addr_t pgd_ptr,
+ unsigned long hyp_stack_ptr,
+ unsigned long vector_ptr,
+ unsigned long tpidr_el2);
-#define kvm_call_hyp_nvhe(f, ...) \
- do { \
- DECLARE_KVM_NVHE_SYM(f); \
- __kvm_call_hyp(kvm_ksym_ref_nvhe(f), ##__VA_ARGS__); \
- } while(0)
-
-#define kvm_call_hyp_nvhe_ret(f, ...) \
+#define kvm_call_hyp_nvhe(f, ...) \
({ \
- DECLARE_KVM_NVHE_SYM(f); \
- __kvm_call_hyp(kvm_ksym_ref_nvhe(f), ##__VA_ARGS__); \
+ struct arm_smccc_res res; \
+ \
+ arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(f), \
+ ##__VA_ARGS__, &res); \
+ WARN_ON(res.a0 != SMCCC_RET_SUCCESS); \
+ \
+ res.a1; \
})
/*
@@ -516,7 +519,7 @@ u64 __kvm_call_hyp(void *hypfn, ...);
ret = f(__VA_ARGS__); \
isb(); \
} else { \
- ret = kvm_call_hyp_nvhe_ret(f, ##__VA_ARGS__); \
+ ret = kvm_call_hyp_nvhe(f, ##__VA_ARGS__); \
} \
\
ret; \
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 3f5d00167674..661fdae8ea3f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1288,7 +1288,7 @@ static void cpu_init_hyp_mode(void)
* cpus_have_const_cap() wrapper.
*/
BUG_ON(!system_capabilities_finalized());
- __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr, tpidr_el2);
+ __kvm_call_hyp_init(pgd_ptr, hyp_stack_ptr, vector_ptr, tpidr_el2);
/*
* Disabling SSBD on a non-VHE system requires us to enable SSBS
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 3c79a1124af2..12aa426f7559 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -11,24 +11,12 @@
#include <asm/cpufeature.h>
/*
- * u64 __kvm_call_hyp(void *hypfn, ...);
- *
- * This is not really a variadic function in the classic C-way and care must
- * be taken when calling this to ensure parameters are passed in registers
- * only, since the stack will change between the caller and the callee.
- *
- * Call the function with the first argument containing a pointer to the
- * function you wish to call in Hyp mode, and subsequent arguments will be
- * passed as x0, x1, and x2 (a maximum of 3 arguments in addition to the
- * function pointer can be passed). The function being called must be mapped
- * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are
- * passed in x0.
- *
- * A function pointer with a value less than 0xfff has a special meaning,
- * and is used to implement hyp stubs in the same way as in
- * arch/arm64/kernel/hyp_stub.S.
+ * u64 __kvm_call_hyp_init(phys_addr_t pgd_ptr,
+ * unsigned long hyp_stack_ptr,
+ * unsigned long vector_ptr,
+ * unsigned long tpidr_el2);
*/
-SYM_FUNC_START(__kvm_call_hyp)
+SYM_FUNC_START(__kvm_call_hyp_init)
hvc #0
ret
-SYM_FUNC_END(__kvm_call_hyp)
+SYM_FUNC_END(__kvm_call_hyp_init)
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index c8938e09f585..13093df70c87 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -12,24 +12,111 @@
#include <asm/kvm_hyp.h>
#include <asm/kvm_mmu.h>
-typedef unsigned long (*hypcall_fn_t)
- (unsigned long, unsigned long, unsigned long);
+#include <kvm/arm_hypercalls.h>
+
+static void handle_host_hcall(unsigned long func_id,
+ struct kvm_cpu_context *host_ctxt)
+{
+ unsigned long ret = 0;
+
+ /*
+ * __kvm_vcpu_run is a hot path of the context switch so identify it
+ * quickly before searching through the other functions IDs.
+ */
+ if (func_id == KVM_HOST_SMCCC_FUNC(__kvm_vcpu_run)) {
+ struct kvm_vcpu *vcpu =
+ (struct kvm_vcpu *)host_ctxt->regs.regs[1];
+
+ ret = __kvm_vcpu_run(vcpu);
+ goto out;
+ }
+
+ switch (func_id) {
+ case KVM_HOST_SMCCC_FUNC(__kvm_flush_vm_context):
+ __kvm_flush_vm_context();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_vmid_ipa): {
+ struct kvm_s2_mmu *mmu =
+ (struct kvm_s2_mmu *)host_ctxt->regs.regs[1];
+ phys_addr_t ipa = host_ctxt->regs.regs[2];
+ int level = host_ctxt->regs.regs[3];
+
+ __kvm_tlb_flush_vmid_ipa(mmu, ipa, level);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_vmid): {
+ struct kvm_s2_mmu *mmu =
+ (struct kvm_s2_mmu *)host_ctxt->regs.regs[1];
+
+ __kvm_tlb_flush_vmid(mmu);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__kvm_tlb_flush_local_vmid): {
+ struct kvm_s2_mmu *mmu =
+ (struct kvm_s2_mmu *)host_ctxt->regs.regs[1];
+
+ __kvm_tlb_flush_local_vmid(mmu);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__kvm_timer_set_cntvoff): {
+ u64 cntvoff = host_ctxt->regs.regs[1];
+
+ __kvm_timer_set_cntvoff(cntvoff);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__kvm_enable_ssbs):
+ __kvm_enable_ssbs();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_get_ich_vtr_el2):
+ ret = __vgic_v3_get_ich_vtr_el2();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_read_vmcr):
+ ret = __vgic_v3_read_vmcr();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_write_vmcr): {
+ u32 vmcr = host_ctxt->regs.regs[1];
+
+ __vgic_v3_write_vmcr(vmcr);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_init_lrs):
+ __vgic_v3_init_lrs();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__kvm_get_mdcr_el2):
+ ret = __kvm_get_mdcr_el2();
+ break;
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_save_aprs): {
+ struct vgic_v3_cpu_if *cpu_if =
+ (struct vgic_v3_cpu_if *)host_ctxt->regs.regs[1];
+
+ __vgic_v3_save_aprs(cpu_if);
+ break;
+ }
+ case KVM_HOST_SMCCC_FUNC(__vgic_v3_restore_aprs): {
+ struct vgic_v3_cpu_if *cpu_if =
+ (struct vgic_v3_cpu_if *)host_ctxt->regs.regs[1];
+
+ __vgic_v3_restore_aprs(cpu_if);
+ break;
+ }
+ default:
+ /* Invalid host HVC. */
+ host_ctxt->regs.regs[0] = SMCCC_RET_NOT_SUPPORTED;
+ return;
+ }
+
+out:
+ host_ctxt->regs.regs[0] = SMCCC_RET_SUCCESS;
+ host_ctxt->regs.regs[1] = ret;
+}
void handle_trap(struct kvm_cpu_context *host_ctxt) {
u64 esr = read_sysreg_el2(SYS_ESR);
- hypcall_fn_t func;
- unsigned long ret;
+ unsigned long func_id;
if (ESR_ELx_EC(esr) != ESR_ELx_EC_HVC64)
hyp_panic();
- /*
- * __kvm_call_hyp takes a pointer in the host address space and
- * up to three arguments.
- */
- func = (hypcall_fn_t)kern_hyp_va(host_ctxt->regs.regs[0]);
- ret = func(host_ctxt->regs.regs[1],
- host_ctxt->regs.regs[2],
- host_ctxt->regs.regs[3]);
- host_ctxt->regs.regs[0] = ret;
+ func_id = host_ctxt->regs.regs[0];
+ handle_host_hcall(func_id, host_ctxt);
}
--
2.28.0.220.ged08abb693-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-08-20 10:36 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-20 10:34 [PATCH v2 00/20] Introduce separate nVHE hyp context Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 01/20] KVM: arm64: Remove __activate_vm wrapper Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 02/20] KVM: arm64: Remove hyp_panic arguments Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 03/20] KVM: arm64: Remove kvm_host_data_t typedef Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 04/20] KVM: arm64: Restrict symbol aliasing to outside nVHE Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 05/20] KVM: arm64: Save chosen hyp vector to a percpu variable Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 06/20] KVM: arm64: nVHE: Use separate vector for the host Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 07/20] KVM: arm64: nVHE: Don't consume host SErrors with ESB Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 08/20] KVM: arm64: Preserve host DISR_EL1 Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 09/20] KVM: arm64: Introduce hyp context Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 10/20] KVM: arm64: Update context references from host to hyp Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 11/20] KVM: arm64: Restore hyp when panicking in guest context Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 12/20] KVM: arm64: Share context save and restore macros Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 13/20] KVM: arm64: nVHE: Switch to hyp context for EL2 Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 14/20] KVM: arm64: nVHE: Handle hyp panics Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 15/20] smccc: Cast arguments to unsigned long Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 16/20] KVM: arm64: nVHE: Pass pointers consistently to hyp-init Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` Andrew Scull [this message]
2020-08-20 10:34 ` [PATCH v2 17/20] KVM: arm64: nVHE: Migrate hyp interface to SMCCC Andrew Scull
2020-08-20 10:34 ` [PATCH v2 18/20] KVM: arm64: nVHE: Migrate hyp-init " Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 19/20] KVM: arm64: nVHE: Fix pointers during SMCCC convertion Andrew Scull
2020-08-20 10:34 ` Andrew Scull
2020-08-20 10:34 ` [PATCH v2 20/20] KVM: arm64: nVHE: Handle stub HVCs in the host loop Andrew Scull
2020-08-20 10:34 ` Andrew Scull
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=20200820103446.959000-18-ascull@google.com \
--to=ascull@google.com \
--cc=catalin.marinas@arm.com \
--cc=kernel-team@android.com \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=maz@kernel.org \
--cc=sudeep.holla@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.