File: x86-only-allow-real-mode-to-access-32bit-without-LMA.patch

package info (click to toggle)
qemu-kvm 1.1.2%2Bdfsg-6%2Bdeb7u12
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 43,848 kB
  • sloc: ansic: 606,321; asm: 10,684; sh: 6,663; perl: 4,223; python: 3,802; makefile: 1,076; objc: 843; xml: 409
file content (33 lines) | stat: -rw-r--r-- 1,389 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Description: x86: only allow real mode to access 32bit without LMA
 When we're running in non-64bit mode with qemu-system-x86_64 we can
 still end up with virtual addresses that are above the 32bit boundary
 if a segment offset is set up.
 .
 GNU Hurd does exactly that. It sets the segment offset to 0x80000000 and
 puts its EIP value to 0x8xxxxxxx to access low memory.
 .
 This doesn't hit us when we enable paging, as there we just mask away the
 unused bits. But with real mode, we assume that vaddr == paddr which is
 wrong in this case. Real hardware wraps the virtual address around at the
 32bit boundary. So let's do the same.
 .
 This fixes booting GNU Hurd in qemu-system-x86_64 for me.
Author: Alexander Graf <agraf@suse.de>
Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commitdiff;h=33dfdb56f2f3c8686d218395b871ec12fd5bf30b
Bug-Debian: https://bugs.debian.org/719633

--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -512,6 +512,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State
 
     if (!(env->cr[0] & CR0_PG_MASK)) {
         pte = addr;
+#ifdef TARGET_X86_64
+        if (!(env->hflags & HF_LMA_MASK)) {
+            /* Without long mode we can only address 32bits in real mode */
+            pte = (uint32_t)pte;
+        }
+#endif
         virt_addr = addr & TARGET_PAGE_MASK;
         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
         page_size = 4096;