.. | .. |
---|
14 | 14 | #include <linux/mm.h> |
---|
15 | 15 | #include <linux/mmu_notifier.h> |
---|
16 | 16 | #include <linux/preempt.h> |
---|
| 17 | +#include <linux/dovetail.h> |
---|
17 | 18 | #include <linux/msi.h> |
---|
18 | 19 | #include <linux/slab.h> |
---|
19 | 20 | #include <linux/vmalloc.h> |
---|
.. | .. |
---|
260 | 261 | unsigned len; |
---|
261 | 262 | }; |
---|
262 | 263 | |
---|
| 264 | +/* |
---|
| 265 | + * Called when the host is about to leave the inband stage. Typically |
---|
| 266 | + * used for switching the current vcpu out of guest mode before a |
---|
| 267 | + * companion core reinstates an oob task context. |
---|
| 268 | + */ |
---|
| 269 | +struct kvm_oob_notifier { |
---|
| 270 | + void (*handler)(struct kvm_oob_notifier *nfy); |
---|
| 271 | + bool put_vcpu; |
---|
| 272 | +}; |
---|
| 273 | + |
---|
263 | 274 | struct kvm_vcpu { |
---|
264 | 275 | struct kvm *kvm; |
---|
265 | 276 | #ifdef CONFIG_PREEMPT_NOTIFIERS |
---|
266 | 277 | struct preempt_notifier preempt_notifier; |
---|
| 278 | +#endif |
---|
| 279 | +#ifdef CONFIG_DOVETAIL |
---|
| 280 | + struct kvm_oob_notifier oob_notifier; |
---|
267 | 281 | #endif |
---|
268 | 282 | int cpu; |
---|
269 | 283 | int vcpu_id; /* id given by userspace at creation */ |
---|
.. | .. |
---|
1502 | 1516 | } |
---|
1503 | 1517 | #endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */ |
---|
1504 | 1518 | |
---|
| 1519 | +#if defined(CONFIG_DOVETAIL) && defined(CONFIG_KVM) |
---|
| 1520 | +static inline void inband_init_vcpu(struct kvm_vcpu *vcpu, |
---|
| 1521 | + void (*preempt_handler)(struct kvm_oob_notifier *nfy)) |
---|
| 1522 | +{ |
---|
| 1523 | + vcpu->oob_notifier.handler = preempt_handler; |
---|
| 1524 | + vcpu->oob_notifier.put_vcpu = false; |
---|
| 1525 | +} |
---|
| 1526 | + |
---|
| 1527 | +static inline void inband_enter_guest(struct kvm_vcpu *vcpu) |
---|
| 1528 | +{ |
---|
| 1529 | + struct irq_pipeline_data *p = raw_cpu_ptr(&irq_pipeline); |
---|
| 1530 | + WRITE_ONCE(p->vcpu_notify, &vcpu->oob_notifier); |
---|
| 1531 | +} |
---|
| 1532 | + |
---|
| 1533 | +static inline void inband_exit_guest(void) |
---|
| 1534 | +{ |
---|
| 1535 | + struct irq_pipeline_data *p = raw_cpu_ptr(&irq_pipeline); |
---|
| 1536 | + WRITE_ONCE(p->vcpu_notify, NULL); |
---|
| 1537 | +} |
---|
| 1538 | + |
---|
| 1539 | +static inline void inband_set_vcpu_release_state(struct kvm_vcpu *vcpu, |
---|
| 1540 | + bool pending) |
---|
| 1541 | +{ |
---|
| 1542 | + vcpu->oob_notifier.put_vcpu = pending; |
---|
| 1543 | +} |
---|
| 1544 | +#else |
---|
| 1545 | +static inline void inband_init_vcpu(struct kvm_vcpu *vcpu, |
---|
| 1546 | + void (*preempt_handler)(struct kvm_oob_notifier *nfy)) |
---|
| 1547 | +{ } |
---|
| 1548 | + |
---|
| 1549 | +static inline void inband_enter_guest(struct kvm_vcpu *vcpu) |
---|
| 1550 | +{ } |
---|
| 1551 | + |
---|
| 1552 | +static inline void inband_exit_guest(void) |
---|
| 1553 | +{ } |
---|
| 1554 | + |
---|
| 1555 | +static inline void inband_set_vcpu_release_state(struct kvm_vcpu *vcpu, |
---|
| 1556 | + bool pending) |
---|
| 1557 | +{ } |
---|
| 1558 | +#endif |
---|
| 1559 | + |
---|
1505 | 1560 | typedef int (*kvm_vm_thread_fn_t)(struct kvm *kvm, uintptr_t data); |
---|
1506 | 1561 | |
---|
1507 | 1562 | int kvm_vm_create_worker_thread(struct kvm *kvm, kvm_vm_thread_fn_t thread_fn, |
---|