From: "Michael S. Tsirkin" <mst@redhat.com>
To: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: KVM <kvm@vger.kernel.org>,
linux-s390 <linux-s390@vger.kernel.org>,
qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [RFC PATCH 3/3] KVM: s390: Hook up ioeventfds.
Date: Sun, 24 Feb 2013 11:37:56 +0200 [thread overview]
Message-ID: <20130224093756.GA25269@redhat.com> (raw)
In-Reply-To: <20130222082208.1a034eac@gondolin>
On Fri, Feb 22, 2013 at 08:22:08AM +0100, Cornelia Huck wrote:
> On Thu, 21 Feb 2013 22:42:41 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
> > On Thu, Feb 21, 2013 at 07:14:31PM +0100, Cornelia Huck wrote:
> > > On Thu, 21 Feb 2013 18:34:59 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > >
> > > > On Thu, Feb 21, 2013 at 04:21:43PM +0100, Cornelia Huck wrote:
> > > > > On Thu, 21 Feb 2013 16:39:05 +0200
> > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > >
> > > > > > On Thu, Feb 21, 2013 at 02:13:00PM +0100, Cornelia Huck wrote:
> > > > > > > As s390 doesn't use memory writes for virtio notifcations, create
> > > > > > > a special kind of ioeventfd instead that hooks up into diagnose
> > > > > > > 0x500 (kvm hypercall) with function code 3 (virtio-ccw notification).
> > > > > > >
> > > > > > > Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > > > > >
> > > > > > Do we really have to put virtio specific stuff into kvm?
> > > > > > How about we add generic functionality to match GPRs
> > > > > > on a hypercall and signal an eventfd?
> > > > >
> > > > > Worth a try implementing that.
> > > > >
> > > > > >
> > > > > > Also, it's a bit unfortunate that this doesn't use
> > > > > > the io bus datastructure, long term the linked list handling
> > > > > > might become a bottleneck, using shared code this could maybe
> > > > > > benefit from performance optimizations there.
> > > > >
> > > > > The linked list stuff was more like an initial implementation that
> > > > > could be improved later.
> > > > >
> > > > > > io bus data structure currently has the ability to match on
> > > > > > two 64 bit fields (addr/datamatch) and a signed 32 bit one (length).
> > > > > > Isn't this sufficient for your purposes?
> > > > > > How about sticking subchannel id in address, vq in data match
> > > > > > and using io bus?
> > > > >
> > > > > I can give that a try. (I must admit that I didn't look at the iobus
> > > > > stuff in detail.)
> > > > >
> > > > > >
> > > > > > BTW maybe we could do this for the user interface too,
> > > > > > while I'm not 100% sure it's the cleanest thing to do
> > > > > > (or will work), it would certainly minimize the patchset.
> > > > >
> > > > > You mean integrating with the generic interface and dropping the new
> > > > > ARCH flag?
> > > >
> > > > Not sure about the flag but we could use the general structure
> > > > without an arch-specific format, if that's a good fit.
> > > >
> > > So I have something that seems to do what I want. I'll see if I can
> > > morph it into something presentable tomorrow.
> > >
> > > diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
> > > index b58dd86..3c43e30 100644
> > > --- a/arch/s390/kvm/Kconfig
> > > +++ b/arch/s390/kvm/Kconfig
> > > @@ -22,6 +22,7 @@ config KVM
> > > select PREEMPT_NOTIFIERS
> > > select ANON_INODES
> > > select HAVE_KVM_CPU_RELAX_INTERCEPT
> > > + select HAVE_KVM_EVENTFD
> > > ---help---
> > > Support hosting paravirtualized guest machines using the SIE
> > > virtualization capability on the mainframe. This should work
> > > diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile
> > > index 3975722..8fe9d65 100644
> > > --- a/arch/s390/kvm/Makefile
> > > +++ b/arch/s390/kvm/Makefile
> > > @@ -6,7 +6,7 @@
> > > # it under the terms of the GNU General Public License (version 2 only)
> > > # as published by the Free Software Foundation.
> > >
> > > -common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o)
> > > +common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o eventfd.o)
> > >
> > > ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
> > >
> > > diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
> > > index a390687..7fc195e 100644
> > > --- a/arch/s390/kvm/diag.c
> > > +++ b/arch/s390/kvm/diag.c
> > > @@ -104,6 +104,20 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
> > > return -EREMOTE;
> > > }
> > >
> > > +static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
> > > +{
> > > + int ret, idx;
> > > + u64 vq = vcpu->run->s.regs.gprs[3];
> > > +
> > > + idx = srcu_read_lock(&vcpu->kvm->srcu);
> > > + ret = kvm_io_bus_write(vcpu->kvm, KVM_CSS_BUS,
> > > + vcpu->run->s.regs.gprs[2],
> > > + vcpu->run->s.regs.gprs[1],
> > > + &vq);
> >
> > Hmm, do you really need three gprs? If not, we could
> > just pass len == 8, which would be cleaner.
> > Also might as well drop the vq variable, no?
>
> If I want to pass generic hypercalls, I need to pass the subcode (in
> gpr 1) in the len variable. If all we'll ever need is the virtio-ccw
> notify hypercall, gprs 2 and 3 are enough. Would perhaps make the
> common code less hacky, but we'd lose (unneeded?) flexibility.
I see. I'm fine with either way, but I note the code above
can overflow int len, which is likely not what you want.
> >
> > > + srcu_read_unlock(&vcpu->kvm->srcu, idx);
> > > + return ret;
> > > +}
> > > +
> > > int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
> > > {
> > > int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16;
> > > @@ -118,6 +132,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
> > > return __diag_time_slice_end_directed(vcpu);
> > > case 0x308:
> > > return __diag_ipl_functions(vcpu);
> > > + case 0x500:
> > > + return __diag_virtio_hypercall(vcpu);
> > > default:
> > > return -EOPNOTSUPP;
> > > }
> > > diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> > > index f822d36..04d2454 100644
> > > --- a/arch/s390/kvm/kvm-s390.c
> > > +++ b/arch/s390/kvm/kvm-s390.c
> > > @@ -142,6 +142,7 @@ int kvm_dev_ioctl_check_extension(long ext)
> > > case KVM_CAP_ONE_REG:
> > > case KVM_CAP_ENABLE_CAP:
> > > case KVM_CAP_S390_CSS_SUPPORT:
> > > + case KVM_CAP_IOEVENTFD:
> > > r = 1;
> > > break;
> > > case KVM_CAP_NR_VCPUS:
> > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > > index 3b768ef..59be516 100644
> > > --- a/include/linux/kvm_host.h
> > > +++ b/include/linux/kvm_host.h
> > > @@ -148,6 +148,7 @@ struct kvm_io_bus {
> > > enum kvm_bus {
> > > KVM_MMIO_BUS,
> > > KVM_PIO_BUS,
> > > + KVM_CSS_BUS,
> > > KVM_NR_BUSES
> > > };
> > >
> > > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> > > index 9a2db57..1df0766 100644
> > > --- a/include/uapi/linux/kvm.h
> > > +++ b/include/uapi/linux/kvm.h
> > > @@ -448,12 +448,14 @@ enum {
> > > kvm_ioeventfd_flag_nr_datamatch,
> > > kvm_ioeventfd_flag_nr_pio,
> > > kvm_ioeventfd_flag_nr_deassign,
> > > + kvm_ioeventfd_flag_nr_css,
> > > kvm_ioeventfd_flag_nr_max,
> > > };
> > >
> > > #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
> > > #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio)
> > > #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign)
> > > +#define KVM_IOEVENTFD_FLAG_CSS (1 << kvm_ioeventfd_flag_nr_css)
> > >
> > > #define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1)
> > >
> > > diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
> > > index f0ced1a..57a06ff 100644
> > > --- a/virt/kvm/eventfd.c
> > > +++ b/virt/kvm/eventfd.c
> > > @@ -576,6 +576,7 @@ struct _ioeventfd {
> > > u64 datamatch;
> > > struct kvm_io_device dev;
> > > bool wildcard;
> > > + bool is_css;
> > > };
> > >
> > > static inline struct _ioeventfd *
> > > @@ -607,24 +608,27 @@ ioeventfd_in_range(struct _ioeventfd *p, gpa_t addr, int len, const void *val)
> > >
> > > /* otherwise, we have to actually compare the data */
> > >
> > > - BUG_ON(!IS_ALIGNED((unsigned long)val, len));
> > > -
> > > - switch (len) {
> > > - case 1:
> > > - _val = *(u8 *)val;
> > > - break;
> > > - case 2:
> > > - _val = *(u16 *)val;
> > > - break;
> > > - case 4:
> > > - _val = *(u32 *)val;
> > > - break;
> > > - case 8:
> > > + if (!p->is_css) {
> > > + BUG_ON(!IS_ALIGNED((unsigned long)val, len));
> > > +
> > > + switch (len) {
> > > + case 1:
> > > + _val = *(u8 *)val;
> > > + break;
> > > + case 2:
> > > + _val = *(u16 *)val;
> > > + break;
> > > + case 4:
> > > + _val = *(u32 *)val;
> > > + break;
> > > + case 8:
> > > + _val = *(u64 *)val;
> > > + break;
> > > + default:
> > > + return false;
> > > + }
> > > + } else
> > > _val = *(u64 *)val;
> > > - break;
> > > - default:
> > > - return false;
> > > - }
> > >
> > > return _val == p->datamatch ? true : false;
> > > }
> > > @@ -679,25 +683,29 @@ static int
> > > kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
> > > {
> > > int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
> > > - enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
> > > + int css = args->flags & KVM_IOEVENTFD_FLAG_CSS;
> > > + enum kvm_bus bus_idx;
> > > struct _ioeventfd *p;
> > > struct eventfd_ctx *eventfd;
> > > int ret;
> > >
> > > - /* must be natural-word sized */
> > > - switch (args->len) {
> > > - case 1:
> > > - case 2:
> > > - case 4:
> > > - case 8:
> > > - break;
> > > - default:
> > > - return -EINVAL;
> > > - }
> > > + bus_idx = pio ? KVM_PIO_BUS : css ? KVM_CSS_BUS: KVM_MMIO_BUS;
> > > + if (!css) {
> > > + /* must be natural-word sized */
> > > + switch (args->len) {
> > > + case 1:
> > > + case 2:
> > > + case 4:
> > > + case 8:
> > > + break;
> > > + default:
> > > + return -EINVAL;
> > > + }
> > >
> > > - /* check for range overflow */
> > > - if (args->addr + args->len < args->addr)
> > > - return -EINVAL;
> > > + /* check for range overflow */
> > > + if (args->addr + args->len < args->addr)
> > > + return -EINVAL;
> > > + }
> > >
> > > /* check for extra flags that we don't understand */
> > > if (args->flags & ~KVM_IOEVENTFD_VALID_FLAG_MASK)
> > > @@ -717,6 +725,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
> > > p->addr = args->addr;
> > > p->length = args->len;
> > > p->eventfd = eventfd;
> > > + p->is_css = css;
> > >
> > > /* The datamatch feature is optional, otherwise this is a wildcard */
> > > if (args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH)
> > > @@ -759,11 +768,13 @@ static int
> > > kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
> > > {
> > > int pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
> > > - enum kvm_bus bus_idx = pio ? KVM_PIO_BUS : KVM_MMIO_BUS;
> > > + int css = args->flags & KVM_IOEVENTFD_FLAG_CSS;
> > > + enum kvm_bus bus_idx;
> > > struct _ioeventfd *p, *tmp;
> > > struct eventfd_ctx *eventfd;
> > > int ret = -ENOENT;
> > >
> > > + bus_idx = pio ? KVM_PIO_BUS : css ? KVM_CSS_BUS: KVM_MMIO_BUS;
> > > eventfd = eventfd_ctx_fdget(args->fd);
> > > if (IS_ERR(eventfd))
> > > return PTR_ERR(eventfd);
> >
prev parent reply other threads:[~2013-02-24 9:37 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-21 13:12 [RFC PATCH 0/3] kvm: Make ioeventfd usable on s390 Cornelia Huck
2013-02-21 13:12 ` [RFC PATCH 1/3] KVM: s390: Move out initialization code Cornelia Huck
2013-02-21 13:43 ` Michael S. Tsirkin
2013-02-21 14:07 ` Cornelia Huck
2013-02-21 14:18 ` Michael S. Tsirkin
2013-02-21 14:56 ` Cornelia Huck
2013-02-21 13:12 ` [RFC PATCH 2/3] KVM: Generalize ioeventfds Cornelia Huck
2013-02-21 13:13 ` [RFC PATCH 3/3] KVM: s390: Hook up ioeventfds Cornelia Huck
2013-02-21 14:39 ` Michael S. Tsirkin
2013-02-21 15:21 ` Cornelia Huck
2013-02-21 16:34 ` Michael S. Tsirkin
2013-02-21 18:14 ` Cornelia Huck
2013-02-21 20:42 ` Michael S. Tsirkin
2013-02-22 7:22 ` Cornelia Huck
2013-02-24 9:37 ` Michael S. Tsirkin [this message]
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=20130224093756.GA25269@redhat.com \
--to=mst@redhat.com \
--cc=cornelia.huck@de.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.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.