]> Git Repo - linux.git/commitdiff
KVM: arm64: Fix debug register indexing
authorMarc Zyngier <[email protected]>
Fri, 14 May 2021 08:05:41 +0000 (09:05 +0100)
committerMarc Zyngier <[email protected]>
Sat, 15 May 2021 09:27:59 +0000 (10:27 +0100)
Commit 03fdfb2690099 ("KVM: arm64: Don't write junk to sysregs on
reset") flipped the register number to 0 for all the debug registers
in the sysreg table, hereby indicating that these registers live
in a separate shadow structure.

However, the author of this patch failed to realise that all the
accessors are using that particular index instead of the register
encoding, resulting in all the registers hitting index 0. Not quite
a valid implementation of the architecture...

Address the issue by fixing all the accessors to use the CRm field
of the encoding, which contains the debug register index.

Fixes: 03fdfb2690099 ("KVM: arm64: Don't write junk to sysregs on reset")
Reported-by: Ricardo Koller <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Cc: [email protected]
arch/arm64/kvm/sys_regs.c

index 76ea2800c33e8240450341b54f207c5129f6a693..1a7968ad078c60a00f0d9e63577674c6b8fa13d9 100644 (file)
@@ -399,14 +399,14 @@ static bool trap_bvr(struct kvm_vcpu *vcpu,
                     struct sys_reg_params *p,
                     const struct sys_reg_desc *rd)
 {
-       u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
+       u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm];
 
        if (p->is_write)
                reg_to_dbg(vcpu, p, rd, dbg_reg);
        else
                dbg_to_reg(vcpu, p, rd, dbg_reg);
 
-       trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
+       trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg);
 
        return true;
 }
@@ -414,7 +414,7 @@ static bool trap_bvr(struct kvm_vcpu *vcpu,
 static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
                const struct kvm_one_reg *reg, void __user *uaddr)
 {
-       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
+       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm];
 
        if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0)
                return -EFAULT;
@@ -424,7 +424,7 @@ static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
        const struct kvm_one_reg *reg, void __user *uaddr)
 {
-       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
+       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm];
 
        if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
                return -EFAULT;
@@ -434,21 +434,21 @@ static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 static void reset_bvr(struct kvm_vcpu *vcpu,
                      const struct sys_reg_desc *rd)
 {
-       vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg] = rd->val;
+       vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = rd->val;
 }
 
 static bool trap_bcr(struct kvm_vcpu *vcpu,
                     struct sys_reg_params *p,
                     const struct sys_reg_desc *rd)
 {
-       u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
+       u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm];
 
        if (p->is_write)
                reg_to_dbg(vcpu, p, rd, dbg_reg);
        else
                dbg_to_reg(vcpu, p, rd, dbg_reg);
 
-       trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
+       trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg);
 
        return true;
 }
@@ -456,7 +456,7 @@ static bool trap_bcr(struct kvm_vcpu *vcpu,
 static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
                const struct kvm_one_reg *reg, void __user *uaddr)
 {
-       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
+       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm];
 
        if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0)
                return -EFAULT;
@@ -467,7 +467,7 @@ static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
        const struct kvm_one_reg *reg, void __user *uaddr)
 {
-       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
+       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm];
 
        if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
                return -EFAULT;
@@ -477,22 +477,22 @@ static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 static void reset_bcr(struct kvm_vcpu *vcpu,
                      const struct sys_reg_desc *rd)
 {
-       vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg] = rd->val;
+       vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = rd->val;
 }
 
 static bool trap_wvr(struct kvm_vcpu *vcpu,
                     struct sys_reg_params *p,
                     const struct sys_reg_desc *rd)
 {
-       u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
+       u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm];
 
        if (p->is_write)
                reg_to_dbg(vcpu, p, rd, dbg_reg);
        else
                dbg_to_reg(vcpu, p, rd, dbg_reg);
 
-       trace_trap_reg(__func__, rd->reg, p->is_write,
-               vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]);
+       trace_trap_reg(__func__, rd->CRm, p->is_write,
+               vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]);
 
        return true;
 }
@@ -500,7 +500,7 @@ static bool trap_wvr(struct kvm_vcpu *vcpu,
 static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
                const struct kvm_one_reg *reg, void __user *uaddr)
 {
-       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
+       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm];
 
        if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0)
                return -EFAULT;
@@ -510,7 +510,7 @@ static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
        const struct kvm_one_reg *reg, void __user *uaddr)
 {
-       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
+       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm];
 
        if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
                return -EFAULT;
@@ -520,21 +520,21 @@ static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 static void reset_wvr(struct kvm_vcpu *vcpu,
                      const struct sys_reg_desc *rd)
 {
-       vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg] = rd->val;
+       vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = rd->val;
 }
 
 static bool trap_wcr(struct kvm_vcpu *vcpu,
                     struct sys_reg_params *p,
                     const struct sys_reg_desc *rd)
 {
-       u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
+       u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm];
 
        if (p->is_write)
                reg_to_dbg(vcpu, p, rd, dbg_reg);
        else
                dbg_to_reg(vcpu, p, rd, dbg_reg);
 
-       trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
+       trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg);
 
        return true;
 }
@@ -542,7 +542,7 @@ static bool trap_wcr(struct kvm_vcpu *vcpu,
 static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
                const struct kvm_one_reg *reg, void __user *uaddr)
 {
-       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
+       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm];
 
        if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0)
                return -EFAULT;
@@ -552,7 +552,7 @@ static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
        const struct kvm_one_reg *reg, void __user *uaddr)
 {
-       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
+       __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm];
 
        if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
                return -EFAULT;
@@ -562,7 +562,7 @@ static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
 static void reset_wcr(struct kvm_vcpu *vcpu,
                      const struct sys_reg_desc *rd)
 {
-       vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg] = rd->val;
+       vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = rd->val;
 }
 
 static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
This page took 0.063008 seconds and 4 git commands to generate.