|
|
169b9a |
From f0254b84d490273e922d04b01a7b48f0ac370185 Mon Sep 17 00:00:00 2001
|
|
|
6e672b |
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
169b9a |
Date: Tue, 15 May 2018 11:56:32 +0200
|
|
|
169b9a |
Subject: [PATCH 06/10] x86/lapic: Load LAPIC state at post_load
|
|
|
6e672b |
|
|
|
6e672b |
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
6e672b |
Message-id: <20180515115634.24469-4-dgilbert@redhat.com>
|
|
|
6e672b |
Patchwork-id: 80273
|
|
|
6e672b |
O-Subject: [RHEL-7.6 qemu-kvm PATCH v2 3/5] x86/lapic: Load LAPIC state at post_load
|
|
|
169b9a |
Bugzilla: 1577680
|
|
|
6e672b |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
6e672b |
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
6e672b |
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
|
|
|
6e672b |
|
|
|
6e672b |
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
6e672b |
|
|
|
6e672b |
Load the LAPIC state during post_load (rather than when the CPU
|
|
|
6e672b |
starts).
|
|
|
6e672b |
|
|
|
6e672b |
This allows an interrupt to be delivered from the ioapic to
|
|
|
6e672b |
the lapic prior to cpu loading, in particular the RTC that starts
|
|
|
6e672b |
ticking as soon as we load it's state.
|
|
|
6e672b |
|
|
|
6e672b |
Fixes a case where Windows hangs after migration due to RTC interrupts
|
|
|
6e672b |
disappearing.
|
|
|
6e672b |
|
|
|
6e672b |
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
6e672b |
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
6e672b |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
6e672b |
(cherry picked from commit 78d6a05d2f69cbfa6e95f0a4a24a2c934969913b)
|
|
|
6e672b |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
6e672b |
---
|
|
|
6e672b |
hw/i386/kvm/apic.c | 27 ++++++++++++++++++++++++---
|
|
|
6e672b |
include/sysemu/kvm.h | 1 -
|
|
|
6e672b |
target-i386/kvm.c | 18 ------------------
|
|
|
6e672b |
3 files changed, 24 insertions(+), 22 deletions(-)
|
|
|
6e672b |
|
|
|
6e672b |
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
|
|
|
6e672b |
index 6ead17c..0f3a80c 100644
|
|
|
6e672b |
--- a/hw/i386/kvm/apic.c
|
|
|
6e672b |
+++ b/hw/i386/kvm/apic.c
|
|
|
6e672b |
@@ -25,9 +25,8 @@ static inline uint32_t kvm_apic_get_reg(struct kvm_lapic_state *kapic,
|
|
|
6e672b |
return *((uint32_t *)(kapic->regs + (reg_id << 4)));
|
|
|
6e672b |
}
|
|
|
6e672b |
|
|
|
6e672b |
-void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic)
|
|
|
6e672b |
+static void kvm_put_apic_state(APICCommonState *s, struct kvm_lapic_state *kapic)
|
|
|
6e672b |
{
|
|
|
6e672b |
- APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
|
|
|
6e672b |
int i;
|
|
|
6e672b |
|
|
|
6e672b |
memset(kapic, 0, sizeof(*kapic));
|
|
|
6e672b |
@@ -122,6 +121,27 @@ static void kvm_apic_vapic_base_update(APICCommonState *s)
|
|
|
6e672b |
}
|
|
|
6e672b |
}
|
|
|
6e672b |
|
|
|
6e672b |
+static void kvm_apic_put(void *data)
|
|
|
6e672b |
+{
|
|
|
6e672b |
+ APICCommonState *s = data;
|
|
|
6e672b |
+ struct kvm_lapic_state kapic;
|
|
|
6e672b |
+ int ret;
|
|
|
6e672b |
+
|
|
|
6e672b |
+ kvm_put_apic_state(s, &kapic);
|
|
|
6e672b |
+
|
|
|
6e672b |
+ ret = kvm_vcpu_ioctl(CPU(s->cpu), KVM_SET_LAPIC, &kapic);
|
|
|
6e672b |
+ if (ret < 0) {
|
|
|
6e672b |
+ fprintf(stderr, "KVM_SET_LAPIC failed: %s\n", strerror(ret));
|
|
|
6e672b |
+ abort();
|
|
|
6e672b |
+ }
|
|
|
6e672b |
+}
|
|
|
6e672b |
+
|
|
|
6e672b |
+static void kvm_apic_post_load(APICCommonState *s)
|
|
|
6e672b |
+{
|
|
|
6e672b |
+ fprintf(stderr, "%s: Yeh\n", __func__);
|
|
|
6e672b |
+ run_on_cpu(CPU(s->cpu), kvm_apic_put, s);
|
|
|
6e672b |
+}
|
|
|
6e672b |
+
|
|
|
6e672b |
static void do_inject_external_nmi(void *data)
|
|
|
6e672b |
{
|
|
|
6e672b |
APICCommonState *s = data;
|
|
|
6e672b |
@@ -173,7 +193,7 @@ static const MemoryRegionOps kvm_apic_io_ops = {
|
|
|
6e672b |
|
|
|
6e672b |
static void kvm_apic_reset(APICCommonState *s)
|
|
|
6e672b |
{
|
|
|
6e672b |
- /* This function intentionally left blank, for now */
|
|
|
6e672b |
+ run_on_cpu(CPU(s->cpu), kvm_apic_put, s);
|
|
|
6e672b |
}
|
|
|
6e672b |
|
|
|
6e672b |
static void kvm_apic_init(APICCommonState *s)
|
|
|
6e672b |
@@ -195,6 +215,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data)
|
|
|
6e672b |
k->set_base = kvm_apic_set_base;
|
|
|
6e672b |
k->set_tpr = kvm_apic_set_tpr;
|
|
|
6e672b |
k->get_tpr = kvm_apic_get_tpr;
|
|
|
6e672b |
+ k->post_load = kvm_apic_post_load;
|
|
|
6e672b |
k->enable_tpr_reporting = kvm_apic_enable_tpr_reporting;
|
|
|
6e672b |
k->vapic_base_update = kvm_apic_vapic_base_update;
|
|
|
6e672b |
k->external_nmi = kvm_apic_external_nmi;
|
|
|
6e672b |
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
|
|
|
6e672b |
index 0c6833f..49cfc42 100644
|
|
|
6e672b |
--- a/include/sysemu/kvm.h
|
|
|
6e672b |
+++ b/include/sysemu/kvm.h
|
|
|
6e672b |
@@ -216,7 +216,6 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
|
|
|
6e672b |
|
|
|
6e672b |
void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
|
|
|
6e672b |
|
|
|
6e672b |
-void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
|
|
|
6e672b |
void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
|
|
|
6e672b |
|
|
|
6e672b |
struct kvm_guest_debug;
|
|
|
6e672b |
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
|
|
|
169b9a |
index 6f3424e..71f1573 100644
|
|
|
6e672b |
--- a/target-i386/kvm.c
|
|
|
6e672b |
+++ b/target-i386/kvm.c
|
|
|
169b9a |
@@ -1863,20 +1863,6 @@ static int kvm_get_apic(X86CPU *cpu)
|
|
|
6e672b |
return 0;
|
|
|
6e672b |
}
|
|
|
6e672b |
|
|
|
6e672b |
-static int kvm_put_apic(X86CPU *cpu)
|
|
|
6e672b |
-{
|
|
|
6e672b |
- CPUX86State *env = &cpu->env;
|
|
|
6e672b |
- DeviceState *apic = env->apic_state;
|
|
|
6e672b |
- struct kvm_lapic_state kapic;
|
|
|
6e672b |
-
|
|
|
6e672b |
- if (apic && kvm_irqchip_in_kernel()) {
|
|
|
6e672b |
- kvm_put_apic_state(apic, &kapic);
|
|
|
6e672b |
-
|
|
|
6e672b |
- return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_LAPIC, &kapic);
|
|
|
6e672b |
- }
|
|
|
6e672b |
- return 0;
|
|
|
6e672b |
-}
|
|
|
6e672b |
-
|
|
|
6e672b |
static int kvm_put_vcpu_events(X86CPU *cpu, int level)
|
|
|
6e672b |
{
|
|
|
6e672b |
CPUX86State *env = &cpu->env;
|
|
|
169b9a |
@@ -2058,10 +2044,6 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
|
|
|
6e672b |
if (ret < 0) {
|
|
|
6e672b |
return ret;
|
|
|
6e672b |
}
|
|
|
6e672b |
- ret = kvm_put_apic(x86_cpu);
|
|
|
6e672b |
- if (ret < 0) {
|
|
|
6e672b |
- return ret;
|
|
|
6e672b |
- }
|
|
|
6e672b |
}
|
|
|
6e672b |
|
|
|
6e672b |
ret = kvm_put_tscdeadline_msr(x86_cpu);
|
|
|
6e672b |
--
|
|
|
6e672b |
1.8.3.1
|
|
|
6e672b |
|