[PATCH 2 of 3] [PATCH] qemu: ppc: kvm-userspace: KVM PowerPC support for qemu gdbstub

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

 



# HG changeset patch
# User Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
# Date 1228989956 -3600
# Node ID 6f228c807ad0b239b7342d2974debfc66418d784
# Parent  38846cef16e56c681da1ddc179e248972c8b2ff9
[PATCH] qemu: ppc: kvm-userspace: KVM PowerPC support for qemu gdbstub

From: Hollis Blanchard <hollisb@xxxxxxxxxx>

Add basic KVM PowerPC support to qemu's gdbstub introducing a kvm ppc style
mmu implementation that uses the kvm_translate ioctl.
This also requires to save the kvm registers prior to the 'm' gdb operations.

Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>
Signed-off-by: Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
---

[diffstat]
 gdbstub.c                   |    2 ++
 hw/ppc440_bamboo.c          |    1 +
 qemu-kvm-powerpc.c          |   28 ++++++++++++++++++++++++++++
 target-ppc/cpu.h            |    2 ++
 target-ppc/helper.c         |    4 ++++
 target-ppc/translate_init.c |    5 +++++
 6 files changed, 42 insertions(+)

[diff]

diff --git a/qemu/gdbstub.c b/qemu/gdbstub.c
--- a/qemu/gdbstub.c
+++ b/qemu/gdbstub.c
@@ -1374,6 +1374,7 @@ static int gdb_handle_packet(GDBState *s
         if (*p == ',')
             p++;
         len = strtoull(p, NULL, 16);
+        kvm_save_registers(s->g_cpu);
         if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
             put_packet (s, "E14");
         } else {
@@ -1389,6 +1390,7 @@ static int gdb_handle_packet(GDBState *s
         if (*p == ':')
             p++;
         hextomem(mem_buf, p, len);
+        kvm_save_registers(s->gcpu);
         if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0)
             put_packet(s, "E14");
         else
diff --git a/qemu/hw/ppc440_bamboo.c b/qemu/hw/ppc440_bamboo.c
--- a/qemu/hw/ppc440_bamboo.c
+++ b/qemu/hw/ppc440_bamboo.c
@@ -99,6 +99,7 @@ void bamboo_init(ram_addr_t ram_size, in
 		fprintf(stderr, "Unable to initialize CPU!\n");
 		exit(1);
 	}
+	env->mmu_model = POWERPC_MMU_KVM;
 
 	/* call init */
 	printf("Calling function ppc440_init\n");
diff --git a/qemu/qemu-kvm-powerpc.c b/qemu/qemu-kvm-powerpc.c
--- a/qemu/qemu-kvm-powerpc.c
+++ b/qemu/qemu-kvm-powerpc.c
@@ -102,6 +102,7 @@ void kvm_arch_save_regs(CPUState *env)
 
     env->spr[SPR_SRR0] = regs.srr0;
     env->spr[SPR_SRR1] = regs.srr1;
+    env->spr[SPR_BOOKE_PID] = regs.pid;
 
     env->spr[SPR_SPRG0] = regs.sprg0;
     env->spr[SPR_SPRG1] = regs.sprg1;
@@ -219,6 +220,33 @@ int handle_powerpc_dcr_write(int vcpu, u
     return 0; /* XXX ignore failed DCR ops */
 }
 
+int mmukvm_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
+                                target_ulong eaddr, int rw, int access_type)
+{
+    struct kvm_translation tr;
+    uint64_t pid;
+    uint64_t as;
+    int r;
+
+    pid = env->spr[SPR_BOOKE_PID];
+
+    if (access_type == ACCESS_CODE)
+        as = env->msr & msr_ir;
+    else
+        as = env->msr & msr_dr;
+
+    tr.linear_address = as << 40 | pid << 32 | eaddr;
+    r = kvm_translate(kvm_context, env->cpu_index, &tr);
+    if (r == -1)
+        return r;
+
+    if (!tr.valid)
+        return -EFAULT;
+
+    ctx->raddr = tr.physical_address;
+    return 0;
+}
+
 void kvm_arch_cpu_reset(CPUState *env)
 {
 }
diff --git a/qemu/target-ppc/cpu.h b/qemu/target-ppc/cpu.h
--- a/qemu/target-ppc/cpu.h
+++ b/qemu/target-ppc/cpu.h
@@ -98,6 +98,8 @@ enum powerpc_mmu_t {
     POWERPC_MMU_BOOKE_FSL  = 0x00000009,
     /* PowerPC 601 MMU model (specific BATs format)            */
     POWERPC_MMU_601        = 0x0000000A,
+    /* KVM managing the MMU state                              */
+    POWERPC_MMU_KVM        = 0x0000000B,
 #if defined(TARGET_PPC64)
 #define POWERPC_MMU_64       0x00010000
     /* 64 bits PowerPC MMU                                     */
diff --git a/qemu/target-ppc/helper.c b/qemu/target-ppc/helper.c
--- a/qemu/target-ppc/helper.c
+++ b/qemu/target-ppc/helper.c
@@ -1429,6 +1429,10 @@ int get_physical_address (CPUState *env,
         fprintf(logfile, "%s\n", __func__);
     }
 #endif
+
+    if (env->mmu_model == POWERPC_MMU_KVM)
+        return mmukvm_get_physical_address(env, ctx, eaddr, rw, access_type);
+
     if ((access_type == ACCESS_CODE && msr_ir == 0) ||
         (access_type != ACCESS_CODE && msr_dr == 0)) {
         /* No address translation */
diff --git a/qemu/target-ppc/translate_init.c b/qemu/target-ppc/translate_init.c
--- a/qemu/target-ppc/translate_init.c
+++ b/qemu/target-ppc/translate_init.c
@@ -9273,6 +9273,11 @@ int cpu_ppc_register_internal (CPUPPCSta
         case POWERPC_MMU_601:
             mmu_model = "PowerPC 601";
             break;
+#ifdef KVM
+        case POWERPC_MMU_KVM:
+            mmu_model = "PowerPC KVM";
+            break;
+#endif
 #if defined (TARGET_PPC64)
         case POWERPC_MMU_64B:
             mmu_model = "PowerPC 64";
--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [KVM Development]     [KVM ARM]     [KVM ia64]     [Linux Virtualization]     [Linux USB Devel]     [Linux Video]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux