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