mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
x86/lapic: Load LAPIC state at post_load
Load the LAPIC state during post_load (rather than when the CPU starts). This allows an interrupt to be delivered from the ioapic to the lapic prior to cpu loading, in particular the RTC that starts ticking as soon as we load it's state. Fixes a case where Windows hangs after migration due to RTC interrupts disappearing. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
0342454f8a
commit
78d6a05d2f
3 changed files with 25 additions and 20 deletions
|
@ -28,9 +28,8 @@ static inline uint32_t kvm_apic_get_reg(struct kvm_lapic_state *kapic,
|
|||
return *((uint32_t *)(kapic->regs + (reg_id << 4)));
|
||||
}
|
||||
|
||||
void kvm_put_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic)
|
||||
static void kvm_put_apic_state(APICCommonState *s, struct kvm_lapic_state *kapic)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
int i;
|
||||
|
||||
memset(kapic, 0, sizeof(*kapic));
|
||||
|
@ -125,6 +124,27 @@ static void kvm_apic_vapic_base_update(APICCommonState *s)
|
|||
}
|
||||
}
|
||||
|
||||
static void kvm_apic_put(void *data)
|
||||
{
|
||||
APICCommonState *s = data;
|
||||
struct kvm_lapic_state kapic;
|
||||
int ret;
|
||||
|
||||
kvm_put_apic_state(s, &kapic);
|
||||
|
||||
ret = kvm_vcpu_ioctl(CPU(s->cpu), KVM_SET_LAPIC, &kapic);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "KVM_SET_LAPIC failed: %s\n", strerror(ret));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_apic_post_load(APICCommonState *s)
|
||||
{
|
||||
fprintf(stderr, "%s: Yeh\n", __func__);
|
||||
run_on_cpu(CPU(s->cpu), kvm_apic_put, s);
|
||||
}
|
||||
|
||||
static void do_inject_external_nmi(void *data)
|
||||
{
|
||||
APICCommonState *s = data;
|
||||
|
@ -178,6 +198,8 @@ static void kvm_apic_reset(APICCommonState *s)
|
|||
{
|
||||
/* Not used by KVM, which uses the CPU mp_state instead. */
|
||||
s->wait_for_sipi = 0;
|
||||
|
||||
run_on_cpu(CPU(s->cpu), kvm_apic_put, s);
|
||||
}
|
||||
|
||||
static void kvm_apic_realize(DeviceState *dev, Error **errp)
|
||||
|
@ -206,6 +228,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data)
|
|||
k->set_base = kvm_apic_set_base;
|
||||
k->set_tpr = kvm_apic_set_tpr;
|
||||
k->get_tpr = kvm_apic_get_tpr;
|
||||
k->post_load = kvm_apic_post_load;
|
||||
k->enable_tpr_reporting = kvm_apic_enable_tpr_reporting;
|
||||
k->vapic_base_update = kvm_apic_vapic_base_update;
|
||||
k->external_nmi = kvm_apic_external_nmi;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue