1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun #ifndef __KVM_IODEV_H__
4*4882a593Smuzhiyun #define __KVM_IODEV_H__
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <linux/kvm_types.h>
7*4882a593Smuzhiyun #include <linux/errno.h>
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun struct kvm_io_device;
10*4882a593Smuzhiyun struct kvm_vcpu;
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun /**
13*4882a593Smuzhiyun * kvm_io_device_ops are called under kvm slots_lock.
14*4882a593Smuzhiyun * read and write handlers return 0 if the transaction has been handled,
15*4882a593Smuzhiyun * or non-zero to have it passed to the next device.
16*4882a593Smuzhiyun **/
17*4882a593Smuzhiyun struct kvm_io_device_ops {
18*4882a593Smuzhiyun int (*read)(struct kvm_vcpu *vcpu,
19*4882a593Smuzhiyun struct kvm_io_device *this,
20*4882a593Smuzhiyun gpa_t addr,
21*4882a593Smuzhiyun int len,
22*4882a593Smuzhiyun void *val);
23*4882a593Smuzhiyun int (*write)(struct kvm_vcpu *vcpu,
24*4882a593Smuzhiyun struct kvm_io_device *this,
25*4882a593Smuzhiyun gpa_t addr,
26*4882a593Smuzhiyun int len,
27*4882a593Smuzhiyun const void *val);
28*4882a593Smuzhiyun void (*destructor)(struct kvm_io_device *this);
29*4882a593Smuzhiyun };
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun struct kvm_io_device {
33*4882a593Smuzhiyun const struct kvm_io_device_ops *ops;
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun
kvm_iodevice_init(struct kvm_io_device * dev,const struct kvm_io_device_ops * ops)36*4882a593Smuzhiyun static inline void kvm_iodevice_init(struct kvm_io_device *dev,
37*4882a593Smuzhiyun const struct kvm_io_device_ops *ops)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun dev->ops = ops;
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun
kvm_iodevice_read(struct kvm_vcpu * vcpu,struct kvm_io_device * dev,gpa_t addr,int l,void * v)42*4882a593Smuzhiyun static inline int kvm_iodevice_read(struct kvm_vcpu *vcpu,
43*4882a593Smuzhiyun struct kvm_io_device *dev, gpa_t addr,
44*4882a593Smuzhiyun int l, void *v)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun return dev->ops->read ? dev->ops->read(vcpu, dev, addr, l, v)
47*4882a593Smuzhiyun : -EOPNOTSUPP;
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun
kvm_iodevice_write(struct kvm_vcpu * vcpu,struct kvm_io_device * dev,gpa_t addr,int l,const void * v)50*4882a593Smuzhiyun static inline int kvm_iodevice_write(struct kvm_vcpu *vcpu,
51*4882a593Smuzhiyun struct kvm_io_device *dev, gpa_t addr,
52*4882a593Smuzhiyun int l, const void *v)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun return dev->ops->write ? dev->ops->write(vcpu, dev, addr, l, v)
55*4882a593Smuzhiyun : -EOPNOTSUPP;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun
kvm_iodevice_destructor(struct kvm_io_device * dev)58*4882a593Smuzhiyun static inline void kvm_iodevice_destructor(struct kvm_io_device *dev)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun if (dev->ops->destructor)
61*4882a593Smuzhiyun dev->ops->destructor(dev);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #endif /* __KVM_IODEV_H__ */
65