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