From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Cc: kvm@vger.kernel.org, patches@linaro.org,
"Marcelo Tosatti" <mtosatti@redhat.com>,
kvmarm@lists.cs.columbia.edu, "Blue Swirl" <blauwirbel@gmail.com>,
"Avi Kivity" <avi@redhat.com>,
"Andreas Färber" <afaerber@suse.de>
Subject: [Qemu-devel] [RFC v3 3/8] ARM KVM: save and load VFP registers from kernel
Date: Tue, 23 Oct 2012 11:50:23 +0100 [thread overview]
Message-ID: <1350989428-941-4-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1350989428-941-1-git-send-email-peter.maydell@linaro.org>
Add support for saving and restoring VFP register state from the
kernel. This includes a check that the KVM-created CPU has full
VFP support (as the TCG Cortex-A15 model always does), since for
the moment ARM QEMU doesn't have any way to tweak optional features
on created CPUs.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/kvm.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 75 insertions(+), 3 deletions(-)
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index f80c707..f7d2235 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -38,10 +38,28 @@ int kvm_arch_init(KVMState *s)
int kvm_arch_init_vcpu(CPUARMState *env)
{
struct kvm_vcpu_init init;
+ int ret;
+ uint64_t v;
+ struct kvm_one_reg r;
init.target = KVM_ARM_TARGET_CORTEX_A15;
memset(init.features, 0, sizeof(init.features));
- return kvm_vcpu_ioctl(env, KVM_ARM_VCPU_INIT, &init);
+ ret = kvm_vcpu_ioctl(env, KVM_ARM_VCPU_INIT, &init);
+ if (ret) {
+ return ret;
+ }
+ /* Query the kernel to make sure it supports 32 VFP
+ * registers: QEMU's "cortex-a15" CPU is always a
+ * VFP-D32 core. The simplest way to do this is just
+ * to attempt to read register d31.
+ */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;
+ r.addr = (uintptr_t)(&v);
+ ret = kvm_vcpu_ioctl(env, KVM_GET_ONE_REG, &r);
+ if (ret == ENOENT) {
+ return EINVAL;
+ }
+ return ret;
}
typedef struct Reg {
@@ -67,6 +85,13 @@ typedef struct Reg {
offsetof(CPUARMState, QEMUFIELD) \
}
+#define VFPSYSREG(R) \
+ { \
+ KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | \
+ KVM_REG_ARM_VFP_##R, \
+ offsetof(CPUARMState, vfp.xregs[ARM_VFP_##R]) \
+ }
+
static const Reg regs[] = {
/* R0_usr .. R14_usr */
COREREG(usr_regs[0], regs[0]),
@@ -114,6 +139,13 @@ static const Reg regs[] = {
CP15REG(1, 0, 0, 0, cp15.c1_sys), /* SCTLR */
CP15REG(2, 0, 0, 2, cp15.c2_control), /* TTBCR */
CP15REG(3, 0, 0, 0, cp15.c3), /* DACR */
+ /* VFP system registers */
+ VFPSYSREG(FPSID),
+ VFPSYSREG(MVFR1),
+ VFPSYSREG(MVFR0),
+ VFPSYSREG(FPEXC),
+ VFPSYSREG(FPINST),
+ VFPSYSREG(FPINST2),
};
int kvm_arch_put_registers(CPUARMState *env, int level)
@@ -121,7 +153,7 @@ int kvm_arch_put_registers(CPUARMState *env, int level)
struct kvm_one_reg r;
int mode, bn;
int ret, i;
- uint32_t cpsr;
+ uint32_t cpsr, fpscr;
uint64_t ttbr;
/* Make sure the banked regs are properly set */
@@ -172,6 +204,26 @@ int kvm_arch_put_registers(CPUARMState *env, int level)
(2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT);
r.addr = (uintptr_t)(&ttbr);
ret = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+
+ /* VFP registers */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
+ for (i = 0; i < 32; i++) {
+ r.addr = (uintptr_t)(&env->vfp.regs[i]);
+ ret = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ r.id++;
+ }
+
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP |
+ KVM_REG_ARM_VFP_FPSCR;
+ fpscr = vfp_get_fpscr(env);
+ r.addr = (uintptr_t)&fpscr;
+ ret = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, &r);
return ret;
}
@@ -181,7 +233,7 @@ int kvm_arch_get_registers(CPUARMState *env)
struct kvm_one_reg r;
int mode, bn;
int ret, i;
- uint32_t cpsr;
+ uint32_t cpsr, fpscr;
uint64_t ttbr;
for (i = 0; i < ARRAY_SIZE(regs); i++) {
@@ -246,6 +298,26 @@ int kvm_arch_get_registers(CPUARMState *env)
env->cp15.c2_mask = ~(0xffffffffu >> env->cp15.c2_control);
env->cp15.c2_base_mask = ~(0x3fffu >> env->cp15.c2_control);
+ /* VFP registers */
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
+ for (i = 0; i < 32; i++) {
+ r.addr = (uintptr_t)(&env->vfp.regs[i]);
+ ret = kvm_vcpu_ioctl(env, KVM_GET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ r.id++;
+ }
+
+ r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP |
+ KVM_REG_ARM_VFP_FPSCR;
+ r.addr = (uintptr_t)&fpscr;
+ ret = kvm_vcpu_ioctl(env, KVM_GET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+ vfp_set_fpscr(env, fpscr);
+
return 0;
}
--
1.7.9.5
next prev parent reply other threads:[~2012-10-23 10:56 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-23 10:50 [Qemu-devel] [RFC v3 0/8] QEMU: Support KVM on ARM Peter Maydell
2012-10-23 10:50 ` [Qemu-devel] [RFC v3 1/8] linux-headers: Add ARM KVM headers (not for upstream) Peter Maydell
2012-10-23 10:50 ` [Qemu-devel] [RFC v3 2/8] ARM: KVM: Add support for KVM on ARM architecture Peter Maydell
2012-10-23 10:50 ` Peter Maydell [this message]
2012-10-23 10:50 ` [Qemu-devel] [RFC v3 4/8] hw/arm_gic: Add presave/postload hooks Peter Maydell
2012-10-23 10:50 ` [Qemu-devel] [RFC v3 5/8] linux-headers: update with VGIC related headers (not for upstream) Peter Maydell
2012-10-23 10:50 ` [Qemu-devel] [RFC v3 6/8] target-arm: Use MemoryListener to identify GIC base address for KVM Peter Maydell
2012-10-23 10:50 ` [Qemu-devel] [RFC v3 7/8] hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC Peter Maydell
2012-10-23 10:50 ` [Qemu-devel] [RFC v3 8/8] configure: Enable KVM on ARM Peter Maydell
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=1350989428-941-4-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=afaerber@suse.de \
--cc=avi@redhat.com \
--cc=blauwirbel@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=mtosatti@redhat.com \
--cc=patches@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).