diff options
| author | Nikolay Nikolaev <n.nikolaev@virtualopensystems.com> | 2015-03-26 10:39:28 -0400 |
|---|---|---|
| committer | Marc Zyngier <marc.zyngier@arm.com> | 2015-03-26 17:43:11 -0400 |
| commit | e32edf4fd0fa4897e12ca66118ab67bf257e16e4 (patch) | |
| tree | 8bd79dc3e3d03576e084ce2dbbde68c95fdd0ea8 /virt | |
| parent | 1a74847885cc87857d631f91cca4d83924f75674 (diff) | |
KVM: Redesign kvm_io_bus_ API to pass VCPU structure to the callbacks.
This is needed in e.g. ARM vGIC emulation, where the MMIO handling
depends on the VCPU that does the access.
Signed-off-by: Nikolay Nikolaev <n.nikolaev@virtualopensystems.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/coalesced_mmio.c | 5 | ||||
| -rw-r--r-- | virt/kvm/eventfd.c | 4 | ||||
| -rw-r--r-- | virt/kvm/iodev.h | 23 | ||||
| -rw-r--r-- | virt/kvm/kvm_main.c | 32 |
4 files changed, 36 insertions, 28 deletions
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index 00d86427af0f..c831a40ffc1a 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c | |||
| @@ -60,8 +60,9 @@ static int coalesced_mmio_has_room(struct kvm_coalesced_mmio_dev *dev) | |||
| 60 | return 1; | 60 | return 1; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | static int coalesced_mmio_write(struct kvm_io_device *this, | 63 | static int coalesced_mmio_write(struct kvm_vcpu *vcpu, |
| 64 | gpa_t addr, int len, const void *val) | 64 | struct kvm_io_device *this, gpa_t addr, |
| 65 | int len, const void *val) | ||
| 65 | { | 66 | { |
| 66 | struct kvm_coalesced_mmio_dev *dev = to_mmio(this); | 67 | struct kvm_coalesced_mmio_dev *dev = to_mmio(this); |
| 67 | struct kvm_coalesced_mmio_ring *ring = dev->kvm->coalesced_mmio_ring; | 68 | struct kvm_coalesced_mmio_ring *ring = dev->kvm->coalesced_mmio_ring; |
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index fc5f43e54a80..26c72f3663f2 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
| @@ -715,8 +715,8 @@ ioeventfd_in_range(struct _ioeventfd *p, gpa_t addr, int len, const void *val) | |||
| 715 | 715 | ||
| 716 | /* MMIO/PIO writes trigger an event if the addr/val match */ | 716 | /* MMIO/PIO writes trigger an event if the addr/val match */ |
| 717 | static int | 717 | static int |
| 718 | ioeventfd_write(struct kvm_io_device *this, gpa_t addr, int len, | 718 | ioeventfd_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this, gpa_t addr, |
| 719 | const void *val) | 719 | int len, const void *val) |
| 720 | { | 720 | { |
| 721 | struct _ioeventfd *p = to_ioeventfd(this); | 721 | struct _ioeventfd *p = to_ioeventfd(this); |
| 722 | 722 | ||
diff --git a/virt/kvm/iodev.h b/virt/kvm/iodev.h index 12fd3caffd2b..9ef709cc2cae 100644 --- a/virt/kvm/iodev.h +++ b/virt/kvm/iodev.h | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <asm/errno.h> | 20 | #include <asm/errno.h> |
| 21 | 21 | ||
| 22 | struct kvm_io_device; | 22 | struct kvm_io_device; |
| 23 | struct kvm_vcpu; | ||
| 23 | 24 | ||
| 24 | /** | 25 | /** |
| 25 | * kvm_io_device_ops are called under kvm slots_lock. | 26 | * kvm_io_device_ops are called under kvm slots_lock. |
| @@ -27,11 +28,13 @@ struct kvm_io_device; | |||
| 27 | * or non-zero to have it passed to the next device. | 28 | * or non-zero to have it passed to the next device. |
| 28 | **/ | 29 | **/ |
| 29 | struct kvm_io_device_ops { | 30 | struct kvm_io_device_ops { |
| 30 | int (*read)(struct kvm_io_device *this, | 31 | int (*read)(struct kvm_vcpu *vcpu, |
| 32 | struct kvm_io_device *this, | ||
| 31 | gpa_t addr, | 33 | gpa_t addr, |
| 32 | int len, | 34 | int len, |
| 33 | void *val); | 35 | void *val); |
| 34 | int (*write)(struct kvm_io_device *this, | 36 | int (*write)(struct kvm_vcpu *vcpu, |
| 37 | struct kvm_io_device *this, | ||
| 35 | gpa_t addr, | 38 | gpa_t addr, |
| 36 | int len, | 39 | int len, |
| 37 | const void *val); | 40 | const void *val); |
| @@ -49,16 +52,20 @@ static inline void kvm_iodevice_init(struct kvm_io_device *dev, | |||
| 49 | dev->ops = ops; | 52 | dev->ops = ops; |
| 50 | } | 53 | } |
| 51 | 54 | ||
| 52 | static inline int kvm_iodevice_read(struct kvm_io_device *dev, | 55 | static inline int kvm_iodevice_read(struct kvm_vcpu *vcpu, |
| 53 | gpa_t addr, int l, void *v) | 56 | struct kvm_io_device *dev, gpa_t addr, |
| 57 | int l, void *v) | ||
| 54 | { | 58 | { |
| 55 | return dev->ops->read ? dev->ops->read(dev, addr, l, v) : -EOPNOTSUPP; | 59 | return dev->ops->read ? dev->ops->read(vcpu, dev, addr, l, v) |
| 60 | : -EOPNOTSUPP; | ||
| 56 | } | 61 | } |
| 57 | 62 | ||
| 58 | static inline int kvm_iodevice_write(struct kvm_io_device *dev, | 63 | static inline int kvm_iodevice_write(struct kvm_vcpu *vcpu, |
| 59 | gpa_t addr, int l, const void *v) | 64 | struct kvm_io_device *dev, gpa_t addr, |
| 65 | int l, const void *v) | ||
| 60 | { | 66 | { |
| 61 | return dev->ops->write ? dev->ops->write(dev, addr, l, v) : -EOPNOTSUPP; | 67 | return dev->ops->write ? dev->ops->write(vcpu, dev, addr, l, v) |
| 68 | : -EOPNOTSUPP; | ||
| 62 | } | 69 | } |
| 63 | 70 | ||
| 64 | static inline void kvm_iodevice_destructor(struct kvm_io_device *dev) | 71 | static inline void kvm_iodevice_destructor(struct kvm_io_device *dev) |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a1093700f3a4..664d67a099f6 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -2997,7 +2997,7 @@ static int kvm_io_bus_get_first_dev(struct kvm_io_bus *bus, | |||
| 2997 | return off; | 2997 | return off; |
| 2998 | } | 2998 | } |
| 2999 | 2999 | ||
| 3000 | static int __kvm_io_bus_write(struct kvm_io_bus *bus, | 3000 | static int __kvm_io_bus_write(struct kvm_vcpu *vcpu, struct kvm_io_bus *bus, |
| 3001 | struct kvm_io_range *range, const void *val) | 3001 | struct kvm_io_range *range, const void *val) |
| 3002 | { | 3002 | { |
| 3003 | int idx; | 3003 | int idx; |
| @@ -3008,7 +3008,7 @@ static int __kvm_io_bus_write(struct kvm_io_bus *bus, | |||
| 3008 | 3008 | ||
| 3009 | while (idx < bus->dev_count && | 3009 | while (idx < bus->dev_count && |
| 3010 | kvm_io_bus_cmp(range, &bus->range[idx]) == 0) { | 3010 | kvm_io_bus_cmp(range, &bus->range[idx]) == 0) { |
| 3011 | if (!kvm_iodevice_write(bus->range[idx].dev, range->addr, | 3011 | if (!kvm_iodevice_write(vcpu, bus->range[idx].dev, range->addr, |
| 3012 | range->len, val)) | 3012 | range->len, val)) |
| 3013 | return idx; | 3013 | return idx; |
| 3014 | idx++; | 3014 | idx++; |
| @@ -3018,7 +3018,7 @@ static int __kvm_io_bus_write(struct kvm_io_bus *bus, | |||
| 3018 | } | 3018 | } |
| 3019 | 3019 | ||
| 3020 | /* kvm_io_bus_write - called under kvm->slots_lock */ | 3020 | /* kvm_io_bus_write - called under kvm->slots_lock */ |
| 3021 | int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | 3021 | int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr, |
| 3022 | int len, const void *val) | 3022 | int len, const void *val) |
| 3023 | { | 3023 | { |
| 3024 | struct kvm_io_bus *bus; | 3024 | struct kvm_io_bus *bus; |
| @@ -3030,14 +3030,14 @@ int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | |||
| 3030 | .len = len, | 3030 | .len = len, |
| 3031 | }; | 3031 | }; |
| 3032 | 3032 | ||
| 3033 | bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu); | 3033 | bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu); |
| 3034 | r = __kvm_io_bus_write(bus, &range, val); | 3034 | r = __kvm_io_bus_write(vcpu, bus, &range, val); |
| 3035 | return r < 0 ? r : 0; | 3035 | return r < 0 ? r : 0; |
| 3036 | } | 3036 | } |
| 3037 | 3037 | ||
| 3038 | /* kvm_io_bus_write_cookie - called under kvm->slots_lock */ | 3038 | /* kvm_io_bus_write_cookie - called under kvm->slots_lock */ |
| 3039 | int kvm_io_bus_write_cookie(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | 3039 | int kvm_io_bus_write_cookie(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, |
| 3040 | int len, const void *val, long cookie) | 3040 | gpa_t addr, int len, const void *val, long cookie) |
| 3041 | { | 3041 | { |
| 3042 | struct kvm_io_bus *bus; | 3042 | struct kvm_io_bus *bus; |
| 3043 | struct kvm_io_range range; | 3043 | struct kvm_io_range range; |
| @@ -3047,12 +3047,12 @@ int kvm_io_bus_write_cookie(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | |||
| 3047 | .len = len, | 3047 | .len = len, |
| 3048 | }; | 3048 | }; |
| 3049 | 3049 | ||
| 3050 | bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu); | 3050 | bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu); |
| 3051 | 3051 | ||
| 3052 | /* First try the device referenced by cookie. */ | 3052 | /* First try the device referenced by cookie. */ |
| 3053 | if ((cookie >= 0) && (cookie < bus->dev_count) && | 3053 | if ((cookie >= 0) && (cookie < bus->dev_count) && |
| 3054 | (kvm_io_bus_cmp(&range, &bus->range[cookie]) == 0)) | 3054 | (kvm_io_bus_cmp(&range, &bus->range[cookie]) == 0)) |
| 3055 | if (!kvm_iodevice_write(bus->range[cookie].dev, addr, len, | 3055 | if (!kvm_iodevice_write(vcpu, bus->range[cookie].dev, addr, len, |
| 3056 | val)) | 3056 | val)) |
| 3057 | return cookie; | 3057 | return cookie; |
| 3058 | 3058 | ||
| @@ -3060,11 +3060,11 @@ int kvm_io_bus_write_cookie(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | |||
| 3060 | * cookie contained garbage; fall back to search and return the | 3060 | * cookie contained garbage; fall back to search and return the |
| 3061 | * correct cookie value. | 3061 | * correct cookie value. |
| 3062 | */ | 3062 | */ |
| 3063 | return __kvm_io_bus_write(bus, &range, val); | 3063 | return __kvm_io_bus_write(vcpu, bus, &range, val); |
| 3064 | } | 3064 | } |
| 3065 | 3065 | ||
| 3066 | static int __kvm_io_bus_read(struct kvm_io_bus *bus, struct kvm_io_range *range, | 3066 | static int __kvm_io_bus_read(struct kvm_vcpu *vcpu, struct kvm_io_bus *bus, |
| 3067 | void *val) | 3067 | struct kvm_io_range *range, void *val) |
| 3068 | { | 3068 | { |
| 3069 | int idx; | 3069 | int idx; |
| 3070 | 3070 | ||
| @@ -3074,7 +3074,7 @@ static int __kvm_io_bus_read(struct kvm_io_bus *bus, struct kvm_io_range *range, | |||
| 3074 | 3074 | ||
| 3075 | while (idx < bus->dev_count && | 3075 | while (idx < bus->dev_count && |
| 3076 | kvm_io_bus_cmp(range, &bus->range[idx]) == 0) { | 3076 | kvm_io_bus_cmp(range, &bus->range[idx]) == 0) { |
| 3077 | if (!kvm_iodevice_read(bus->range[idx].dev, range->addr, | 3077 | if (!kvm_iodevice_read(vcpu, bus->range[idx].dev, range->addr, |
| 3078 | range->len, val)) | 3078 | range->len, val)) |
| 3079 | return idx; | 3079 | return idx; |
| 3080 | idx++; | 3080 | idx++; |
| @@ -3085,7 +3085,7 @@ static int __kvm_io_bus_read(struct kvm_io_bus *bus, struct kvm_io_range *range, | |||
| 3085 | EXPORT_SYMBOL_GPL(kvm_io_bus_write); | 3085 | EXPORT_SYMBOL_GPL(kvm_io_bus_write); |
| 3086 | 3086 | ||
| 3087 | /* kvm_io_bus_read - called under kvm->slots_lock */ | 3087 | /* kvm_io_bus_read - called under kvm->slots_lock */ |
| 3088 | int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | 3088 | int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr, |
| 3089 | int len, void *val) | 3089 | int len, void *val) |
| 3090 | { | 3090 | { |
| 3091 | struct kvm_io_bus *bus; | 3091 | struct kvm_io_bus *bus; |
| @@ -3097,8 +3097,8 @@ int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | |||
| 3097 | .len = len, | 3097 | .len = len, |
| 3098 | }; | 3098 | }; |
| 3099 | 3099 | ||
| 3100 | bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu); | 3100 | bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu); |
| 3101 | r = __kvm_io_bus_read(bus, &range, val); | 3101 | r = __kvm_io_bus_read(vcpu, bus, &range, val); |
| 3102 | return r < 0 ? r : 0; | 3102 | return r < 0 ? r : 0; |
| 3103 | } | 3103 | } |
| 3104 | 3104 | ||
