From: Paul Mackerras <paulus@samba.org>
To: Alexander Graf <agraf@suse.de>
Cc: kvm@vger.kernel.org, kvm-ppc@vger.kernel.org,
Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: [RFC PATCH 9/9] KVM: PPC: Book 3S: Facilities to save/restore XICS source controller state
Date: Mon, 5 Nov 2012 14:25:20 +1100 [thread overview]
Message-ID: <20121105032520.GJ22409@drongo> (raw)
In-Reply-To: <20121105031806.GA22409@drongo>
This adds the ability for userspace to save and restore the state of
the XICS interrupt source controllers (ICS) via two new VM ioctls,
KVM_IRQCHIP_GET_SOURCES and KVM_IRQCHIP_SET_SOURCES. Both take an
argument struct that gives the starting interrupt source number, the
number of interrupt sources to be processed, and a pointer to an array
with space for 64 bits per source where the state of the interrupt
sources are to be stored or loaded. The interrupt sources are required
to all be within one ICS.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
Documentation/virtual/kvm/api.txt | 33 ++++++++++++
arch/powerpc/kvm/book3s_xics.c | 108 +++++++++++++++++++++++++++++++++++++
arch/powerpc/kvm/powerpc.c | 4 +-
include/uapi/linux/kvm.h | 17 ++++++
4 files changed, 161 insertions(+), 1 deletion(-)
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index fbe018e..2ba53a1 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2107,6 +2107,39 @@ struct. When creating an ICS, the argument struct further indicates
the BUID (Bus Unit ID) and number of interrupt sources for the new
ICS.
+4.80 KVM_IRQCHIP_GET_SOURCES
+
+Capability: KVM_CAP_SPAPR_XICS
+Architectures: ppc
+Type: vm ioctl
+Parameters: struct kvm_irq_sources
+Returns: 0 on success, -1 on error
+
+Copies configuration and status information about a range of interrupt
+sources into a user-supplied buffer. The argument struct gives the
+starting interrupt source number and the number of interrupt sources.
+All of the interrupt sources must be within the range of a single
+interrupt source controller (ICS). The user buffer is an array of
+64-bit quantities, one per interrupt source, with (from the least-
+significant bit) 32 bits of interrupt server number, 8 bits of
+priority, and 1 bit each for a level-sensitive indicator, a masked
+indicator, and a pending indicator.
+
+4.81 KVM_IRQCHIP_SET_SOURCES
+
+Capability: KVM_CAP_SPAPR_XICS
+Architectures: ppc
+Type: vm ioctl
+Parameters: struct kvm_irq_sources
+Returns: 0 on success, -1 on error
+
+Sets the configuration and status for a range of interrupt sources
+from information supplied in a user-supplied buffer. The argument
+struct gives the starting interrupt source number and the number of
+interrupt sources. All of the interrupt sources must be within the
+range of a single interrupt source controller (ICS). The user buffer
+is formatted as for KVM_IRQCHIP_GET_SOURCES.
+
5. The kvm_run structure
------------------------
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index 8314cd9..8071c7e 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -1066,6 +1066,88 @@ int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval)
return 0;
}
+static int kvm_xics_get_sources(struct kvm *kvm, struct kvm_irq_sources *srcs)
+{
+ int ret = 0;
+ struct kvmppc_xics *xics = kvm->arch.xics;
+ struct kvmppc_ics *ics;
+ struct ics_irq_state *irqp;
+ u64 __user *ubufp;
+ u16 idx;
+ u64 val;
+ long int i;
+
+ ics = kvmppc_xics_find_ics(xics, srcs->irq, &idx);
+ if (!ics || idx + srcs->nr_irqs > ics->nr_irqs)
+ return -ENOENT;
+
+ irqp = &ics->irq_state[idx];
+ ubufp = srcs->irqbuf;
+ mutex_lock(&ics->lock);
+ for (i = 0; i < srcs->nr_irqs; ++i, ++irqp, ++ubufp) {
+ val = irqp->server;
+ if (irqp->priority == MASKED && irqp->saved_priority != MASKED)
+ val |= KVM_IRQ_MASKED | ((u64)irqp->saved_priority <<
+ KVM_IRQ_PRIORITY_SHIFT);
+ else
+ val |= ((u64)irqp->priority << KVM_IRQ_PRIORITY_SHIFT);
+ if (irqp->asserted)
+ val |= KVM_IRQ_LEVEL_SENSITIVE | KVM_IRQ_PENDING;
+ else if (irqp->masked_pending || irqp->resend)
+ val |= KVM_IRQ_PENDING;
+ ret = -EFAULT;
+ if (__put_user(val, ubufp))
+ break;
+ ret = 0;
+ }
+ mutex_unlock(&ics->lock);
+ return ret;
+}
+
+static int kvm_xics_set_sources(struct kvm *kvm, struct kvm_irq_sources *srcs)
+{
+ int ret = 0;
+ struct kvmppc_xics *xics = kvm->arch.xics;
+ struct kvmppc_ics *ics;
+ struct ics_irq_state *irqp;
+ u64 __user *ubufp;
+ u16 idx;
+ u64 val;
+ long int i;
+
+ ics = kvmppc_xics_find_ics(xics, srcs->irq, &idx);
+ if (!ics || idx + srcs->nr_irqs > ics->nr_irqs)
+ return -ENOENT;
+
+ irqp = &ics->irq_state[idx];
+ ubufp = srcs->irqbuf;
+ for (i = 0; i < srcs->nr_irqs; ++i, ++irqp, ++ubufp) {
+ ret = -EFAULT;
+ if (__get_user(val, ubufp))
+ break;
+ ret = 0;
+
+ mutex_lock(&ics->lock);
+ irqp->server = val & KVM_IRQ_SERVER_MASK;
+ irqp->saved_priority = val >> KVM_IRQ_PRIORITY_SHIFT;
+ if (val & KVM_IRQ_MASKED)
+ irqp->priority = MASKED;
+ else
+ irqp->priority = irqp->saved_priority;
+ irqp->resend = 0;
+ irqp->masked_pending = 0;
+ irqp->asserted = 0;
+ if ((val & KVM_IRQ_PENDING) && (val & KVM_IRQ_LEVEL_SENSITIVE))
+ irqp->asserted = 1;
+ mutex_unlock(&ics->lock);
+
+ if (val & KVM_IRQ_PENDING)
+ icp_deliver_irq(xics, NULL, irqp->number);
+ }
+
+ return ret;
+}
+
/* -- ioctls -- */
static int kvm_vm_ioctl_create_icp(struct kvm *kvm,
@@ -1200,6 +1282,32 @@ int kvmppc_xics_ioctl(struct kvm *kvm, unsigned ioctl, unsigned long arg)
break;
}
+ case KVM_IRQCHIP_GET_SOURCES: {
+ struct kvm_irq_sources sources;
+
+ rc = -EFAULT;
+ if (copy_from_user(&sources, argp, sizeof(sources)))
+ break;
+ if (!access_ok(VERIFY_WRITE, sources.irqbuf,
+ sources.nr_irqs * sizeof(u64)))
+ break;
+ rc = kvm_xics_get_sources(kvm, &sources);
+ break;
+ }
+
+ case KVM_IRQCHIP_SET_SOURCES: {
+ struct kvm_irq_sources sources;
+
+ rc = -EFAULT;
+ if (copy_from_user(&sources, argp, sizeof(sources)))
+ break;
+ if (!access_ok(VERIFY_READ, sources.irqbuf,
+ sources.nr_irqs * sizeof(u64)))
+ break;
+ rc = kvm_xics_set_sources(kvm, &sources);
+ break;
+ }
+
default:
rc = -ENOTTY;
break;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 90b5b5c..0d443d4 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -955,7 +955,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = kvm_vm_ioctl_rtas_define_token(kvm, argp);
break;
}
- case KVM_IRQ_LINE: {
+ case KVM_IRQ_LINE:
+ case KVM_IRQCHIP_GET_SOURCES:
+ case KVM_IRQCHIP_SET_SOURCES: {
struct kvm *kvm = filp->private_data;
r = -ENOTTY;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 8674d32..edcf78d 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -779,6 +779,21 @@ struct kvm_msi {
__u8 pad[16];
};
+struct kvm_irq_sources {
+ __u32 irq;
+ __u32 nr_irqs;
+ __u64 __user *irqbuf;
+};
+
+/* irqbuf entries are laid out like this: */
+#define KVM_IRQ_SERVER_SHIFT 0
+#define KVM_IRQ_SERVER_MASK 0xffffffffULL
+#define KVM_IRQ_PRIORITY_SHIFT 32
+#define KVM_IRQ_PRIORITY_MASK 0xff
+#define KVM_IRQ_LEVEL_SENSITIVE (1ULL << 40)
+#define KVM_IRQ_MASKED (1ULL << 41)
+#define KVM_IRQ_PENDING (1ULL << 42)
+
/*
* ioctls for VM fds
*/
@@ -867,6 +882,8 @@ struct kvm_s390_ucas_mapping {
#ifdef __KVM_HAVE_IRQCHIP_ARGS
#define KVM_CREATE_IRQCHIP_ARGS _IOW(KVMIO, 0xab, struct kvm_irqchip_args)
#endif
+#define KVM_IRQCHIP_GET_SOURCES _IOW(KVMIO, 0xac, struct kvm_irq_sources)
+#define KVM_IRQCHIP_SET_SOURCES _IOW(KVMIO, 0xad, struct kvm_irq_sources)
/*
* ioctls for vcpu fds
--
1.7.10.4
next prev parent reply other threads:[~2012-11-05 3:26 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-05 3:18 [RFC PATCH 0/9] KVM: PPC: In-kernel PAPR interrupt controller emulation Paul Mackerras
2012-11-05 3:19 ` [RFC PATCH 1/9] KVM: PPC: Remove unused argument to kvmppc_core_dequeue_external Paul Mackerras
2012-11-05 3:20 ` [RFC PATCH 2/9] KVM: PPC: Book3S: Add infrastructure to implement kernel-side RTAS calls Paul Mackerras
2012-11-05 3:21 ` [RFC PATCH 3/9] KVM: PPC: Book3S: Add kernel emulation for the XICS interrupt controller Paul Mackerras
2012-11-05 3:21 ` [RFC PATCH 4/9] KVM: PPC: Book3S HV: Speed up wakeups of CPUs on HV KVM Paul Mackerras
2012-11-05 3:22 ` [RFC PATCH 5/9] KVM: PPC: Book3S HV: Add support for real mode ICP in XICS emulation Paul Mackerras
2012-11-05 3:23 ` [RFC PATCH 6/9] KVM: PPC: Book3S HV: Improve real-mode handling of external interrupts Paul Mackerras
2012-11-05 3:23 ` [RFC PATCH 7/9] KVM: PPC: Book3S: Add support for ibm,int-on/off RTAS calls Paul Mackerras
2012-11-05 3:24 ` [RFC PATCH 8/9] KVM: PPC: Book3S: Facilities to save/restore XICS presentation ctrler state Paul Mackerras
2012-11-05 3:25 ` Paul Mackerras [this message]
2012-12-15 0:46 ` [RFC PATCH 0/9] KVM: PPC: In-kernel PAPR interrupt controller emulation Alexander Graf
2012-12-15 2:06 ` Benjamin Herrenschmidt
2013-01-10 5:09 ` Paul Mackerras
2013-01-10 11:42 ` Alexander Graf
2013-01-10 19:06 ` Scott Wood
2013-01-21 0:08 ` Paul Mackerras
2013-01-21 0:22 ` Alexander Graf
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=20121105032520.GJ22409@drongo \
--to=paulus@samba.org \
--cc=agraf@suse.de \
--cc=benh@kernel.crashing.org \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.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).