[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Stable-8.2.8 23/49] target/i386: Walk NPT in guest real mode
From: |
Michael Tokarev |
Subject: |
[Stable-8.2.8 23/49] target/i386: Walk NPT in guest real mode |
Date: |
Sat, 9 Nov 2024 13:14:14 +0300 |
From: Alexander Graf <graf@amazon.com>
When translating virtual to physical address with a guest CPU that
supports nested paging (NPT), we need to perform every page table walk
access indirectly through the NPT, which we correctly do.
However, we treat real mode (no page table walk) special: In that case,
we currently just skip any walks and translate VA -> PA. With NPT
enabled, we also need to then perform NPT walk to do GVA -> GPA -> HPA
which we fail to do so far.
The net result of that is that TCG VMs with NPT enabled that execute
real mode code (like SeaBIOS) end up with GPA==HPA mappings which means
the guest accesses host code and data. This typically shows as failure
to boot guests.
This patch changes the page walk logic for NPT enabled guests so that we
always perform a GVA -> GPA translation and then skip any logic that
requires an actual PTE.
That way, all remaining logic to walk the NPT stays and we successfully
walk the NPT in real mode.
Cc: qemu-stable@nongnu.org
Fixes: fe441054bb3f0 ("target-i386: Add NPT support")
Signed-off-by: Alexander Graf <graf@amazon.com>
Reported-by: Eduard Vlad <evlad@amazon.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20240921085712.28902-1-graf@amazon.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit b56617bbcb473c25815d1bf475e326f84563b1de)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/target/i386/tcg/sysemu/excp_helper.c
b/target/i386/tcg/sysemu/excp_helper.c
index 7a57b7dd10..319b23762c 100644
--- a/target/i386/tcg/sysemu/excp_helper.c
+++ b/target/i386/tcg/sysemu/excp_helper.c
@@ -149,6 +149,7 @@ static bool mmu_translate(CPUX86State *env, const
TranslateParams *in,
uint32_t pkr;
int page_size;
int error_code;
+ int prot;
restart_all:
rsvd_mask = ~MAKE_64BIT_MASK(0, env_archcpu(env)->phys_bits);
@@ -297,7 +298,7 @@ static bool mmu_translate(CPUX86State *env, const
TranslateParams *in,
/* combine pde and pte nx, user and rw protections */
ptep &= pte ^ PG_NX_MASK;
page_size = 4096;
- } else {
+ } else if (pg_mode) {
/*
* Page table level 2
*/
@@ -342,6 +343,15 @@ static bool mmu_translate(CPUX86State *env, const
TranslateParams *in,
ptep &= pte | PG_NX_MASK;
page_size = 4096;
rsvd_mask = 0;
+ } else {
+ /*
+ * No paging (real mode), let's tentatively resolve the address as 1:1
+ * here, but conditionally still perform an NPT walk on it later.
+ */
+ page_size = 0x40000000;
+ paddr = in->addr;
+ prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ goto stage2;
}
do_check_protect:
@@ -357,7 +367,7 @@ do_check_protect_pse36:
goto do_fault_protect;
}
- int prot = 0;
+ prot = 0;
if (!is_mmu_index_smap(in->mmu_idx) || !(ptep & PG_USER_MASK)) {
prot |= PAGE_READ;
if ((ptep & PG_RW_MASK) || !(is_user || (pg_mode & PG_MODE_WP))) {
@@ -419,6 +429,7 @@ do_check_protect_pse36:
/* merge offset within page */
paddr = (pte & PG_ADDRESS_MASK & ~(page_size - 1)) | (addr & (page_size -
1));
+ stage2:
/*
* Note that NPT is walked (for both paging structures and final guest
@@ -561,7 +572,7 @@ static bool get_physical_address(CPUX86State *env, vaddr
addr,
addr = (uint32_t)addr;
}
- if (likely(env->cr[0] & CR0_PG_MASK)) {
+ if (likely(env->cr[0] & CR0_PG_MASK || use_stage2)) {
in.cr3 = env->cr[3];
in.mmu_idx = mmu_idx;
in.ptw_idx = use_stage2 ? MMU_NESTED_IDX : MMU_PHYS_IDX;
--
2.39.5
- [Stable-8.2.8 02/49] target/arm: Correct ID_AA64ISAR1_EL1 value for neoverse-v1, (continued)
- [Stable-8.2.8 02/49] target/arm: Correct ID_AA64ISAR1_EL1 value for neoverse-v1, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 12/49] tcg/ppc: Use TCG_REG_TMP2 for scratch index in prepare_host_addr, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 08/49] testing: bump mips64el cross to bookworm and fix package list, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 15/49] hw/audio/hda: free timer on exit, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 10/49] linux-user: Fix parse_elf_properties GNU0_MAGIC check, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 13/49] target/m68k: Always return a temporary from gen_lea_mode, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 14/49] hw/intc/arm_gicv3_cpuif: Add cast to match the documentation, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 22/49] tcg: Reset data_gen_ptr correctly, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 17/49] KVM: Dynamic sized kvm memslots array, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 24/49] target/i386: Use probe_access_full_mmu in ptw_translate, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 23/49] target/i386: Walk NPT in guest real mode,
Michael Tokarev <=
- [Stable-8.2.8 16/49] ui/win32: fix potential use-after-free with dbus shared memory, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 18/49] accel/kvm: check for KVM_CAP_READONLY_MEM on VM, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 20/49] tests/qemu-iotests/211.out: Update to expect MapEntry 'compressed' field, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 19/49] tests: Wait for migration completion on destination QEMU to avoid failures, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 28/49] gitlab: make check-[dco|patch] a little more verbose, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 29/49] dockerfiles: fix default targets for debian-loongarch-cross, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 11/49] tcg/ppc: Use TCG_REG_TMP2 for scratch tcg_out_qemu_st, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 27/49] vfio/migration: Report only stop-copy size in vfio_state_pending_exact(), Michael Tokarev, 2024/11/09
- [Stable-8.2.8 34/49] target/arm: Fix arithmetic underflow in SETM instruction, Michael Tokarev, 2024/11/09
- [Stable-8.2.8 31/49] net: fix build when libbpf is disabled, but libxdp is enabled, Michael Tokarev, 2024/11/09