From: Jens Freimann <jfrei@linux.vnet.ibm.com>
To: Alexander Graf <agraf@suse.de>
Cc: Heinz Graalfs <graalfs@linux.vnet.ibm.com>,
qemu-devel <qemu-devel@nongnu.org>,
Christian Borntraeger <borntraeger@de.ibm.com>,
Jens Freimann <jfrei@linux.vnet.ibm.com>,
Cornelia Huck <cornelia.huck@de.ibm.com>,
Einar Lueck <elelueck@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH] s390: use sync regs for register transfer
Date: Thu, 4 Oct 2012 09:56:49 +0200 [thread overview]
Message-ID: <1349337409-33389-1-git-send-email-jfrei@linux.vnet.ibm.com> (raw)
In-Reply-To: <CAAu8pHu7ZdG=-yu4MF1f6i=VB38mtOBnEjaYmyrEZWkzV61iNw@mail.gmail.com>
From: Christian Borntraeger <borntraeger@de.ibm.com>
Newer kernels provide the guest registers in kvm_run. Lets use
those if available (i.e. the capability is set). This avoids
ioctls on cpu_synchronize_state making intercepts faster.
In addition, we have now the prefix register, the access registers
the control registers up to date. This helps in certain cases,
e.g. for resolving kernel module addresses with gdb on a guest.
On return, we update the registers according to the level statement,
i.e. we put all registers for KVM_PUT_FULL_STATE and _RESET_STATE.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
---
target-s390x/kvm.c | 119 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 99 insertions(+), 20 deletions(-)
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 07edf93..321ab49 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -67,8 +67,11 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
+static int cap_sync_regs;
+
int kvm_arch_init(KVMState *s)
{
+ cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
return 0;
}
@@ -88,49 +91,125 @@ void kvm_arch_reset_vcpu(CPUS390XState *env)
/* FIXME: add code to reset vcpu. */
}
+/* we want to have the prefix, the GPRS, the ACRS and the CRS up to date */
+#define QEMU_NEEDED_REGS (KVM_SYNC_PREFIX | KVM_SYNC_GPRS | \
+ KVM_SYNC_ACRS | KVM_SYNC_CRS)
+
+/* But qemu only changes the GPRS */
+#define QEMU_DIRTY_REGS (KVM_SYNC_GPRS)
+
int kvm_arch_put_registers(CPUS390XState *env, int level)
{
+ struct kvm_sregs sregs;
struct kvm_regs regs;
int ret;
int i;
- ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
- if (ret < 0) {
- return ret;
- }
+ /* always save the PSW and the GPRS*/
+ env->kvm_run->psw_addr = env->psw.addr;
+ env->kvm_run->psw_mask = env->psw.mask;
- for (i = 0; i < 16; i++) {
- regs.gprs[i] = env->regs[i];
+ if (cap_sync_regs && env->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {
+ for (i = 0; i < 16; i++) {
+ env->kvm_run->s.regs.gprs[i] = env->regs[i];
+ env->kvm_run->kvm_dirty_regs |= KVM_SYNC_GPRS;
+ }
+ } else {
+ for (i = 0; i < 16; i++) {
+ regs.gprs[i] = env->regs[i];
+ }
+ ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, ®s);
+ if (ret < 0) {
+ return ret;
+ }
}
- ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, ®s);
- if (ret < 0) {
- return ret;
+ /* Do we need to save more than that? */
+ if (level == KVM_PUT_RUNTIME_STATE) {
+ return 0;
}
- env->kvm_run->psw_addr = env->psw.addr;
- env->kvm_run->psw_mask = env->psw.mask;
+ if (cap_sync_regs &&
+ env->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
+ env->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
+ for (i = 0; i < 16; i++) {
+ env->kvm_run->s.regs.acrs[i] = env->aregs[i];
+ env->kvm_run->s.regs.crs[i] = env->cregs[i];
+ }
+ env->kvm_run->kvm_dirty_regs |= KVM_SYNC_ACRS;
+ env->kvm_run->kvm_dirty_regs |= KVM_SYNC_CRS;
+ } else {
+ for (i = 0; i < 16; i++) {
+ sregs.acrs[i] = env->aregs[i];
+ sregs.crs[i] = env->cregs[i];
+ }
+ ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
+ if (ret < 0) {
+ return ret;
+ }
+ }
- return ret;
+ /* Finally the prefix */
+ if (cap_sync_regs && env->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
+ env->kvm_run->s.regs.prefix = env->psa;
+ env->kvm_run->kvm_dirty_regs |= KVM_SYNC_PREFIX;
+ } else {
+ /* prefix is only supported via sync regs */
+ }
+ return 0;
}
int kvm_arch_get_registers(CPUS390XState *env)
{
- int ret;
+ struct kvm_sregs sregs;
struct kvm_regs regs;
+ int ret;
int i;
- ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
- if (ret < 0) {
- return ret;
+ /* get the PSW */
+ env->psw.addr = env->kvm_run->psw_addr;
+ env->psw.mask = env->kvm_run->psw_mask;
+
+ /* the GPRS */
+ if (cap_sync_regs && env->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {
+ for (i = 0; i < 16; i++) {
+ env->regs[i] = env->kvm_run->s.regs.gprs[i];
+ }
+ } else {
+ ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
+ if (ret < 0) {
+ return ret;
+ }
+ for (i = 0; i < 16; i++) {
+ env->regs[i] = regs.gprs[i];
+ }
}
- for (i = 0; i < 16; i++) {
- env->regs[i] = regs.gprs[i];
+ /* The ACRS and CRS */
+ if (cap_sync_regs &&
+ env->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
+ env->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
+ for (i = 0; i < 16; i++) {
+ env->aregs[i] = env->kvm_run->s.regs.acrs[i];
+ env->cregs[i] = env->kvm_run->s.regs.crs[i];
+ }
+ } else {
+ ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
+ if (ret < 0) {
+ return ret;
+ }
+ for (i = 0; i < 16; i++) {
+ env->aregs[i] = sregs.acrs[i];
+ env->cregs[i] = sregs.crs[i];
+ }
}
- env->psw.addr = env->kvm_run->psw_addr;
- env->psw.mask = env->kvm_run->psw_mask;
+ /* Finally the prefix */
+ if (cap_sync_regs && env->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
+ env->psa = env->kvm_run->s.regs.prefix;
+ } else {
+ /* no prefix without sync regs */
+ }
return 0;
}
--
1.7.11.7
next prev parent reply other threads:[~2012-10-04 7:57 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-02 7:33 [Qemu-devel] [PATCH 0/5] s390: current patches Jens Freimann
2012-10-02 7:33 ` [Qemu-devel] [PATCH 1/5] s390: use sync regs for register transfer Jens Freimann
2012-10-03 20:08 ` Blue Swirl
2012-10-04 7:56 ` Jens Freimann [this message]
2012-10-02 7:33 ` [Qemu-devel] [PATCH 2/5] s390: sclp base support Jens Freimann
2012-10-02 7:33 ` [Qemu-devel] [PATCH 3/5] s390: sclp event support Jens Freimann
2012-10-02 7:33 ` [Qemu-devel] [PATCH 4/5] s390: sclp signal quiesce support Jens Freimann
2012-10-12 0:36 ` Alexander Graf
2012-10-12 4:12 ` Christian Borntraeger
2012-10-02 7:33 ` [Qemu-devel] [PATCH 5/5] s390: sclp ascii console support Jens Freimann
-- strict thread matches above, loose matches on Subject: below --
2012-08-22 11:54 [Qemu-devel] [PATCH] s390: use sync regs for register transfer Jens Freimann
2012-09-20 12:19 ` Alexander Graf
2012-09-20 12:49 ` Christian Borntraeger
2012-09-20 14:13 ` Alexander Graf
2012-09-20 15:21 ` Christian Borntraeger
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=1349337409-33389-1-git-send-email-jfrei@linux.vnet.ibm.com \
--to=jfrei@linux.vnet.ibm.com \
--cc=agraf@suse.de \
--cc=borntraeger@de.ibm.com \
--cc=cornelia.huck@de.ibm.com \
--cc=elelueck@linux.vnet.ibm.com \
--cc=graalfs@linux.vnet.ibm.com \
--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).