Skip to contentSkip to conversation

target-i386: x86_cpu_get_phys_page_debug(): support 1GB page translation

PATCH Applied Luiz Capitulino 4 participants 8 messages Mar 19, 2014 – Mar 27, 2014

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 target-i386: x86_cpu_get_phys_page_debug(): support 1GB page translation

Linux guests, when using more than 4GB of RAM, may end up using 1GB pages to store (kernel) data. When this happens, we're unable to debug a running Linux kernel with GDB:

(gdb) p node_data[0]->node_id
Cannot access memory at address 0xffff88013fffd3a0 (gdb)

GDB returns this error because x86_cpu_get_phys_page_debug() doesn't support translating 1GB pages in IA-32e paging mode and returns an error to GDB.

This commit adds support for 1GB page translation for IA32e paging.

---

- I'm proposing this patch for 2.0 because GDB debugging of large Linux guests is kind of broken

- Changelog v2:
- Move PS bit handling to if (env->hflags & HF_LMA_MASK) block
- Update changelog

 target-i386/helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)
target-i386/helper.c +9 -0
index 4f447b8..7cee501 100644
@@ -941,6 +941,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             pdpe = ldq_phys(cs->as, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
+
+            if (pdpe & PG_PSE_MASK) {
+                page_size = 1024 * 1024 * 1024;
+                pte = pdpe & ~( (page_size - 1) & ~0xfff);
+                pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
+                goto out;
+            }
+
         } else
 #endif
         {
@@ -993,6 +1001,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         pte = pte & env->a20_mask;
     }
 
+out:
     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     return paddr;
Signature · 1 line
1.8.3.1
#1 lore raw

Am 19.03.2014 22:03, schrieb Luiz Capitulino:

Quoted 8 lines

Linux guests, when using more than 4GB of RAM, may end up using 1GB pages to store (kernel) data. When this happens, we're unable to debug a running Linux kernel with GDB:

(gdb) p node_data[0]->node_id
Cannot access memory at address 0xffff88013fffd3a0 (gdb)

Quoted 6 lines

GDB returns this error because x86_cpu_get_phys_page_debug() doesn't support translating 1GB pages in IA-32e paging mode and returns an error to GDB.

This commit adds support for 1GB page translation for IA32e paging.

Capitulino? :)

Quoted 4 lines

---

- I'm proposing this patch for 2.0 because GDB debugging of large Linux guests is kind of broken

Agree that it would be nice to fix, but having mainly touched the function interface, I am dependent on reviewers here. => rc2 or .1

Regards,
Andreas

Quoted 7 lines

- Changelog v2:
- Move PS bit handling to if (env->hflags & HF_LMA_MASK) block
- Update changelog

 target-i386/helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
#2 lore raw
Quoted 9 lines · On Wed, 19 Mar 2014 22:58:11 +0100 Andreas Färber <[email protected]> wrote:

Am 19.03.2014 22:03, schrieb Luiz Capitulino:

Quoted 8 lines

Linux guests, when using more than 4GB of RAM, may end up using 1GB pages to store (kernel) data. When this happens, we're unable to debug a running Linux kernel with GDB:

(gdb) p node_data[0]->node_id
Cannot access memory at address 0xffff88013fffd3a0 (gdb)

Quoted 8 lines
Quoted 6 lines

GDB returns this error because x86_cpu_get_phys_page_debug() doesn't support translating 1GB pages in IA-32e paging mode and returns an error to GDB.

This commit adds support for 1GB page translation for IA32e paging.

Capitulino? :)

Can you or Peter fix it when merging?

Quoted 7 lines
Quoted 4 lines

---

- I'm proposing this patch for 2.0 because GDB debugging of large Linux guests is kind of broken

Agree that it would be nice to fix, but having mainly touched the function interface, I am dependent on reviewers here. => rc2 or .1

I think Paolo and/or Jan will review it.

Quoted 12 lines

Regards,
Andreas

Quoted 7 lines

- Changelog v2:
- Move PS bit handling to if (env->hflags & HF_LMA_MASK) block
- Update changelog

 target-i386/helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)
Reviewed-by on v2 1/1
#5 lore raw
In reply to Luiz Capitulino

Il 19/03/2014 22:03, Luiz Capitulino ha scritto:

Quoted 47 lines

Linux guests, when using more than 4GB of RAM, may end up using 1GB pages to store (kernel) data. When this happens, we're unable to debug a running Linux kernel with GDB:

(gdb) p node_data[0]->node_id
Cannot access memory at address 0xffff88013fffd3a0 (gdb)

GDB returns this error because x86_cpu_get_phys_page_debug() doesn't support translating 1GB pages in IA-32e paging mode and returns an error to GDB.

This commit adds support for 1GB page translation for IA32e paging.

---

- I'm proposing this patch for 2.0 because GDB debugging of large Linux guests is kind of broken

- Changelog v2:
- Move PS bit handling to if (env->hflags & HF_LMA_MASK) block
- Update changelog

 target-i386/helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)
target-i386/helper.c +8 -0
index 4f447b8..7cee501 100644
@@ -941,6 +941,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             pdpe = ldq_phys(cs->as, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
+
+            if (pdpe & PG_PSE_MASK) {
+                page_size = 1024 * 1024 * 1024;
+                pte = pdpe & ~( (page_size - 1) & ~0xfff);
+                pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
+                goto out;
+            }
+
         } else
 #endif
         {

target-i386/helper.c hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) · line 1007

Quoted 7 lines
target-i386/helper.c +1 -0
@@ -993,6 +1001,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         pte = pte & env->a20_mask;
     }
 
+out:
     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     return paddr;

Paolo

Reviewed-by on v2 1/1
#6 lore raw
In reply to Luiz Capitulino
Quoted 47 lines · Luiz Capitulino

Linux guests, when using more than 4GB of RAM, may end up using 1GB pages to store (kernel) data. When this happens, we're unable to debug a running Linux kernel with GDB:

(gdb) p node_data[0]->node_id
Cannot access memory at address 0xffff88013fffd3a0 (gdb)

GDB returns this error because x86_cpu_get_phys_page_debug() doesn't support translating 1GB pages in IA-32e paging mode and returns an error to GDB.

This commit adds support for 1GB page translation for IA32e paging.

---

- I'm proposing this patch for 2.0 because GDB debugging of large Linux guests is kind of broken

- Changelog v2:
- Move PS bit handling to if (env->hflags & HF_LMA_MASK) block
- Update changelog

 target-i386/helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)
target-i386/helper.c +8 -0
index 4f447b8..7cee501 100644
@@ -941,6 +941,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             pdpe = ldq_phys(cs->as, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
+
+            if (pdpe & PG_PSE_MASK) {
+                page_size = 1024 * 1024 * 1024;
+                pte = pdpe & ~( (page_size - 1) & ~0xfff);
+                pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
+                goto out;
+            }
+
         } else
 #endif
         {

target-i386/helper.c hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) · line 1007

Quoted 7 lines
target-i386/helper.c +1 -0
@@ -993,6 +1001,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         pte = pte & env->a20_mask;
     }
 
+out:
     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     return paddr;
Signature · 2 lines
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux
#7 lore raw
In reply to Luiz Capitulino
Quoted 4 lines · On Wed, 19 Mar 2014 17:03:53 -0400 Luiz Capitulino <[email protected]>…

Linux guests, when using more than 4GB of RAM, may end up using 1GB pages to store (kernel) data. When this happens, we're unable to debug a running Linux kernel with GDB:

Quoted 8 lines

(gdb) p node_data[0]->node_id
Cannot access memory at address 0xffff88013fffd3a0 (gdb)

GDB returns this error because x86_cpu_get_phys_page_debug() doesn't support translating 1GB pages in IA-32e paging mode and returns an error to GDB.

This commit adds support for 1GB page translation for IA32e paging.

Peter, can you pick up this one please?

Quoted 41 lines

---

- I'm proposing this patch for 2.0 because GDB debugging of large Linux guests is kind of broken

- Changelog v2:
- Move PS bit handling to if (env->hflags & HF_LMA_MASK) block
- Update changelog

 target-i386/helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)
target-i386/helper.c +9 -0
index 4f447b8..7cee501 100644
@@ -941,6 +941,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             pdpe = ldq_phys(cs->as, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
+
+            if (pdpe & PG_PSE_MASK) {
+                page_size = 1024 * 1024 * 1024;
+                pte = pdpe & ~( (page_size - 1) & ~0xfff);
+                pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
+                goto out;
+            }
+
         } else
 #endif
         {
@@ -993,6 +1001,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         pte = pte & env->a20_mask;
     }
 
+out:
     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     return paddr;
#3 lore raw
In reply to Luiz Capitulino

Am 20.03.2014 13:56, schrieb Luiz Capitulino:

Quoted 15 lines
Quoted 12 lines · On Wed, 19 Mar 2014 22:58:11 +0100 Andreas Färber <[email protected]> wrote:

Am 19.03.2014 22:03, schrieb Luiz Capitulino:

Quoted 11 lines

Linux guests, when using more than 4GB of RAM, may end up using 1GB pages to store (kernel) data. When this happens, we're unable to debug a running Linux kernel with GDB:

(gdb) p node_data[0]->node_id
Cannot access memory at address 0xffff88013fffd3a0 (gdb)

GDB returns this error because x86_cpu_get_phys_page_debug() doesn't support translating 1GB pages in IA-32e paging mode and returns an error to GDB.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

This commit adds support for 1GB page translation for IA32e paging.

Capitulino? :)

Can you or Peter fix it when merging?

Done.

Quoted 9 lines
Quoted 7 lines
Quoted 4 lines

---

- I'm proposing this patch for 2.0 because GDB debugging of large Linux guests is kind of broken

Agree that it would be nice to fix, but having mainly touched the function interface, I am dependent on reviewers here. => rc2 or .1

I think Paolo and/or Jan will review it.

Thanks to them. I did need the followup build fix though:

target-i386/helper.c +0 -0
index 7cee501..372f0e3 100644
@@ -1001,7 +1001,9 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs,

vaddr addr)

         pte = pte & env->a20_mask;
     }

+#ifdef TARGET_X86_64
out:
+#endif

     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     return paddr;

Thanks, applied to qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas

Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
#4 lore raw
Quoted 31 lines · On Thu, 27 Mar 2014 19:25:31 +0100 Andreas Färber <[email protected]> wrote:

Am 20.03.2014 13:56, schrieb Luiz Capitulino:

Quoted 15 lines
Quoted 12 lines · On Wed, 19 Mar 2014 22:58:11 +0100 Andreas Färber <[email protected]> wrote:

Am 19.03.2014 22:03, schrieb Luiz Capitulino:

Quoted 11 lines

Linux guests, when using more than 4GB of RAM, may end up using 1GB pages to store (kernel) data. When this happens, we're unable to debug a running Linux kernel with GDB:

(gdb) p node_data[0]->node_id
Cannot access memory at address 0xffff88013fffd3a0 (gdb)

GDB returns this error because x86_cpu_get_phys_page_debug() doesn't support translating 1GB pages in IA-32e paging mode and returns an error to GDB.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

This commit adds support for 1GB page translation for IA32e paging.

Capitulino? :)

Can you or Peter fix it when merging?

Done.

Quoted 5 lines
Quoted 5 lines
Quoted 4 lines

---

- I'm proposing this patch for 2.0 because GDB debugging of large Linux guests is kind of broken

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

Agree that it would be nice to fix, but having mainly touched the function interface, I am dependent on reviewers here. => rc2 or .1

I think Paolo and/or Jan will review it.

Thanks to them. I did need the followup build fix though:

Thanks a lot.

Quoted 22 lines
target-i386/helper.c +2 -0
index 7cee501..372f0e3 100644
@@ -1001,7 +1001,9 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs,
 vaddr addr)
         pte = pte & env->a20_mask;
     }
 
+#ifdef TARGET_X86_64
 out:
+#endif
     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
     return paddr;

Thanks, applied to qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas