* [PATCH 1/7] KVM: arm64: Set ESR_ELx.IL for injected undefined exceptions at EL2
2026-06-14 16:33 [PATCH 0/7] KVM: arm64: Fix missing ESR_ELx.IL in syndrome injection Fuad Tabba
@ 2026-06-14 16:33 ` Fuad Tabba
2026-06-14 16:33 ` [PATCH 2/7] KVM: arm64: Unconditionally set IL for injected undefined exceptions Fuad Tabba
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Fuad Tabba @ 2026-06-14 16:33 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, linux-arm-kernel, kvmarm,
linux-kernel
Cc: Catalin Marinas, Will Deacon, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Vincent Donnefort, Sascha Bischoff,
tabba
inject_undef64() constructs an ESR with EC=0 (Unknown) but does not set
IL. The architecture mandates IL=1 for EC=0 unconditionally (ARM DDI
0487, ESR_ELx.IL description), so the injected syndrome is one that
conforming hardware cannot produce.
Set ESR_ELx_IL in the constructed syndrome.
Fixes: e5d40a5a97c1 ("KVM: arm64: pkvm: Add a generic synchronous exception injection primitive")
Reported-by: sashiko <sashiko@sashiko.dev>
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/hyp/nvhe/sys_regs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 8c3fbb413a06..9767adf1f73e 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -278,7 +278,7 @@ static void inject_sync64(struct kvm_vcpu *vcpu, u64 esr)
*/
static void inject_undef64(struct kvm_vcpu *vcpu)
{
- inject_sync64(vcpu, (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT));
+ inject_sync64(vcpu, (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT) | ESR_ELx_IL);
}
static u64 read_id_reg(const struct kvm_vcpu *vcpu,
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/7] KVM: arm64: Unconditionally set IL for injected undefined exceptions
2026-06-14 16:33 [PATCH 0/7] KVM: arm64: Fix missing ESR_ELx.IL in syndrome injection Fuad Tabba
2026-06-14 16:33 ` [PATCH 1/7] KVM: arm64: Set ESR_ELx.IL for injected undefined exceptions at EL2 Fuad Tabba
@ 2026-06-14 16:33 ` Fuad Tabba
2026-06-14 16:33 ` [PATCH 3/7] KVM: arm64: Unconditionally set IL for injected abort exceptions Fuad Tabba
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Fuad Tabba @ 2026-06-14 16:33 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, linux-arm-kernel, kvmarm,
linux-kernel
Cc: Catalin Marinas, Will Deacon, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Vincent Donnefort, Sascha Bischoff,
tabba
inject_undef64() derives IL from the triggering trap's instruction
length (kvm_vcpu_trap_il_is32bit()), but the IL of the injected
exception is fixed by its EC, not by the triggering instruction. The
architecture mandates IL=1 for EC=0 (Unknown) unconditionally, so the
conditional is wrong. The undef-injection paths are not reached from
16-bit instructions, so there is no functional change today, but the
logic should not rely on that.
Set ESR_ELx_IL unconditionally.
Fixes: aa8eff9bfbd5 ("arm64: KVM: fault injection into a guest")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/inject_fault.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index 89982bd3345f..9dfae1bcdf99 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -170,14 +170,7 @@ void kvm_inject_sync(struct kvm_vcpu *vcpu, u64 esr)
static void inject_undef64(struct kvm_vcpu *vcpu)
{
- u64 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
-
- /*
- * Build an unknown exception, depending on the instruction
- * set.
- */
- if (kvm_vcpu_trap_il_is32bit(vcpu))
- esr |= ESR_ELx_IL;
+ u64 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT) | ESR_ELx_IL;
kvm_inject_sync(vcpu, esr);
}
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/7] KVM: arm64: Unconditionally set IL for injected abort exceptions
2026-06-14 16:33 [PATCH 0/7] KVM: arm64: Fix missing ESR_ELx.IL in syndrome injection Fuad Tabba
2026-06-14 16:33 ` [PATCH 1/7] KVM: arm64: Set ESR_ELx.IL for injected undefined exceptions at EL2 Fuad Tabba
2026-06-14 16:33 ` [PATCH 2/7] KVM: arm64: Unconditionally set IL for injected undefined exceptions Fuad Tabba
@ 2026-06-14 16:33 ` Fuad Tabba
2026-06-14 16:33 ` [PATCH 4/7] KVM: arm64: Set IL for injected FPAC exceptions during ERET emulation Fuad Tabba
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Fuad Tabba @ 2026-06-14 16:33 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, linux-arm-kernel, kvmarm,
linux-kernel
Cc: Catalin Marinas, Will Deacon, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Vincent Donnefort, Sascha Bischoff,
tabba
inject_abt64() derives IL from the triggering trap's instruction length
(kvm_vcpu_trap_il_is32bit()), but the IL of the injected abort is fixed
by its EC, not by the triggering instruction. The architecture mandates
IL=1 for Instruction Aborts unconditionally and for Data Aborts with
ISV=0, and this function never sets ISV (the FSC is always EXTABT or
SEA_TTW). For a 16-bit T32 trap (a 32-bit EL0 task under an AArch64 EL1
guest) the trap has IL=0, so the abort is injected with the wrong IL.
Set ESR_ELx_IL unconditionally.
Fixes: aa8eff9bfbd5 ("arm64: KVM: fault injection into a guest")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/inject_fault.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index 9dfae1bcdf99..444d219b0217 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -138,11 +138,10 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
pend_sync_exception(vcpu);
/*
- * Build an {i,d}abort, depending on the level and the
- * instruction set. Report an external synchronous abort.
+ * Build an {i,d}abort, depending on the level.
+ * Report an external synchronous abort.
*/
- if (kvm_vcpu_trap_il_is32bit(vcpu))
- esr |= ESR_ELx_IL;
+ esr |= ESR_ELx_IL;
/*
* Here, the guest runs in AArch64 mode when in EL1. If we get
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/7] KVM: arm64: Set IL for injected FPAC exceptions during ERET emulation
2026-06-14 16:33 [PATCH 0/7] KVM: arm64: Fix missing ESR_ELx.IL in syndrome injection Fuad Tabba
` (2 preceding siblings ...)
2026-06-14 16:33 ` [PATCH 3/7] KVM: arm64: Unconditionally set IL for injected abort exceptions Fuad Tabba
@ 2026-06-14 16:33 ` Fuad Tabba
2026-06-14 16:33 ` [PATCH 5/7] KVM: arm64: Set IL for emulated SError injection Fuad Tabba
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Fuad Tabba @ 2026-06-14 16:33 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, linux-arm-kernel, kvmarm,
linux-kernel
Cc: Catalin Marinas, Will Deacon, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Vincent Donnefort, Sascha Bischoff,
tabba
The FPAC syndrome constructed during nested ERET emulation does not set
IL. For FPAC (EC=0x1C), IL reflects the instruction length. ERET and
its authenticated variants are always A64 32-bit instructions, so IL
must be 1.
Fixes: 213b3d1ea161 ("KVM: arm64: nv: Handle ERETA[AB] instructions")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/emulate-nested.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index dba7ced74ca5..4b39363cf891 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2777,7 +2777,7 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
*/
if (kvm_has_pauth(vcpu->kvm, FPACCOMBINE) && !(spsr & PSR_IL_BIT)) {
esr &= ESR_ELx_ERET_ISS_ERETA;
- esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_FPAC);
+ esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_FPAC) | ESR_ELx_IL;
kvm_inject_nested_sync(vcpu, esr);
return;
}
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 5/7] KVM: arm64: Set IL for emulated SError injection
2026-06-14 16:33 [PATCH 0/7] KVM: arm64: Fix missing ESR_ELx.IL in syndrome injection Fuad Tabba
` (3 preceding siblings ...)
2026-06-14 16:33 ` [PATCH 4/7] KVM: arm64: Set IL for injected FPAC exceptions during ERET emulation Fuad Tabba
@ 2026-06-14 16:33 ` Fuad Tabba
2026-06-14 16:33 ` [PATCH 6/7] KVM: arm64: Set IL for nested " Fuad Tabba
2026-06-14 16:33 ` [PATCH 7/7] KVM: arm64: Set IL in fake ESR for pKVM memory sharing exit Fuad Tabba
6 siblings, 0 replies; 8+ messages in thread
From: Fuad Tabba @ 2026-06-14 16:33 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, linux-arm-kernel, kvmarm,
linux-kernel
Cc: Catalin Marinas, Will Deacon, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Vincent Donnefort, Sascha Bischoff,
tabba
kvm_inject_serror_esr() constructs an SError syndrome without IL. The
architecture mandates IL=1 for SError unconditionally.
Fixes: f6e2262dfa1a ("KVM: arm64: Populate ESR_ELx.EC for emulated SError injection")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/inject_fault.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index 444d219b0217..d6c4fc16f879 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -381,7 +381,7 @@ int kvm_inject_serror_esr(struct kvm_vcpu *vcpu, u64 esr)
*/
if (!serror_is_masked(vcpu)) {
pend_serror_exception(vcpu);
- esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SERROR);
+ esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SERROR) | ESR_ELx_IL;
vcpu_write_sys_reg(vcpu, esr, exception_esr_elx(vcpu));
return 1;
}
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 6/7] KVM: arm64: Set IL for nested SError injection
2026-06-14 16:33 [PATCH 0/7] KVM: arm64: Fix missing ESR_ELx.IL in syndrome injection Fuad Tabba
` (4 preceding siblings ...)
2026-06-14 16:33 ` [PATCH 5/7] KVM: arm64: Set IL for emulated SError injection Fuad Tabba
@ 2026-06-14 16:33 ` Fuad Tabba
2026-06-14 16:33 ` [PATCH 7/7] KVM: arm64: Set IL in fake ESR for pKVM memory sharing exit Fuad Tabba
6 siblings, 0 replies; 8+ messages in thread
From: Fuad Tabba @ 2026-06-14 16:33 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, linux-arm-kernel, kvmarm,
linux-kernel
Cc: Catalin Marinas, Will Deacon, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Vincent Donnefort, Sascha Bischoff,
tabba
kvm_inject_nested_serror() constructs an SError syndrome without IL.
The architecture mandates IL=1 for SError unconditionally.
Fixes: 77ee70a07357 ("KVM: arm64: nv: Honor SError exception routing / masking")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/emulate-nested.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 4b39363cf891..4262d4c17a87 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -2938,6 +2938,6 @@ int kvm_inject_nested_serror(struct kvm_vcpu *vcpu, u64 esr)
* vSError injection. Manually populate EC for an emulated SError
* exception.
*/
- esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SERROR);
+ esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SERROR) | ESR_ELx_IL;
return kvm_inject_nested(vcpu, esr, except_type_serror);
}
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 7/7] KVM: arm64: Set IL in fake ESR for pKVM memory sharing exit
2026-06-14 16:33 [PATCH 0/7] KVM: arm64: Fix missing ESR_ELx.IL in syndrome injection Fuad Tabba
` (5 preceding siblings ...)
2026-06-14 16:33 ` [PATCH 6/7] KVM: arm64: Set IL for nested " Fuad Tabba
@ 2026-06-14 16:33 ` Fuad Tabba
6 siblings, 0 replies; 8+ messages in thread
From: Fuad Tabba @ 2026-06-14 16:33 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, linux-arm-kernel, kvmarm,
linux-kernel
Cc: Catalin Marinas, Will Deacon, Joey Gouly, Steffen Eiden,
Suzuki K Poulose, Zenghui Yu, Vincent Donnefort, Sascha Bischoff,
tabba
__pkvm_memshare_page_req() constructs a fake DABT ESR_EL2 to exit to
the host without setting IL. The ESR has ISV=0, so IL must be 1 per the
architecture. The host does not read IL on this path, but the
constructed syndrome should still be architecturally valid.
Set ESR_ELx_IL.
Fixes: 03313efed5e2 ("KVM: arm64: Implement the MEM_SHARE hypercall for protected VMs")
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/kvm/hyp/nvhe/pkvm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index eb1c10120f9f..c982a3a04c37 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -1054,7 +1054,8 @@ static u64 __pkvm_memshare_page_req(struct kvm_vcpu *vcpu, u64 ipa)
/* Fake up a data abort (level 3 translation fault on write) */
vcpu->arch.fault.esr_el2 = (ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT) |
- ESR_ELx_WNR | ESR_ELx_FSC_FAULT |
+ ESR_ELx_IL | ESR_ELx_WNR |
+ ESR_ELx_FSC_FAULT |
FIELD_PREP(ESR_ELx_FSC_LEVEL, 3);
/* Shuffle the IPA around into the HPFAR */
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread