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