diff mbox

KVM: x86: fix guest-initiated crash with x2apic (CVE-2013-6376)

Message ID 1386880614-23300-4-git-send-email-pbonzini@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Paolo Bonzini Dec. 12, 2013, 8:36 p.m. UTC
From: Gleb Natapov <gleb@redhat.com>

A guest can cause a BUG_ON() leading to a host kernel crash.
When the guest writes to the ICR to request an IPI, while in x2apic
mode the following things happen, the destination is read from
ICR2, which is a register that the guest can control.

kvm_irq_delivery_to_apic_fast uses the high 16 bits of ICR2 as the
cluster id.  A BUG_ON is triggered, which is a protection against
accessing map->logical_map with an out-of-bounds access and manages
to avoid that anything really unsafe occurs.

The logic in the code is correct from real HW point of view. The problem
is that KVM supports only one cluster with ID 0 in clustered mode, but
the code that has the bug does not take this into account.

Reported-by: Lars Bull <larsbull@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/lapic.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Radim Krčmář Dec. 13, 2013, 4:07 p.m. UTC | #1
2013-12-12 21:36+0100, Paolo Bonzini:
> From: Gleb Natapov <gleb@redhat.com>
> 
> A guest can cause a BUG_ON() leading to a host kernel crash.
> When the guest writes to the ICR to request an IPI, while in x2apic
> mode the following things happen, the destination is read from
> ICR2, which is a register that the guest can control.
> 
> kvm_irq_delivery_to_apic_fast uses the high 16 bits of ICR2 as the
> cluster id.  A BUG_ON is triggered, which is a protection against
> accessing map->logical_map with an out-of-bounds access and manages
> to avoid that anything really unsafe occurs.
> 
> The logic in the code is correct from real HW point of view. The problem
> is that KVM supports only one cluster with ID 0 in clustered mode, but
> the code that has the bug does not take this into account.

The more I read about x2apic, the more confused I am ...

 - How was the cluster x2apic enabled?

   Linux won't enable cluster x2apic without interrupt remapping and I
   had no idea we were allowed to do it.

 - A hardware test-suite found this?

   This bug can only be hit when the destination cpu is > 256, so the
   request itself is buggy -- we don't support that many in kvm and it
   would crash when initializing the vcpus if we did.
   => It looks like we should just ignore the ipi, because we have no
      vcpus in that cluster.

 - Where does the 'only one supported cluster' come from?

   I only see we use 'struct kvm_lapic *logical_map[16][16];', which
   supports 16 clusters of 16 apics = first 256 vcpus, so if we map
   everything to logical_map[0][0:15], we would not work correctly in
   the cluster x2apic, with > 16 vcpus.

Thanks.

> Reported-by: Lars Bull <larsbull@google.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  arch/x86/kvm/lapic.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index b8bec45c1610..801dc3fd66e1 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -143,6 +143,8 @@ static inline int kvm_apic_id(struct kvm_lapic *apic)
>  	return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
>  }
>  
> +#define KMV_X2APIC_CID_BITS 0
> +
>  static void recalculate_apic_map(struct kvm *kvm)
>  {
>  	struct kvm_apic_map *new, *old = NULL;
> @@ -180,7 +182,8 @@ static void recalculate_apic_map(struct kvm *kvm)
>  		if (apic_x2apic_mode(apic)) {
>  			new->ldr_bits = 32;
>  			new->cid_shift = 16;
> -			new->cid_mask = new->lid_mask = 0xffff;
> +			new->cid_mask = (1 << KMV_X2APIC_CID_BITS) - 1;
> +			new->lid_mask = 0xffff;
>  		} else if (kvm_apic_sw_enabled(apic) &&
>  				!new->cid_mask /* flat mode */ &&
>  				kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) {
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov Dec. 14, 2013, 9:46 a.m. UTC | #2
On Fri, Dec 13, 2013 at 05:07:54PM +0100, Radim Kr?má? wrote:
> 2013-12-12 21:36+0100, Paolo Bonzini:
> > From: Gleb Natapov <gleb@redhat.com>
> > 
> > A guest can cause a BUG_ON() leading to a host kernel crash.
> > When the guest writes to the ICR to request an IPI, while in x2apic
> > mode the following things happen, the destination is read from
> > ICR2, which is a register that the guest can control.
> > 
> > kvm_irq_delivery_to_apic_fast uses the high 16 bits of ICR2 as the
> > cluster id.  A BUG_ON is triggered, which is a protection against
> > accessing map->logical_map with an out-of-bounds access and manages
> > to avoid that anything really unsafe occurs.
> > 
> > The logic in the code is correct from real HW point of view. The problem
> > is that KVM supports only one cluster with ID 0 in clustered mode, but
> > the code that has the bug does not take this into account.
> 
> The more I read about x2apic, the more confused I am ...
> 
>  - How was the cluster x2apic enabled?
> 
>    Linux won't enable cluster x2apic without interrupt remapping and I
>    had no idea we were allowed to do it.
> 
Malicious code can do it.

>  - A hardware test-suite found this?
> 
>    This bug can only be hit when the destination cpu is > 256, so the
>    request itself is buggy -- we don't support that many in kvm and it
>    would crash when initializing the vcpus if we did.
>    => It looks like we should just ignore the ipi, because we have no
>       vcpus in that cluster.
> 
That's the nature of malicious code: it does what your code does not expects
it to do :)


>  - Where does the 'only one supported cluster' come from?
> 
"only one supported cluster" comes from 8 bit cpuid limitation of KVM's x2apic
implementation. With 8 bit cpuid you can only address cluster 0 in logical mode.

>    I only see we use 'struct kvm_lapic *logical_map[16][16];', which
>    supports 16 clusters of 16 apics = first 256 vcpus, so if we map
>    everything to logical_map[0][0:15], we would not work correctly in
>    the cluster x2apic, with > 16 vcpus.
> 
Such config cannot work today because of 8 bit cpuid limitation. When the limitation
will be removed KMV_X2APIC_CID_BITS will be set to actual number of bits we want to support.
It will likely be smaller then 16 bit though since full 18 bit support will require huge tables.

> Thanks.
> 
> > Reported-by: Lars Bull <larsbull@google.com>
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Gleb Natapov <gleb@redhat.com>
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> >  arch/x86/kvm/lapic.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> > index b8bec45c1610..801dc3fd66e1 100644
> > --- a/arch/x86/kvm/lapic.c
> > +++ b/arch/x86/kvm/lapic.c
> > @@ -143,6 +143,8 @@ static inline int kvm_apic_id(struct kvm_lapic *apic)
> >  	return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
> >  }
> >  
> > +#define KMV_X2APIC_CID_BITS 0
> > +
> >  static void recalculate_apic_map(struct kvm *kvm)
> >  {
> >  	struct kvm_apic_map *new, *old = NULL;
> > @@ -180,7 +182,8 @@ static void recalculate_apic_map(struct kvm *kvm)
> >  		if (apic_x2apic_mode(apic)) {
> >  			new->ldr_bits = 32;
> >  			new->cid_shift = 16;
> > -			new->cid_mask = new->lid_mask = 0xffff;
> > +			new->cid_mask = (1 << KMV_X2APIC_CID_BITS) - 1;
> > +			new->lid_mask = 0xffff;
> >  		} else if (kvm_apic_sw_enabled(apic) &&
> >  				!new->cid_mask /* flat mode */ &&
> >  				kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) {
> > -- 
> > 1.8.3.1
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Radim Krčmář Dec. 16, 2013, 12:01 p.m. UTC | #3
2013-12-14 11:46+0200, Gleb Natapov:
> On Fri, Dec 13, 2013 at 05:07:54PM +0100, Radim Kr?má? wrote:
> > 2013-12-12 21:36+0100, Paolo Bonzini:
> > > From: Gleb Natapov <gleb@redhat.com>
> > > 
> > > A guest can cause a BUG_ON() leading to a host kernel crash.
> > > When the guest writes to the ICR to request an IPI, while in x2apic
> > > mode the following things happen, the destination is read from
> > > ICR2, which is a register that the guest can control.
> > > 
> > > kvm_irq_delivery_to_apic_fast uses the high 16 bits of ICR2 as the
> > > cluster id.  A BUG_ON is triggered, which is a protection against
> > > accessing map->logical_map with an out-of-bounds access and manages
> > > to avoid that anything really unsafe occurs.
> > > 
> > > The logic in the code is correct from real HW point of view. The problem
> > > is that KVM supports only one cluster with ID 0 in clustered mode, but
> > > the code that has the bug does not take this into account.
> > 
> > The more I read about x2apic, the more confused I am ...
> > 
> >  - How was the cluster x2apic enabled?
> > 
> >    Linux won't enable cluster x2apic without interrupt remapping and I
> >    had no idea we were allowed to do it.
> > 
> Malicious code can do it.
> 
> >  - A hardware test-suite found this?
> > 
> >    This bug can only be hit when the destination cpu is > 256, so the
> >    request itself is buggy -- we don't support that many in kvm and it
> >    would crash when initializing the vcpus if we did.
> >    => It looks like we should just ignore the ipi, because we have no
> >       vcpus in that cluster.
> > 
> That's the nature of malicious code: it does what your code does not expects
> it to do :)

I was wondering if there wasn't malicious linux on the other side too :)

> >  - Where does the 'only one supported cluster' come from?
> > 
> "only one supported cluster" comes from 8 bit cpuid limitation of KVM's x2apic
> implementation. With 8 bit cpuid you can only address cluster 0 in logical mode.

One x2apic cluster has 16 cpus and we generate the x2apic LDR correctly,
so 8 bit cpuid can address first 16 clusters as well.

  u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));

> >    I only see we use 'struct kvm_lapic *logical_map[16][16];', which
> >    supports 16 clusters of 16 apics = first 256 vcpus, so if we map
> >    everything to logical_map[0][0:15], we would not work correctly in
> >    the cluster x2apic, with > 16 vcpus.
> > 
> Such config cannot work today because of 8 bit cpuid limitation. When the limitation
> will be removed KMV_X2APIC_CID_BITS will be set to actual number of bits we want to support.

Even with KMV_X2APIC_CID_BITS = 4, which would allow us to support 8 bit
cpuid, we would still deliver interrupts destined for cpuid > 256 to
potentially plugged cpus.

> It will likely be smaller then 16 bit though since full 18 bit support will require huge tables.

Yeah, we'll have to do dynamic allocation if we are ever going to need
the full potential of x2apic.
(2^20-16 cpus in cluster and 2^32-1 in flat mode)
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov Dec. 16, 2013, 12:16 p.m. UTC | #4
On Mon, Dec 16, 2013 at 01:01:10PM +0100, Radim Kr?má? wrote:
> > >  - Where does the 'only one supported cluster' come from?
> > > 
> > "only one supported cluster" comes from 8 bit cpuid limitation of KVM's x2apic
> > implementation. With 8 bit cpuid you can only address cluster 0 in logical mode.
> 
> One x2apic cluster has 16 cpus and we generate the x2apic LDR correctly,
> so 8 bit cpuid can address first 16 clusters as well.
> 
>   u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
> 
Interrupt from a device cannot generate such ldr, only IPI can. Only
4 cpus in cluster zero are addressable in clustering mode by a
device. Without irq remapping x2apic is a PV interface between host
and guest where guest needs to know KVM implementation's limitation to
use it. I do not see a point in fixing problems in x2apic logical mode
emulation right now since it will not make it usable, as long as
there is not security problems there.

> > >    I only see we use 'struct kvm_lapic *logical_map[16][16];', which
> > >    supports 16 clusters of 16 apics = first 256 vcpus, so if we map
> > >    everything to logical_map[0][0:15], we would not work correctly in
> > >    the cluster x2apic, with > 16 vcpus.
> > > 
> > Such config cannot work today because of 8 bit cpuid limitation. When the limitation
> > will be removed KMV_X2APIC_CID_BITS will be set to actual number of bits we want to support.
> 
> Even with KMV_X2APIC_CID_BITS = 4, which would allow us to support 8 bit
> cpuid, we would still deliver interrupts destined for cpuid > 256 to
> potentially plugged cpus.
Again, KMV_X2APIC_CID_BITS = 4 will not allow us to support 8 bit cpuids
unfortunately, not sure what you mean by the second part of the sentence.

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Radim Krčmář Dec. 16, 2013, 12:55 p.m. UTC | #5
2013-12-16 14:16+0200, Gleb Natapov:
> On Mon, Dec 16, 2013 at 01:01:10PM +0100, Radim Kr?má? wrote:
> > > >  - Where does the 'only one supported cluster' come from?
> > > > 
> > > "only one supported cluster" comes from 8 bit cpuid limitation of KVM's x2apic
> > > implementation. With 8 bit cpuid you can only address cluster 0 in logical mode.
> > 
> > One x2apic cluster has 16 cpus and we generate the x2apic LDR correctly,
> > so 8 bit cpuid can address first 16 clusters as well.
> > 
> >   u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
> > 
> Interrupt from a device cannot generate such ldr, only IPI can. Only
> 4 cpus in cluster zero are addressable in clustering mode by a
> device. Without irq remapping x2apic is a PV interface between host
> and guest where guest needs to know KVM implementation's limitation to
> use it.

Thanks, I'll read more about devices ... still no idea how could they
address cluster > 15.

>         I do not see a point in fixing problems in x2apic logical mode
> emulation right now since it will not make it usable, as long as
> there is not security problems there.

Agreed; I wanted to know why this patch was correct, if we cared.

> > > >    I only see we use 'struct kvm_lapic *logical_map[16][16];', which
> > > >    supports 16 clusters of 16 apics = first 256 vcpus, so if we map
> > > >    everything to logical_map[0][0:15], we would not work correctly in
> > > >    the cluster x2apic, with > 16 vcpus.
> > > > 
> > > Such config cannot work today because of 8 bit cpuid limitation. When the limitation
> > > will be removed KMV_X2APIC_CID_BITS will be set to actual number of bits we want to support.
> > 
> > Even with KMV_X2APIC_CID_BITS = 4, which would allow us to support 8 bit
> > cpuid, we would still deliver interrupts destined for cpuid > 256 to
> > potentially plugged cpus.
> Again, KMV_X2APIC_CID_BITS = 4 will not allow us to support 8 bit cpuids
> unfortunately, not sure what you mean by the second part of the sentence.

Sorry, I meant that with this change, we map all clusters to cluster 0,
which has two flaws:
 - in kvm_lapic_set_base(), the order of vcpu creation determines those
   assigned to cluster 0, and the rest is unaddressable (overwritten)
 - we can send IPI to an unplugged high cpuid and it arives in cluster 0
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Radim Krčmář Dec. 16, 2013, 1:31 p.m. UTC | #6
2013-12-16 13:55+0100, Radim Kr?má?:
> 2013-12-16 14:16+0200, Gleb Natapov:
> > On Mon, Dec 16, 2013 at 01:01:10PM +0100, Radim Kr?má? wrote:
> > > > >  - Where does the 'only one supported cluster' come from?
> > > > > 
> > > > "only one supported cluster" comes from 8 bit cpuid limitation of KVM's x2apic
> > > > implementation. With 8 bit cpuid you can only address cluster 0 in logical mode.
> > > 
> > > One x2apic cluster has 16 cpus and we generate the x2apic LDR correctly,
> > > so 8 bit cpuid can address first 16 clusters as well.
> > > 
> > >   u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
> > > 
> > Interrupt from a device cannot generate such ldr, only IPI can. Only
> > 4 cpus in cluster zero are addressable in clustering mode by a
> > device. Without irq remapping x2apic is a PV interface between host
> > and guest where guest needs to know KVM implementation's limitation to
> > use it.
> 
> Thanks, I'll read more about devices ... still no idea how could they
> address cluster > 15.
> 
> >         I do not see a point in fixing problems in x2apic logical mode
> > emulation right now since it will not make it usable, as long as
> > there is not security problems there.
> 
> Agreed; I wanted to know why this patch was correct, if we cared.
> 
> > > > >    I only see we use 'struct kvm_lapic *logical_map[16][16];', which
> > > > >    supports 16 clusters of 16 apics = first 256 vcpus, so if we map
> > > > >    everything to logical_map[0][0:15], we would not work correctly in
> > > > >    the cluster x2apic, with > 16 vcpus.
> > > > > 
> > > > Such config cannot work today because of 8 bit cpuid limitation. When the limitation
> > > > will be removed KMV_X2APIC_CID_BITS will be set to actual number of bits we want to support.
> > > 
> > > Even with KMV_X2APIC_CID_BITS = 4, which would allow us to support 8 bit
> > > cpuid, we would still deliver interrupts destined for cpuid > 256 to
> > > potentially plugged cpus.
> > Again, KMV_X2APIC_CID_BITS = 4 will not allow us to support 8 bit cpuids
> > unfortunately, not sure what you mean by the second part of the sentence.
> 
> Sorry, I meant that with this change, we map all clusters to cluster 0,
> which has two flaws:
>  - in kvm_lapic_set_base(), the order of vcpu creation determines those

Gah, should have been 'recalculate_apic_map()' ...

The patch would be especially surprising with a dynamic adding of vcpus.

>    assigned to cluster 0, and the rest is unaddressable (overwritten)
>  - we can send IPI to an unplugged high cpuid and it arives in cluster 0
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov Dec. 16, 2013, 4:22 p.m. UTC | #7
On Mon, Dec 16, 2013 at 02:31:43PM +0100, Radim Kr?má? wrote:
> 2013-12-16 13:55+0100, Radim Kr?má?:
> > 2013-12-16 14:16+0200, Gleb Natapov:
> > > On Mon, Dec 16, 2013 at 01:01:10PM +0100, Radim Kr?má? wrote:
> > > > > >  - Where does the 'only one supported cluster' come from?
> > > > > > 
> > > > > "only one supported cluster" comes from 8 bit cpuid limitation of KVM's x2apic
> > > > > implementation. With 8 bit cpuid you can only address cluster 0 in logical mode.
> > > > 
> > > > One x2apic cluster has 16 cpus and we generate the x2apic LDR correctly,
> > > > so 8 bit cpuid can address first 16 clusters as well.
> > > > 
> > > >   u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
> > > > 
> > > Interrupt from a device cannot generate such ldr, only IPI can. Only
> > > 4 cpus in cluster zero are addressable in clustering mode by a
> > > device. Without irq remapping x2apic is a PV interface between host
> > > and guest where guest needs to know KVM implementation's limitation to
> > > use it.
> > 
> > Thanks, I'll read more about devices ... still no idea how could they
> > address cluster > 15.
> > 
With irq remapping device they will be able to provide 32bit apic addresses.

> > >         I do not see a point in fixing problems in x2apic logical mode
> > > emulation right now since it will not make it usable, as long as
> > > there is not security problems there.
> > 
> > Agreed; I wanted to know why this patch was correct, if we cared.
> > 
> > > > > >    I only see we use 'struct kvm_lapic *logical_map[16][16];', which
> > > > > >    supports 16 clusters of 16 apics = first 256 vcpus, so if we map
> > > > > >    everything to logical_map[0][0:15], we would not work correctly in
> > > > > >    the cluster x2apic, with > 16 vcpus.
> > > > > > 
> > > > > Such config cannot work today because of 8 bit cpuid limitation. When the limitation
> > > > > will be removed KMV_X2APIC_CID_BITS will be set to actual number of bits we want to support.
> > > > 
> > > > Even with KMV_X2APIC_CID_BITS = 4, which would allow us to support 8 bit
> > > > cpuid, we would still deliver interrupts destined for cpuid > 256 to
> > > > potentially plugged cpus.
> > > Again, KMV_X2APIC_CID_BITS = 4 will not allow us to support 8 bit cpuids
> > > unfortunately, not sure what you mean by the second part of the sentence.
> > 
> > Sorry, I meant that with this change, we map all clusters to cluster 0,
> > which has two flaws:
> >  - in kvm_lapic_set_base(), the order of vcpu creation determines those
> 
> Gah, should have been 'recalculate_apic_map()' ...
> 
> The patch would be especially surprising with a dynamic adding of vcpus.
> 
> >    assigned to cluster 0, and the rest is unaddressable (overwritten)
> >  - we can send IPI to an unplugged high cpuid and it arives in cluster 0
It does not matter since well behaved guest is not supposed to configure apic like
that.

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index b8bec45c1610..801dc3fd66e1 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -143,6 +143,8 @@  static inline int kvm_apic_id(struct kvm_lapic *apic)
 	return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
 }
 
+#define KMV_X2APIC_CID_BITS 0
+
 static void recalculate_apic_map(struct kvm *kvm)
 {
 	struct kvm_apic_map *new, *old = NULL;
@@ -180,7 +182,8 @@  static void recalculate_apic_map(struct kvm *kvm)
 		if (apic_x2apic_mode(apic)) {
 			new->ldr_bits = 32;
 			new->cid_shift = 16;
-			new->cid_mask = new->lid_mask = 0xffff;
+			new->cid_mask = (1 << KMV_X2APIC_CID_BITS) - 1;
+			new->lid_mask = 0xffff;
 		} else if (kvm_apic_sw_enabled(apic) &&
 				!new->cid_mask /* flat mode */ &&
 				kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) {