KVM: s390: add clear I/O irq operation for FLIC

Introduce a FLIC operation for clearing I/O interrupts for a subchannel.

Rationale: According to the platform specification, pending I/O
interruption requests have to be revoked in certain situations. For
instance, according to the Principles of Operation (page 17-27), a
subchannel put into the installed parameters initialized state is in the
same state as after an I/O system reset (just parameters possibly changed).
This implies that any I/O interrupts for that subchannel are no longer
pending (as I/O system resets clear I/O interrupts). Therefore, we need an
interface to clear pending I/O interrupts.

Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
Halil Pasic 2016-01-25 19:10:40 +01:00 committed by Cornelia Huck
parent dad7eefbd0
commit 6d28f789bf
3 changed files with 32 additions and 0 deletions

View file

@ -11,6 +11,7 @@ FLIC provides support to
- add interrupts (KVM_DEV_FLIC_ENQUEUE) - add interrupts (KVM_DEV_FLIC_ENQUEUE)
- inspect currently pending interrupts (KVM_FLIC_GET_ALL_IRQS) - inspect currently pending interrupts (KVM_FLIC_GET_ALL_IRQS)
- purge all pending floating interrupts (KVM_DEV_FLIC_CLEAR_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 - enable/disable for the guest transparent async page faults
- register and modify adapter interrupt sources (KVM_DEV_FLIC_ADAPTER_*) - register and modify adapter interrupt sources (KVM_DEV_FLIC_ADAPTER_*)
@ -40,6 +41,11 @@ Groups:
Simply deletes all elements from the list of currently pending floating Simply deletes all elements from the list of currently pending floating
interrupts. No interrupts are injected into the guest. 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 KVM_DEV_FLIC_APF_ENABLE
Enables async page faults for the guest. So in case of a major page fault 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. the host is allowed to handle this async and continues the guest.

View file

@ -25,6 +25,7 @@
#define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 #define KVM_DEV_FLIC_APF_DISABLE_WAIT 5
#define KVM_DEV_FLIC_ADAPTER_REGISTER 6 #define KVM_DEV_FLIC_ADAPTER_REGISTER 6
#define KVM_DEV_FLIC_ADAPTER_MODIFY 7 #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, * 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. * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts.

View file

@ -2034,6 +2034,27 @@ static int modify_io_adapter(struct kvm_device *dev,
return ret; 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) static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
{ {
int r = 0; int r = 0;
@ -2067,6 +2088,9 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
case KVM_DEV_FLIC_ADAPTER_MODIFY: case KVM_DEV_FLIC_ADAPTER_MODIFY:
r = modify_io_adapter(dev, attr); r = modify_io_adapter(dev, attr);
break; break;
case KVM_DEV_FLIC_CLEAR_IO_IRQ:
r = clear_io_irq(dev->kvm, attr);
break;
default: default:
r = -EINVAL; r = -EINVAL;
} }
@ -2085,6 +2109,7 @@ static int flic_has_attr(struct kvm_device *dev,
case KVM_DEV_FLIC_APF_DISABLE_WAIT: case KVM_DEV_FLIC_APF_DISABLE_WAIT:
case KVM_DEV_FLIC_ADAPTER_REGISTER: case KVM_DEV_FLIC_ADAPTER_REGISTER:
case KVM_DEV_FLIC_ADAPTER_MODIFY: case KVM_DEV_FLIC_ADAPTER_MODIFY:
case KVM_DEV_FLIC_CLEAR_IO_IRQ:
return 0; return 0;
} }
return -ENXIO; return -ENXIO;