qemu-devel
[Top][All Lists]
Advanced

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

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


From: address@hidden
Subject: Re: [Qemu-devel] [PATCH] Add PowerPC 32-bit guest memory dump support
Date: Fri, 10 Feb 2017 14:21:23 +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.

Erm..  I'm trying to work out exactly what you mean by that
assumption.

A TARGET_PPC64=y qemu supports 32-bit as well as 64-bit machine types,
so it could be running a 32-bit guest inside it.

So, arguably compile time switching between 32bit and 64-bit dumps
isn't quite correct; but then it's not any worse than what we have now
which is a compile time switch between 64-bit dumps and nothing at
all.

I think this change should be ok, but I'm no ELF or dump expert.

> Signed-off-by: Mike Nawrocki <address@hidden>
> ---
>  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]