Commit 0ed60bc1 authored by Marc Zyngier's avatar Marc Zyngier Committed by Ben Hutchings

arm64: KVM: Fix decoding of Rt/Rt2 when trapping AArch32 CP accesses

commit c667186f upstream.

Our 32bit CP14/15 handling inherited some of the ARMv7 code for handling
the trapped system registers, completely missing the fact that the
fields for Rt and Rt2 are now 5 bit wide, and not 4...

Let's fix it, and provide an accessor for the most common Rt case.
Reviewed-by: default avatarChristoffer Dall <cdall@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarChristoffer Dall <cdall@linaro.org>
[bwh: Backported to 3.16:
 - Use literal numbers in kvm_vcpu_sys_get_rt()
 - Adjust context]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 4171fcef
...@@ -187,6 +187,12 @@ static inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu) ...@@ -187,6 +187,12 @@ static inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu)
return kvm_vcpu_get_hsr(vcpu) & ESR_EL2_FSC_TYPE; return kvm_vcpu_get_hsr(vcpu) & ESR_EL2_FSC_TYPE;
} }
static inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
{
u32 esr = kvm_vcpu_get_hsr(vcpu);
return (esr >> 5) & 0x1f;
}
static inline unsigned long kvm_vcpu_get_mpidr(struct kvm_vcpu *vcpu) static inline unsigned long kvm_vcpu_get_mpidr(struct kvm_vcpu *vcpu)
{ {
return vcpu_sys_reg(vcpu, MPIDR_EL1); return vcpu_sys_reg(vcpu, MPIDR_EL1);
......
...@@ -504,12 +504,12 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) ...@@ -504,12 +504,12 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
{ {
struct sys_reg_params params; struct sys_reg_params params;
u32 hsr = kvm_vcpu_get_hsr(vcpu); u32 hsr = kvm_vcpu_get_hsr(vcpu);
int Rt2 = (hsr >> 10) & 0xf; int Rt2 = (hsr >> 10) & 0x1f;
params.is_aarch32 = true; params.is_aarch32 = true;
params.is_32bit = false; params.is_32bit = false;
params.CRm = (hsr >> 1) & 0xf; params.CRm = (hsr >> 1) & 0xf;
params.Rt = (hsr >> 5) & 0xf; params.Rt = kvm_vcpu_sys_get_rt(vcpu);
params.is_write = ((hsr & 1) == 0); params.is_write = ((hsr & 1) == 0);
params.Op0 = 0; params.Op0 = 0;
...@@ -554,7 +554,7 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) ...@@ -554,7 +554,7 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
params.is_aarch32 = true; params.is_aarch32 = true;
params.is_32bit = true; params.is_32bit = true;
params.CRm = (hsr >> 1) & 0xf; params.CRm = (hsr >> 1) & 0xf;
params.Rt = (hsr >> 5) & 0xf; params.Rt = kvm_vcpu_sys_get_rt(vcpu);
params.is_write = ((hsr & 1) == 0); params.is_write = ((hsr & 1) == 0);
params.CRn = (hsr >> 10) & 0xf; params.CRn = (hsr >> 10) & 0xf;
params.Op0 = 0; params.Op0 = 0;
...@@ -629,7 +629,7 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run) ...@@ -629,7 +629,7 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
params.CRn = (esr >> 10) & 0xf; params.CRn = (esr >> 10) & 0xf;
params.CRm = (esr >> 1) & 0xf; params.CRm = (esr >> 1) & 0xf;
params.Op2 = (esr >> 17) & 0x7; params.Op2 = (esr >> 17) & 0x7;
params.Rt = (esr >> 5) & 0x1f; params.Rt = kvm_vcpu_sys_get_rt(vcpu);
params.is_write = !(esr & 1); params.is_write = !(esr & 1);
return emulate_sys_reg(vcpu, &params); return emulate_sys_reg(vcpu, &params);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment