Blame SOURCES/kvm-slow-train-kvm-clear-out-KVM_ASYNC_PF_DELIVERY_AS_PF.patch

ae23c9
From 68d5cd786a054bc1e84b1ee6a0deeefbfe2c33b9 Mon Sep 17 00:00:00 2001
ae23c9
From: Bandan Das <bsd@redhat.com>
ae23c9
Date: Fri, 14 Dec 2018 19:35:46 +0000
ae23c9
Subject: [PATCH 5/5] slow train kvm: clear out
ae23c9
 KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT for older machine types
ae23c9
ae23c9
RH-Author: Bandan Das <bsd@redhat.com>
ae23c9
Message-id: <jpgftuz9a0d.fsf@linux.bootlegged.copy>
ae23c9
Patchwork-id: 83524
ae23c9
O-Subject: [RHEL8 qemu-kvm PATCH] slow train kvm: clear out KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT for older machine types
ae23c9
Bugzilla: 1656829
ae23c9
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
ae23c9
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
ae23c9
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
ae23c9
ae23c9
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1656829
ae23c9
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=19521977
ae23c9
Upstream: Not applicable
ae23c9
Branch: rhel8/master-2.12.0
ae23c9
ae23c9
After the addition of support for async pf injection to L1, newer
ae23c9
hypervisors  advertise the feature using bit 2 of the
ae23c9
MSR_KVM_ASYNC_PF_EN msr. However, this was reserved in older
ae23c9
hypervisors which results in an error during migration like so:
ae23c9
ae23c9
qemu-kvm: error: failed to set MSR 0x4b564d02 to 0x27fc13285
ae23c9
qemu-kvm: /builddir/build/BUILD/qemu-2.12.0/target/i386/kvm.c:1940: kvm_put_msrs: Assertion `ret == cpu->kvm_msr_buf->nmsrs' failed.
ae23c9
Aborted (core dumped)
ae23c9
ae23c9
This patch introduces a new bool that is set for older machine types.
ae23c9
When set, Qemu's stored value clears out bit 2. This should be safe
ae23c9
because the guest can still enable it by writing to the MSR after
ae23c9
checking for support. A reset/migration for <7.6 machine type would
ae23c9
reset the bit though.
ae23c9
ae23c9
Signed-off-by: Bandan Das <bsd@redhat.com>
ae23c9
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ae23c9
---
ae23c9
 hw/i386/pc.c        | 5 +++++
ae23c9
 include/hw/boards.h | 2 ++
ae23c9
 target/i386/kvm.c   | 4 ++++
ae23c9
 3 files changed, 11 insertions(+)
ae23c9
ae23c9
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
ae23c9
index 9034f02..9e1e6ae 100644
ae23c9
--- a/hw/i386/pc.c
ae23c9
+++ b/hw/i386/pc.c
ae23c9
@@ -2363,6 +2363,11 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
ae23c9
     pcmc->save_tsc_khz = true;
ae23c9
     pcmc->linuxboot_dma_enabled = true;
ae23c9
     pcmc->pc_rom_ro = true;
ae23c9
+    /*
ae23c9
+     * This might have to be set to false
ae23c9
+     * when and if there's a new machine type
ae23c9
+     */
ae23c9
+    mc->async_pf_vmexit_disable = true;
ae23c9
     mc->get_hotplug_handler = pc_get_hotpug_handler;
ae23c9
     mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
ae23c9
     mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
ae23c9
diff --git a/include/hw/boards.h b/include/hw/boards.h
ae23c9
index a609239..9b4a69b 100644
ae23c9
--- a/include/hw/boards.h
ae23c9
+++ b/include/hw/boards.h
ae23c9
@@ -203,6 +203,8 @@ struct MachineClass {
ae23c9
     const char **valid_cpu_types;
ae23c9
     strList *allowed_dynamic_sysbus_devices;
ae23c9
     bool auto_enable_numa_with_memhp;
ae23c9
+    /* RHEL only */
ae23c9
+    bool async_pf_vmexit_disable;
ae23c9
     void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes,
ae23c9
                                  int nb_nodes, ram_addr_t size);
ae23c9
 
ae23c9
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
ae23c9
index 00f2141..87e4771 100644
ae23c9
--- a/target/i386/kvm.c
ae23c9
+++ b/target/i386/kvm.c
ae23c9
@@ -2072,6 +2072,7 @@ static int kvm_get_msrs(X86CPU *cpu)
ae23c9
     struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries;
ae23c9
     int ret, i;
ae23c9
     uint64_t mtrr_top_bits;
ae23c9
+    MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
ae23c9
 
ae23c9
     kvm_msr_buf_reset(cpu);
ae23c9
 
ae23c9
@@ -2364,6 +2365,9 @@ static int kvm_get_msrs(X86CPU *cpu)
ae23c9
             break;
ae23c9
         case MSR_KVM_ASYNC_PF_EN:
ae23c9
             env->async_pf_en_msr = msrs[i].data;
ae23c9
+            if (mc->async_pf_vmexit_disable) {
ae23c9
+                env->async_pf_en_msr &= ~(1ULL << 2);
ae23c9
+            }
ae23c9
             break;
ae23c9
         case MSR_KVM_PV_EOI_EN:
ae23c9
             env->pv_eoi_en_msr = msrs[i].data;
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9