qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Aurelien Jarno <aurelien@aurel32.net>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [4239] x86/x86-64 MMU PAE fixes
Date: Tue, 22 Apr 2008 20:37:44 +0000	[thread overview]
Message-ID: <E1JoPFI-0006oi-2m@cvs.savannah.gnu.org> (raw)

Revision: 4239
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4239
Author:   aurel32
Date:     2008-04-22 20:37:43 +0000 (Tue, 22 Apr 2008)

Log Message:
-----------
x86/x86-64 MMU PAE fixes

This patch fixes MMU emulation in PAE mode for > 4GB physical addresses:
- a20_mask should have the correct size to not clear the high part of
  the addresses.
- PHYS_ADDR_MASK should not clear the high part of the addresses.
- pdpe, pde and pte could be located anywhere in memory on x86-64, but
  only in the first 4GB on x86, define their pointer to as target_ulong.
- pml4e_addr could be located anywhere in memory, define its pointer
  as uint64_t.
- paddr represents a physical address and thus should be of type
  target_phys_addr_t.

Modified Paths:
--------------
    trunk/target-i386/cpu.h
    trunk/target-i386/helper2.c

Modified: trunk/target-i386/cpu.h
===================================================================
--- trunk/target-i386/cpu.h	2008-04-22 20:37:34 UTC (rev 4238)
+++ trunk/target-i386/cpu.h	2008-04-22 20:37:43 UTC (rev 4239)
@@ -499,7 +499,7 @@
     SegmentCache idt; /* only base and limit are used */
 
     target_ulong cr[9]; /* NOTE: cr1, cr5-7 are unused */
-    uint32_t a20_mask;
+    uint64_t a20_mask;
 
     /* FPU state */
     unsigned int fpstt; /* top of stack index */

Modified: trunk/target-i386/helper2.c
===================================================================
--- trunk/target-i386/helper2.c	2008-04-22 20:37:34 UTC (rev 4238)
+++ trunk/target-i386/helper2.c	2008-04-22 20:37:43 UTC (rev 4239)
@@ -377,7 +377,7 @@
     env->hflags |= HF_GIF_MASK;
 
     cpu_x86_update_cr0(env, 0x60000010);
-    env->a20_mask = 0xffffffff;
+    env->a20_mask = ~0x0;
     env->smbase = 0x30000;
 
     env->idt.limit = 0xffff;
@@ -695,7 +695,7 @@
         /* when a20 is changed, all the MMU mappings are invalid, so
            we must flush everything */
         tlb_flush(env, 1);
-        env->a20_mask = 0xffefffff | (a20_state << 20);
+        env->a20_mask = (~0x100000) | (a20_state << 20);
     }
 }
 
@@ -800,7 +800,7 @@
 
 #else
 
-#define PHYS_ADDR_MASK 0xfffff000
+#define PHYS_ADDR_MASK (~0xfff)
 
 /* return value:
    -1 = cannot handle fault
@@ -812,9 +812,10 @@
                              int is_write1, int mmu_idx, int is_softmmu)
 {
     uint64_t ptep, pte;
-    uint32_t pdpe_addr, pde_addr, pte_addr;
+    target_ulong pde_addr, pte_addr;
     int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
-    unsigned long paddr, page_offset;
+    target_phys_addr_t paddr;
+    uint32_t page_offset;
     target_ulong vaddr, virt_addr;
 
     is_user = mmu_idx == MMU_USER_IDX;
@@ -834,12 +835,11 @@
 
     if (env->cr[4] & CR4_PAE_MASK) {
         uint64_t pde, pdpe;
+        target_ulong pdpe_addr;
 
-        /* XXX: we only use 32 bit physical addresses */
 #ifdef TARGET_X86_64
         if (env->hflags & HF_LMA_MASK) {
-            uint32_t pml4e_addr;
-            uint64_t pml4e;
+            uint64_t pml4e_addr, pml4e;
             int32_t sext;
 
             /* test virtual address sign extension */
@@ -1101,17 +1101,19 @@
 
 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 {
-    uint32_t pde_addr, pte_addr;
-    uint32_t pde, pte, paddr, page_offset, page_size;
+    target_ulong pde_addr, pte_addr;
+    uint64_t pte;
+    target_phys_addr_t paddr;
+    uint32_t page_offset;
+    int page_size;
 
     if (env->cr[4] & CR4_PAE_MASK) {
-        uint32_t pdpe_addr, pde_addr, pte_addr;
-        uint32_t pdpe;
+        target_ulong pdpe_addr;
+        uint64_t pde, pdpe;
 
-        /* XXX: we only use 32 bit physical addresses */
 #ifdef TARGET_X86_64
         if (env->hflags & HF_LMA_MASK) {
-            uint32_t pml4e_addr, pml4e;
+            uint64_t pml4e_addr, pml4e;
             int32_t sext;
 
             /* test virtual address sign extension */
@@ -1121,13 +1123,13 @@
 
             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
                 env->a20_mask;
-            pml4e = ldl_phys(pml4e_addr);
+            pml4e = ldq_phys(pml4e_addr);
             if (!(pml4e & PG_PRESENT_MASK))
                 return -1;
 
             pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
                 env->a20_mask;
-            pdpe = ldl_phys(pdpe_addr);
+            pdpe = ldq_phys(pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
         } else
@@ -1135,14 +1137,14 @@
         {
             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
                 env->a20_mask;
-            pdpe = ldl_phys(pdpe_addr);
+            pdpe = ldq_phys(pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
         }
 
         pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
             env->a20_mask;
-        pde = ldl_phys(pde_addr);
+        pde = ldq_phys(pde_addr);
         if (!(pde & PG_PRESENT_MASK)) {
             return -1;
         }
@@ -1155,9 +1157,11 @@
             pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
                 env->a20_mask;
             page_size = 4096;
-            pte = ldl_phys(pte_addr);
+            pte = ldq_phys(pte_addr);
         }
     } else {
+        uint32_t pde;
+
         if (!(env->cr[0] & CR0_PG_MASK)) {
             pte = addr;
             page_size = 4096;

             reply	other threads:[~2008-04-22 20:37 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-22 20:37 Aurelien Jarno [this message]
2008-04-22 20:57 ` [Qemu-devel] [4239] x86/x86-64 MMU PAE fixes Paul Brook
2008-04-22 22:19   ` Stuart Brady
2008-04-22 22:29     ` Paul Brook
2008-04-22 22:37     ` Stuart Brady

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1JoPFI-0006oi-2m@cvs.savannah.gnu.org \
    --to=aurelien@aurel32.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).