diff options
Diffstat (limited to 'kvm-all.c')
-rw-r--r-- | kvm-all.c | 107 |
1 files changed, 58 insertions, 49 deletions
@@ -24,6 +24,7 @@ #include "qemu/atomic.h" #include "qemu/option.h" #include "qemu/config-file.h" +#include "qemu/error-report.h" #include "hw/hw.h" #include "hw/pci/msi.h" #include "hw/s390x/adapter.h" @@ -76,8 +77,6 @@ struct KVMState #ifdef KVM_CAP_SET_GUEST_DEBUG struct kvm_sw_breakpoint_head kvm_sw_breakpoints; #endif - int pit_state2; - int xsave, xcrs; int many_ioeventfds; int intx_set_mask; /* The man page (and posix) say ioctl numbers are signed int, but @@ -92,7 +91,6 @@ struct KVMState uint32_t *used_gsi_bitmap; unsigned int gsi_count; QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; - bool direct_msi; #endif KVMMemoryListener memory_listener; }; @@ -110,6 +108,8 @@ bool kvm_gsi_direct_mapping; bool kvm_allowed; bool kvm_readonly_mem_allowed; bool kvm_vm_attributes_allowed; +bool kvm_direct_msi_allowed; +bool kvm_ioeventfd_any_length_allowed; static const KVMCapabilityInfo kvm_required_capabilites[] = { KVM_CAP_INFO(USER_MEMORY), @@ -641,15 +641,15 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, /* kvm works in page size chunks, but the function may be called with sub-page size and unaligned start address. Pad the start address to next and truncate size to previous page boundary. */ - delta = (TARGET_PAGE_SIZE - (start_addr & ~TARGET_PAGE_MASK)); - delta &= ~TARGET_PAGE_MASK; + delta = qemu_real_host_page_size - (start_addr & ~qemu_real_host_page_mask); + delta &= ~qemu_real_host_page_mask; if (delta > size) { return; } start_addr += delta; size -= delta; - size &= TARGET_PAGE_MASK; - if (!size || (start_addr & ~TARGET_PAGE_MASK)) { + size &= qemu_real_host_page_mask; + if (!size || (start_addr & ~qemu_real_host_page_mask)) { return; } @@ -978,7 +978,7 @@ void kvm_init_irq_routing(KVMState *s) s->irq_routes = g_malloc0(sizeof(*s->irq_routes)); s->nr_allocated_irq_routes = 0; - if (!s->direct_msi) { + if (!kvm_direct_msi_allowed) { for (i = 0; i < KVM_MSI_HASHTAB_SIZE; i++) { QTAILQ_INIT(&s->msi_hashtab[i]); } @@ -1112,7 +1112,7 @@ static int kvm_irqchip_get_virq(KVMState *s) * number can succeed even though a new route entry cannot be added. * When this happens, flush dynamic MSI entries to free IRQ route entries. */ - if (!s->direct_msi && s->irq_routes->nr == s->gsi_count) { + if (!kvm_direct_msi_allowed && s->irq_routes->nr == s->gsi_count) { kvm_flush_dynamic_msi_routes(s); } @@ -1149,7 +1149,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg) struct kvm_msi msi; KVMMSIRoute *route; - if (s->direct_msi) { + if (kvm_direct_msi_allowed) { msi.address_lo = (uint32_t)msg.address; msi.address_hi = msg.address >> 32; msi.data = le32_to_cpu(msg.data); @@ -1188,7 +1188,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg) return kvm_set_irq(s, route->kroute.gsi, 1); } -int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) +int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev) { struct kvm_irq_routing_entry kroute = {}; int virq; @@ -1212,7 +1212,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) kroute.u.msi.address_lo = (uint32_t)msg.address; kroute.u.msi.address_hi = msg.address >> 32; kroute.u.msi.data = le32_to_cpu(msg.data); - if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) { + if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data, dev)) { kvm_irqchip_release_virq(s, virq); return -EINVAL; } @@ -1223,7 +1223,8 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) return virq; } -int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) +int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg, + PCIDevice *dev) { struct kvm_irq_routing_entry kroute = {}; @@ -1241,7 +1242,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) kroute.u.msi.address_lo = (uint32_t)msg.address; kroute.u.msi.address_hi = msg.address >> 32; kroute.u.msi.data = le32_to_cpu(msg.data); - if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) { + if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data, dev)) { return -EINVAL; } @@ -1293,7 +1294,6 @@ int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter) kroute.u.adapter.adapter_id = adapter->adapter_id; kvm_add_routing_entry(s, &kroute); - kvm_irqchip_commit_routes(s); return virq; } @@ -1462,7 +1462,6 @@ static int kvm_init(MachineState *ms) * page size for the system though. */ assert(TARGET_PAGE_SIZE <= getpagesize()); - page_size_init(); s->sigmask_len = 8; @@ -1585,20 +1584,8 @@ static int kvm_init(MachineState *ms) s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS); #endif -#ifdef KVM_CAP_XSAVE - s->xsave = kvm_check_extension(s, KVM_CAP_XSAVE); -#endif - -#ifdef KVM_CAP_XCRS - s->xcrs = kvm_check_extension(s, KVM_CAP_XCRS); -#endif - -#ifdef KVM_CAP_PIT_STATE2 - s->pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2); -#endif - #ifdef KVM_CAP_IRQ_ROUTING - s->direct_msi = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0); + kvm_direct_msi_allowed = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0); #endif s->intx_set_mask = kvm_check_extension(s, KVM_CAP_PCI_2_3); @@ -1625,6 +1612,9 @@ static int kvm_init(MachineState *ms) kvm_vm_attributes_allowed = (kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES) > 0); + kvm_ioeventfd_any_length_allowed = + (kvm_check_extension(s, KVM_CAP_IOEVENTFD_ANY_LENGTH) > 0); + ret = kvm_arch_init(ms, s); if (ret < 0) { goto err; @@ -1779,11 +1769,6 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu) run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, cpu); } -void kvm_cpu_clean_state(CPUState *cpu) -{ - cpu->kvm_vcpu_dirty = false; -} - int kvm_cpu_exec(CPUState *cpu) { struct kvm_run *run = cpu->kvm_run; @@ -1890,6 +1875,12 @@ int kvm_cpu_exec(CPUState *cpu) qemu_system_reset_request(); ret = EXCP_INTERRUPT; break; + case KVM_SYSTEM_EVENT_CRASH: + qemu_mutex_lock_iothread(); + qemu_system_guest_panicked(); + qemu_mutex_unlock_iothread(); + ret = 0; + break; default: DPRINTF("kvm_arch_handle_exit\n"); ret = kvm_arch_handle_exit(cpu, run); @@ -2003,6 +1994,39 @@ int kvm_vm_check_attr(KVMState *s, uint32_t group, uint64_t attr) return ret ? 0 : 1; } +int kvm_device_check_attr(int dev_fd, uint32_t group, uint64_t attr) +{ + struct kvm_device_attr attribute = { + .group = group, + .attr = attr, + .flags = 0, + }; + + return kvm_device_ioctl(dev_fd, KVM_HAS_DEVICE_ATTR, &attribute) ? 0 : 1; +} + +void kvm_device_access(int fd, int group, uint64_t attr, + void *val, bool write) +{ + struct kvm_device_attr kvmattr; + int err; + + kvmattr.flags = 0; + kvmattr.group = group; + kvmattr.attr = attr; + kvmattr.addr = (uintptr_t)val; + + err = kvm_device_ioctl(fd, + write ? KVM_SET_DEVICE_ATTR : KVM_GET_DEVICE_ATTR, + &kvmattr); + if (err < 0) { + error_report("KVM_%s_DEVICE_ATTR failed: %s\n" + "Group %d attr 0x%016" PRIx64, write ? "SET" : "GET", + strerror(-err), group, attr); + abort(); + } +} + int kvm_has_sync_mmu(void) { return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU); @@ -2023,21 +2047,6 @@ int kvm_has_debugregs(void) return kvm_state->debugregs; } -int kvm_has_xsave(void) -{ - return kvm_state->xsave; -} - -int kvm_has_xcrs(void) -{ - return kvm_state->xcrs; -} - -int kvm_has_pit_state2(void) -{ - return kvm_state->pit_state2; -} - int kvm_has_many_ioeventfds(void) { if (!kvm_enabled()) { |