X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=kvm-all.c;h=8222729773f2800f451b21714d77537d63d47ba2;hb=1fb147f4431759a442b024db47e9904cf0d90131;hp=fc0c6e7798c4c8b3c4460a546f3165c3bce9a31c;hpb=079944e695589364d19de31f27761c6bdea1c207;p=qemu.git diff --git a/kvm-all.c b/kvm-all.c index fc0c6e779..822272977 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -33,6 +33,7 @@ #include "exec/memory.h" #include "exec/address-spaces.h" #include "qemu/event_notifier.h" +#include "trace.h" /* This check must be after config-host.h is included */ #ifdef CONFIG_EVENTFD @@ -109,6 +110,7 @@ bool kvm_async_interrupts_allowed; bool kvm_irqfds_allowed; bool kvm_msi_via_irqfd_allowed; bool kvm_gsi_routing_allowed; +bool kvm_allowed; static const KVMCapabilityInfo kvm_required_capabilites[] = { KVM_CAP_INFO(USER_MEMORY), @@ -214,16 +216,15 @@ static void kvm_reset_vcpu(void *opaque) kvm_arch_reset_vcpu(cpu); } -int kvm_init_vcpu(CPUArchState *env) +int kvm_init_vcpu(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env); KVMState *s = kvm_state; long mmap_size; int ret; DPRINTF("kvm_init_vcpu\n"); - ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index); + ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu)); if (ret < 0) { DPRINTF("kvm_create_vcpu failed\n"); goto err; @@ -501,6 +502,66 @@ int kvm_check_extension(KVMState *s, unsigned int extension) return ret; } +static int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val, + bool assign, uint32_t size, bool datamatch) +{ + int ret; + struct kvm_ioeventfd iofd; + + iofd.datamatch = datamatch ? val : 0; + iofd.addr = addr; + iofd.len = size; + iofd.flags = 0; + iofd.fd = fd; + + if (!kvm_enabled()) { + return -ENOSYS; + } + + if (datamatch) { + iofd.flags |= KVM_IOEVENTFD_FLAG_DATAMATCH; + } + if (!assign) { + iofd.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; + } + + ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &iofd); + + if (ret < 0) { + return -errno; + } + + return 0; +} + +static int kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint16_t val, + bool assign, uint32_t size, bool datamatch) +{ + struct kvm_ioeventfd kick = { + .datamatch = datamatch ? val : 0, + .addr = addr, + .flags = KVM_IOEVENTFD_FLAG_PIO, + .len = size, + .fd = fd, + }; + int r; + if (!kvm_enabled()) { + return -ENOSYS; + } + if (datamatch) { + kick.flags |= KVM_IOEVENTFD_FLAG_DATAMATCH; + } + if (!assign) { + kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; + } + r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); + if (r < 0) { + return r; + } + return 0; +} + + static int kvm_check_many_ioeventfds(void) { /* Userspace can use ioeventfd for io notification. This requires a host @@ -518,7 +579,7 @@ static int kvm_check_many_ioeventfds(void) if (ioeventfds[i] < 0) { break; } - ret = kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, true); + ret = kvm_set_ioeventfd_pio(ioeventfds[i], 0, i, true, 2, true); if (ret < 0) { close(ioeventfds[i]); break; @@ -529,7 +590,7 @@ static int kvm_check_many_ioeventfds(void) ret = i == ARRAY_SIZE(ioeventfds); while (i-- > 0) { - kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, false); + kvm_set_ioeventfd_pio(ioeventfds[i], 0, i, false, 2, true); close(ioeventfds[i]); } return ret; @@ -749,10 +810,8 @@ static void kvm_mem_ioeventfd_add(MemoryListener *listener, int fd = event_notifier_get_fd(e); int r; - assert(match_data && section->size <= 8); - r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space, - data, true, section->size); + data, true, section->size, match_data); if (r < 0) { abort(); } @@ -767,7 +826,7 @@ static void kvm_mem_ioeventfd_del(MemoryListener *listener, int r; r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space, - data, false, section->size); + data, false, section->size, match_data); if (r < 0) { abort(); } @@ -781,10 +840,8 @@ static void kvm_io_ioeventfd_add(MemoryListener *listener, int fd = event_notifier_get_fd(e); int r; - assert(match_data && section->size == 2); - - r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space, - data, true); + r = kvm_set_ioeventfd_pio(fd, section->offset_within_address_space, + data, true, section->size, match_data); if (r < 0) { abort(); } @@ -799,8 +856,8 @@ static void kvm_io_ioeventfd_del(MemoryListener *listener, int fd = event_notifier_get_fd(e); int r; - r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space, - data, false); + r = kvm_set_ioeventfd_pio(fd, section->offset_within_address_space, + data, false, section->size, match_data); if (r < 0) { abort(); } @@ -827,11 +884,9 @@ static MemoryListener kvm_io_listener = { .priority = 10, }; -static void kvm_handle_interrupt(CPUArchState *env, int mask) +static void kvm_handle_interrupt(CPUState *cpu, int mask) { - CPUState *cpu = ENV_GET_CPU(env); - - env->interrupt_request |= mask; + cpu->interrupt_request |= mask; if (!qemu_cpu_is_self(cpu)) { qemu_cpu_kick(cpu); @@ -1182,6 +1237,11 @@ static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign) { abort(); } + +int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) +{ + return -ENOSYS; +} #endif /* !KVM_CAP_IRQ_ROUTING */ int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq) @@ -1508,18 +1568,14 @@ void kvm_cpu_synchronize_state(CPUArchState *env) } } -void kvm_cpu_synchronize_post_reset(CPUArchState *env) +void kvm_cpu_synchronize_post_reset(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env); - kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE); cpu->kvm_vcpu_dirty = false; } -void kvm_cpu_synchronize_post_init(CPUArchState *env) +void kvm_cpu_synchronize_post_init(CPUState *cpu) { - CPUState *cpu = ENV_GET_CPU(env); - kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); cpu->kvm_vcpu_dirty = false; } @@ -1533,7 +1589,7 @@ int kvm_cpu_exec(CPUArchState *env) DPRINTF("kvm_cpu_exec()\n"); if (kvm_arch_process_async_events(cpu)) { - env->exit_request = 0; + cpu->exit_request = 0; return EXCP_HLT; } @@ -1544,7 +1600,7 @@ int kvm_cpu_exec(CPUArchState *env) } kvm_arch_pre_run(cpu, run); - if (env->exit_request) { + if (cpu->exit_request) { DPRINTF("interrupt exit requested\n"); /* * KVM requires us to reenter the kernel after IO exits to complete @@ -1571,6 +1627,7 @@ int kvm_cpu_exec(CPUArchState *env) abort(); } + trace_kvm_run_exit(cpu->cpu_index, run->exit_reason); switch (run->exit_reason) { case KVM_EXIT_IO: DPRINTF("handle_io\n"); @@ -1618,7 +1675,7 @@ int kvm_cpu_exec(CPUArchState *env) vm_stop(RUN_STATE_INTERNAL_ERROR); } - env->exit_request = 0; + cpu->exit_request = 0; return ret; } @@ -1632,6 +1689,7 @@ int kvm_ioctl(KVMState *s, int type, ...) arg = va_arg(ap, void *); va_end(ap); + trace_kvm_ioctl(type, arg); ret = ioctl(s->fd, type, arg); if (ret == -1) { ret = -errno; @@ -1649,6 +1707,7 @@ int kvm_vm_ioctl(KVMState *s, int type, ...) arg = va_arg(ap, void *); va_end(ap); + trace_kvm_vm_ioctl(type, arg); ret = ioctl(s->vmfd, type, arg); if (ret == -1) { ret = -errno; @@ -1666,6 +1725,7 @@ int kvm_vcpu_ioctl(CPUState *cpu, int type, ...) arg = va_arg(ap, void *); va_end(ap); + trace_kvm_vcpu_ioctl(cpu->cpu_index, type, arg); ret = ioctl(cpu->kvm_fd, type, arg); if (ret == -1) { ret = -errno; @@ -1730,17 +1790,17 @@ int kvm_has_intx_set_mask(void) return kvm_state->intx_set_mask; } -void *kvm_vmalloc(ram_addr_t size) +void *kvm_ram_alloc(ram_addr_t size) { #ifdef TARGET_S390X void *mem; - mem = kvm_arch_vmalloc(size); + mem = kvm_arch_ram_alloc(size); if (mem) { return mem; } #endif - return qemu_vmalloc(size); + return qemu_anon_ram_alloc(size); } void kvm_setup_guest_memory(void *start, size_t size) @@ -1969,62 +2029,8 @@ int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset) return r; } - -int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val, bool assign, - uint32_t size) +int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr) { - int ret; - struct kvm_ioeventfd iofd; - - iofd.datamatch = val; - iofd.addr = addr; - iofd.len = size; - iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH; - iofd.fd = fd; - - if (!kvm_enabled()) { - return -ENOSYS; - } - - if (!assign) { - iofd.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; - } - - ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &iofd); - - if (ret < 0) { - return -errno; - } - - return 0; -} - -int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) -{ - struct kvm_ioeventfd kick = { - .datamatch = val, - .addr = addr, - .len = 2, - .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO, - .fd = fd, - }; - int r; - if (!kvm_enabled()) { - return -ENOSYS; - } - if (!assign) { - kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; - } - r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); - if (r < 0) { - return r; - } - return 0; -} - -int kvm_on_sigbus_vcpu(CPUArchState *env, int code, void *addr) -{ - CPUState *cpu = ENV_GET_CPU(env); return kvm_arch_on_sigbus_vcpu(cpu, code, addr); }