diff mbox series

target-i386: add pcid to both Sandy Bridge and Ivy Bridge

Message ID 20180108205052.24385-1-vincent@bernat.im
State New
Headers show
Series target-i386: add pcid to both Sandy Bridge and Ivy Bridge | expand

Commit Message

Vincent Bernat Jan. 8, 2018, 8:50 p.m. UTC
PCID has been introduced in Sandy Bridge and, currently, KVM doesn't
object exposing it to VM as long as it is present on the host. Update
CPU model for both Sandy Bridge and Ivy Bridge accordingly.

Signed-off-by: Vincent Bernat <vincent@bernat.im>
---
 target/i386/cpu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Comments

Eduardo Habkost Jan. 8, 2018, 9:16 p.m. UTC | #1
On Mon, Jan 08, 2018 at 09:50:52PM +0100, Vincent Bernat wrote:
> PCID has been introduced in Sandy Bridge and, currently, KVM doesn't
> object exposing it to VM as long as it is present on the host. Update
> CPU model for both Sandy Bridge and Ivy Bridge accordingly.
> 
> Signed-off-by: Vincent Bernat <vincent@bernat.im>

Thanks for your patch.

We need two things, though:

First, confirming that all hosts where the SandyBridge and
IvyBridge CPU models are runnable will support exposing PCID to
guests (otherwise updating QEMU can make a runnable VM
configuration suddenly stop being runnable).  This can happen if
the host kernel is too old.

One possible way to work around this problem is to declare that
QEMU 2.12 with KVM will require Linux v3.6 and newer (because we
need Linux kernel commit ad756a1603c5 "KVM: VMX: Implement
PCID/INVPCID for guests with EPT").  I have proposed something
similar to allow us to enable kvm_pv_eoi by default, some time
ago:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg486559.html
("qemu-doc: Document minimum kernel version for KVM in x86_64").

Second, we need compatibility entries setting pcid=off on
PC_COMPAT_2_10 so we don't break compatibility on older
machine-types.


> ---
>  target/i386/cpu.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 3818d7283158..bb2b4bd1b4fe 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -1109,7 +1109,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
>              CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
>              CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
> -            CPUID_EXT_SSE3,
> +            CPUID_EXT_SSE3 | CPUID_EXT_PCID,
>          .features[FEAT_8000_0001_EDX] =
>              CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
>              CPUID_EXT2_SYSCALL,
> @@ -1140,7 +1140,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
>              CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
>              CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
>              CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
> -            CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
> +            CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND |
> +            CPUID_EXT_PCID,
>          .features[FEAT_7_0_EBX] =
>              CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
>              CPUID_7_0_EBX_ERMS,
> -- 
> 2.15.1
>
Vincent Bernat Jan. 8, 2018, 9:51 p.m. UTC | #2
❦  8 janvier 2018 19:16 -0200, Eduardo Habkost <ehabkost@redhat.com> :

> One possible way to work around this problem is to declare that
> QEMU 2.12 with KVM will require Linux v3.6 and newer (because we
> need Linux kernel commit ad756a1603c5 "KVM: VMX: Implement
> PCID/INVPCID for guests with EPT").  I have proposed something
> similar to allow us to enable kvm_pv_eoi by default, some time
> ago:
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg486559.html
> ("qemu-doc: Document minimum kernel version for KVM in x86_64").

I don't see a way to probe KVM to know what's supported, so yes. Should
I add a paragraph similar to yours or would your patch be merged soon?
What are the consequences of running a too old kernel? Would KVM just
hide PCID flag?

> Second, we need compatibility entries setting pcid=off on
> PC_COMPAT_2_10 so we don't break compatibility on older
> machine-types.

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 6f77eb066587..da5bd8304eb0 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -327,6 +327,14 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
         .driver   = TYPE_X86_CPU,\
         .property = "x-hv-max-vps",\
         .value    = "0x40",\
+    },{\
+        .driver   = "SandyBridge-" TYPE_X86_CPU,\
+        .property = "pcid",\
+        .value    = "off",\
+    },{\
+        .driver   = "IvyBridge-" TYPE_X86_CPU,\
+        .property = "pcid",\
+        .value    = "off",\
     },{\
         .driver   = "i440FX-pcihost",\
         .property = "x-pci-hole64-fix",\

I'll resend a proper patch once the first point is cleared.
Eduardo Habkost Jan. 8, 2018, 10:14 p.m. UTC | #3
On Mon, Jan 08, 2018 at 10:51:48PM +0100, Vincent Bernat wrote:
>  ❦  8 janvier 2018 19:16 -0200, Eduardo Habkost <ehabkost@redhat.com> :
> 
> > One possible way to work around this problem is to declare that
> > QEMU 2.12 with KVM will require Linux v3.6 and newer (because we
> > need Linux kernel commit ad756a1603c5 "KVM: VMX: Implement
> > PCID/INVPCID for guests with EPT").  I have proposed something
> > similar to allow us to enable kvm_pv_eoi by default, some time
> > ago:
> > https://www.mail-archive.com/qemu-devel@nongnu.org/msg486559.html
> > ("qemu-doc: Document minimum kernel version for KVM in x86_64").
> 
> I don't see a way to probe KVM to know what's supported, so yes.

We do have a way to probe KVM: GET_SUPPORTED_CPUID.  The problem
here is breaking libvirt and management software expectations.

libvirt assumes "stable runnability": a CPU model that is
runnable on a host using QEMU/machine-type version will stay
runnable on the same host after a QEMU or machine-type upgrade.


> Should
> I add a paragraph similar to yours or would your patch be merged soon?

My patch was dropped because we decided to wait a bit before
enabling kvm_pv_eoi by default.  My paragraph could be improved
by a description of what could happen if an older kernel version
is used (see below).


> What are the consequences of running a too old kernel? Would KVM just
> hide PCID flag?

On an old kernel, the SandyBridge and IvyBridge CPU models will
be unexpectedly become not runnable.


> 
> > Second, we need compatibility entries setting pcid=off on
> > PC_COMPAT_2_10 so we don't break compatibility on older
> > machine-types.

(Oops, I should have said PC_COMPAT_2_11 here)

> 
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 6f77eb066587..da5bd8304eb0 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -327,6 +327,14 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
>          .driver   = TYPE_X86_CPU,\
>          .property = "x-hv-max-vps",\
>          .value    = "0x40",\
> +    },{\
> +        .driver   = "SandyBridge-" TYPE_X86_CPU,\
> +        .property = "pcid",\
> +        .value    = "off",\
> +    },{\
> +        .driver   = "IvyBridge-" TYPE_X86_CPU,\
> +        .property = "pcid",\
> +        .value    = "off",\
>      },{\
>          .driver   = "i440FX-pcihost",\
>          .property = "x-pci-hole64-fix",\

This is correct, but it should be done on PC_COMPAT_2_11 instead
(sorry for my confusion above).

If you don't find PC_COMPAT_2_11 on master, please look for the
"pc: add 2.12 machine types" patch.  I thought it was already
merged on master.  I just queued it on my x86-next tree[1].


[1] https://github.com/ehabkost/qemu x86-next

> 
> I'll resend a proper patch once the first point is cleared.

Thanks!
Vincent Bernat Jan. 8, 2018, 10:22 p.m. UTC | #4
❦  8 janvier 2018 20:14 -0200, Eduardo Habkost <ehabkost@redhat.com> :

>> What are the consequences of running a too old kernel? Would KVM just
>> hide PCID flag?
>
> On an old kernel, the SandyBridge and IvyBridge CPU models will
> be unexpectedly become not runnable.

But, isn't it the same for more recent models that already have PCID
enabled?
Eduardo Habkost Jan. 8, 2018, 10:28 p.m. UTC | #5
On Mon, Jan 08, 2018 at 11:22:36PM +0100, Vincent Bernat wrote:
>  ❦  8 janvier 2018 20:14 -0200, Eduardo Habkost <ehabkost@redhat.com> :
> 
> >> What are the consequences of running a too old kernel? Would KVM just
> >> hide PCID flag?
> >
> > On an old kernel, the SandyBridge and IvyBridge CPU models will
> > be unexpectedly become not runnable.
> 
> But, isn't it the same for more recent models that already have PCID
> enabled?

Yes, the more recent models are already not runnable on those
hosts.  The key here is "unexpectedly": management software can
assume that the CPU model won't become unrunnable when it was
runnable in the past, and logic that decides if/where a VM can be
started (or migrated to) might break.
Paolo Bonzini Jan. 8, 2018, 10:37 p.m. UTC | #6
----- Original Message -----
> From: "Eduardo Habkost" <ehabkost@redhat.com>
> To: "Vincent Bernat" <vincent@bernat.im>
> Cc: "Paolo Bonzini" <pbonzini@redhat.com>, "Richard Henderson" <rth@twiddle.net>, qemu-devel@nongnu.org
> Sent: Monday, January 8, 2018 10:16:23 PM
> Subject: Re: [PATCH] target-i386: add pcid to both Sandy Bridge and Ivy Bridge
> 
> On Mon, Jan 08, 2018 at 09:50:52PM +0100, Vincent Bernat wrote:
> > PCID has been introduced in Sandy Bridge and, currently, KVM doesn't
> > object exposing it to VM as long as it is present on the host. Update
> > CPU model for both Sandy Bridge and Ivy Bridge accordingly.
> > 
> > Signed-off-by: Vincent Bernat <vincent@bernat.im>
> 
> Thanks for your patch.
> 
> We need two things, though:
> 
> First, confirming that all hosts where the SandyBridge and
> IvyBridge CPU models are runnable will support exposing PCID to
> guests (otherwise updating QEMU can make a runnable VM
> configuration suddenly stop being runnable).  This can happen if
> the host kernel is too old.

I've been reading it's also Westmere.  I'll check more carefully tomorrow.
The difference between consumer and server SKUs is important too.

> One possible way to work around this problem is to declare that
> QEMU 2.12 with KVM will require Linux v3.6 and newer (because we
> need Linux kernel commit ad756a1603c5 "KVM: VMX: Implement
> PCID/INVPCID for guests with EPT").

Note that PCID is still not supported for guests without EPT, so
this would break ept=0 with recent "-cpu" models.  I'm not sure of
a way to fix it; probably it just has to be documented.

Paolo
Eduardo Habkost Jan. 8, 2018, 10:56 p.m. UTC | #7
On Mon, Jan 08, 2018 at 05:37:16PM -0500, Paolo Bonzini wrote:
> 
> 
> ----- Original Message -----
> > From: "Eduardo Habkost" <ehabkost@redhat.com>
> > To: "Vincent Bernat" <vincent@bernat.im>
> > Cc: "Paolo Bonzini" <pbonzini@redhat.com>, "Richard Henderson" <rth@twiddle.net>, qemu-devel@nongnu.org
> > Sent: Monday, January 8, 2018 10:16:23 PM
> > Subject: Re: [PATCH] target-i386: add pcid to both Sandy Bridge and Ivy Bridge
> > 
> > On Mon, Jan 08, 2018 at 09:50:52PM +0100, Vincent Bernat wrote:
> > > PCID has been introduced in Sandy Bridge and, currently, KVM doesn't
> > > object exposing it to VM as long as it is present on the host. Update
> > > CPU model for both Sandy Bridge and Ivy Bridge accordingly.
> > > 
> > > Signed-off-by: Vincent Bernat <vincent@bernat.im>
> > 
> > Thanks for your patch.
> > 
> > We need two things, though:
> > 
> > First, confirming that all hosts where the SandyBridge and
> > IvyBridge CPU models are runnable will support exposing PCID to
> > guests (otherwise updating QEMU can make a runnable VM
> > configuration suddenly stop being runnable).  This can happen if
> > the host kernel is too old.
> 
> I've been reading it's also Westmere.  I'll check more carefully tomorrow.
> The difference between consumer and server SKUs is important too.
> 
> > One possible way to work around this problem is to declare that
> > QEMU 2.12 with KVM will require Linux v3.6 and newer (because we
> > need Linux kernel commit ad756a1603c5 "KVM: VMX: Implement
> > PCID/INVPCID for guests with EPT").
> 
> Note that PCID is still not supported for guests without EPT, so
> this would break ept=0 with recent "-cpu" models.  I'm not sure of
> a way to fix it; probably it just has to be documented.

GET_SUPPORTED_CPUID seems to still return PCID as supported
without EPT, doesn't it?

(BTW, is PCID useful for KPTI performance without INVPCID?)
Paolo Bonzini Jan. 8, 2018, 11:09 p.m. UTC | #8
----- Original Message -----
> From: "Eduardo Habkost" <ehabkost@redhat.com>
> To: "Paolo Bonzini" <pbonzini@redhat.com>
> Cc: "Vincent Bernat" <vincent@bernat.im>, "Richard Henderson" <rth@twiddle.net>, qemu-devel@nongnu.org
> Sent: Monday, January 8, 2018 11:56:25 PM
> Subject: Re: [PATCH] target-i386: add pcid to both Sandy Bridge and Ivy Bridge
> 
> On Mon, Jan 08, 2018 at 05:37:16PM -0500, Paolo Bonzini wrote:
> > 
> > 
> > ----- Original Message -----
> > > From: "Eduardo Habkost" <ehabkost@redhat.com>
> > > To: "Vincent Bernat" <vincent@bernat.im>
> > > Cc: "Paolo Bonzini" <pbonzini@redhat.com>, "Richard Henderson"
> > > <rth@twiddle.net>, qemu-devel@nongnu.org
> > > Sent: Monday, January 8, 2018 10:16:23 PM
> > > Subject: Re: [PATCH] target-i386: add pcid to both Sandy Bridge and Ivy
> > > Bridge
> > > 
> > > On Mon, Jan 08, 2018 at 09:50:52PM +0100, Vincent Bernat wrote:
> > > > PCID has been introduced in Sandy Bridge and, currently, KVM doesn't
> > > > object exposing it to VM as long as it is present on the host. Update
> > > > CPU model for both Sandy Bridge and Ivy Bridge accordingly.
> > > > 
> > > > Signed-off-by: Vincent Bernat <vincent@bernat.im>
> > > 
> > > Thanks for your patch.
> > > 
> > > We need two things, though:
> > > 
> > > First, confirming that all hosts where the SandyBridge and
> > > IvyBridge CPU models are runnable will support exposing PCID to
> > > guests (otherwise updating QEMU can make a runnable VM
> > > configuration suddenly stop being runnable).  This can happen if
> > > the host kernel is too old.
> > 
> > I've been reading it's also Westmere.  I'll check more carefully tomorrow.
> > The difference between consumer and server SKUs is important too.
> > 
> > > One possible way to work around this problem is to declare that
> > > QEMU 2.12 with KVM will require Linux v3.6 and newer (because we
> > > need Linux kernel commit ad756a1603c5 "KVM: VMX: Implement
> > > PCID/INVPCID for guests with EPT").
> > 
> > Note that PCID is still not supported for guests without EPT, so
> > this would break ept=0 with recent "-cpu" models.  I'm not sure of
> > a way to fix it; probably it just has to be documented.
> 
> GET_SUPPORTED_CPUID seems to still return PCID as supported
> without EPT, doesn't it?

Indeed it is!  It will also be useful for KPTI performance without
INVPCID, but it won't be useful without EPT.

Paolo

> (BTW, is PCID useful for KPTI performance without INVPCID?)
Eduardo Habkost Jan. 8, 2018, 11:19 p.m. UTC | #9
On Mon, Jan 08, 2018 at 06:09:30PM -0500, Paolo Bonzini wrote:
> 
> 
> ----- Original Message -----
> > From: "Eduardo Habkost" <ehabkost@redhat.com>
> > To: "Paolo Bonzini" <pbonzini@redhat.com>
> > Cc: "Vincent Bernat" <vincent@bernat.im>, "Richard Henderson" <rth@twiddle.net>, qemu-devel@nongnu.org
> > Sent: Monday, January 8, 2018 11:56:25 PM
> > Subject: Re: [PATCH] target-i386: add pcid to both Sandy Bridge and Ivy Bridge
> > 
> > On Mon, Jan 08, 2018 at 05:37:16PM -0500, Paolo Bonzini wrote:
> > > 
> > > 
> > > ----- Original Message -----
> > > > From: "Eduardo Habkost" <ehabkost@redhat.com>
> > > > To: "Vincent Bernat" <vincent@bernat.im>
> > > > Cc: "Paolo Bonzini" <pbonzini@redhat.com>, "Richard Henderson"
> > > > <rth@twiddle.net>, qemu-devel@nongnu.org
> > > > Sent: Monday, January 8, 2018 10:16:23 PM
> > > > Subject: Re: [PATCH] target-i386: add pcid to both Sandy Bridge and Ivy
> > > > Bridge
> > > > 
> > > > On Mon, Jan 08, 2018 at 09:50:52PM +0100, Vincent Bernat wrote:
> > > > > PCID has been introduced in Sandy Bridge and, currently, KVM doesn't
> > > > > object exposing it to VM as long as it is present on the host. Update
> > > > > CPU model for both Sandy Bridge and Ivy Bridge accordingly.
> > > > > 
> > > > > Signed-off-by: Vincent Bernat <vincent@bernat.im>
> > > > 
> > > > Thanks for your patch.
> > > > 
> > > > We need two things, though:
> > > > 
> > > > First, confirming that all hosts where the SandyBridge and
> > > > IvyBridge CPU models are runnable will support exposing PCID to
> > > > guests (otherwise updating QEMU can make a runnable VM
> > > > configuration suddenly stop being runnable).  This can happen if
> > > > the host kernel is too old.
> > > 
> > > I've been reading it's also Westmere.  I'll check more carefully tomorrow.
> > > The difference between consumer and server SKUs is important too.
> > > 
> > > > One possible way to work around this problem is to declare that
> > > > QEMU 2.12 with KVM will require Linux v3.6 and newer (because we
> > > > need Linux kernel commit ad756a1603c5 "KVM: VMX: Implement
> > > > PCID/INVPCID for guests with EPT").
> > > 
> > > Note that PCID is still not supported for guests without EPT, so
> > > this would break ept=0 with recent "-cpu" models.  I'm not sure of
> > > a way to fix it; probably it just has to be documented.
> > 
> > GET_SUPPORTED_CPUID seems to still return PCID as supported
> > without EPT, doesn't it?
> 
> Indeed it is!  It will also be useful for KPTI performance without
> INVPCID, but it won't be useful without EPT.

Well, I can live with "not useful without EPT", as long as it
doesn't mean "broken without EPT".  It looks like we can safely
enable it, as long as:

2) we confirm if all Intel Westmere/SandyBridge/IvyBridge CPUs
   have PCID;
1) QEMU documentation states that it requires Linux v3.6 or newer
   for KVM.
Vincent Bernat Jan. 9, 2018, 6:40 a.m. UTC | #10
❦  8 janvier 2018 17:37 -0500, Paolo Bonzini <pbonzini@redhat.com> :

>> One possible way to work around this problem is to declare that
>> QEMU 2.12 with KVM will require Linux v3.6 and newer (because we
>> need Linux kernel commit ad756a1603c5 "KVM: VMX: Implement
>> PCID/INVPCID for guests with EPT").
>
> Note that PCID is still not supported for guests without EPT, so
> this would break ept=0 with recent "-cpu" models.  I'm not sure of
> a way to fix it; probably it just has to be documented.

From the above patch, it seems only INVPCID needs EPT. KVM exposes PCID
whenever it is present on the host.
Vincent Bernat Jan. 9, 2018, 6:41 a.m. UTC | #11
❦  8 janvier 2018 20:56 -0200, Eduardo Habkost <ehabkost@redhat.com> :


> (BTW, is PCID useful for KPTI performance without INVPCID?)

It seems it is:

https://mail-archive.com/linux-kernel@vger.kernel.org/msg1576774.html
Vincent Bernat Jan. 9, 2018, 7:04 a.m. UTC | #12
❦  8 janvier 2018 21:19 -0200, Eduardo Habkost <ehabkost@redhat.com> :

>> > GET_SUPPORTED_CPUID seems to still return PCID as supported
>> > without EPT, doesn't it?
>> 
>> Indeed it is!  It will also be useful for KPTI performance without
>> INVPCID, but it won't be useful without EPT.
>
> Well, I can live with "not useful without EPT", as long as it
> doesn't mean "broken without EPT".  It looks like we can safely
> enable it, as long as:
>
> 2) we confirm if all Intel Westmere/SandyBridge/IvyBridge CPUs
>    have PCID;

I didn't find an authoritative information about that on Intel
website. Various sites indeed says the feature was introduced in
Westmere. And Greg KH mentions Westmere here too:
 https://mail-archive.com/linux-kernel@vger.kernel.org/msg1576774.html

> 1) QEMU documentation states that it requires Linux v3.6 or newer
>    for KVM.

I have updated the patch and sent it in a new thread. It's now based on
x86-next.
diff mbox series

Patch

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 3818d7283158..bb2b4bd1b4fe 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1109,7 +1109,7 @@  static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
             CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
-            CPUID_EXT_SSE3,
+            CPUID_EXT_SSE3 | CPUID_EXT_PCID,
         .features[FEAT_8000_0001_EDX] =
             CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
             CPUID_EXT2_SYSCALL,
@@ -1140,7 +1140,8 @@  static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
             CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
-            CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+            CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND |
+            CPUID_EXT_PCID,
         .features[FEAT_7_0_EBX] =
             CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
             CPUID_7_0_EBX_ERMS,