All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rusty Russell <rusty.russell@linaro.org>
To: Rusty Russell <rusty.russell@linaro.org>, peter.maydell@linaro.org
Cc: kvmarm@lists.cs.columbia.edu, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 2/3] target-arm: kvm: use KVM_GET_MSRS/KVM_SET_MSRS for CP15 registers.
Date: Fri, 13 Jul 2012 13:13:30 +0930	[thread overview]
Message-ID: <874npcz5p9.fsf@rustcorp.com.au> (raw)
In-Reply-To: <878veoz5yv.fsf@rustcorp.com.au>

Recent kernels use this to set the CP15 registers, rather than putting
them in 'struct kvm_regs'.  The changed size of that struct changes the
ioctl number, so we have a temporary hack to try both.

Signed-off-by: Rusty Russell <rusty.russell@linaro.org>

diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
index 988890a..4842e85 100644
--- a/linux-headers/asm-arm/kvm.h
+++ b/linux-headers/asm-arm/kvm.h
@@ -75,6 +75,37 @@ struct kvm_sregs {
 	__u32 features[14];
 };
 
+/* Exactly like x86. */
+struct kvm_msr_entry {
+	__u32 index;
+	__u32 reserved;
+	__u64 data;
+};
+
+/* for KVM_GET_MSRS and KVM_SET_MSRS */
+struct kvm_msrs {
+	__u32 nmsrs; /* number of msrs in entries */
+	__u32 pad;
+
+	struct kvm_msr_entry entries[0];
+};
+
+/* for KVM_GET_MSR_INDEX_LIST */
+struct kvm_msr_list {
+	__u32 nmsrs; /* number of msrs in entries */
+	__u32 indices[0];
+};
+
+/* If you need to interpret the index values, here's the key. */
+#define KVM_ARM_MSR_COPROC_MASK		0xFFFF0000
+#define KVM_ARM_MSR_64_BIT_MASK		0x00008000
+#define KVM_ARM_MSR_64_OPC1_MASK	0x000000F0
+#define KVM_ARM_MSR_64_CRM_MASK		0x0000000F
+#define KVM_ARM_MSR_32_CRM_MASK		0x0000000F
+#define KVM_ARM_MSR_32_OPC2_MASK	0x00000070
+#define KVM_ARM_MSR_32_CRN_MASK		0x00000780
+#define KVM_ARM_MSR_32_OPC1_MASK	0x00003800
+
 struct kvm_fpu {
 };
 
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 67d005f..2c149bd 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -43,15 +43,28 @@ int kvm_arch_init_vcpu(CPUARMState *env)
     return kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs) ? 0 : 0;
 }
 
+#define MSR32_INDEX_OF(coproc, crn, opc1, crm, opc2) \
+	(((coproc)<<16) | ((opc1)<<11) | ((crn)<<7) | ((opc2)<<4) | (crm))
+
+/* A modern kernel has a smaller struct kvm_regs, so ioctls differ: */
+#define KVM_GET_REGS_MODERN 2157227649U
+#define KVM_SET_REGS_MODERN 1083485826U
+
 int kvm_arch_put_registers(CPUARMState *env, int level)
 {
     struct kvm_regs regs;
     int mode, bn;
+    struct cp15 {
+	    struct kvm_msrs hdr;
+	    struct kvm_msr_entry e[2];
+    } cp15;
     int ret;
 
     ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
     if (ret < 0)
-        return ret;
+	ret = kvm_vcpu_ioctl(env, KVM_GET_REGS_MODERN, &regs);
+    if (ret < 0)
+	return ret;
 
     /* We make sure the banked regs are properly set */
     mode = env->uncached_cpsr & CPSR_M;
@@ -91,8 +104,18 @@ int kvm_arch_put_registers(CPUARMState *env, int level)
     regs.cp15.c0_midr = env->cp15.c0_cpuid;
     regs.cp15.c1_sys = env->cp15.c1_sys;
 
-    ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
+    cp15.hdr.nmsrs = ARRAY_SIZE(cp15.e);
+    cp15.e[0].index = MSR32_INDEX_OF(15, 0, 0, 0, 0); /* MIDR */
+    cp15.e[0].data = env->cp15.c0_cpuid;
+    cp15.e[1].index = MSR32_INDEX_OF(15, 1, 0, 0, 0); /* SCTLR */
+    cp15.e[1].data = env->cp15.c1_sys;
 
+    ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
+    if (ret < 0) {
+	ret = kvm_vcpu_ioctl(env, KVM_SET_REGS_MODERN, &regs);
+	if (ret == 0)
+	    ret = kvm_vcpu_ioctl(env, KVM_SET_MSRS, &cp15);
+    }
     return ret;
 }
 
@@ -101,11 +124,27 @@ int kvm_arch_get_registers(CPUARMState *env)
     struct kvm_regs regs;
     int mode, bn;
     int32_t ret;
+    struct cp15 {
+	    struct kvm_msrs hdr;
+	    struct kvm_msr_entry e[6];
+    } cp15;
 
     ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
     if (ret < 0)
+	ret = kvm_vcpu_ioctl(env, KVM_GET_REGS_MODERN, &regs);
+    if (ret < 0)
         return ret;
 
+    cp15.hdr.nmsrs = ARRAY_SIZE(cp15.e);
+    cp15.e[0].index = MSR32_INDEX_OF(15, 0, 0, 0, 0); /* MIDR */
+    cp15.e[1].index = MSR32_INDEX_OF(15, 1, 0, 0, 0); /* SCTLR */
+    cp15.e[2].index = MSR32_INDEX_OF(15, 2, 0, 0, 0); /* TTBR0 */
+    cp15.e[3].index = MSR32_INDEX_OF(15, 2, 0, 0, 1); /* TTBR1 */
+    cp15.e[4].index = MSR32_INDEX_OF(15, 2, 0, 0, 2); /* TTBCR */
+    cp15.e[5].index = MSR32_INDEX_OF(15, 3, 0, 0, 0); /* DACR */
+
+    ret = kvm_vcpu_ioctl(env, KVM_GET_MSRS, &cp15);
+
     /* First, let's transfer the banked state */
     cpsr_write(env, regs.cpsr, 0xFFFFFFFF);
     memcpy(env->regs, regs.regs0_7, sizeof(uint32_t) * 8);
@@ -142,18 +181,33 @@ int kvm_arch_get_registers(CPUARMState *env)
     env->regs[14] = env->banked_r14[bn];
     env->spsr = env->banked_spsr[bn];
 
-    //env->cp15.c0_cpuid = regs.cp15.c0_midr;
-    env->cp15.c1_sys = regs.cp15.c1_sys;
-    env->cp15.c2_base0 = regs.cp15.c2_base0;
-    env->cp15.c2_base1 = regs.cp15.c2_base1;
+    /* Old KVM version. */
+    if (ret != 0) {
+	    //env->cp15.c0_cpuid = regs.cp15.c0_midr;
+	    env->cp15.c1_sys = regs.cp15.c1_sys;
+	    env->cp15.c2_base0 = regs.cp15.c2_base0;
+	    env->cp15.c2_base1 = regs.cp15.c2_base1;
 
-    /* This is ugly, but necessary for GDB compatibility */
-    env->cp15.c2_control = regs.cp15.c2_control;
-    env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> regs.cp15.c2_control);
-    env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> regs.cp15.c2_control);
+	    /* This is ugly, but necessary for GDB compatibility */
+	    env->cp15.c2_control = regs.cp15.c2_control;
+	    env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> regs.cp15.c2_control);
+	    env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> regs.cp15.c2_control);
 
-    env->cp15.c3 = regs.cp15.c3_dacr;
+	    env->cp15.c3 = regs.cp15.c3_dacr;
+	    return 0;
+    }
+
+    //env->cp15.c0_cpuid = cp15.e[0].data;
+    env->cp15.c1_sys = cp15.e[1].data;
+    env->cp15.c2_base0 = cp15.e[2].data;
+    env->cp15.c2_base1 = cp15.e[3].data;
+
+    /* This is ugly, but necessary for GDB compatibility */
+    env->cp15.c2_control = cp15.e[4].data;
+    env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> cp15.e[4].data);
+    env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> cp15.e[4].data);
 
+    env->cp15.c3 = cp15.e[5].data;
     return 0;
 }
 

  reply	other threads:[~2012-07-13  3:43 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-13  3:37 [Qemu-devel] [PATCH] target-arm: kvm: use KVM_SET_SREGS to set target to Cortex A15 Rusty Russell
2012-07-13  3:43 ` Rusty Russell [this message]
2012-07-13 14:27   ` [Qemu-devel] [PATCH 2/3] target-arm: kvm: use KVM_GET_MSRS/KVM_SET_MSRS for CP15 registers Blue Swirl
2012-07-13  3:43 ` [Qemu-devel] [PATCH 3/3] target-arm: kvm: remove old kernel support Rusty Russell
2012-07-13  8:06 ` [Qemu-devel] [PATCH] target-arm: kvm: use KVM_SET_SREGS to set target to Cortex A15 Peter Maydell
2012-07-16  7:22   ` Rusty Russell
2012-07-13 10:06 ` [Qemu-devel] [kvmarm] " Alexander Graf
2012-07-16  7:19   ` Rusty Russell
2012-07-16  8:08     ` Alexander Graf
2012-07-16  8:09     ` Avi Kivity
2012-07-17 17:31 ` [Qemu-devel] " Peter Maydell
2012-07-17 18:19   ` Peter Maydell
2012-07-25  6:17     ` Rusty Russell
2012-07-25 15:04       ` Peter Maydell
2012-07-31 21:52       ` [Qemu-devel] [kvmarm] " Antonios Motakis
2012-08-01  1:53         ` Rusty Russell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874npcz5p9.fsf@rustcorp.com.au \
    --to=rusty.russell@linaro.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.