From ada4135f84adcacd9294269e22113460650ae1ab Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 9 May 2014 10:06:46 +0200 Subject: kvm: make one_reg helpers available for everyone s390x introduced helper functions for getting/setting one_regs with commit 860643bc. However, nothing about these is s390-specific. Alexey Kardashevskiy had already posted a general version, so let's merge the two patches and massage the code a bit. CC: Alexey Kardashevskiy Signed-off-by: Cornelia Huck Signed-off-by: Paolo Bonzini --- include/sysemu/kvm.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include') diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 5ad4e0e1e2..a6c2823352 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -383,4 +383,24 @@ void kvm_init_irq_routing(KVMState *s); * > 0: irq chip was created */ int kvm_arch_irqchip_create(KVMState *s); + +/** + * kvm_set_one_reg - set a register value in KVM via KVM_SET_ONE_REG ioctl + * @id: The register ID + * @source: The pointer to the value to be set. It must point to a variable + * of the correct type/size for the register being accessed. + * + * Returns: 0 on success, or a negative errno on failure. + */ +int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source); + +/** + * kvm_get_one_reg - get a register value from KVM via KVM_GET_ONE_REG ioctl + * @id: The register ID + * @target: The pointer where the value is to be stored. It must point to a + * variable of the correct type/size for the register being accessed. + * + * Returns: 0 on success, or a negative errno on failure. + */ +int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target); #endif -- cgit v1.2.3-55-g7522 From 50a2c6e55fa2ce5a2916a2c206bad2c6b0e06df1 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 Mar 2013 13:11:56 +0100 Subject: kvm: reset state from the CPU's reset method Now that we have a CPU object with a reset method, it is better to keep the KVM reset close to the CPU reset. Using qemu_register_reset as we do now keeps them far apart. With this patch, PPC no longer calls the kvm_arch_ function, so it can get removed there. Other arches call it from their CPU reset handler, and the function gets an ARMCPU/X86CPU/S390CPU. Note that ARM- and s390-specific functions are called kvm_arm_* and kvm_s390_*, while x86-specific functions are called kvm_arch_*. That follows the convention used by the different architectures. Changing that is the topic of a separate patch. Reviewed-by: Gleb Natapov Reviewed-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- include/sysemu/kvm.h | 2 -- kvm-all.c | 11 ----------- target-arm/cpu.c | 7 +++++++ target-arm/kvm32.c | 4 +--- target-arm/kvm64.c | 2 +- target-arm/kvm_arm.h | 8 ++++++++ target-i386/cpu.c | 5 +++++ target-i386/kvm.c | 3 +-- target-i386/kvm_i386.h | 1 + target-ppc/kvm.c | 4 ---- target-s390x/cpu.c | 4 ++++ target-s390x/cpu.h | 5 +++++ target-s390x/kvm.c | 6 ++++-- 13 files changed, 37 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index a6c2823352..e7ad9d159a 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -245,8 +245,6 @@ int kvm_arch_init_vcpu(CPUState *cpu); /* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */ unsigned long kvm_arch_vcpu_id(CPUState *cpu); -void kvm_arch_reset_vcpu(CPUState *cpu); - int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr); int kvm_arch_on_sigbus(int code, void *addr); diff --git a/kvm-all.c b/kvm-all.c index 94520e5915..a343ede4d4 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -223,13 +223,6 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot) return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); } -static void kvm_reset_vcpu(void *opaque) -{ - CPUState *cpu = opaque; - - kvm_arch_reset_vcpu(cpu); -} - int kvm_init_vcpu(CPUState *cpu) { KVMState *s = kvm_state; @@ -269,10 +262,6 @@ int kvm_init_vcpu(CPUState *cpu) } ret = kvm_arch_init_vcpu(cpu); - if (ret == 0) { - qemu_register_reset(kvm_reset_vcpu, cpu); - kvm_arch_reset_vcpu(cpu); - } err: return ret; } diff --git a/target-arm/cpu.c b/target-arm/cpu.c index c0ddc3e3df..6c6f2b3d46 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -29,6 +29,7 @@ #include "hw/arm/arm.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" +#include "kvm_arm.h" static void arm_cpu_set_pc(CPUState *cs, vaddr value) { @@ -165,6 +166,12 @@ static void arm_cpu_reset(CPUState *s) * tb_flush(). */ tb_flush(env); + +#ifndef CONFIG_USER_ONLY + if (kvm_enabled()) { + kvm_arm_reset_vcpu(cpu); + } +#endif } #ifndef CONFIG_USER_ONLY diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c index a690d9935f..b79750c57e 100644 --- a/target-arm/kvm32.c +++ b/target-arm/kvm32.c @@ -510,11 +510,9 @@ int kvm_arch_get_registers(CPUState *cs) return 0; } -void kvm_arch_reset_vcpu(CPUState *cs) +void kvm_arm_reset_vcpu(ARMCPU *cpu) { /* Feed the kernel back its initial register state */ - ARMCPU *cpu = ARM_CPU(cs); - memmove(cpu->cpreg_values, cpu->cpreg_reset_values, cpu->cpreg_array_len * sizeof(cpu->cpreg_values[0])); diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c index e115879d9a..c729b9ec9f 100644 --- a/target-arm/kvm64.c +++ b/target-arm/kvm64.c @@ -260,6 +260,6 @@ int kvm_arch_get_registers(CPUState *cs) return ret; } -void kvm_arch_reset_vcpu(CPUState *cs) +void kvm_arm_reset_vcpu(ARMCPU *cpu) { } diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h index 137c5671e9..dc4e2336fa 100644 --- a/target-arm/kvm_arm.h +++ b/target-arm/kvm_arm.h @@ -67,6 +67,14 @@ bool write_list_to_kvmstate(ARMCPU *cpu); */ bool write_kvmstate_to_list(ARMCPU *cpu); +/** + * kvm_arm_reset_vcpu: + * @cpu: ARMCPU + * + * Called at reset time to kernel registers to their initial values. + */ +void kvm_arm_reset_vcpu(ARMCPU *cpu); + #ifdef CONFIG_KVM /** * kvm_arm_create_scratch_host_vcpu: diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 8f193a9330..c04aed929f 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -24,6 +24,7 @@ #include "cpu.h" #include "sysemu/kvm.h" #include "sysemu/cpus.h" +#include "kvm_i386.h" #include "topology.h" #include "qemu/option.h" @@ -2494,6 +2495,10 @@ static void x86_cpu_reset(CPUState *s) } s->halted = !cpu_is_bsp(cpu); + + if (kvm_enabled()) { + kvm_arch_reset_vcpu(cpu); + } #endif } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index d17eea3186..2882e14dad 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -723,9 +723,8 @@ int kvm_arch_init_vcpu(CPUState *cs) return 0; } -void kvm_arch_reset_vcpu(CPUState *cs) +void kvm_arch_reset_vcpu(X86CPU *cpu) { - X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; env->exception_injected = -1; diff --git a/target-i386/kvm_i386.h b/target-i386/kvm_i386.h index 4392ab4359..b0b2193b1f 100644 --- a/target-i386/kvm_i386.h +++ b/target-i386/kvm_i386.h @@ -14,6 +14,7 @@ #include "sysemu/kvm.h" bool kvm_allows_irq0_override(void); +void kvm_arch_reset_vcpu(X86CPU *cs); int kvm_device_pci_assign(KVMState *s, PCIHostDeviceAddress *dev_addr, uint32_t flags, uint32_t *dev_id); diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 4b81e5f253..8ff1777dcb 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -430,10 +430,6 @@ int kvm_arch_init_vcpu(CPUState *cs) return ret; } -void kvm_arch_reset_vcpu(CPUState *cpu) -{ -} - static void kvm_sw_tlb_put(PowerPCCPU *cpu) { CPUPPCState *env = &cpu->env; diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index dfd83e8aef..c3082b73c5 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -152,6 +152,10 @@ static void s390_cpu_full_reset(CPUState *s) * after incrementing the cpu counter */ #if !defined(CONFIG_USER_ONLY) s->halted = 1; + + if (kvm_enabled()) { + kvm_s390_reset_vcpu(cpu); + } #endif tlb_flush(s, 1); } diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index aad277af49..06454d6da5 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -359,11 +359,16 @@ void s390x_cpu_timer(void *opaque); int s390_virtio_hypercall(CPUS390XState *env); #ifdef CONFIG_KVM +void kvm_s390_reset_vcpu(S390CPU *cpu); void kvm_s390_interrupt(S390CPU *cpu, int type, uint32_t code); void kvm_s390_virtio_irq(S390CPU *cpu, int config_change, uint64_t token); void kvm_s390_interrupt_internal(S390CPU *cpu, int type, uint32_t parm, uint64_t parm64, int vm); #else +static inline void kvm_s390_reset_vcpu(S390CPU *cpu) +{ +} + static inline void kvm_s390_interrupt(S390CPU *cpu, int type, uint32_t code) { } diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index ba2dffe3dd..56179afece 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -117,14 +117,16 @@ int kvm_arch_init_vcpu(CPUState *cpu) return 0; } -void kvm_arch_reset_vcpu(CPUState *cpu) +void kvm_s390_reset_vcpu(S390CPU *cpu) { + CPUState *cs = CPU(cpu); + /* The initial reset call is needed here to reset in-kernel * vcpu data that we can't access directly from QEMU * (i.e. with older kernels which don't support sync_regs/ONE_REG). * Before this ioctl cpu_synchronize_state() is called in common kvm * code (kvm-all) */ - if (kvm_vcpu_ioctl(cpu, KVM_S390_INITIAL_RESET, NULL)) { + if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) { perror("Can't reset vcpu\n"); } } -- cgit v1.2.3-55-g7522 From 4a92a558f49cb0693e36bd6d4f9217f298045be2 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 5 Mar 2013 15:35:17 +0100 Subject: cpu: make CPU_INTERRUPT_RESET available on all targets On the x86, some devices need access to the CPU reset pin (INIT#). Provide a generic service to do this, using one of the internal cpu_interrupt targets. Generalize the PPC-specific code for CPU_INTERRUPT_RESET to other targets. Since PPC does not support migration across QEMU versions (its machine types are not versioned yet), I picked the value that is used on x86, CPU_INTERRUPT_TGT_INT_1. Consequently, TGT_INT_2 and TGT_INT_3 are shifted down by one while keeping their value. Reviewed-by: Anthony Liguori Reviewed-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- cpu-exec.c | 23 +++++++++++++---------- include/exec/cpu-all.h | 8 +++++--- target-i386/cpu.h | 7 ++++--- target-ppc/cpu.h | 3 --- 4 files changed, 22 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/cpu-exec.c b/cpu-exec.c index 2f54054d8c..38e5f02a30 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -335,6 +335,18 @@ int cpu_exec(CPUArchState *env) cpu_loop_exit(cpu); } #endif +#if defined(TARGET_I386) + if (interrupt_request & CPU_INTERRUPT_INIT) { + cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0); + do_cpu_init(x86_cpu); + cpu->exception_index = EXCP_HALTED; + cpu_loop_exit(cpu); + } +#else + if (interrupt_request & CPU_INTERRUPT_RESET) { + cpu_reset(cpu); + } +#endif #if defined(TARGET_I386) #if !defined(CONFIG_USER_ONLY) if (interrupt_request & CPU_INTERRUPT_POLL) { @@ -342,13 +354,7 @@ int cpu_exec(CPUArchState *env) apic_poll_irq(x86_cpu->apic_state); } #endif - if (interrupt_request & CPU_INTERRUPT_INIT) { - cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, - 0); - do_cpu_init(x86_cpu); - cpu->exception_index = EXCP_HALTED; - cpu_loop_exit(cpu); - } else if (interrupt_request & CPU_INTERRUPT_SIPI) { + if (interrupt_request & CPU_INTERRUPT_SIPI) { do_cpu_sipi(x86_cpu); } else if (env->hflags2 & HF2_GIF_MASK) { if ((interrupt_request & CPU_INTERRUPT_SMI) && @@ -405,9 +411,6 @@ int cpu_exec(CPUArchState *env) } } #elif defined(TARGET_PPC) - if ((interrupt_request & CPU_INTERRUPT_RESET)) { - cpu_reset(cpu); - } if (interrupt_request & CPU_INTERRUPT_HARD) { ppc_hw_interrupt(env); if (env->pending_interrupts == 0) { diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index fb649a4029..9cab592dc5 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -381,6 +381,9 @@ CPUArchState *cpu_copy(CPUArchState *env); /* Debug event pending. */ #define CPU_INTERRUPT_DEBUG 0x0080 +/* Reset signal. */ +#define CPU_INTERRUPT_RESET 0x0400 + /* Several target-specific external hardware interrupts. Each target/cpu.h should define proper names based on these defines. */ #define CPU_INTERRUPT_TGT_EXT_0 0x0008 @@ -395,9 +398,8 @@ CPUArchState *cpu_copy(CPUArchState *env); instruction being executed. These, therefore, are not masked while single-stepping within the debugger. */ #define CPU_INTERRUPT_TGT_INT_0 0x0100 -#define CPU_INTERRUPT_TGT_INT_1 0x0400 -#define CPU_INTERRUPT_TGT_INT_2 0x0800 -#define CPU_INTERRUPT_TGT_INT_3 0x2000 +#define CPU_INTERRUPT_TGT_INT_1 0x0800 +#define CPU_INTERRUPT_TGT_INT_2 0x2000 /* First unused bit: 0x4000. */ diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 5fd1e20b57..e9cbdabc03 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -606,10 +606,11 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3 #define CPU_INTERRUPT_MCE CPU_INTERRUPT_TGT_EXT_4 #define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_INT_0 -#define CPU_INTERRUPT_INIT CPU_INTERRUPT_TGT_INT_1 -#define CPU_INTERRUPT_SIPI CPU_INTERRUPT_TGT_INT_2 -#define CPU_INTERRUPT_TPR CPU_INTERRUPT_TGT_INT_3 +#define CPU_INTERRUPT_SIPI CPU_INTERRUPT_TGT_INT_1 +#define CPU_INTERRUPT_TPR CPU_INTERRUPT_TGT_INT_2 +/* Use a clearer name for this. */ +#define CPU_INTERRUPT_INIT CPU_INTERRUPT_RESET typedef enum { CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */ diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index d4983405a2..75ed5fa636 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2042,9 +2042,6 @@ enum { PPC_INTERRUPT_PERFM, /* Performance monitor interrupt */ }; -/* CPU should be reset next, restart from scratch afterwards */ -#define CPU_INTERRUPT_RESET CPU_INTERRUPT_TGT_INT_0 - /*****************************************************************************/ static inline target_ulong cpu_read_xer(CPUPPCState *env) -- cgit v1.2.3-55-g7522