diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-07-17 17:06:32 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-07-17 17:06:32 +0100 |
commit | 59b5552f020b739e273e969a0933c23d8f4e2284 (patch) | |
tree | ff90e006b6500ec58d0abb8d495a9a95151589f0 /target | |
parent | ccf02d73d18930a15282556e577c0777fa09081b (diff) | |
parent | dfaa7d50b0f72060764096ffcae4a0c06ce24f9b (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
Bug fixes.
# gpg: Signature made Tue 17 Jul 2018 16:06:07 BST
# gpg: using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream:
Document command line options with single dash
opts: remove redundant check for NULL parameter
i386: only parse the initrd_filename once for multiboot modules
i386: fix regression parsing multiboot initrd modules
virtio-scsi: fix hotplug ->reset() vs event race
qdev: add HotplugHandler->post_plug() callback
hw/char/serial: retry write if EAGAIN
PC Chipset: Improve serial divisor calculation
vhost-user-test: added proper TestServer *dest initialization in test_migrate()
hyperv: ensure VP index equal to QEMU cpu_index
hyperv: rename vcpu_id to vp_index
accel: Fix typo and grammar in comment
dump: add kernel_gs_base to QEMU CPU state
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/i386/arch_dump.c | 10 | ||||
-rw-r--r-- | target/i386/hyperv.c | 16 | ||||
-rw-r--r-- | target/i386/hyperv.h | 7 | ||||
-rw-r--r-- | target/i386/kvm-stub.c | 5 | ||||
-rw-r--r-- | target/i386/kvm.c | 47 | ||||
-rw-r--r-- | target/i386/kvm_i386.h | 2 |
6 files changed, 82 insertions, 5 deletions
diff --git a/target/i386/arch_dump.c b/target/i386/arch_dump.c index 35b55fc200..004141fc04 100644 --- a/target/i386/arch_dump.c +++ b/target/i386/arch_dump.c @@ -258,6 +258,12 @@ struct QEMUCPUState { QEMUCPUSegment cs, ds, es, fs, gs, ss; QEMUCPUSegment ldt, tr, gdt, idt; uint64_t cr[5]; + /* + * Fields below are optional and are being added at the end without + * changing the version. External tools may identify their presence + * by checking 'size' field. + */ + uint64_t kernel_gs_base; }; typedef struct QEMUCPUState QEMUCPUState; @@ -315,6 +321,10 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env) s->cr[2] = env->cr[2]; s->cr[3] = env->cr[3]; s->cr[4] = env->cr[4]; + +#ifdef TARGET_X86_64 + s->kernel_gs_base = env->kernelgsbase; +#endif } static inline int cpu_write_qemu_note(WriteCoreDumpFunction f, diff --git a/target/i386/hyperv.c b/target/i386/hyperv.c index a050c9d2d1..3065d765ed 100644 --- a/target/i386/hyperv.c +++ b/target/i386/hyperv.c @@ -16,6 +16,16 @@ #include "hyperv.h" #include "hyperv-proto.h" +uint32_t hyperv_vp_index(X86CPU *cpu) +{ + return CPU(cpu)->cpu_index; +} + +X86CPU *hyperv_find_vcpu(uint32_t vp_index) +{ + return X86_CPU(qemu_get_cpu(vp_index)); +} + int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit) { CPUX86State *env = &cpu->env; @@ -72,7 +82,7 @@ static void kvm_hv_sint_ack_handler(EventNotifier *notifier) } } -HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint, +HvSintRoute *kvm_hv_sint_route_create(uint32_t vp_index, uint32_t sint, HvSintAckClb sint_ack_clb) { HvSintRoute *sint_route; @@ -92,7 +102,7 @@ HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint, event_notifier_set_handler(&sint_route->sint_ack_notifier, kvm_hv_sint_ack_handler); - gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vcpu_id, sint); + gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vp_index, sint); if (gsi < 0) { goto err_gsi; } @@ -105,7 +115,7 @@ HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint, } sint_route->gsi = gsi; sint_route->sint_ack_clb = sint_ack_clb; - sint_route->vcpu_id = vcpu_id; + sint_route->vp_index = vp_index; sint_route->sint = sint; return sint_route; diff --git a/target/i386/hyperv.h b/target/i386/hyperv.h index 0c3b562018..00c9b454bb 100644 --- a/target/i386/hyperv.h +++ b/target/i386/hyperv.h @@ -23,7 +23,7 @@ typedef void (*HvSintAckClb)(HvSintRoute *sint_route); struct HvSintRoute { uint32_t sint; - uint32_t vcpu_id; + uint32_t vp_index; int gsi; EventNotifier sint_set_notifier; EventNotifier sint_ack_notifier; @@ -32,11 +32,14 @@ struct HvSintRoute { int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit); -HvSintRoute *kvm_hv_sint_route_create(uint32_t vcpu_id, uint32_t sint, +HvSintRoute *kvm_hv_sint_route_create(uint32_t vp_index, uint32_t sint, HvSintAckClb sint_ack_clb); void kvm_hv_sint_route_destroy(HvSintRoute *sint_route); int kvm_hv_sint_route_set_sint(HvSintRoute *sint_route); +uint32_t hyperv_vp_index(X86CPU *cpu); +X86CPU *hyperv_find_vcpu(uint32_t vp_index); + #endif diff --git a/target/i386/kvm-stub.c b/target/i386/kvm-stub.c index bda4dc2f0c..e7a673e5db 100644 --- a/target/i386/kvm-stub.c +++ b/target/i386/kvm-stub.c @@ -40,3 +40,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function, abort(); } #endif + +bool kvm_hv_vpindex_settable(void) +{ + return false; +} diff --git a/target/i386/kvm.c b/target/i386/kvm.c index ebb2d23aa4..9313602d3d 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -85,6 +85,7 @@ static bool has_msr_hv_hypercall; static bool has_msr_hv_crash; static bool has_msr_hv_reset; static bool has_msr_hv_vpindex; +static bool hv_vpindex_settable; static bool has_msr_hv_runtime; static bool has_msr_hv_synic; static bool has_msr_hv_stimer; @@ -162,6 +163,11 @@ bool kvm_enable_x2apic(void) has_x2apic_api); } +bool kvm_hv_vpindex_settable(void) +{ + return hv_vpindex_settable; +} + static int kvm_get_tsc(CPUState *cs) { X86CPU *cpu = X86_CPU(cs); @@ -745,6 +751,37 @@ static int hyperv_handle_properties(CPUState *cs) return 0; } +static int hyperv_init_vcpu(X86CPU *cpu) +{ + if (cpu->hyperv_vpindex && !hv_vpindex_settable) { + /* + * the kernel doesn't support setting vp_index; assert that its value + * is in sync + */ + int ret; + struct { + struct kvm_msrs info; + struct kvm_msr_entry entries[1]; + } msr_data = { + .info.nmsrs = 1, + .entries[0].index = HV_X64_MSR_VP_INDEX, + }; + + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data); + if (ret < 0) { + return ret; + } + assert(ret == 1); + + if (msr_data.entries[0].data != hyperv_vp_index(cpu)) { + error_report("kernel's vp_index != QEMU's vp_index"); + return -ENXIO; + } + } + + return 0; +} + static Error *invtsc_mig_blocker; #define KVM_MAX_CPUID_ENTRIES 100 @@ -1160,6 +1197,11 @@ int kvm_arch_init_vcpu(CPUState *cs) has_msr_tsc_aux = false; } + r = hyperv_init_vcpu(cpu); + if (r) { + goto fail; + } + return 0; fail: @@ -1351,6 +1393,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s) has_pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2); #endif + hv_vpindex_settable = kvm_check_extension(s, KVM_CAP_HYPERV_VP_INDEX); + ret = kvm_get_supported_msrs(s); if (ret < 0) { return ret; @@ -1900,6 +1944,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level) if (has_msr_hv_runtime) { kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, env->msr_hv_runtime); } + if (cpu->hyperv_vpindex && hv_vpindex_settable) { + kvm_msr_entry_add(cpu, HV_X64_MSR_VP_INDEX, hyperv_vp_index(cpu)); + } if (cpu->hyperv_synic) { int j; diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h index e5df24cad1..3057ba4f7d 100644 --- a/target/i386/kvm_i386.h +++ b/target/i386/kvm_i386.h @@ -63,4 +63,6 @@ void kvm_put_apicbase(X86CPU *cpu, uint64_t value); bool kvm_enable_x2apic(void); bool kvm_has_x2apic_api(void); + +bool kvm_hv_vpindex_settable(void); #endif |