aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/diag.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kvm/diag.c')
-rw-r--r--arch/s390/kvm/diag.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index a390687feb13..1c01a9912989 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/kvm.h> 14#include <linux/kvm.h>
15#include <linux/kvm_host.h> 15#include <linux/kvm_host.h>
16#include <asm/virtio-ccw.h>
16#include "kvm-s390.h" 17#include "kvm-s390.h"
17#include "trace.h" 18#include "trace.h"
18#include "trace-s390.h" 19#include "trace-s390.h"
@@ -104,6 +105,29 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
104 return -EREMOTE; 105 return -EREMOTE;
105} 106}
106 107
108static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
109{
110 int ret, idx;
111
112 /* No virtio-ccw notification? Get out quickly. */
113 if (!vcpu->kvm->arch.css_support ||
114 (vcpu->run->s.regs.gprs[1] != KVM_S390_VIRTIO_CCW_NOTIFY))
115 return -EOPNOTSUPP;
116
117 idx = srcu_read_lock(&vcpu->kvm->srcu);
118 /*
119 * The layout is as follows:
120 * - gpr 2 contains the subchannel id (passed as addr)
121 * - gpr 3 contains the virtqueue index (passed as datamatch)
122 */
123 ret = kvm_io_bus_write(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS,
124 vcpu->run->s.regs.gprs[2],
125 8, &vcpu->run->s.regs.gprs[3]);
126 srcu_read_unlock(&vcpu->kvm->srcu, idx);
127 /* kvm_io_bus_write returns -EOPNOTSUPP if it found no match. */
128 return ret < 0 ? ret : 0;
129}
130
107int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) 131int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
108{ 132{
109 int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16; 133 int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16;
@@ -118,6 +142,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
118 return __diag_time_slice_end_directed(vcpu); 142 return __diag_time_slice_end_directed(vcpu);
119 case 0x308: 143 case 0x308:
120 return __diag_ipl_functions(vcpu); 144 return __diag_ipl_functions(vcpu);
145 case 0x500:
146 return __diag_virtio_hypercall(vcpu);
121 default: 147 default:
122 return -EOPNOTSUPP; 148 return -EOPNOTSUPP;
123 } 149 }