Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751959AbdCPJkB (ORCPT ); Thu, 16 Mar 2017 05:40:01 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:33662 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751492AbdCPJj7 (ORCPT ); Thu, 16 Mar 2017 05:39:59 -0400 MIME-Version: 1.0 In-Reply-To: <20170315201348.GA14076@potion> References: <1489605443-21045-1-git-send-email-mst@redhat.com> <20170315201348.GA14076@potion> From: Wanpeng Li Date: Thu, 16 Mar 2017 17:30:06 +0800 Message-ID: Subject: Re: [PATCH v4] kvm: better MWAIT emulation for guests To: =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= Cc: "Michael S. Tsirkin" , "linux-kernel@vger.kernel.org" , "Gabriel L. Somlo" , Paolo Bonzini , Jonathan Corbet , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , "the arch/x86 maintainers" , Joerg Roedel , kvm , linux-doc@vger.kernel.org Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by mail.home.local id v2G9e5er001519 Content-Length: 3740 Lines: 104 2017-03-16 4:13 GMT+08:00 Radim Krčmář : > 2017-03-15 21:28+0200, Michael S. Tsirkin: >> Guests running Mac OS 5, 6, and 7 (Leopard through Lion) have a problem: >> unless explicitly provided with kernel command line argument >> "idlehalt=0" they'd implicitly assume MONITOR and MWAIT availability, >> without checking CPUID. >> >> We currently emulate that as a NOP but on VMX we can do better: let >> guest stop the CPU until timer, IPI or memory change. CPU will be busy >> but that isn't any worse than a NOP emulation. >> >> Note that mwait within guests is not the same as on real hardware >> because halt causes an exit while mwait doesn't. For this reason it >> might not be a good idea to use the regular MWAIT flag in CPUID to >> signal this capability. Add a flag in the hypervisor leaf instead. >> >> Additionally, we add a capability for QEMU - e.g. if it knows there's an >> isolated CPU dedicated for the VCPU it can set the standard MWAIT flag >> to improve guest behaviour. >> >> Reported-by: "Gabriel L. Somlo" >> Signed-off-by: Michael S. Tsirkin >> --- >> >> Note: SVM bits are untested at this point. Seems pretty >> obvious though. >> >> changes from v3: >> - don't enable capability if cli+mwait blocks interrupts >> - doc typo fixes (drop drop ppc doc) >> >> changes from v2: >> - add a capability to allow host userspace to detect new kernels >> - more documentation to clarify the semantics of the feature flag >> and why it's useful >> - svm support as suggested by Radim >> >> changes from v1: >> - typo fix resulting in rest of leaf flags being overwritten >> Reported by: Wanpeng Li >> - updated commit log with data about guests helped by this feature >> - better document differences between mwait and halt for guests >> >> diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h >> @@ -212,4 +213,28 @@ static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec) >> __rem; \ >> }) >> >> +static bool kvm_mwait_in_guest(void) >> +{ >> + unsigned int eax, ebx, ecx; >> + >> + if (!cpu_has(&boot_cpu_data, X86_FEATURE_MWAIT)) >> + return -ENODEV; >> + >> + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) >> + return -ENODEV; >> + >> + /* >> + * Intel CPUs without CPUID5_ECX_INTERRUPT_BREAK are problematic as >> + * they would allow guest to stop the CPU completely by disabling >> + * interrupts then invoking MWAIT. >> + */ >> + if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) >> + return -ENODEV; >> + >> + cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); >> + >> + if (!(ecx & CPUID5_ECX_INTERRUPT_BREAK)) >> + return -ENODEV; > > The guest is still able to set ecx=0 with MWAIT, which should be the How can guest rewrite this? Regards, Wanpeng Li > same as not having the CPUID flag, so I'm wondering how this check > prevents anything harmful ... is it really a cpu "feature"? > > If we somehow report ecx bit 1 in CPUID[5], then the guest might try to > set ecx bit 0 for MWAIT, which will cause #GP(0) and could explain the > hang that Gabriel is hitting. > > Gabriel, > > - do you see VM exits on the "hung" VCPU? > - what is your CPU model? > - what do you get after running this C program on host and guest? > > #include > #include > > int main(void) { > uint32_t eax = 5, ebx, ecx = 0, edx; > asm ("cpuid" : "+a"(eax), "=b"(ebx), "+c"(ecx), "=d"(edx)); > > printf("eax=%#08x ebx=%#08x ecx=%#08x edx=%#08x\n", eax, ebx, ecx, edx); > > return 0; > } > > Thanks.