Message ID | 20240223130948.237186-1-pbonzini@redhat.com |
---|---|
Headers | show |
Series | target/i386: Fix physical address masking bugs | expand |
On 23/02/2024 13:09, Paolo Bonzini wrote: > The address translation logic in get_physical_address() will currently > truncate physical addresses to 32 bits unless long mode is enabled. > This is incorrect when using physical address extensions (PAE) outside > of long mode, with the result that a 32-bit operating system using PAE > to access memory above 4G will experience undefined behaviour. > Instead, truncation must be applied to the linear address. Because > this truncation is diffent between 32- and 64-bit modes, the series > opts to split 32- and 64-bit modes to separate MMU indices, which is > the simplest way to ensure that, for example, a kernel that runs both > 32-bit and 64-bit programs looks up the correct address in the > (64-bit) page tables. > > Furthermore, when inspecting the code I noticed that the A20 mask is > applied incorrectly when NPT is active. The mask should not be applied > to the addresses that are looked up in the NPT, only to the physical > addresses. Obviously no hypervisor is going to leave A20 masking on, > but the code actually becomes simpler so let's do it. > > Patches 1 and 2 fix cases in which the addresses must be masked, > or overflow is otherwise invalid, for MMU_PHYS_IDX accesses. > > Patches 3 and 4 introduce separate MMU indexes for 32- and 64-bit > accesses. > > Patch 5 fixes the bug, by limiting the masking to the 32-bit MMU indexes. > > Patches 6 and 7 further clean up the MMU functions to centralize > application of the A20 mask and fix bugs in the process. > > Tested with kvm-unit-tests SVM tests and with an old 32-bit Debian image. > > Paolo Bonzini (7): > target/i386: mask high bits of CR3 in 32-bit mode > target/i386: check validity of VMCB addresses > target/i386: introduce function to query MMU indices > target/i386: use separate MMU indexes for 32-bit accesses > target/i386: Fix physical address truncation > target/i386: remove unnecessary/wrong application of the A20 mask > target/i386: leave the A20 bit set in the final NPT walk > > target/i386/cpu.h | 46 +++++++++++++++++++----- > target/i386/cpu.c | 9 +++-- > target/i386/tcg/sysemu/excp_helper.c | 52 +++++++++++++--------------- > target/i386/tcg/sysemu/misc_helper.c | 3 ++ > target/i386/tcg/sysemu/svm_helper.c | 27 +++++++++++---- > 5 files changed, 92 insertions(+), 45 deletions(-) Thank you for putting in the work to fix this all up! I confirm that this patch series resolves the issue that I originally observed in https://gitlab.com/qemu-project/qemu/-/issues/2040 and that Windows 10 32-bit is able to boot with PAE enabled and memory over 4G. Tested-by: Michael Brown <mcb30@ipxe.org> Thanks, Michael