diff options
-rw-r--r-- | exec.c | 1 | ||||
-rw-r--r-- | hw/i386/kvmvapic.c | 17 | ||||
-rw-r--r-- | include/sysemu/kvm.h | 29 | ||||
-rw-r--r-- | kvm-all.c | 82 | ||||
-rw-r--r-- | kvm-stub.c | 1 | ||||
-rw-r--r-- | linux-headers/asm-arm64/kvm.h | 168 | ||||
-rw-r--r-- | linux-headers/asm-arm64/kvm_para.h | 1 | ||||
-rw-r--r-- | linux-headers/asm-mips/kvm.h | 81 | ||||
-rw-r--r-- | linux-headers/asm-x86/kvm_para.h | 1 | ||||
-rw-r--r-- | linux-headers/linux/kvm.h | 4 | ||||
-rw-r--r-- | linux-headers/linux/kvm_para.h | 1 | ||||
-rw-r--r-- | linux-headers/linux/vfio.h | 80 | ||||
-rw-r--r-- | linux-headers/linux/virtio_config.h | 3 | ||||
-rw-r--r-- | qom/cpu.c | 1 | ||||
-rw-r--r-- | target-i386/cpu-qom.h | 3 | ||||
-rw-r--r-- | target-i386/cpu.c | 21 | ||||
-rw-r--r-- | target-i386/helper.c | 2 | ||||
-rw-r--r-- | target-i386/machine.c | 6 | ||||
-rw-r--r-- | target-ppc/translate.c | 2 | ||||
-rw-r--r-- | trace-events | 6 |
20 files changed, 411 insertions, 99 deletions
@@ -1184,6 +1184,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, qemu_ram_setup_dump(new_block->host, size); qemu_madvise(new_block->host, size, QEMU_MADV_HUGEPAGE); + qemu_madvise(new_block->host, size, QEMU_MADV_DONTFORK); if (kvm_enabled()) kvm_setup_guest_memory(new_block->host, size); diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index d3a6fbe..1c2dbf5 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -510,9 +510,8 @@ static void vapic_reset(DeviceState *dev) { VAPICROMState *s = VAPIC(dev); - if (s->state == VAPIC_ACTIVE) { - s->state = VAPIC_STANDBY; - } + s->state = VAPIC_INACTIVE; + s->rom_state_paddr = 0; vapic_enable_tpr_reporting(false); } @@ -578,7 +577,7 @@ static int patch_hypercalls(VAPICROMState *s) * enable write access to the option ROM so that variables can be updated by * the guest. */ -static void vapic_map_rom_writable(VAPICROMState *s) +static int vapic_map_rom_writable(VAPICROMState *s) { hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK; MemoryRegionSection section; @@ -599,6 +598,9 @@ static void vapic_map_rom_writable(VAPICROMState *s) /* read ROM size from RAM region */ ram = memory_region_get_ram_ptr(section.mr); rom_size = ram[rom_paddr + 2] * ROM_BLOCK_SIZE; + if (rom_size == 0) { + return -1; + } s->rom_size = rom_size; /* We need to round to avoid creating subpages @@ -612,11 +614,15 @@ static void vapic_map_rom_writable(VAPICROMState *s) memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000); s->rom_mapped_writable = true; memory_region_unref(section.mr); + + return 0; } static int vapic_prepare(VAPICROMState *s) { - vapic_map_rom_writable(s); + if (vapic_map_rom_writable(s) < 0) { + return -1; + } if (patch_hypercalls(s) < 0) { return -1; @@ -659,6 +665,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data, } if (vapic_prepare(s) < 0) { s->state = VAPIC_INACTIVE; + s->rom_state_paddr = 0; break; } break; diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 9bbe3db..3b25f27 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -46,6 +46,7 @@ extern bool kvm_halt_in_kernel_allowed; extern bool kvm_irqfds_allowed; extern bool kvm_msi_via_irqfd_allowed; extern bool kvm_gsi_routing_allowed; +extern bool kvm_gsi_direct_mapping; extern bool kvm_readonly_mem_allowed; #if defined CONFIG_KVM || !defined NEED_CPU_H @@ -108,6 +109,13 @@ extern bool kvm_readonly_mem_allowed; #define kvm_gsi_routing_enabled() (kvm_gsi_routing_allowed) /** + * kvm_gsi_direct_mapping: + * + * Returns: true if GSI direct mapping is enabled. + */ +#define kvm_gsi_direct_mapping() (kvm_gsi_direct_mapping) + +/** * kvm_readonly_mem_enabled: * * Returns: true if KVM readonly memory is enabled (ie the kernel @@ -123,6 +131,7 @@ extern bool kvm_readonly_mem_allowed; #define kvm_irqfds_enabled() (false) #define kvm_msi_via_irqfd_enabled() (false) #define kvm_gsi_routing_allowed() (false) +#define kvm_gsi_direct_mapping() (false) #define kvm_readonly_mem_enabled() (false) #endif @@ -265,16 +274,6 @@ int kvm_check_extension(KVMState *s, unsigned int extension); uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function, uint32_t index, int reg); -void kvm_cpu_synchronize_state(CPUState *cpu); - -/* generic hooks - to be moved/refactored once there are more users */ - -static inline void cpu_synchronize_state(CPUState *cpu) -{ - if (kvm_enabled()) { - kvm_cpu_synchronize_state(cpu); - } -} #if !defined(CONFIG_USER_ONLY) int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr, @@ -283,9 +282,19 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr, #endif /* NEED_CPU_H */ +void kvm_cpu_synchronize_state(CPUState *cpu); void kvm_cpu_synchronize_post_reset(CPUState *cpu); void kvm_cpu_synchronize_post_init(CPUState *cpu); +/* generic hooks - to be moved/refactored once there are more users */ + +static inline void cpu_synchronize_state(CPUState *cpu) +{ + if (kvm_enabled()) { + kvm_cpu_synchronize_state(cpu); + } +} + static inline void cpu_synchronize_post_reset(CPUState *cpu) { if (kvm_enabled()) { @@ -111,6 +111,7 @@ bool kvm_halt_in_kernel_allowed; bool kvm_irqfds_allowed; bool kvm_msi_via_irqfd_allowed; bool kvm_gsi_routing_allowed; +bool kvm_gsi_direct_mapping; bool kvm_allowed; bool kvm_readonly_mem_allowed; @@ -1069,6 +1070,10 @@ void kvm_irqchip_release_virq(KVMState *s, int virq) struct kvm_irq_routing_entry *e; int i; + if (kvm_gsi_direct_mapping()) { + return; + } + for (i = 0; i < s->irq_routes->nr; i++) { e = &s->irq_routes->entries[i]; if (e->gsi == virq) { @@ -1190,6 +1195,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) struct kvm_irq_routing_entry kroute = {}; int virq; + if (kvm_gsi_direct_mapping()) { + return msg.data & 0xffff; + } + if (!kvm_gsi_routing_enabled()) { return -ENOSYS; } @@ -1216,6 +1225,10 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) { struct kvm_irq_routing_entry kroute = {}; + if (kvm_gsi_direct_mapping()) { + return 0; + } + if (!kvm_irqchip_in_kernel()) { return -ENOSYS; } @@ -1322,24 +1335,20 @@ static int kvm_irqchip_create(KVMState *s) return 0; } -static int kvm_max_vcpus(KVMState *s) +/* Find number of supported CPUs using the recommended + * procedure from the kernel API documentation to cope with + * older kernels that may be missing capabilities. + */ +static int kvm_recommended_vcpus(KVMState *s) { - int ret; - - /* Find number of supported CPUs using the recommended - * procedure from the kernel API documentation to cope with - * older kernels that may be missing capabilities. - */ - ret = kvm_check_extension(s, KVM_CAP_MAX_VCPUS); - if (ret) { - return ret; - } - ret = kvm_check_extension(s, KVM_CAP_NR_VCPUS); - if (ret) { - return ret; - } + int ret = kvm_check_extension(s, KVM_CAP_NR_VCPUS); + return (ret) ? ret : 4; +} - return 4; +static int kvm_max_vcpus(KVMState *s) +{ + int ret = kvm_check_extension(s, KVM_CAP_MAX_VCPUS); + return (ret) ? ret : kvm_recommended_vcpus(s); } int kvm_init(void) @@ -1347,11 +1356,19 @@ int kvm_init(void) static const char upgrade_note[] = "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n" "(see http://sourceforge.net/projects/kvm).\n"; + struct { + const char *name; + int num; + } num_cpus[] = { + { "SMP", smp_cpus }, + { "hotpluggable", max_cpus }, + { NULL, } + }, *nc = num_cpus; + int soft_vcpus_limit, hard_vcpus_limit; KVMState *s; const KVMCapabilityInfo *missing_cap; int ret; int i; - int max_vcpus; s = g_malloc0(sizeof(KVMState)); @@ -1392,19 +1409,26 @@ int kvm_init(void) goto err; } - max_vcpus = kvm_max_vcpus(s); - if (smp_cpus > max_vcpus) { - ret = -EINVAL; - fprintf(stderr, "Number of SMP cpus requested (%d) exceeds max cpus " - "supported by KVM (%d)\n", smp_cpus, max_vcpus); - goto err; - } + /* check the vcpu limits */ + soft_vcpus_limit = kvm_recommended_vcpus(s); + hard_vcpus_limit = kvm_max_vcpus(s); - if (max_cpus > max_vcpus) { - ret = -EINVAL; - fprintf(stderr, "Number of hotpluggable cpus requested (%d) exceeds max cpus " - "supported by KVM (%d)\n", max_cpus, max_vcpus); - goto err; + while (nc->name) { + if (nc->num > soft_vcpus_limit) { + fprintf(stderr, + "Warning: Number of %s cpus requested (%d) exceeds " + "the recommended cpus supported by KVM (%d)\n", + nc->name, nc->num, soft_vcpus_limit); + + if (nc->num > hard_vcpus_limit) { + ret = -EINVAL; + fprintf(stderr, "Number of %s cpus requested (%d) exceeds " + "the maximum cpus supported by KVM (%d)\n", + nc->name, nc->num, hard_vcpus_limit); + goto err; + } + } + nc++; } s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0); @@ -25,6 +25,7 @@ bool kvm_async_interrupts_allowed; bool kvm_irqfds_allowed; bool kvm_msi_via_irqfd_allowed; bool kvm_gsi_routing_allowed; +bool kvm_gsi_direct_mapping; bool kvm_allowed; bool kvm_readonly_mem_allowed; diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h new file mode 100644 index 0000000..5031f42 --- /dev/null +++ b/linux-headers/asm-arm64/kvm.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2012,2013 - ARM Ltd + * Author: Marc Zyngier <marc.zyngier@arm.com> + * + * Derived from arch/arm/include/uapi/asm/kvm.h: + * Copyright (C) 2012 - Virtual Open Systems and Columbia University + * Author: Christoffer Dall <c.dall@virtualopensystems.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __ARM_KVM_H__ +#define __ARM_KVM_H__ + +#define KVM_SPSR_EL1 0 +#define KVM_SPSR_SVC KVM_SPSR_EL1 +#define KVM_SPSR_ABT 1 +#define KVM_SPSR_UND 2 +#define KVM_SPSR_IRQ 3 +#define KVM_SPSR_FIQ 4 +#define KVM_NR_SPSR 5 + +#ifndef __ASSEMBLY__ +#include <asm/types.h> +#include <asm/ptrace.h> + +#define __KVM_HAVE_GUEST_DEBUG +#define __KVM_HAVE_IRQ_LINE + +#define KVM_REG_SIZE(id) \ + (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT)) + +struct kvm_regs { + struct user_pt_regs regs; /* sp = sp_el0 */ + + __u64 sp_el1; + __u64 elr_el1; + + __u64 spsr[KVM_NR_SPSR]; + + struct user_fpsimd_state fp_regs; +}; + +/* Supported Processor Types */ +#define KVM_ARM_TARGET_AEM_V8 0 +#define KVM_ARM_TARGET_FOUNDATION_V8 1 +#define KVM_ARM_TARGET_CORTEX_A57 2 + +#define KVM_ARM_NUM_TARGETS 3 + +/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */ +#define KVM_ARM_DEVICE_TYPE_SHIFT 0 +#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT) +#define KVM_ARM_DEVICE_ID_SHIFT 16 +#define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT) + +/* Supported device IDs */ +#define KVM_ARM_DEVICE_VGIC_V2 0 + +/* Supported VGIC address types */ +#define KVM_VGIC_V2_ADDR_TYPE_DIST 0 +#define KVM_VGIC_V2_ADDR_TYPE_CPU 1 + +#define KVM_VGIC_V2_DIST_SIZE 0x1000 +#define KVM_VGIC_V2_CPU_SIZE 0x2000 + +#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ +#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */ + +struct kvm_vcpu_init { + __u32 target; + __u32 features[7]; +}; + +struct kvm_sregs { +}; + +struct kvm_fpu { +}; + +struct kvm_guest_debug_arch { +}; + +struct kvm_debug_exit_arch { +}; + +struct kvm_sync_regs { +}; + +struct kvm_arch_memory_slot { +}; + +/* If you need to interpret the index values, here is the key: */ +#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000 +#define KVM_REG_ARM_COPROC_SHIFT 16 + +/* Normal registers are mapped as coprocessor 16. */ +#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / sizeof(__u32)) + +/* Some registers need more space to represent values. */ +#define KVM_REG_ARM_DEMUX (0x0011 << KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM_DEMUX_ID_MASK 0x000000000000FF00 +#define KVM_REG_ARM_DEMUX_ID_SHIFT 8 +#define KVM_REG_ARM_DEMUX_ID_CCSIDR (0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT) +#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00000000000000FF +#define KVM_REG_ARM_DEMUX_VAL_SHIFT 0 + +/* AArch64 system registers */ +#define KVM_REG_ARM64_SYSREG (0x0013 << KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM64_SYSREG_OP0_MASK 0x000000000000c000 +#define KVM_REG_ARM64_SYSREG_OP0_SHIFT 14 +#define KVM_REG_ARM64_SYSREG_OP1_MASK 0x0000000000003800 +#define KVM_REG_ARM64_SYSREG_OP1_SHIFT 11 +#define KVM_REG_ARM64_SYSREG_CRN_MASK 0x0000000000000780 +#define KVM_REG_ARM64_SYSREG_CRN_SHIFT 7 +#define KVM_REG_ARM64_SYSREG_CRM_MASK 0x0000000000000078 +#define KVM_REG_ARM64_SYSREG_CRM_SHIFT 3 +#define KVM_REG_ARM64_SYSREG_OP2_MASK 0x0000000000000007 +#define KVM_REG_ARM64_SYSREG_OP2_SHIFT 0 + +/* KVM_IRQ_LINE irq field index values */ +#define KVM_ARM_IRQ_TYPE_SHIFT 24 +#define KVM_ARM_IRQ_TYPE_MASK 0xff +#define KVM_ARM_IRQ_VCPU_SHIFT 16 +#define KVM_ARM_IRQ_VCPU_MASK 0xff +#define KVM_ARM_IRQ_NUM_SHIFT 0 +#define KVM_ARM_IRQ_NUM_MASK 0xffff + +/* irq_type field */ +#define KVM_ARM_IRQ_TYPE_CPU 0 +#define KVM_ARM_IRQ_TYPE_SPI 1 +#define KVM_ARM_IRQ_TYPE_PPI 2 + +/* out-of-kernel GIC cpu interrupt injection irq_number field */ +#define KVM_ARM_IRQ_CPU_IRQ 0 +#define KVM_ARM_IRQ_CPU_FIQ 1 + +/* Highest supported SPI, from VGIC_NR_IRQS */ +#define KVM_ARM_IRQ_GIC_MAX 127 + +/* PSCI interface */ +#define KVM_PSCI_FN_BASE 0x95c1ba5e +#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) + +#define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0) +#define KVM_PSCI_FN_CPU_OFF KVM_PSCI_FN(1) +#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2) +#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3) + +#define KVM_PSCI_RET_SUCCESS 0 +#define KVM_PSCI_RET_NI ((unsigned long)-1) +#define KVM_PSCI_RET_INVAL ((unsigned long)-2) +#define KVM_PSCI_RET_DENIED ((unsigned long)-3) + +#endif + +#endif /* __ARM_KVM_H__ */ diff --git a/linux-headers/asm-arm64/kvm_para.h b/linux-headers/asm-arm64/kvm_para.h new file mode 100644 index 0000000..14fab8f --- /dev/null +++ b/linux-headers/asm-arm64/kvm_para.h @@ -0,0 +1 @@ +#include <asm-generic/kvm_para.h> diff --git a/linux-headers/asm-mips/kvm.h b/linux-headers/asm-mips/kvm.h index 3f424f5..f09ff5a 100644 --- a/linux-headers/asm-mips/kvm.h +++ b/linux-headers/asm-mips/kvm.h @@ -58,56 +58,53 @@ struct kvm_fpu { * bits[2..0] - Register 'sel' index. * bits[7..3] - Register 'rd' index. * bits[15..8] - Must be zero. - * bits[63..16] - 1 -> CP0 registers. + * bits[31..16] - 1 -> CP0 registers. + * bits[51..32] - Must be zero. + * bits[63..52] - As per linux/kvm.h * * Other sets registers may be added in the future. Each set would - * have its own identifier in bits[63..16]. - * - * The addr field of struct kvm_one_reg must point to an aligned - * 64-bit wide location. For registers that are narrower than - * 64-bits, the value is stored in the low order bits of the location, - * and sign extended to 64-bits. + * have its own identifier in bits[31..16]. * * The registers defined in struct kvm_regs are also accessible, the * id values for these are below. */ -#define KVM_REG_MIPS_R0 0 -#define KVM_REG_MIPS_R1 1 -#define KVM_REG_MIPS_R2 2 -#define KVM_REG_MIPS_R3 3 -#define KVM_REG_MIPS_R4 4 -#define KVM_REG_MIPS_R5 5 -#define KVM_REG_MIPS_R6 6 -#define KVM_REG_MIPS_R7 7 -#define KVM_REG_MIPS_R8 8 -#define KVM_REG_MIPS_R9 9 -#define KVM_REG_MIPS_R10 10 -#define KVM_REG_MIPS_R11 11 -#define KVM_REG_MIPS_R12 12 -#define KVM_REG_MIPS_R13 13 -#define KVM_REG_MIPS_R14 14 -#define KVM_REG_MIPS_R15 15 -#define KVM_REG_MIPS_R16 16 -#define KVM_REG_MIPS_R17 17 -#define KVM_REG_MIPS_R18 18 -#define KVM_REG_MIPS_R19 19 -#define KVM_REG_MIPS_R20 20 -#define KVM_REG_MIPS_R21 21 -#define KVM_REG_MIPS_R22 22 -#define KVM_REG_MIPS_R23 23 -#define KVM_REG_MIPS_R24 24 -#define KVM_REG_MIPS_R25 25 -#define KVM_REG_MIPS_R26 26 -#define KVM_REG_MIPS_R27 27 -#define KVM_REG_MIPS_R28 28 -#define KVM_REG_MIPS_R29 29 -#define KVM_REG_MIPS_R30 30 -#define KVM_REG_MIPS_R31 31 +#define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0) +#define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1) +#define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2) +#define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3) +#define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4) +#define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5) +#define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6) +#define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7) +#define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8) +#define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9) +#define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10) +#define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11) +#define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12) +#define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13) +#define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14) +#define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15) +#define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16) +#define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17) +#define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18) +#define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19) +#define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20) +#define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21) +#define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22) +#define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23) +#define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24) +#define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25) +#define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26) +#define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27) +#define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28) +#define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 29) +#define KVM_REG_MIPS_R30 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 30) +#define KVM_REG_MIPS_R31 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 31) -#define KVM_REG_MIPS_HI 32 -#define KVM_REG_MIPS_LO 33 -#define KVM_REG_MIPS_PC 34 +#define KVM_REG_MIPS_HI (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 32) +#define KVM_REG_MIPS_LO (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 33) +#define KVM_REG_MIPS_PC (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 34) /* * KVM MIPS specific structures and definitions diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index a1c3d72..e41c5c1 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -23,6 +23,7 @@ #define KVM_FEATURE_ASYNC_PF 4 #define KVM_FEATURE_STEAL_TIME 5 #define KVM_FEATURE_PV_EOI 6 +#define KVM_FEATURE_PV_UNHALT 7 /* The last 8 bits are used to indicate how to interpret the flags field * in pvclock structure. If no bits are set, all flags are ignored. diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index c614070..13e890c 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -666,6 +666,8 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_IRQ_MPIC 90 #define KVM_CAP_PPC_RTAS 91 #define KVM_CAP_IRQ_XICS 92 +#define KVM_CAP_ARM_EL1_32BIT 93 +#define KVM_CAP_SPAPR_MULTITCE 94 #ifdef KVM_CAP_IRQ_ROUTING @@ -783,6 +785,8 @@ struct kvm_dirty_tlb { #define KVM_REG_IA64 0x3000000000000000ULL #define KVM_REG_ARM 0x4000000000000000ULL #define KVM_REG_S390 0x5000000000000000ULL +#define KVM_REG_ARM64 0x6000000000000000ULL +#define KVM_REG_MIPS 0x7000000000000000ULL #define KVM_REG_SIZE_SHIFT 52 #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index 7bdcf93..2dff783 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -19,6 +19,7 @@ #define KVM_HC_MMU_OP 2 #define KVM_HC_FEATURES 3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +#define KVM_HC_KICK_CPU 5 /* * hypercalls use architecture specific diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h index 7ec1864..17c58e0 100644 --- a/linux-headers/linux/vfio.h +++ b/linux-headers/linux/vfio.h @@ -22,6 +22,7 @@ /* Extensions */ #define VFIO_TYPE1_IOMMU 1 +#define VFIO_SPAPR_TCE_IOMMU 2 /* * The IOCTL interface is designed for extensibility by embedding the @@ -323,6 +324,44 @@ enum { VFIO_PCI_NUM_IRQS }; +/** + * VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IORW(VFIO_TYPE, VFIO_BASE + 12, + * struct vfio_pci_hot_reset_info) + * + * Return: 0 on success, -errno on failure: + * -enospc = insufficient buffer, -enodev = unsupported for device. + */ +struct vfio_pci_dependent_device { + __u32 group_id; + __u16 segment; + __u8 bus; + __u8 devfn; /* Use PCI_SLOT/PCI_FUNC */ +}; + +struct vfio_pci_hot_reset_info { + __u32 argsz; + __u32 flags; + __u32 count; + struct vfio_pci_dependent_device devices[]; +}; + +#define VFIO_DEVICE_GET_PCI_HOT_RESET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12) + +/** + * VFIO_DEVICE_PCI_HOT_RESET - _IOW(VFIO_TYPE, VFIO_BASE + 13, + * struct vfio_pci_hot_reset) + * + * Return: 0 on success, -errno on failure. + */ +struct vfio_pci_hot_reset { + __u32 argsz; + __u32 flags; + __u32 count; + __s32 group_fds[]; +}; + +#define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13) + /* -------- API for Type1 VFIO IOMMU -------- */ /** @@ -361,10 +400,14 @@ struct vfio_iommu_type1_dma_map { #define VFIO_IOMMU_MAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 13) /** - * VFIO_IOMMU_UNMAP_DMA - _IOW(VFIO_TYPE, VFIO_BASE + 14, struct vfio_dma_unmap) + * VFIO_IOMMU_UNMAP_DMA - _IOWR(VFIO_TYPE, VFIO_BASE + 14, + * struct vfio_dma_unmap) * * Unmap IO virtual addresses using the provided struct vfio_dma_unmap. - * Caller sets argsz. + * Caller sets argsz. The actual unmapped size is returned in the size + * field. No guarantee is made to the user that arbitrary unmaps of iova + * or size different from those used in the original mapping call will + * succeed. */ struct vfio_iommu_type1_dma_unmap { __u32 argsz; @@ -375,4 +418,37 @@ struct vfio_iommu_type1_dma_unmap { #define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14) +/* + * IOCTLs to enable/disable IOMMU container usage. + * No parameters are supported. + */ +#define VFIO_IOMMU_ENABLE _IO(VFIO_TYPE, VFIO_BASE + 15) +#define VFIO_IOMMU_DISABLE _IO(VFIO_TYPE, VFIO_BASE + 16) + +/* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */ + +/* + * The SPAPR TCE info struct provides the information about the PCI bus + * address ranges available for DMA, these values are programmed into + * the hardware so the guest has to know that information. + * + * The DMA 32 bit window start is an absolute PCI bus address. + * The IOVA address passed via map/unmap ioctls are absolute PCI bus + * addresses too so the window works as a filter rather than an offset + * for IOVA addresses. + * + * A flag will need to be added if other page sizes are supported, + * so as defined here, it is always 4k. + */ +struct vfio_iommu_spapr_tce_info { + __u32 argsz; + __u32 flags; /* reserved for future use */ + __u32 dma32_window_start; /* 32 bit window start (bytes) */ + __u32 dma32_window_size; /* 32 bit window size (bytes) */ +}; + +#define VFIO_IOMMU_SPAPR_TCE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12) + +/* ***************************************************************** */ + #endif /* VFIO_H */ diff --git a/linux-headers/linux/virtio_config.h b/linux-headers/linux/virtio_config.h index 4f51d8f..75dc20b 100644 --- a/linux-headers/linux/virtio_config.h +++ b/linux-headers/linux/virtio_config.h @@ -51,4 +51,7 @@ * suppressed them? */ #define VIRTIO_F_NOTIFY_ON_EMPTY 24 +/* Can the device handle any descriptor layout? */ +#define VIRTIO_F_ANY_LAYOUT 27 + #endif /* _LINUX_VIRTIO_CONFIG_H */ @@ -162,6 +162,7 @@ void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, CPUClass *cc = CPU_GET_CLASS(cpu); if (cc->dump_state) { + cpu_synchronize_state(cpu); cc->dump_state(cpu, f, cpu_fprintf, flags); } } diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index c4447c2..f4fab15 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -70,6 +70,9 @@ typedef struct X86CPU { bool hyperv_relaxed_timing; int hyperv_spinlock_attempts; + /* if true the CPUID code directly forward host cache leaves to the guest */ + bool cache_info_passthrough; + /* Features that were filtered out because of missing host capabilities */ uint32_t filtered_features[FEATURE_WORDS]; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index c36345e..b682802 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -235,7 +235,7 @@ static const char *ext4_feature_name[] = { static const char *kvm_feature_name[] = { "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", - "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", NULL, + "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", "kvm_pv_unhalt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -486,6 +486,7 @@ typedef struct x86_def_t { int stepping; FeatureWordArray features; char model_id[48]; + bool cache_info_passthrough; } x86_def_t; #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) @@ -1139,6 +1140,7 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) assert(kvm_enabled()); x86_cpu_def->name = "host"; + x86_cpu_def->cache_info_passthrough = true; host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx); x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx); @@ -1888,6 +1890,7 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp) env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX]; env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX]; env->cpuid_xlevel2 = def->xlevel2; + cpu->cache_info_passthrough = def->cache_info_passthrough; object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp); } @@ -2062,6 +2065,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; case 2: /* cache info: needed for Pentium Pro compatibility */ + if (cpu->cache_info_passthrough) { + host_cpuid(index, 0, eax, ebx, ecx, edx); + break; + } *eax = 1; /* Number of CPUID[EAX=2] calls required */ *ebx = 0; *ecx = 0; @@ -2071,6 +2078,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; case 4: /* cache info: needed for Core compatibility */ + if (cpu->cache_info_passthrough) { + host_cpuid(index, count, eax, ebx, ecx, edx); + break; + } if (cs->nr_cores > 1) { *eax = (cs->nr_cores - 1) << 26; } else { @@ -2228,6 +2239,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; case 0x80000005: /* cache info (L1 cache) */ + if (cpu->cache_info_passthrough) { + host_cpuid(index, 0, eax, ebx, ecx, edx); + break; + } *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \ (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES); *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \ @@ -2239,6 +2254,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; case 0x80000006: /* cache info (L2 cache) */ + if (cpu->cache_info_passthrough) { + host_cpuid(index, 0, eax, ebx, ecx, edx); + break; + } *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \ (L2_DTLB_2M_ENTRIES << 16) | \ (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \ diff --git a/target-i386/helper.c b/target-i386/helper.c index 8bf85ec..678503a 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -188,8 +188,6 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, char cc_op_name[32]; static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" }; - cpu_synchronize_state(cs); - eflags = cpu_compute_eflags(env); #ifdef TARGET_X86_64 if (env->hflags & HF_CS64_MASK) { diff --git a/target-i386/machine.c b/target-i386/machine.c index dc81cde..e568da2 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -330,9 +330,9 @@ static bool pv_eoi_msr_needed(void *opaque) static bool steal_time_msr_needed(void *opaque) { - CPUX86State *cpu = opaque; + X86CPU *cpu = opaque; - return cpu->steal_time_msr != 0; + return cpu->env.steal_time_msr != 0; } static const VMStateDescription vmstate_steal_time_msr = { @@ -341,7 +341,7 @@ static const VMStateDescription vmstate_steal_time_msr = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField []) { - VMSTATE_UINT64(steal_time_msr, CPUX86State), + VMSTATE_UINT64(env.steal_time_msr, X86CPU), VMSTATE_END_OF_LIST() } }; diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 2da7bc7..9c59f69 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -9536,8 +9536,6 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env = &cpu->env; int i; - cpu_synchronize_state(cs); - cpu_fprintf(f, "NIP " TARGET_FMT_lx " LR " TARGET_FMT_lx " CTR " TARGET_FMT_lx " XER " TARGET_FMT_lx "\n", env->nip, env->lr, env->ctr, cpu_read_xer(env)); diff --git a/trace-events b/trace-events index d4dba24..6bbceaf 100644 --- a/trace-events +++ b/trace-events @@ -1167,9 +1167,9 @@ virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char *dev migrate_set_state(int new_state) "new state %d" # kvm-all.c -kvm_ioctl(int type, void *arg) "type %d, arg %p" -kvm_vm_ioctl(int type, void *arg) "type %d, arg %p" -kvm_vcpu_ioctl(int cpu_index, int type, void *arg) "cpu_index %d, type %d, arg %p" +kvm_ioctl(int type, void *arg) "type 0x%x, arg %p" +kvm_vm_ioctl(int type, void *arg) "type 0x%x, arg %p" +kvm_vcpu_ioctl(int cpu_index, int type, void *arg) "cpu_index %d, type 0x%x, arg %p" kvm_run_exit(int cpu_index, uint32_t reason) "cpu_index %d, reason %d" # memory.c |