Skip to content

Commit

Permalink
Merge tag 'kvms390-20160420' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/kvms390/linux into next

KVM/s390 patches for 4.7:
- improve perf output
- cleanup and a new feature in the floating interrupt controller (FLIC)
  • Loading branch information
Radim Krčmář committed Apr 20, 2016
2 parents 5e1b59a + 6d28f78 commit 05b1159
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 1 deletion.
12 changes: 12 additions & 0 deletions Documentation/virtual/kvm/devices/s390_flic.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ FLIC provides support to
- add interrupts (KVM_DEV_FLIC_ENQUEUE)
- inspect currently pending interrupts (KVM_FLIC_GET_ALL_IRQS)
- purge all pending floating interrupts (KVM_DEV_FLIC_CLEAR_IRQS)
- purge one pending floating I/O interrupt (KVM_DEV_FLIC_CLEAR_IO_IRQ)
- enable/disable for the guest transparent async page faults
- register and modify adapter interrupt sources (KVM_DEV_FLIC_ADAPTER_*)

Expand Down Expand Up @@ -40,6 +41,11 @@ Groups:
Simply deletes all elements from the list of currently pending floating
interrupts. No interrupts are injected into the guest.

KVM_DEV_FLIC_CLEAR_IO_IRQ
Deletes one (if any) I/O interrupt for a subchannel identified by the
subsystem identification word passed via the buffer specified by
attr->addr (address) and attr->attr (length).

KVM_DEV_FLIC_APF_ENABLE
Enables async page faults for the guest. So in case of a major page fault
the host is allowed to handle this async and continues the guest.
Expand Down Expand Up @@ -94,3 +100,9 @@ struct kvm_s390_io_adapter_req {
KVM_S390_IO_ADAPTER_UNMAP
release a userspace page for the translated address specified in addr
from the list of mappings

Note: The KVM_SET_DEVICE_ATTR/KVM_GET_DEVICE_ATTR device ioctls executed on
FLIC with an unknown group or attribute gives the error code EINVAL (instead of
ENXIO, as specified in the API documentation). It is not possible to conclude
that a FLIC operation is unavailable based on the error code resulting from a
usage attempt.
1 change: 1 addition & 0 deletions arch/s390/include/uapi/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define KVM_DEV_FLIC_APF_DISABLE_WAIT 5
#define KVM_DEV_FLIC_ADAPTER_REGISTER 6
#define KVM_DEV_FLIC_ADAPTER_MODIFY 7
#define KVM_DEV_FLIC_CLEAR_IO_IRQ 8
/*
* We can have up to 4*64k pending subchannels + 8 adapter interrupts,
* as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts.
Expand Down
7 changes: 6 additions & 1 deletion arch/s390/include/uapi/asm/sie.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@
{ 0x01, "SIGP sense" }, \
{ 0x02, "SIGP external call" }, \
{ 0x03, "SIGP emergency signal" }, \
{ 0x04, "SIGP start" }, \
{ 0x05, "SIGP stop" }, \
{ 0x06, "SIGP restart" }, \
{ 0x09, "SIGP stop and store status" }, \
{ 0x0b, "SIGP initial cpu reset" }, \
{ 0x0c, "SIGP cpu reset" }, \
{ 0x0d, "SIGP set prefix" }, \
{ 0x0e, "SIGP store status at address" }, \
{ 0x12, "SIGP set architecture" }, \
{ 0x15, "SIGP sense running" }
{ 0x13, "SIGP conditional emergency signal" }, \
{ 0x15, "SIGP sense running" }, \
{ 0x16, "SIGP set multithreading"}, \
{ 0x17, "SIGP store additional status ait address"}

#define icpt_prog_codes \
{ 0x0001, "Prog Operation" }, \
Expand Down
42 changes: 42 additions & 0 deletions arch/s390/kvm/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2034,6 +2034,27 @@ static int modify_io_adapter(struct kvm_device *dev,
return ret;
}

static int clear_io_irq(struct kvm *kvm, struct kvm_device_attr *attr)

{
const u64 isc_mask = 0xffUL << 24; /* all iscs set */
u32 schid;

if (attr->flags)
return -EINVAL;
if (attr->attr != sizeof(schid))
return -EINVAL;
if (copy_from_user(&schid, (void __user *) attr->addr, sizeof(schid)))
return -EFAULT;
kfree(kvm_s390_get_io_int(kvm, isc_mask, schid));
/*
* If userspace is conforming to the architecture, we can have at most
* one pending I/O interrupt per subchannel, so this is effectively a
* clear all.
*/
return 0;
}

static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
{
int r = 0;
Expand Down Expand Up @@ -2067,13 +2088,33 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
case KVM_DEV_FLIC_ADAPTER_MODIFY:
r = modify_io_adapter(dev, attr);
break;
case KVM_DEV_FLIC_CLEAR_IO_IRQ:
r = clear_io_irq(dev->kvm, attr);
break;
default:
r = -EINVAL;
}

return r;
}

static int flic_has_attr(struct kvm_device *dev,
struct kvm_device_attr *attr)
{
switch (attr->group) {
case KVM_DEV_FLIC_GET_ALL_IRQS:
case KVM_DEV_FLIC_ENQUEUE:
case KVM_DEV_FLIC_CLEAR_IRQS:
case KVM_DEV_FLIC_APF_ENABLE:
case KVM_DEV_FLIC_APF_DISABLE_WAIT:
case KVM_DEV_FLIC_ADAPTER_REGISTER:
case KVM_DEV_FLIC_ADAPTER_MODIFY:
case KVM_DEV_FLIC_CLEAR_IO_IRQ:
return 0;
}
return -ENXIO;
}

static int flic_create(struct kvm_device *dev, u32 type)
{
if (!dev)
Expand All @@ -2095,6 +2136,7 @@ struct kvm_device_ops kvm_flic_ops = {
.name = "kvm-flic",
.get_attr = flic_get_attr,
.set_attr = flic_set_attr,
.has_attr = flic_has_attr,
.create = flic_create,
.destroy = flic_destroy,
};
Expand Down

0 comments on commit 05b1159

Please sign in to comment.