diff options
| author | Fuad Tabba <fuad.tabba@linux.dev> | 2026-07-06 12:55:21 +0100 |
|---|---|---|
| committer | Marc Zyngier <maz@kernel.org> | 2026-07-06 17:18:34 +0100 |
| commit | 85f56708a443ec02a290878f00d79a1ff5110e41 (patch) | |
| tree | d5067fbd21d529315f9a5807c026865a80c29ed2 /drivers/gpu/nova-core/fsp/hal/git@git.tavy.me:linux.git | |
| parent | f35c08c092505f3a83ce097d94fe51eb8bc9c1b5 (diff) | |
KVM: arm64: Fix sign-extension of MMIO loads
A sign-extending load (LDRSB, LDRSH, LDRSW) from MMIO returns a
zero-extended value to the guest. The architecture performs such a load
as a memory read of the access size, then a sign-extension to the
register width. For LDRSH (DDI 0487 M.b C6.2.225, with the Mem accessor
at J1.2.3.111):
data = Mem{16}(address, accdesc);
X{regsize}(t) = SignExtend{regsize}(data);
The byte order is handled inside the Mem accessor, keyed on the access
size; the register width is separate, applied afterwards by SignExtend().
kvm_handle_mmio_return() runs these in the wrong order: it sign-extends
the access-width data, then calls vcpu_data_host_to_guest(), which masks
the value back to the access width (the size-keyed byte-order step). The
mask drops the sign bits that sign-extension produced.
Reorder so vcpu_data_host_to_guest() runs first, with the sign-extension
to register width after it. trace_kvm_mmio() moves with it and now logs
the access-width data before sign-extension.
Fixes: b30070862edbd ("ARM64: KVM: MMIO support BE host running LE code")
Reviewed-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20260706115522.954913-2-fuad.tabba@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
Diffstat (limited to 'drivers/gpu/nova-core/fsp/hal/git@git.tavy.me:linux.git')
0 files changed, 0 insertions, 0 deletions
