qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-ppc] [PATCH] Add PowerPC 32-bit guest memory dump support


From: address@hidden
Subject: Re: [Qemu-ppc] [PATCH] Add PowerPC 32-bit guest memory dump support
Date: Tue, 28 Feb 2017 11:47:06 +1100
User-agent: Mutt/1.7.1 (2016-10-04)

On Wed, Feb 08, 2017 at 08:39:36PM +0000, Nawrocki, Michael wrote:
> This patch extends support for the `dump-guest-memory` command to the 32-bit 
> PowerPC architecture. It relies on the assumption that a 64-bit guest will 
> not dump a 32-bit core file (and vice versa); if this assumption is invalid, 
> please let me know.
> 
> Signed-off-by: Mike Nawrocki <address@hidden>

Sorry I've taken so long to review this.  I'm not really sure if this
is correct for all machine type combinations (particularly 32-bit
machines with a 64-bit compiled qemu), but fairly clearly it does
strictly more than the existing code.

Unfortunately, updates since you posted this means it no longer
applies, so you'll need to rebase.

When I tried applying, git am also had some complaints about trailing
whitespace.

> ---
>  target/ppc/Makefile.objs    |   4 +-
>  target/ppc/arch_dump.c      | 154 
> ++++++++++++++++++++++++--------------------
>  target/ppc/cpu.h            |   2 +
>  target/ppc/translate_init.c |   5 +-
>  4 files changed, 91 insertions(+), 74 deletions(-)
> 
> diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs
> index a8c7a30..f50ffac 100644
> --- a/target/ppc/Makefile.objs
> +++ b/target/ppc/Makefile.objs
> @@ -1,8 +1,8 @@
>  obj-y += cpu-models.o
>  obj-y += translate.o
>  ifeq ($(CONFIG_SOFTMMU),y)
> -obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o
> -obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o compat.o
> +obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o arch_dump.o
> +obj-$(TARGET_PPC64) += mmu-hash64.o compat.o
>  endif
>  obj-$(CONFIG_KVM) += kvm.o
>  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
> index 40282a1..28d9cc7 100644
> --- a/target/ppc/arch_dump.c
> +++ b/target/ppc/arch_dump.c
> @@ -1,5 +1,5 @@
>  /*
> - * writing ELF notes for ppc64 arch
> + * writing ELF notes for ppc{64,} arch
>   *
>   *
>   * Copyright IBM, Corp. 2013
> @@ -19,36 +19,48 @@
>  #include "sysemu/dump.h"
>  #include "sysemu/kvm.h"
>  
> -struct PPC64UserRegStruct {
> -    uint64_t gpr[32];
> -    uint64_t nip;
> -    uint64_t msr;
> -    uint64_t orig_gpr3;
> -    uint64_t ctr;
> -    uint64_t link;
> -    uint64_t xer;
> -    uint64_t ccr;
> -    uint64_t softe;
> -    uint64_t trap;
> -    uint64_t dar;
> -    uint64_t dsisr;
> -    uint64_t result;
> +#ifdef TARGET_PPC64
> +#define ELFCLASS ELFCLASS64
> +#define cpu_to_dump_reg cpu_to_dump64
> +typedef uint64_t reg_t;
> +typedef Elf64_Nhdr Elf_Nhdr;
> +#else
> +#define ELFCLASS ELFCLASS32
> +#define cpu_to_dump_reg cpu_to_dump32
> +typedef uint32_t reg_t;
> +typedef Elf32_Nhdr Elf_Nhdr;
> +#endif /* TARGET_PPC64 */
> +
> +struct PPCUserRegStruct {
> +    reg_t gpr[32];
> +    reg_t nip;
> +    reg_t msr;
> +    reg_t orig_gpr3;
> +    reg_t ctr;
> +    reg_t link;
> +    reg_t xer;
> +    reg_t ccr;
> +    reg_t softe;
> +    reg_t trap;
> +    reg_t dar;
> +    reg_t dsisr;
> +    reg_t result;
>  } QEMU_PACKED;
>  
> -struct PPC64ElfPrstatus {
> +struct PPCElfPrstatus {
>      char pad1[112];
> -    struct PPC64UserRegStruct pr_reg;
> -    uint64_t pad2[4];
> +    struct PPCUserRegStruct pr_reg;
> +    reg_t pad2[4];
>  } QEMU_PACKED;
>  
>  
> -struct PPC64ElfFpregset {
> +struct PPCElfFpregset {
>      uint64_t fpr[32];
> -    uint64_t fpscr;
> +    reg_t fpscr;
>  }  QEMU_PACKED;
>  
>  
> -struct PPC64ElfVmxregset {
> +struct PPCElfVmxregset {
>      ppc_avr_t avr[32];
>      ppc_avr_t vscr;
>      union {
> @@ -57,26 +69,26 @@ struct PPC64ElfVmxregset {
>      } vrsave;
>  }  QEMU_PACKED;
>  
> -struct PPC64ElfVsxregset {
> +struct PPCElfVsxregset {
>      uint64_t vsr[32];
>  }  QEMU_PACKED;
>  
> -struct PPC64ElfSperegset {
> +struct PPCElfSperegset {
>      uint32_t evr[32];
>      uint64_t spe_acc;
>      uint32_t spe_fscr;
>  }  QEMU_PACKED;
>  
>  typedef struct noteStruct {
> -    Elf64_Nhdr hdr;
> +    Elf_Nhdr hdr;
>      char name[5];
>      char pad3[3];
>      union {
> -        struct PPC64ElfPrstatus  prstatus;
> -        struct PPC64ElfFpregset  fpregset;
> -        struct PPC64ElfVmxregset vmxregset;
> -        struct PPC64ElfVsxregset vsxregset;
> -        struct PPC64ElfSperegset speregset;
> +        struct PPCElfPrstatus  prstatus;
> +        struct PPCElfFpregset  fpregset;
> +        struct PPCElfVmxregset vmxregset;
> +        struct PPCElfVsxregset vsxregset;
> +        struct PPCElfSperegset speregset;
>      } contents;
>  } QEMU_PACKED Note;
>  
> @@ -85,12 +97,12 @@ typedef struct NoteFuncArg {
>      DumpState *state;
>  } NoteFuncArg;
>  
> -static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    uint64_t cr;
> -    struct PPC64ElfPrstatus *prstatus;
> -    struct PPC64UserRegStruct *reg;
> +    reg_t cr;
> +    struct PPCElfPrstatus *prstatus;
> +    struct PPCUserRegStruct *reg;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -101,25 +113,25 @@ static void ppc64_write_elf64_prstatus(NoteFuncArg 
> *arg, PowerPCCPU *cpu)
>      reg = &prstatus->pr_reg;
>  
>      for (i = 0; i < 32; i++) {
> -        reg->gpr[i] = cpu_to_dump64(s, cpu->env.gpr[i]);
> +        reg->gpr[i] = cpu_to_dump_reg(s, cpu->env.gpr[i]);
>      }
> -    reg->nip = cpu_to_dump64(s, cpu->env.nip);
> -    reg->msr = cpu_to_dump64(s, cpu->env.msr);
> -    reg->ctr = cpu_to_dump64(s, cpu->env.ctr);
> -    reg->link = cpu_to_dump64(s, cpu->env.lr);
> -    reg->xer = cpu_to_dump64(s, cpu_read_xer(&cpu->env));
> +    reg->nip = cpu_to_dump_reg(s, cpu->env.nip);
> +    reg->msr = cpu_to_dump_reg(s, cpu->env.msr);
> +    reg->ctr = cpu_to_dump_reg(s, cpu->env.ctr);
> +    reg->link = cpu_to_dump_reg(s, cpu->env.lr);
> +    reg->xer = cpu_to_dump_reg(s, cpu_read_xer(&cpu->env));
>  
>      cr = 0;
>      for (i = 0; i < 8; i++) {
>          cr |= (cpu->env.crf[i] & 15) << (4 * (7 - i));
>      }
> -    reg->ccr = cpu_to_dump64(s, cr);
> +    reg->ccr = cpu_to_dump_reg(s, cr);
>  }
>  
> -static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfFpregset  *fpregset;
> +    struct PPCElfFpregset  *fpregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -131,13 +143,13 @@ static void ppc64_write_elf64_fpregset(NoteFuncArg 
> *arg, PowerPCCPU *cpu)
>      for (i = 0; i < 32; i++) {
>          fpregset->fpr[i] = cpu_to_dump64(s, cpu->env.fpr[i]);
>      }
> -    fpregset->fpscr = cpu_to_dump64(s, cpu->env.fpscr);
> +    fpregset->fpscr = cpu_to_dump_reg(s, cpu->env.fpscr);
>  }
>  
> -static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfVmxregset *vmxregset;
> +    struct PPCElfVmxregset *vmxregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -164,10 +176,11 @@ static void ppc64_write_elf64_vmxregset(NoteFuncArg 
> *arg, PowerPCCPU *cpu)
>      }
>      vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr);
>  }
> -static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +
> +static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
>      int i;
> -    struct PPC64ElfVsxregset *vsxregset;
> +    struct PPCElfVsxregset *vsxregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -179,9 +192,10 @@ static void ppc64_write_elf64_vsxregset(NoteFuncArg 
> *arg, PowerPCCPU *cpu)
>          vsxregset->vsr[i] = cpu_to_dump64(s, cpu->env.vsr[i]);
>      }
>  }
> -static void ppc64_write_elf64_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> +
> +static void ppc_write_elf_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>  {
> -    struct PPC64ElfSperegset *speregset;
> +    struct PPCElfSperegset *speregset;
>      Note *note = &arg->note;
>      DumpState *s = arg->state;
>  
> @@ -197,11 +211,11 @@ static const struct NoteFuncDescStruct {
>      int contents_size;
>      void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu);
>  } note_func[] = {
> -    {sizeof(((Note *)0)->contents.prstatus),  ppc64_write_elf64_prstatus},
> -    {sizeof(((Note *)0)->contents.fpregset),  ppc64_write_elf64_fpregset},
> -    {sizeof(((Note *)0)->contents.vmxregset), ppc64_write_elf64_vmxregset},
> -    {sizeof(((Note *)0)->contents.vsxregset), ppc64_write_elf64_vsxregset},
> -    {sizeof(((Note *)0)->contents.speregset), ppc64_write_elf64_speregset},
> +    {sizeof(((Note *)0)->contents.prstatus),  ppc_write_elf_prstatus},
> +    {sizeof(((Note *)0)->contents.fpregset),  ppc_write_elf_fpregset},
> +    {sizeof(((Note *)0)->contents.vmxregset), ppc_write_elf_vmxregset},
> +    {sizeof(((Note *)0)->contents.vsxregset), ppc_write_elf_vsxregset},
> +    {sizeof(((Note *)0)->contents.speregset), ppc_write_elf_speregset},
>      { 0, NULL}
>  };
>  
> @@ -213,8 +227,9 @@ int cpu_get_dump_info(ArchDumpInfo *info,
>      PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
>      PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
>  
> -    info->d_machine = EM_PPC64;
> -    info->d_class = ELFCLASS64;
> +    info->d_machine = PPC_ELF_MACHINE;
> +    info->d_class = ELFCLASS;
> +
>      if ((*pcc->interrupts_big_endian)(cpu)) {
>          info->d_endian = ELFDATA2MSB;
>      } else {
> @@ -236,25 +251,19 @@ ssize_t cpu_get_note_size(int class, int machine, int 
> nr_cpus)
>      int note_head_size;
>      const NoteFuncDesc *nf;
>  
> -    if (class != ELFCLASS64) {
> -        return -1;
> -    }
> -    assert(machine == EM_PPC64);
> -
> -    note_head_size = sizeof(Elf64_Nhdr);
> -
> +    note_head_size = sizeof(Elf_Nhdr);
>      for (nf = note_func; nf->note_contents_func; nf++) {
>          elf_note_size = elf_note_size + note_head_size + name_size +
> -                        nf->contents_size;
> +            nf->contents_size;
>      }
>  
>      return (elf_note_size) * nr_cpus;
>  }
>  
> -static int ppc64_write_all_elf64_notes(const char *note_name,
> -                                       WriteCoreDumpFunction f,
> -                                       PowerPCCPU *cpu, int id,
> -                                       void *opaque)
> +static int ppc_write_all_elf_notes(const char *note_name,
> +                                   WriteCoreDumpFunction f,
> +                                   PowerPCCPU *cpu, int id,
> +                                   void *opaque)
>  {
>      NoteFuncArg arg = { .state = opaque };
>      int ret = -1;
> @@ -282,5 +291,12 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, 
> CPUState *cs,
>                                 int cpuid, void *opaque)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
> -    return ppc64_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);
> +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
> +}
> +
> +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> +                               int cpuid, void *opaque)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
>  }
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index bc2a2ce..61efd7b 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1225,6 +1225,8 @@ int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t 
> *buf, int reg);
>  int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
>  int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>                                 int cpuid, void *opaque);
> +int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
> +                               int cpuid, void *opaque);
>  #ifndef CONFIG_USER_ONLY
>  void ppc_cpu_do_system_reset(CPUState *cs);
>  extern const struct VMStateDescription vmstate_ppc_cpu;
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 76f79fa..ebb3d8a 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -10478,11 +10478,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, 
> void *data)
>  #else
>      cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
>      cc->vmsd = &vmstate_ppc_cpu;
> -#if defined(TARGET_PPC64)
> -    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
> -#endif
>  #endif
>      cc->cpu_exec_enter = ppc_cpu_exec_enter;
> +    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
> +    cc->write_elf32_note = ppc32_cpu_write_elf32_note;
>  
>      cc->gdb_num_core_regs = 71;
>  

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]