All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server
@ 2013-10-01 16:19 Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 1/6] target-ppc: Update slb array with correct index values Aneesh Kumar K.V
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Aneesh Kumar K.V @ 2013-10-01 16:19 UTC (permalink / raw
  To: agraf, paulus; +Cc: qemu-ppc, qemu-devel

Hi,

This patch series implement support for dumping guest memory using qemu gdb server. The last patch also enable qemu monitor command dump-guest-memory

With this patch series we can now do

(gdb) x/4i htab_call_hpte_insert1
   0xc0000000000470d8 <.htab_call_hpte_insert1>:        bl      0xc0000000000470d8 <.htab_call_hpte_insert1>
   0xc0000000000470dc <.htab_call_hpte_insert1+4>:      cmpdi   r3,0
   0xc0000000000470e0 <.htab_call_hpte_insert1+8>:      bge     0xc000000000047190 <htab_pte_insert_ok>
   0xc0000000000470e4 <.htab_call_hpte_insert1+12>:     cmpdi   r3,-2
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
.plpar_hcall_norets () at arch/powerpc/platforms/pseries/hvCall.S:119
119             HCALL_INST_POSTCALL_NORETS
(gdb) x/4i htab_call_hpte_insert1
   0xc0000000000470d8 <.htab_call_hpte_insert1>:        bl      0xc00000000005f8f0 <pSeries_lpar_hpte_insert>
   0xc0000000000470dc <.htab_call_hpte_insert1+4>:      cmpdi   r3,0
   0xc0000000000470e0 <.htab_call_hpte_insert1+8>:      bge     0xc000000000047190 <htab_pte_insert_ok>
   0xc0000000000470e4 <.htab_call_hpte_insert1+12>:     cmpdi   r3,-2
(gdb)

NOTE: We still don't support inserting breakpoints.

Before Fix:
(qemu) memsave 0xc0000000000470d8 10 memdump
Invalid parameter 'addr'
(qemu)

After fix:

(qemu)  memsave 0xc0000000000470d8 10 memdump
(qemu)

Changes from V3:
* Address review feedback
* Updated "target-ppc: Fix page table lookup with kvm enabled" to not
  reopen the htab in loop

Changes from V2:
* Address review comments updating "target-ppc: Update slb array with correct index values"
* Add new patch "target-ppc: Use #define for max slb entries"
* Drop the patch "target-ppc: Use #define instead of opencoding SLB valid bit"
   because it got picked from last series.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH -V4 RESEND 1/6] target-ppc: Update slb array with correct index values.
  2013-10-01 16:19 [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Aneesh Kumar K.V
@ 2013-10-01 16:19 ` Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 2/6] target-ppc: Fix page table lookup with kvm enabled Aneesh Kumar K.V
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Aneesh Kumar K.V @ 2013-10-01 16:19 UTC (permalink / raw
  To: agraf, paulus; +Cc: qemu-ppc, qemu-devel, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

Without this, a value of rb=0 and rs=0 results in replacing the 0th
index. This can be observed when using gdb remote debugging support.

(gdb) x/10i do_fork
   0xc000000000085330 <do_fork>:        Cannot access memory at address 0xc000000000085330
(gdb)

This is because when we do the slb sync via kvm_cpu_synchronize_state,
we overwrite the slb entry (0th entry) for 0xc000000000085330

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 target-ppc/kvm.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 8a196c6..e318250 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1033,9 +1033,22 @@ int kvm_arch_get_registers(CPUState *cs)
 
         /* Sync SLB */
 #ifdef TARGET_PPC64
+        /*
+         * The packed SLB array we get from KVM_GET_SREGS only contains
+         * information about valid entries. So we flush our internal
+         * copy to get rid of stale ones, then put all valid SLB entries
+         * back in.
+         */
+        memset(env->slb, 0, sizeof(env->slb));
         for (i = 0; i < 64; i++) {
-            ppc_store_slb(env, sregs.u.s.ppc64.slb[i].slbe,
-                               sregs.u.s.ppc64.slb[i].slbv);
+            target_ulong rb = sregs.u.s.ppc64.slb[i].slbe;
+            target_ulong rs = sregs.u.s.ppc64.slb[i].slbv;
+            /*
+             * Only restore valid entries
+             */
+            if (rb & SLB_ESID_V) {
+                ppc_store_slb(env, rb, rs);
+            }
         }
 #endif
 
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH -V4 RESEND 2/6] target-ppc: Fix page table lookup with kvm enabled
  2013-10-01 16:19 [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 1/6] target-ppc: Update slb array with correct index values Aneesh Kumar K.V
@ 2013-10-01 16:19 ` Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 3/6] target-ppc: Check for error on address translation in memsave command Aneesh Kumar K.V
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Aneesh Kumar K.V @ 2013-10-01 16:19 UTC (permalink / raw
  To: agraf, paulus; +Cc: qemu-ppc, qemu-devel, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

With kvm enabled, we store the hash page table information in the hypervisor.
Use ioctl to read the htab contents. Without this we get the below error when
trying to read the guest address

 (gdb) x/10 do_fork
 0xc000000000098660 <do_fork>:   Cannot access memory at address 0xc000000000098660
 (gdb)

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 target-ppc/kvm.c        | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/kvm_ppc.h    | 12 +++++++++-
 target-ppc/mmu-hash64.c | 57 ++++++++++++++++++++++++++++-------------------
 3 files changed, 104 insertions(+), 24 deletions(-)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index e318250..8a53c75 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1888,3 +1888,62 @@ int kvm_arch_on_sigbus(int code, void *addr)
 void kvm_arch_init_irq_routing(KVMState *s)
 {
 }
+
+hwaddr kvmppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
+                                 bool secondary, target_ulong ptem,
+                                 target_ulong *hpte0, target_ulong *hpte1)
+{
+    int htab_fd;
+    uint64_t index;
+    hwaddr pte_offset;
+    target_ulong pte0, pte1;
+    struct kvm_get_htab_fd ghf;
+    struct kvm_get_htab_buf {
+        struct kvm_get_htab_header header;
+        /*
+         * Older kernel required one extra byte.
+         */
+        unsigned long hpte[(HPTES_PER_GROUP * 2) + 1];
+    } hpte_buf;
+
+    index = (hash * HPTES_PER_GROUP) & cpu->env.htab_mask;
+    *hpte0 = 0;
+    *hpte1 = 0;
+    if (!cap_htab_fd) {
+        return 0;
+    }
+
+    ghf.flags = 0;
+    ghf.start_index = index;
+    htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf);
+    if (htab_fd < 0) {
+        goto error_out;
+    }
+    /*
+     * Read the hpte group
+     */
+    if (read(htab_fd, &hpte_buf, sizeof(hpte_buf)) < 0) {
+        goto out;
+    }
+
+    index = 0;
+    pte_offset = (hash * HASH_PTEG_SIZE_64) & cpu->env.htab_mask;;
+    while (index < hpte_buf.header.n_valid) {
+        pte0 = hpte_buf.hpte[(index * 2)];
+        pte1 = hpte_buf.hpte[(index * 2) + 1];
+        if ((pte0 & HPTE64_V_VALID)
+            && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
+            && HPTE64_V_COMPARE(pte0, ptem)) {
+            *hpte0 = pte0;
+            *hpte1 = pte1;
+            close(htab_fd);
+            return pte_offset;
+        }
+        index++;
+        pte_offset += HASH_PTE_SIZE_64;
+    }
+out:
+    close(htab_fd);
+error_out:
+    return -1;
+}
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 4ae7bf2..dad0e57 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -42,7 +42,9 @@ int kvmppc_get_htab_fd(bool write);
 int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns);
 int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
                            uint16_t n_valid, uint16_t n_invalid);
-
+hwaddr kvmppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
+                                 bool secondary, target_ulong ptem,
+                                 target_ulong *hpte0, target_ulong *hpte1);
 #else
 
 static inline uint32_t kvmppc_get_tbfreq(void)
@@ -181,6 +183,14 @@ static inline int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
     abort();
 }
 
+static inline hwaddr kvmppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
+                                               bool secondary,
+                                               target_ulong ptem,
+                                               target_ulong *hpte0,
+                                               target_ulong *hpte1)
+{
+    abort();
+}
 #endif
 
 #ifndef CONFIG_KVM
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 67fc1b5..2288fe8 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -302,37 +302,50 @@ static int ppc_hash64_amr_prot(CPUPPCState *env, ppc_hash_pte64_t pte)
     return prot;
 }
 
-static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr pteg_off,
+static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr hash,
                                      bool secondary, target_ulong ptem,
                                      ppc_hash_pte64_t *pte)
 {
-    hwaddr pte_offset = pteg_off;
+    hwaddr pte_offset;
     target_ulong pte0, pte1;
-    int i;
-
-    for (i = 0; i < HPTES_PER_GROUP; i++) {
-        pte0 = ppc_hash64_load_hpte0(env, pte_offset);
-        pte1 = ppc_hash64_load_hpte1(env, pte_offset);
-
-        if ((pte0 & HPTE64_V_VALID)
-            && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
-            && HPTE64_V_COMPARE(pte0, ptem)) {
-            pte->pte0 = pte0;
-            pte->pte1 = pte1;
-            return pte_offset;
+    int i, ret = 0;
+
+    if (kvm_enabled()) {
+        ret = kvmppc_hash64_pteg_search(ppc_env_get_cpu(env), hash,
+                                        secondary, ptem,
+                                        &pte->pte0, &pte->pte1);
+    }
+    /*
+     * We don't support htab fd, check whether we have a copy of htab
+     */
+    if (!ret) {
+        pte_offset = (hash * HASH_PTEG_SIZE_64) & env->htab_mask;;
+        for (i = 0; i < HPTES_PER_GROUP; i++) {
+            pte0 = ppc_hash64_load_hpte0(env, pte_offset);
+            pte1 = ppc_hash64_load_hpte1(env, pte_offset);
+
+            if ((pte0 & HPTE64_V_VALID)
+                && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
+                && HPTE64_V_COMPARE(pte0, ptem)) {
+                pte->pte0 = pte0;
+                pte->pte1 = pte1;
+                return pte_offset;
+            }
+            pte_offset += HASH_PTE_SIZE_64;
         }
-
-        pte_offset += HASH_PTE_SIZE_64;
+        /*
+         * We didn't find a valid entry.
+         */
+        ret = -1;
     }
-
-    return -1;
+    return ret;
 }
 
 static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
                                      ppc_slb_t *slb, target_ulong eaddr,
                                      ppc_hash_pte64_t *pte)
 {
-    hwaddr pteg_off, pte_offset;
+    hwaddr pte_offset;
     hwaddr hash;
     uint64_t vsid, epnshift, epnmask, epn, ptem;
 
@@ -367,8 +380,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
             " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
             " hash=" TARGET_FMT_plx "\n",
             env->htab_base, env->htab_mask, vsid, ptem,  hash);
-    pteg_off = (hash * HASH_PTEG_SIZE_64) & env->htab_mask;
-    pte_offset = ppc_hash64_pteg_search(env, pteg_off, 0, ptem, pte);
+    pte_offset = ppc_hash64_pteg_search(env, hash, 0, ptem, pte);
 
     if (pte_offset == -1) {
         /* Secondary PTEG lookup */
@@ -377,8 +389,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
                 " hash=" TARGET_FMT_plx "\n", env->htab_base,
                 env->htab_mask, vsid, ptem, ~hash);
 
-        pteg_off = (~hash * HASH_PTEG_SIZE_64) & env->htab_mask;
-        pte_offset = ppc_hash64_pteg_search(env, pteg_off, 1, ptem, pte);
+        pte_offset = ppc_hash64_pteg_search(env, ~hash, 1, ptem, pte);
     }
 
     return pte_offset;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH -V4 RESEND 3/6] target-ppc: Check for error on address translation in memsave command
  2013-10-01 16:19 [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 1/6] target-ppc: Update slb array with correct index values Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 2/6] target-ppc: Fix page table lookup with kvm enabled Aneesh Kumar K.V
@ 2013-10-01 16:19 ` Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 4/6] target-ppc: Use #define for max slb entries Aneesh Kumar K.V
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Aneesh Kumar K.V @ 2013-10-01 16:19 UTC (permalink / raw
  To: agraf, paulus; +Cc: qemu-ppc, qemu-devel, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

When we translate the virtual address to physical check for error.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 cpus.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/cpus.c b/cpus.c
index e566297..52470a6 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1333,7 +1333,10 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
         l = sizeof(buf);
         if (l > size)
             l = size;
-        cpu_memory_rw_debug(cpu, addr, buf, l, 0);
+        if (cpu_memory_rw_debug(cpu, addr, buf, l, 0) != 0) {
+            error_setg(errp, "Invalid addr 0x%016" PRIx64 "specified", addr);
+            goto exit;
+        }
         if (fwrite(buf, 1, l, f) != l) {
             error_set(errp, QERR_IO_ERROR);
             goto exit;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH -V4 RESEND 4/6] target-ppc: Use #define for max slb entries
  2013-10-01 16:19 [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Aneesh Kumar K.V
                   ` (2 preceding siblings ...)
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 3/6] target-ppc: Check for error on address translation in memsave command Aneesh Kumar K.V
@ 2013-10-01 16:19 ` Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 5/6] dump-guest-memory: Check for the correct return value Aneesh Kumar K.V
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Aneesh Kumar K.V @ 2013-10-01 16:19 UTC (permalink / raw
  To: agraf, paulus; +Cc: qemu-ppc, qemu-devel, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

Instead of opencoding 64 use MAX_SLB_ENTRIES. We don't update the kernel
header here.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 target-ppc/cpu.h     | 3 ++-
 target-ppc/kvm.c     | 4 ++--
 target-ppc/machine.c | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 422a6bb..26acdba 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -405,6 +405,7 @@ struct ppc_slb_t {
     uint64_t vsid;
 };
 
+#define MAX_SLB_ENTRIES         64
 #define SEGMENT_SHIFT_256M      28
 #define SEGMENT_MASK_256M       (~((1ULL << SEGMENT_SHIFT_256M) - 1))
 
@@ -949,7 +950,7 @@ struct CPUPPCState {
 #if !defined(CONFIG_USER_ONLY)
 #if defined(TARGET_PPC64)
     /* PowerPC 64 SLB area */
-    ppc_slb_t slb[64];
+    ppc_slb_t slb[MAX_SLB_ENTRIES];
     int32_t slb_nr;
 #endif
     /* segment registers */
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 8a53c75..30f14c6 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -818,7 +818,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 
         /* Sync SLB */
 #ifdef TARGET_PPC64
-        for (i = 0; i < 64; i++) {
+        for (i = 0; i < ARRAY_SIZE(env->slb); i++) {
             sregs.u.s.ppc64.slb[i].slbe = env->slb[i].esid;
             sregs.u.s.ppc64.slb[i].slbv = env->slb[i].vsid;
         }
@@ -1040,7 +1040,7 @@ int kvm_arch_get_registers(CPUState *cs)
          * back in.
          */
         memset(env->slb, 0, sizeof(env->slb));
-        for (i = 0; i < 64; i++) {
+        for (i = 0; i < ARRAY_SIZE(env->slb); i++) {
             target_ulong rb = sregs.u.s.ppc64.slb[i].slbe;
             target_ulong rs = sregs.u.s.ppc64.slb[i].slbv;
             /*
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 12e1512..12c174f 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -312,7 +312,7 @@ static const VMStateDescription vmstate_slb = {
     .minimum_version_id_old = 1,
     .fields      = (VMStateField []) {
         VMSTATE_INT32_EQUAL(env.slb_nr, PowerPCCPU),
-        VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, 64),
+        VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, MAX_SLB_ENTRIES),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH -V4 RESEND 5/6] dump-guest-memory: Check for the correct return value
  2013-10-01 16:19 [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Aneesh Kumar K.V
                   ` (3 preceding siblings ...)
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 4/6] target-ppc: Use #define for max slb entries Aneesh Kumar K.V
@ 2013-10-01 16:19 ` Aneesh Kumar K.V
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 6/6] target-ppc: dump-guest-memory support Aneesh Kumar K.V
  2013-10-02 14:06 ` [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Alexander Graf
  6 siblings, 0 replies; 8+ messages in thread
From: Aneesh Kumar K.V @ 2013-10-01 16:19 UTC (permalink / raw
  To: agraf, paulus; +Cc: qemu-ppc, qemu-devel, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

We should check for error with s->note_size

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 dump.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dump.c b/dump.c
index 846155c..80a9116 100644
--- a/dump.c
+++ b/dump.c
@@ -66,7 +66,7 @@ typedef struct DumpState {
     uint32_t sh_info;
     bool have_section;
     bool resume;
-    size_t note_size;
+    ssize_t note_size;
     hwaddr memory_offset;
     int fd;
 
@@ -765,7 +765,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
 
     s->note_size = cpu_get_note_size(s->dump_info.d_class,
                                      s->dump_info.d_machine, nr_cpus);
-    if (ret < 0) {
+    if (s->note_size < 0) {
         error_set(errp, QERR_UNSUPPORTED);
         goto cleanup;
     }
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH -V4 RESEND 6/6] target-ppc: dump-guest-memory support
  2013-10-01 16:19 [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Aneesh Kumar K.V
                   ` (4 preceding siblings ...)
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 5/6] dump-guest-memory: Check for the correct return value Aneesh Kumar K.V
@ 2013-10-01 16:19 ` Aneesh Kumar K.V
  2013-10-02 14:06 ` [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Alexander Graf
  6 siblings, 0 replies; 8+ messages in thread
From: Aneesh Kumar K.V @ 2013-10-01 16:19 UTC (permalink / raw
  To: agraf, paulus; +Cc: qemu-ppc, qemu-devel, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

This patch add support for dumping guest memory using dump-guest-memory
monitor command.

Before patch:

(qemu) dump-guest-memory testcrash
this feature or command is not currently supported
(qemu)

After patch:

(qemu) dump-guest-memory testcrash
(qemu)

crash was able to read the file

crash> bt
PID: 0      TASK: c000000000c0d0d0  CPU: 0   COMMAND: "swapper/0"

 R0:  0000000028000084    R1:  c000000000cafa50    R2:  c000000000cb05b0
 R3:  0000000000000000    R4:  c000000000bc4cb0    R5:  0000000000000000
 R6:  001efe93b8000000    R7:  0000000000000000    R8:  0000000000000000
 R9:  b000000000001032    R10: 0000000000000001    R11: 0001eb2117e00d55
....
...

NOTE: Currently crash tools doesn't look at ELF notes in the dump on ppc64.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 include/elf.h               |   3 +
 target-ppc/Makefile.objs    |   2 +-
 target-ppc/arch_dump.c      | 253 ++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/cpu-qom.h        |   5 +-
 target-ppc/translate_init.c |   4 +
 5 files changed, 265 insertions(+), 2 deletions(-)
 create mode 100644 target-ppc/arch_dump.c

diff --git a/include/elf.h b/include/elf.h
index 58bfbf8..b818091 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -1359,6 +1359,9 @@ typedef struct elf64_shdr {
 #define NT_S390_TODPREG 0x303           /* s390 TOD programmable register */
 #define NT_S390_TODCMP  0x302           /* s390 TOD clock comparator register */
 #define NT_S390_TIMER   0x301           /* s390 timer register */
+#define NT_PPC_VMX       0x100          /* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE       0x101          /* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX       0x102          /* PowerPC VSX registers */
 
 
 /* Note header in a PT_NOTE section */
diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs
index f72e399..ec06e50 100644
--- a/target-ppc/Makefile.objs
+++ b/target-ppc/Makefile.objs
@@ -2,7 +2,7 @@ obj-y += cpu-models.o
 obj-y += translate.o
 ifeq ($(CONFIG_SOFTMMU),y)
 obj-y += machine.o mmu_helper.o mmu-hash32.o
-obj-$(TARGET_PPC64) += mmu-hash64.o
+obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o
 endif
 obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
diff --git a/target-ppc/arch_dump.c b/target-ppc/arch_dump.c
new file mode 100644
index 0000000..17fd4c6
--- /dev/null
+++ b/target-ppc/arch_dump.c
@@ -0,0 +1,253 @@
+/*
+ * writing ELF notes for ppc64 arch
+ *
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * Authors:
+ * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "cpu.h"
+#include "elf.h"
+#include "exec/cpu-all.h"
+#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;
+} QEMU_PACKED;
+
+struct PPC64ElfPrstatus {
+    char pad1[112];
+    struct PPC64UserRegStruct pr_reg;
+    uint64_t pad2[4];
+} QEMU_PACKED;
+
+
+struct PPC64ElfFpregset {
+    uint64_t fpr[32];
+    uint64_t fpscr;
+}  QEMU_PACKED;
+
+
+struct PPC64ElfVmxregset {
+    ppc_avr_t avr[32];
+    ppc_avr_t vscr;
+    union {
+        ppc_avr_t unused;
+        uint32_t value;
+    } vrsave;
+}  QEMU_PACKED;
+
+struct PPC64ElfVsxregset {
+    uint64_t vsr[32];
+}  QEMU_PACKED;
+
+struct PPC64ElfSperegset {
+    uint32_t evr[32];
+    uint64_t spe_acc;
+    uint32_t spe_fscr;
+}  QEMU_PACKED;
+
+typedef struct noteStruct {
+    Elf64_Nhdr hdr;
+    char name[5];
+    char pad3[3];
+    union {
+        struct PPC64ElfPrstatus  prstatus;
+        struct PPC64ElfFpregset  fpregset;
+        struct PPC64ElfVmxregset vmxregset;
+        struct PPC64ElfVsxregset vsxregset;
+        struct PPC64ElfSperegset speregset;
+    } contents;
+} QEMU_PACKED Note;
+
+
+static void ppc64_write_elf64_prstatus(Note *note, PowerPCCPU *cpu)
+{
+    int i;
+    uint64_t cr;
+    struct PPC64ElfPrstatus *prstatus;
+    struct PPC64UserRegStruct *reg;
+
+    note->hdr.n_type = cpu_to_be32(NT_PRSTATUS);
+
+    prstatus = &note->contents.prstatus;
+    memset(prstatus, 0, sizeof(*prstatus));
+    reg = &prstatus->pr_reg;
+
+    for (i = 0; i < 32; i++) {
+        reg->gpr[i] = cpu_to_be64(cpu->env.gpr[i]);
+    }
+    reg->nip = cpu_to_be64(cpu->env.nip);
+    reg->msr = cpu_to_be64(cpu->env.msr);
+    reg->ctr = cpu_to_be64(cpu->env.ctr);
+    reg->link = cpu_to_be64(cpu->env.lr);
+    reg->xer = cpu_to_be64(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_be64(cr);
+}
+
+static void ppc64_write_elf64_fpregset(Note *note, PowerPCCPU *cpu)
+{
+    int i;
+    struct PPC64ElfFpregset  *fpregset;
+
+    note->hdr.n_type = cpu_to_be32(NT_PRFPREG);
+
+    fpregset = &note->contents.fpregset;
+    memset(fpregset, 0, sizeof(*fpregset));
+
+    for (i = 0; i < 32; i++) {
+        fpregset->fpr[i] = cpu_to_be64(cpu->env.fpr[i]);
+    }
+    fpregset->fpscr = cpu_to_be64(cpu->env.fpscr);
+}
+
+static void ppc64_write_elf64_vmxregset(Note *note, PowerPCCPU *cpu)
+{
+    int i;
+    struct PPC64ElfVmxregset *vmxregset;
+
+    note->hdr.n_type = cpu_to_be32(NT_PPC_VMX);
+    vmxregset = &note->contents.vmxregset;
+    memset(vmxregset, 0, sizeof(*vmxregset));
+
+    for (i = 0; i < 32; i++) {
+        vmxregset->avr[i].u64[0] = cpu_to_be64(cpu->env.avr[i].u64[0]);
+        vmxregset->avr[i].u64[1] = cpu_to_be64(cpu->env.avr[i].u64[1]);
+    }
+    vmxregset->vscr.u32[3] = cpu_to_be32(cpu->env.vscr);
+}
+static void ppc64_write_elf64_vsxregset(Note *note, PowerPCCPU *cpu)
+{
+    int i;
+    struct PPC64ElfVsxregset *vsxregset;
+
+    note->hdr.n_type = cpu_to_be32(NT_PPC_VSX);
+    vsxregset = &note->contents.vsxregset;
+    memset(vsxregset, 0, sizeof(*vsxregset));
+
+    for (i = 0; i < 32; i++) {
+        vsxregset->vsr[i] = cpu_to_be64(cpu->env.vsr[i]);
+    }
+}
+static void ppc64_write_elf64_speregset(Note *note, PowerPCCPU *cpu)
+{
+    struct PPC64ElfSperegset *speregset;
+    note->hdr.n_type = cpu_to_be32(NT_PPC_SPE);
+    speregset = &note->contents.speregset;
+    memset(speregset, 0, sizeof(*speregset));
+
+    speregset->spe_acc = cpu_to_be64(cpu->env.spe_acc);
+    speregset->spe_fscr = cpu_to_be32(cpu->env.spe_fscr);
+}
+
+struct NoteFuncDescStruct {
+    int contents_size;
+    void (*note_contents_func)(Note *note, 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},
+    { 0, NULL}
+};
+
+typedef struct NoteFuncDescStruct NoteFuncDesc;
+
+int cpu_get_dump_info(ArchDumpInfo *info,
+                      const struct GuestPhysBlockList *guest_phys_blocks)
+{
+    /*
+     * Currently only handling PPC64 big endian.
+     */
+    info->d_machine = EM_PPC64;
+    info->d_endian = ELFDATA2MSB;
+    info->d_class = ELFCLASS64;
+
+    return 0;
+}
+
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+{
+    int name_size = 8; /* "CORE" or "QEMU" rounded */
+    size_t elf_note_size = 0;
+    int note_head_size;
+    NoteFuncDesc *nf;
+
+    if (class != ELFCLASS64) {
+        return -1;
+    }
+    assert(machine == EM_PPC64);
+
+    note_head_size = sizeof(Elf64_Nhdr);
+
+    for (nf = note_func; nf->note_contents_func; nf++) {
+        elf_note_size = elf_note_size + note_head_size + name_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)
+{
+    Note note;
+    int ret = -1;
+    int note_size;
+    NoteFuncDesc *nf;
+
+    for (nf = note_func; nf->note_contents_func; nf++) {
+        note.hdr.n_namesz = cpu_to_be32(sizeof(note.name));
+        note.hdr.n_descsz = cpu_to_be32(nf->contents_size);
+        strncpy(note.name, note_name, sizeof(note.name));
+
+        (*nf->note_contents_func)(&note, cpu);
+
+        note_size = sizeof(note) - sizeof(note.contents) + nf->contents_size;
+        ret = f(&note, note_size, opaque);
+        if (ret < 0) {
+            return -1;
+        }
+    }
+    return 0;
+}
+
+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);
+}
+
+int ppc64_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,
+                                   CPUState *cpu, void *opaque)
+{
+    return 0;
+}
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index f3c710a..827e5dd 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -108,7 +108,10 @@ void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-
+int ppc64_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,
+                                   CPUState *cpu, void *opaque);
+int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                               int cpuid, void *opaque);
 #ifndef CONFIG_USER_ONLY
 extern const struct VMStateDescription vmstate_ppc_cpu;
 #endif
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index d2645ba..4c0f4c6 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8570,6 +8570,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
 #ifndef CONFIG_USER_ONLY
     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;
+    cc->write_elf64_qemunote = ppc64_cpu_write_elf64_qemunote;
+#endif
 #endif
 
     cc->gdb_num_core_regs = 71;
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server
  2013-10-01 16:19 [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Aneesh Kumar K.V
                   ` (5 preceding siblings ...)
  2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 6/6] target-ppc: dump-guest-memory support Aneesh Kumar K.V
@ 2013-10-02 14:06 ` Alexander Graf
  6 siblings, 0 replies; 8+ messages in thread
From: Alexander Graf @ 2013-10-02 14:06 UTC (permalink / raw
  To: Aneesh Kumar K.V; +Cc: qemu-ppc, paulus, qemu-devel


On 01.10.2013, at 18:19, Aneesh Kumar K.V wrote:

> Hi,
> 
> This patch series implement support for dumping guest memory using qemu gdb server. The last patch also enable qemu monitor command dump-guest-memory

Thanks, applied all but 2/6 to ppc-next. I think the core dump bits should be more smart eventually to determine whether we want to save ppc32 or ppc64 dumps, as qemu-system-ppc64 can execute 32bit CPUs. But for now your patch as is should work.


Alex

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-10-02 14:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-01 16:19 [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Aneesh Kumar K.V
2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 1/6] target-ppc: Update slb array with correct index values Aneesh Kumar K.V
2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 2/6] target-ppc: Fix page table lookup with kvm enabled Aneesh Kumar K.V
2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 3/6] target-ppc: Check for error on address translation in memsave command Aneesh Kumar K.V
2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 4/6] target-ppc: Use #define for max slb entries Aneesh Kumar K.V
2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 5/6] dump-guest-memory: Check for the correct return value Aneesh Kumar K.V
2013-10-01 16:19 ` [Qemu-devel] [PATCH -V4 RESEND 6/6] target-ppc: dump-guest-memory support Aneesh Kumar K.V
2013-10-02 14:06 ` [Qemu-devel] [PATCH -V4 RESEND 0/6] target-ppc: Add support for dumping guest memory using qemu gdb server Alexander Graf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.