Skip to content

Commit 178ec0a

Browse files
committed
KVM: arm64: nv: Ensure Address size faults affect correct ESR
For historical reasons, Address size faults are first injected into the guest as an SEA and ESR_EL1 is subsequently modified to reflect the correct FSC. Of course, when dealing with a vEL2 this should poke ESR_EL2. Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 720ef46 commit 178ec0a

File tree

1 file changed

+21
-18
lines changed

1 file changed

+21
-18
lines changed

arch/arm64/kvm/inject_fault.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ static unsigned int exception_target_el(struct kvm_vcpu *vcpu)
4141
}
4242
}
4343

44+
static enum vcpu_sysreg exception_esr_elx(struct kvm_vcpu *vcpu)
45+
{
46+
if (exception_target_el(vcpu) == PSR_MODE_EL2h)
47+
return ESR_EL2;
48+
49+
return ESR_EL1;
50+
}
51+
52+
static enum vcpu_sysreg exception_far_elx(struct kvm_vcpu *vcpu)
53+
{
54+
if (exception_target_el(vcpu) == PSR_MODE_EL2h)
55+
return FAR_EL2;
56+
57+
return FAR_EL1;
58+
}
59+
4460
static void pend_sync_exception(struct kvm_vcpu *vcpu)
4561
{
4662
if (exception_target_el(vcpu) == PSR_MODE_EL1h)
@@ -49,11 +65,6 @@ static void pend_sync_exception(struct kvm_vcpu *vcpu)
4965
kvm_pend_exception(vcpu, EXCEPT_AA64_EL2_SYNC);
5066
}
5167

52-
static bool match_target_el(struct kvm_vcpu *vcpu, unsigned long target)
53-
{
54-
return (vcpu_get_flag(vcpu, EXCEPT_MASK) == target);
55-
}
56-
5768
static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr)
5869
{
5970
unsigned long cpsr = *vcpu_cpsr(vcpu);
@@ -83,13 +94,8 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
8394

8495
esr |= ESR_ELx_FSC_EXTABT;
8596

86-
if (match_target_el(vcpu, unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC))) {
87-
vcpu_write_sys_reg(vcpu, addr, FAR_EL1);
88-
vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
89-
} else {
90-
vcpu_write_sys_reg(vcpu, addr, FAR_EL2);
91-
vcpu_write_sys_reg(vcpu, esr, ESR_EL2);
92-
}
97+
vcpu_write_sys_reg(vcpu, addr, exception_far_elx(vcpu));
98+
vcpu_write_sys_reg(vcpu, esr, exception_esr_elx(vcpu));
9399
}
94100

95101
static void inject_undef64(struct kvm_vcpu *vcpu)
@@ -105,10 +111,7 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
105111
if (kvm_vcpu_trap_il_is32bit(vcpu))
106112
esr |= ESR_ELx_IL;
107113

108-
if (match_target_el(vcpu, unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC)))
109-
vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
110-
else
111-
vcpu_write_sys_reg(vcpu, esr, ESR_EL2);
114+
vcpu_write_sys_reg(vcpu, esr, exception_esr_elx(vcpu));
112115
}
113116

114117
#define DFSR_FSC_EXTABT_LPAE 0x10
@@ -199,9 +202,9 @@ void kvm_inject_size_fault(struct kvm_vcpu *vcpu)
199202
!(vcpu_read_sys_reg(vcpu, TCR_EL1) & TTBCR_EAE))
200203
return;
201204

202-
esr = vcpu_read_sys_reg(vcpu, ESR_EL1);
205+
esr = vcpu_read_sys_reg(vcpu, exception_esr_elx(vcpu));
203206
esr &= ~GENMASK_ULL(5, 0);
204-
vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
207+
vcpu_write_sys_reg(vcpu, esr, exception_esr_elx(vcpu));
205208
}
206209

207210
/**

0 commit comments

Comments
 (0)