Merge remote-tracking branch 'qemu-kvm/uq/master' into staging
# By Alexey Kardashevskiy (3) and others # Via Paolo Bonzini * qemu-kvm/uq/master: target-i386: add feature kvm_pv_unhalt linux-headers: update to 3.12-rc1 target-i386: forward CPUID cache leaves when -cpu host is used linux-headers: update to 3.11 kvm: fix traces to use %x instead of %d kvmvapic: Clear also physical ROM address when entering INACTIVE state kvmvapic: Enter inactive state on hardware reset kvmvapic: Catch invalid ROM size kvm irqfd: support direct msimessage to irq translation fix steal time MSR vmsd callback to proper opaque type kvm: warn if num cpus is greater than num recommended cpu: Move cpu state syncs up into cpu_dump_state() exec: always use MADV_DONTFORK Message-id: 1379694292-1601-1-git-send-email-pbonzini@redhat.com
This commit is contained in:
commit
3e4be9c297
1
exec.c
1
exec.c
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
@ -107,6 +108,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:
|
||||
*
|
||||
@ -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,7 +274,17 @@ 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);
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
|
||||
hwaddr *phys_addr);
|
||||
#endif
|
||||
|
||||
#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 */
|
||||
|
||||
@ -276,16 +295,6 @@ static inline void cpu_synchronize_state(CPUState *cpu)
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
|
||||
hwaddr *phys_addr);
|
||||
#endif
|
||||
|
||||
#endif /* NEED_CPU_H */
|
||||
|
||||
void kvm_cpu_synchronize_post_reset(CPUState *cpu);
|
||||
void kvm_cpu_synchronize_post_init(CPUState *cpu);
|
||||
|
||||
static inline void cpu_synchronize_post_reset(CPUState *cpu)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
|
74
kvm-all.c
74
kvm-all.c
@ -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)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Find number of supported CPUs using the recommended
|
||||
/* 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;
|
||||
}
|
||||
static int kvm_recommended_vcpus(KVMState *s)
|
||||
{
|
||||
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) {
|
||||
/* check the vcpu limits */
|
||||
soft_vcpus_limit = kvm_recommended_vcpus(s);
|
||||
hard_vcpus_limit = kvm_max_vcpus(s);
|
||||
|
||||
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 SMP cpus requested (%d) exceeds max cpus "
|
||||
"supported by KVM (%d)\n", smp_cpus, max_vcpus);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
|
168
linux-headers/asm-arm64/kvm.h
Normal file
168
linux-headers/asm-arm64/kvm.h
Normal file
@ -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__ */
|
1
linux-headers/asm-arm64/kvm_para.h
Normal file
1
linux-headers/asm-arm64/kvm_para.h
Normal file
@ -0,0 +1 @@
|
||||
#include <asm-generic/kvm_para.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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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) | \
|
||||
|
@ -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) {
|
||||
|
@ -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()
|
||||
}
|
||||
};
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user