18571ed35SPaolo Bonzini /* 28571ed35SPaolo Bonzini * Internal definitions for a target's KVM support 38571ed35SPaolo Bonzini * 48571ed35SPaolo Bonzini * This work is licensed under the terms of the GNU GPL, version 2 or later. 58571ed35SPaolo Bonzini * See the COPYING file in the top-level directory. 68571ed35SPaolo Bonzini * 78571ed35SPaolo Bonzini */ 88571ed35SPaolo Bonzini 98571ed35SPaolo Bonzini #ifndef QEMU_KVM_INT_H 108571ed35SPaolo Bonzini #define QEMU_KVM_INT_H 118571ed35SPaolo Bonzini 12ec150c7eSMarkus Armbruster #include "exec/memory.h" 135f8a6bceSChenyi Qiang #include "qapi/qapi-types-common.h" 14940e43aaSClaudio Fontana #include "qemu/accel.h" 15f39b7d2bSDavid Hildenbrand #include "qemu/queue.h" 168571ed35SPaolo Bonzini #include "sysemu/kvm.h" 178571ed35SPaolo Bonzini 188571ed35SPaolo Bonzini typedef struct KVMSlot 198571ed35SPaolo Bonzini { 208571ed35SPaolo Bonzini hwaddr start_addr; 218571ed35SPaolo Bonzini ram_addr_t memory_size; 228571ed35SPaolo Bonzini void *ram; 238571ed35SPaolo Bonzini int slot; 248571ed35SPaolo Bonzini int flags; 256c090d4aSShannon Zhao int old_flags; 269f4bf4baSPeter Xu /* Dirty bitmap cache for the slot */ 279f4bf4baSPeter Xu unsigned long *dirty_bmap; 28563d32baSPeter Xu unsigned long dirty_bmap_size; 29e65e5f50SPeter Xu /* Cache of the address space ID */ 30e65e5f50SPeter Xu int as_id; 312c20b27eSPeter Xu /* Cache of the offset in ram address space */ 322c20b27eSPeter Xu ram_addr_t ram_start_offset; 338571ed35SPaolo Bonzini } KVMSlot; 348571ed35SPaolo Bonzini 35f39b7d2bSDavid Hildenbrand typedef struct KVMMemoryUpdate { 36f39b7d2bSDavid Hildenbrand QSIMPLEQ_ENTRY(KVMMemoryUpdate) next; 37f39b7d2bSDavid Hildenbrand MemoryRegionSection section; 38f39b7d2bSDavid Hildenbrand } KVMMemoryUpdate; 39f39b7d2bSDavid Hildenbrand 407bbda04cSPaolo Bonzini typedef struct KVMMemoryListener { 417bbda04cSPaolo Bonzini MemoryListener listener; 427bbda04cSPaolo Bonzini KVMSlot *slots; 43*5b23186aSDavid Hildenbrand unsigned int nr_used_slots; 4438bfe691SPaolo Bonzini int as_id; 45f39b7d2bSDavid Hildenbrand QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add; 46f39b7d2bSDavid Hildenbrand QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del; 477bbda04cSPaolo Bonzini } KVMMemoryListener; 487bbda04cSPaolo Bonzini 495f8a6bceSChenyi Qiang #define KVM_MSI_HASHTAB_SIZE 256 505f8a6bceSChenyi Qiang 515f8a6bceSChenyi Qiang enum KVMDirtyRingReaperState { 525f8a6bceSChenyi Qiang KVM_DIRTY_RING_REAPER_NONE = 0, 535f8a6bceSChenyi Qiang /* The reaper is sleeping */ 545f8a6bceSChenyi Qiang KVM_DIRTY_RING_REAPER_WAIT, 555f8a6bceSChenyi Qiang /* The reaper is reaping for dirty pages */ 565f8a6bceSChenyi Qiang KVM_DIRTY_RING_REAPER_REAPING, 575f8a6bceSChenyi Qiang }; 585f8a6bceSChenyi Qiang 595f8a6bceSChenyi Qiang /* 605f8a6bceSChenyi Qiang * KVM reaper instance, responsible for collecting the KVM dirty bits 615f8a6bceSChenyi Qiang * via the dirty ring. 625f8a6bceSChenyi Qiang */ 635f8a6bceSChenyi Qiang struct KVMDirtyRingReaper { 645f8a6bceSChenyi Qiang /* The reaper thread */ 655f8a6bceSChenyi Qiang QemuThread reaper_thr; 665f8a6bceSChenyi Qiang volatile uint64_t reaper_iteration; /* iteration number of reaper thr */ 675f8a6bceSChenyi Qiang volatile enum KVMDirtyRingReaperState reaper_state; /* reap thr state */ 685f8a6bceSChenyi Qiang }; 695f8a6bceSChenyi Qiang struct KVMState 705f8a6bceSChenyi Qiang { 715f8a6bceSChenyi Qiang AccelState parent_obj; 725f8a6bceSChenyi Qiang 735f8a6bceSChenyi Qiang int nr_slots; 745f8a6bceSChenyi Qiang int fd; 755f8a6bceSChenyi Qiang int vmfd; 765f8a6bceSChenyi Qiang int coalesced_mmio; 775f8a6bceSChenyi Qiang int coalesced_pio; 785f8a6bceSChenyi Qiang struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; 795f8a6bceSChenyi Qiang bool coalesced_flush_in_progress; 805f8a6bceSChenyi Qiang int vcpu_events; 815f8a6bceSChenyi Qiang #ifdef KVM_CAP_SET_GUEST_DEBUG 825f8a6bceSChenyi Qiang QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints; 835f8a6bceSChenyi Qiang #endif 845f8a6bceSChenyi Qiang int max_nested_state_len; 855f8a6bceSChenyi Qiang int kvm_shadow_mem; 865f8a6bceSChenyi Qiang bool kernel_irqchip_allowed; 875f8a6bceSChenyi Qiang bool kernel_irqchip_required; 885f8a6bceSChenyi Qiang OnOffAuto kernel_irqchip_split; 895f8a6bceSChenyi Qiang bool sync_mmu; 905f8a6bceSChenyi Qiang uint64_t manual_dirty_log_protect; 915f8a6bceSChenyi Qiang /* The man page (and posix) say ioctl numbers are signed int, but 925f8a6bceSChenyi Qiang * they're not. Linux, glibc and *BSD all treat ioctl numbers as 935f8a6bceSChenyi Qiang * unsigned, and treating them as signed here can break things */ 945f8a6bceSChenyi Qiang unsigned irq_set_ioctl; 955f8a6bceSChenyi Qiang unsigned int sigmask_len; 965f8a6bceSChenyi Qiang GHashTable *gsimap; 975f8a6bceSChenyi Qiang #ifdef KVM_CAP_IRQ_ROUTING 985f8a6bceSChenyi Qiang struct kvm_irq_routing *irq_routes; 995f8a6bceSChenyi Qiang int nr_allocated_irq_routes; 1005f8a6bceSChenyi Qiang unsigned long *used_gsi_bitmap; 1015f8a6bceSChenyi Qiang unsigned int gsi_count; 1025f8a6bceSChenyi Qiang #endif 1035f8a6bceSChenyi Qiang KVMMemoryListener memory_listener; 1045f8a6bceSChenyi Qiang QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; 1055f8a6bceSChenyi Qiang 1065f8a6bceSChenyi Qiang /* For "info mtree -f" to tell if an MR is registered in KVM */ 1075f8a6bceSChenyi Qiang int nr_as; 1085f8a6bceSChenyi Qiang struct KVMAs { 1095f8a6bceSChenyi Qiang KVMMemoryListener *ml; 1105f8a6bceSChenyi Qiang AddressSpace *as; 1115f8a6bceSChenyi Qiang } *as; 1125f8a6bceSChenyi Qiang uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */ 1135f8a6bceSChenyi Qiang uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */ 114b20cc776SGavin Shan bool kvm_dirty_ring_with_bitmap; 115c8f2eb5dSShameer Kolothum uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */ 1165f8a6bceSChenyi Qiang struct KVMDirtyRingReaper reaper; 1175f8a6bceSChenyi Qiang NotifyVmexitOption notify_vmexit; 1185f8a6bceSChenyi Qiang uint32_t notify_window; 11961491cf4SDavid Woodhouse uint32_t xen_version; 12061491cf4SDavid Woodhouse uint32_t xen_caps; 1216f43f2eeSDavid Woodhouse uint16_t xen_gnttab_max_frames; 122e16aff4cSDavid Woodhouse uint16_t xen_evtchn_max_pirq; 1235f8a6bceSChenyi Qiang }; 1245f8a6bceSChenyi Qiang 12538bfe691SPaolo Bonzini void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, 126142518bdSPeter Xu AddressSpace *as, int as_id, const char *name); 12738bfe691SPaolo Bonzini 128023ae9a8SIgor Mammedov void kvm_set_max_memslot_size(hwaddr max_slot_size); 1296b552b9bSDongjiu Geng 1306b552b9bSDongjiu Geng /** 1316b552b9bSDongjiu Geng * kvm_hwpoison_page_add: 1326b552b9bSDongjiu Geng * 1336b552b9bSDongjiu Geng * Parameters: 1346b552b9bSDongjiu Geng * @ram_addr: the address in the RAM for the poisoned page 1356b552b9bSDongjiu Geng * 1366b552b9bSDongjiu Geng * Add a poisoned page to the list 1376b552b9bSDongjiu Geng * 1386b552b9bSDongjiu Geng * Return: None. 1396b552b9bSDongjiu Geng */ 1406b552b9bSDongjiu Geng void kvm_hwpoison_page_add(ram_addr_t ram_addr); 1418571ed35SPaolo Bonzini #endif 142