diff mbox series

[PULL,25/30] Fix wrong behavior of cpu_memory_rw_debug() function in SMM

Message ID 1570035113-56848-26-git-send-email-pbonzini@redhat.com (mailing list archive)
State New, archived
Headers show
Series [PULL,01/30] tests/migration: Add a test for auto converge | expand

Commit Message

Paolo Bonzini Oct. 2, 2019, 4:51 p.m. UTC
From: Dmitry Poletaev <poletaev@ispras.ru>

There is a problem, that you don't have access to the data using cpu_memory_rw_debug() function when in SMM. You can't remotely debug SMM mode program because of that for example.
Likely attrs version of get_phys_page_debug should be used to get correct asidx at the end to handle access properly.
Here the patch to fix it.

Signed-off-by: Dmitry Poletaev <poletaev@ispras.ru>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c    | 2 +-
 target/i386/cpu.h    | 3 ++-
 target/i386/helper.c | 5 ++++-
 3 files changed, 7 insertions(+), 3 deletions(-)

Comments

Laszlo Ersek Oct. 7, 2019, 8:29 a.m. UTC | #1
Hi Paolo,

(+Peter)

On 10/02/19 18:51, Paolo Bonzini wrote:
> From: Dmitry Poletaev <poletaev@ispras.ru>
> 
> There is a problem, that you don't have access to the data using cpu_memory_rw_debug() function when in SMM. You can't remotely debug SMM mode program because of that for example.
> Likely attrs version of get_phys_page_debug should be used to get correct asidx at the end to handle access properly.
> Here the patch to fix it.
> 
> Signed-off-by: Dmitry Poletaev <poletaev@ispras.ru>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  target/i386/cpu.c    | 2 +-
>  target/i386/cpu.h    | 3 ++-
>  target/i386/helper.c | 5 ++++-
>  3 files changed, 7 insertions(+), 3 deletions(-)

If it's not too late yet -- I've just pulled the master branch and this patch doesn't appear to be on it --, can you please edit the commit message a little?

It would be nice if the commit message included the following two links, to the original issue report from Dmitry (both links point to the same message, just in different archives):

  "Can not read SMI handler code with cpu_memory_rw_debug while in SMM"
  https://lists.gnu.org/archive/html/qemu-devel/2019-08/msg06039.html
  http://mid.mail-archive.com/51deeefdf33168ff11234ffd96ee646d@rainloop.ispras.ru

(Thank you Dmitry for the patch BTW, I'll probably rely quite a bit on it in the future.)

Thank you,
Laszlo

> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 313a2ef..8fcb571 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -6245,7 +6245,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
>  #ifndef CONFIG_USER_ONLY
>      cc->asidx_from_attrs = x86_asidx_from_attrs;
>      cc->get_memory_mapping = x86_cpu_get_memory_mapping;
> -    cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
> +    cc->get_phys_page_attrs_debug = x86_cpu_get_phys_page_attrs_debug;
>      cc->write_elf64_note = x86_cpu_write_elf64_note;
>      cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
>      cc->write_elf32_note = x86_cpu_write_elf32_note;
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index 033991c..eaa5395 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -1690,7 +1690,8 @@ void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
>  
>  void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags);
>  
> -hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
> +hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
> +                                         MemTxAttrs *attrs);
>  
>  int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
>  int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
> diff --git a/target/i386/helper.c b/target/i386/helper.c
> index 0fa51be..c3a6e4f 100644
> --- a/target/i386/helper.c
> +++ b/target/i386/helper.c
> @@ -715,7 +715,8 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
>  }
>  
>  #if !defined(CONFIG_USER_ONLY)
> -hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
> +hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
> +                                         MemTxAttrs *attrs)
>  {
>      X86CPU *cpu = X86_CPU(cs);
>      CPUX86State *env = &cpu->env;
> @@ -725,6 +726,8 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>      uint32_t page_offset;
>      int page_size;
>  
> +    *attrs = cpu_get_mem_attrs(env);
> +
>      a20_mask = x86_get_a20_mask(env);
>      if (!(env->cr[0] & CR0_PG_MASK)) {
>          pte = addr & a20_mask;
>
diff mbox series

Patch

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 313a2ef..8fcb571 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6245,7 +6245,7 @@  static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 #ifndef CONFIG_USER_ONLY
     cc->asidx_from_attrs = x86_asidx_from_attrs;
     cc->get_memory_mapping = x86_cpu_get_memory_mapping;
-    cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
+    cc->get_phys_page_attrs_debug = x86_cpu_get_phys_page_attrs_debug;
     cc->write_elf64_note = x86_cpu_write_elf64_note;
     cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
     cc->write_elf32_note = x86_cpu_write_elf32_note;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 033991c..eaa5395 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1690,7 +1690,8 @@  void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
 
 void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 
-hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
+                                         MemTxAttrs *attrs);
 
 int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target/i386/helper.c b/target/i386/helper.c
index 0fa51be..c3a6e4f 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -715,7 +715,8 @@  void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
 }
 
 #if !defined(CONFIG_USER_ONLY)
-hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
+hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
+                                         MemTxAttrs *attrs)
 {
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
@@ -725,6 +726,8 @@  hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     uint32_t page_offset;
     int page_size;
 
+    *attrs = cpu_get_mem_attrs(env);
+
     a20_mask = x86_get_a20_mask(env);
     if (!(env->cr[0] & CR0_PG_MASK)) {
         pte = addr & a20_mask;