In order to be able to propagate the pointer to the sys_reg descriptor
being currently emulated without having to rewrite a lot of the sys_reg
handling, let's allow the vcpu structure to have a pointer to the
current sys_reg_params.

The pointer is set in a helper function that calls the trap handler,
and reset just after.

Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  5 +++++
 arch/arm64/kvm/sys_regs.c         | 40 +++++++++++++++++++++------------------
 2 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 4a758cba1262..9dfce56de9c0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -194,6 +194,8 @@ struct kvm_cpu_context {
 
 typedef struct kvm_cpu_context kvm_cpu_context_t;
 
+struct sys_reg_params;
+
 struct kvm_vcpu_arch {
        struct kvm_cpu_context ctxt;
 
@@ -270,6 +272,9 @@ struct kvm_vcpu_arch {
 
        /* Detect first run of a vcpu */
        bool has_run_once;
+
+       /* system register emulation in progress */
+       struct sys_reg_params *sys_reg;
 };
 
 #define vcpu_gp_regs(v)                (&(v)->arch.ctxt.gp_regs)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 7ac7fb021dde..33bad02c0a00 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1557,6 +1557,26 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, 
struct kvm_run *run)
        return 1;
 }
 
+static bool perform_access(struct kvm_vcpu *vcpu,
+                          struct sys_reg_params *params,
+                          const struct sys_reg_desc *r)
+{
+       bool res;
+
+       /*
+        * Not having an accessor means that we have configured a trap
+        * that we don't know how to handle. This certainly qualifies
+        * as a gross bug that should be fixed right away.
+        */
+       BUG_ON(!r->access);
+
+       vcpu->arch.sys_reg = params;
+       res = r->access(vcpu, params, r);
+       vcpu->arch.sys_reg = NULL;
+
+       return res;
+}
+
 /*
  * emulate_cp --  tries to match a sys_reg access in a handling table, and
  *                call the corresponding trap handler.
@@ -1580,15 +1600,7 @@ static int emulate_cp(struct kvm_vcpu *vcpu,
        r = find_reg(params, table, num);
 
        if (r) {
-               /*
-                * Not having an accessor means that we have
-                * configured a trap that we don't know how to
-                * handle. This certainly qualifies as a gross bug
-                * that should be fixed right away.
-                */
-               BUG_ON(!r->access);
-
-               if (likely(r->access(vcpu, params, r))) {
+               if (likely(perform_access(vcpu, params, r))) {
                        /* Skip instruction, since it was emulated */
                        if (!params->exception_pending)
                                kvm_skip_instr(vcpu, 
kvm_vcpu_trap_il_is32bit(vcpu));
@@ -1766,15 +1778,7 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu,
                r = find_reg(params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
 
        if (likely(r)) {
-               /*
-                * Not having an accessor means that we have
-                * configured a trap that we don't know how to
-                * handle. This certainly qualifies as a gross bug
-                * that should be fixed right away.
-                */
-               BUG_ON(!r->access);
-
-               if (likely(r->access(vcpu, params, r))) {
+               if (likely(perform_access(vcpu, params, r))) {
                        /* Skip instruction, since it was emulated */
                        if (!params->exception_pending)
                                kvm_skip_instr(vcpu, 
kvm_vcpu_trap_il_is32bit(vcpu));
-- 
2.11.0

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to