diff mbox

[v2,for-2.0] target-i386: x86_cpu_get_phys_page_debug(): support 1GB page translation

Message ID 20140319170353.4428b501@redhat.com
State New
Headers show

Commit Message

Luiz Capitulino March 19, 2014, 9:03 p.m. UTC
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.

Signed-off-by: Luiz capitulino <lcapitulino@redhat.com>
---

- 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(+)

Comments

Andreas Färber March 19, 2014, 9:58 p.m. UTC | #1
Am 19.03.2014 22:03, schrieb 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.
> 
> Signed-off-by: Luiz capitulino <lcapitulino@redhat.com>

Capitulino? :)

> ---
> 
> - 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

> 
> - 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(+)
Luiz Capitulino March 20, 2014, 12:56 p.m. UTC | #2
On Wed, 19 Mar 2014 22:58:11 +0100
Andreas Färber <afaerber@suse.de> wrote:

> Am 19.03.2014 22:03, schrieb 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.
> > 
> > Signed-off-by: Luiz capitulino <lcapitulino@redhat.com>
> 
> Capitulino? :)

Can you or Peter fix it when merging?

> > ---
> > 
> > - 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.

> 
> Regards,
> Andreas
> 
> > 
> > - 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(+)
>
Paolo Bonzini March 20, 2014, 1:07 p.m. UTC | #3
Il 19/03/2014 22:03, Luiz Capitulino ha scritto:
> 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.
>
> Signed-off-by: Luiz capitulino <lcapitulino@redhat.com>
> ---
>
> - 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(+)
>
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 4f447b8..7cee501 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -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;
>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo
Jan Kiszka March 20, 2014, 1:07 p.m. UTC | #4
On 2014-03-19 22:03, Luiz Capitulino wrote:
> 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.
> 
> Signed-off-by: Luiz capitulino <lcapitulino@redhat.com>
> ---
> 
> - 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(+)
> 
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 4f447b8..7cee501 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -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;
> 

Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
Luiz Capitulino March 27, 2014, 5:48 p.m. UTC | #5
On Wed, 19 Mar 2014 17:03:53 -0400
Luiz Capitulino <lcapitulino@redhat.com> wrote:

> 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.

Peter, can you pick up this one please?

> 
> Signed-off-by: Luiz capitulino <lcapitulino@redhat.com>
> ---
> 
> - 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(+)
> 
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 4f447b8..7cee501 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -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;
diff mbox

Patch

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 4f447b8..7cee501 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -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;