Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] KVM: arm64: Fix missing ESR_ELx.IL in syndrome injection
@ 2026-06-14 16:33 Fuad Tabba
  2026-06-14 16:33 ` [PATCH 1/7] KVM: arm64: Set ESR_ELx.IL for injected undefined exceptions at EL2 Fuad Tabba
                   ` (6 more replies)
  0 siblings, 7 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

Hi folks,

After sashiko caught the missing IL bug [1], I did an audit of all ESR
syndrome construction sites in KVM/arm64 as Marc suggested. This series
is the result of that audit.

The ARM architecture mandates ESR_ELx.IL=1 for several exception
classes regardless of instruction length: EC=Unknown, Instruction
Aborts, Data Aborts with ISV=0, and SError. For FPAC (EC=0x1C), IL
reflects instruction length, but FPAC can only be generated by A64
instructions, so IL must also be 1.

Patch 1 is the bug sashiko found: inject_undef64() in the pKVM hyp (EL2)
path never set IL.
Patch 2 makes the same fix to inject_undef64() in the normal host path,
where IL was derived from the triggering trap's instruction length. No
instruction that reaches undef injection has a 16-bit encoding, so patch
2 has no functional change today.
Patch 3 makes the matching fix to inject_abt64(). Unlike undef injection,
abort injection is reachable from a 16-bit T32 instruction (a 32-bit EL0
task under an AArch64 EL1 guest), so the old code there injects an abort
with IL=0.
Patch 4 fixes the FPAC syndrome constructed during nested ERET
emulation, which did not set IL.
Patches 5-6 fix SError injection in the emulated and nested paths,
neither of which set IL.
Patch 7 fixes a fake ESR used to exit to the host. The host does not
read IL there, so it is not guest-visible.

Based on Linux 7.1-rc7

Cheers,
/fuad

[1] https://lore.kernel.org/all/87pl1t8q24.wl-maz@kernel.org/

Fuad Tabba (7):
  KVM: arm64: Set ESR_ELx.IL for injected undefined exceptions at EL2
  KVM: arm64: Unconditionally set IL for injected undefined exceptions
  KVM: arm64: Unconditionally set IL for injected abort exceptions
  KVM: arm64: Set IL for injected FPAC exceptions during ERET emulation
  KVM: arm64: Set IL for emulated SError injection
  KVM: arm64: Set IL for nested SError injection
  KVM: arm64: Set IL in fake ESR for pKVM memory sharing exit

 arch/arm64/kvm/emulate-nested.c    |  4 ++--
 arch/arm64/kvm/hyp/nvhe/pkvm.c     |  3 ++-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c |  2 +-
 arch/arm64/kvm/inject_fault.c      | 18 +++++-------------
 4 files changed, 10 insertions(+), 17 deletions(-)

-- 
2.54.0.1136.gdb2ca164c4-goog



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [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

end of thread, other threads:[~2026-06-14 16:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 3/7] KVM: arm64: Unconditionally set IL for injected abort exceptions Fuad Tabba
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 ` [PATCH 5/7] KVM: arm64: Set IL for emulated SError injection 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox