|
|
9ae3a8 |
From 4142f7546da561898f15169f6e8085167601e878 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
9ae3a8 |
Date: Tue, 15 May 2018 11:56:34 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 08/10] kvm: apic: set APIC base as part of kvm_apic_put
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
9ae3a8 |
Message-id: <20180515115634.24469-6-dgilbert@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 80271
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.6 qemu-kvm PATCH v2 5/5] kvm: apic: set APIC base as part of kvm_apic_put
|
|
|
9ae3a8 |
Bugzilla: 1577680
|
|
|
9ae3a8 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
The parsing of KVM_SET_LAPIC's input depends on the current value of the
|
|
|
9ae3a8 |
APIC base MSR---which indeed is stored in APICCommonState---but for historical
|
|
|
9ae3a8 |
reasons APIC base is set through KVM_SET_SREGS together with cr8 (which is
|
|
|
9ae3a8 |
really just the APIC TPR) and the actual "special CPU registers".
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
APIC base must now be set before the actual LAPIC registers, so do that
|
|
|
9ae3a8 |
in kvm_apic_put. It will be set again to the same value with KVM_SET_SREGS,
|
|
|
9ae3a8 |
but that's not a big issue.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
This only happens since Linux 4.8, which checks for x2apic mode in
|
|
|
9ae3a8 |
KVM_SET_LAPIC. However it's really a QEMU bug; until the recent
|
|
|
9ae3a8 |
commit 78d6a05 ("x86/lapic: Load LAPIC state at post_load", 2016-09-13)
|
|
|
9ae3a8 |
QEMU was indeed setting APIC base (via KVM_SET_SREGS) before the other
|
|
|
9ae3a8 |
LAPIC registers.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit f8d9ccf8d5f9f4b7d364100871c4c7303b546de5)
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
hw/i386/kvm/apic.c | 2 ++
|
|
|
9ae3a8 |
target-i386/kvm.c | 8 ++++++++
|
|
|
9ae3a8 |
target-i386/kvm_i386.h | 2 ++
|
|
|
9ae3a8 |
3 files changed, 12 insertions(+)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
|
|
|
9ae3a8 |
index d47d8da..77d2999 100644
|
|
|
9ae3a8 |
--- a/hw/i386/kvm/apic.c
|
|
|
9ae3a8 |
+++ b/hw/i386/kvm/apic.c
|
|
|
9ae3a8 |
@@ -12,6 +12,7 @@
|
|
|
9ae3a8 |
#include "hw/i386/apic_internal.h"
|
|
|
9ae3a8 |
#include "hw/pci/msi.h"
|
|
|
9ae3a8 |
#include "sysemu/kvm.h"
|
|
|
9ae3a8 |
+#include "target-i386/kvm_i386.h"
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic,
|
|
|
9ae3a8 |
int reg_id, uint32_t val)
|
|
|
9ae3a8 |
@@ -127,6 +128,7 @@ static void kvm_apic_put(void *data)
|
|
|
9ae3a8 |
struct kvm_lapic_state kapic;
|
|
|
9ae3a8 |
int ret;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ kvm_put_apicbase(s->cpu, s->apicbase);
|
|
|
9ae3a8 |
kvm_put_apic_state(s, &kapic);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
ret = kvm_vcpu_ioctl(CPU(s->cpu), KVM_SET_LAPIC, &kapic);
|
|
|
9ae3a8 |
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
|
|
|
9ae3a8 |
index 71f1573..a1a49d8 100644
|
|
|
9ae3a8 |
--- a/target-i386/kvm.c
|
|
|
9ae3a8 |
+++ b/target-i386/kvm.c
|
|
|
9ae3a8 |
@@ -1152,6 +1152,14 @@ static int kvm_put_one_msr(X86CPU *cpu, int index, uint64_t value)
|
|
|
9ae3a8 |
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+void kvm_put_apicbase(X86CPU *cpu, uint64_t value)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ int ret;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ ret = kvm_put_one_msr(cpu, MSR_IA32_APICBASE, value);
|
|
|
9ae3a8 |
+ assert(ret == 1);
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
static int kvm_put_tscdeadline_msr(X86CPU *cpu)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
CPUX86State *env = &cpu->env;
|
|
|
9ae3a8 |
diff --git a/target-i386/kvm_i386.h b/target-i386/kvm_i386.h
|
|
|
9ae3a8 |
index 4392ab4..b260b31 100644
|
|
|
9ae3a8 |
--- a/target-i386/kvm_i386.h
|
|
|
9ae3a8 |
+++ b/target-i386/kvm_i386.h
|
|
|
9ae3a8 |
@@ -35,4 +35,6 @@ int kvm_device_msix_set_vector(KVMState *s, uint32_t dev_id, uint32_t vector,
|
|
|
9ae3a8 |
int kvm_device_msix_assign(KVMState *s, uint32_t dev_id);
|
|
|
9ae3a8 |
int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|