Loading Documentation/virtual/kvm/devices/s390_flic.txt +12 −0 Original line number Diff line number Diff line Loading @@ -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_*) Loading Loading @@ -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. Loading Loading @@ -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. arch/s390/include/uapi/asm/kvm.h +1 −0 Original line number Diff line number Diff line Loading @@ -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. Loading arch/s390/include/uapi/asm/sie.h +6 −1 Original line number Diff line number Diff line Loading @@ -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" }, \ Loading arch/s390/kvm/interrupt.c +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -2067,6 +2088,9 @@ 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; } Loading @@ -2074,6 +2098,23 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) 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) Loading @@ -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, }; Loading Loading
Documentation/virtual/kvm/devices/s390_flic.txt +12 −0 Original line number Diff line number Diff line Loading @@ -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_*) Loading Loading @@ -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. Loading Loading @@ -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.
arch/s390/include/uapi/asm/kvm.h +1 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
arch/s390/include/uapi/asm/sie.h +6 −1 Original line number Diff line number Diff line Loading @@ -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" }, \ Loading
arch/s390/kvm/interrupt.c +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -2067,6 +2088,9 @@ 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; } Loading @@ -2074,6 +2098,23 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) 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) Loading @@ -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, }; Loading