Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1434841 > unrolled thread
| Started by | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| First post | 2016-06-30 23:00 +0200 |
| Last post | 2016-06-30 23:00 +0200 |
| Articles | 20 on this page of 42 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v1 00/11] KVM: x86: break the xAPIC barrier Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
[PATCH v1 06/11] KVM: x86: use hardware-compatible format for APIC ID register Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Re: [PATCH v1 06/11] KVM: x86: use hardware-compatible format for APIC ID register Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 10:40 +0200
Re: [PATCH v1 06/11] KVM: x86: use hardware-compatible format for APIC ID register Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 15:20 +0200
Re: [PATCH v1 06/11] KVM: x86: use hardware-compatible format for APIC ID register Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 16:20 +0200
Re: [PATCH v1 06/11] KVM: x86: use hardware-compatible format for APIC ID register Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 17:00 +0200
Re: [PATCH v1 06/11] KVM: x86: use hardware-compatible format for APIC ID register Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 17:10 +0200
Re: [PATCH v1 06/11] KVM: x86: use hardware-compatible format for APIC ID register Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 18:00 +0200
Re: [PATCH v1 06/11] KVM: x86: use hardware-compatible format for APIC ID register Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 18:40 +0200
[PATCH v1 10/11] KVM: x86: add KVM_CAP_X2APIC_API Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Re: [PATCH v1 10/11] KVM: x86: add KVM_CAP_X2APIC_API Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 10:30 +0200
Re: [PATCH v1 10/11] KVM: x86: add KVM_CAP_X2APIC_API Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 15:30 +0200
Re: [PATCH v1 10/11] KVM: x86: add KVM_CAP_X2APIC_API David Matlack <dmatlack@google.com> - 2016-07-01 20:20 +0200
Re: [PATCH v1 10/11] KVM: x86: add KVM_CAP_X2APIC_API Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 20:40 +0200
[PATCH v1 04/11] KVM: x86: use u16 for logical VCPU mask in lapic Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Re: [PATCH v1 04/11] KVM: x86: use u16 for logical VCPU mask in lapic Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 10:20 +0200
Re: [PATCH v1 04/11] KVM: x86: use u16 for logical VCPU mask in lapic Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 14:50 +0200
Re: [PATCH v1 04/11] KVM: x86: use u16 for logical VCPU mask in lapic Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 16:20 +0200
[PATCH v1 07/11] KVM: VMX: optimize APIC ID read with APICv Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
[PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Andrew Honig <ahonig@google.com> - 2016-07-01 00:20 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 10:50 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 14:50 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 16:10 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 16:40 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 17:10 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 17:20 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 18:00 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 18:40 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 17:40 +0200
Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 09:40 +0200
[PATCH v1 01/11] KVM: x86: bump KVM_SOFT_MAX_VCPUS to 240 Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Re: [PATCH v1 01/11] KVM: x86: bump KVM_SOFT_MAX_VCPUS to 240 Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 10:50 +0200
[PATCH v1 05/11] KVM: x86: use generic function for MSI parsing Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
[PATCH v1 11/11] KVM: x86: bump MAX_VCPUS to 288 Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Re: [PATCH v1 11/11] KVM: x86: bump MAX_VCPUS to 288 Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 10:50 +0200
[PATCH v1 09/11] KVM: x86: reset lapic base in kvm_lapic_reset Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Re: [PATCH v1 09/11] KVM: x86: reset lapic base in kvm_lapic_reset Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 10:50 +0200
[PATCH v1 02/11] KVM: x86: add kvm_apic_map_get_dest_lapic Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Re: [PATCH v1 02/11] KVM: x86: add kvm_apic_map_get_dest_lapic Paolo Bonzini <pbonzini@redhat.com> - 2016-07-01 10:00 +0200
Re: [PATCH v1 02/11] KVM: x86: add kvm_apic_map_get_dest_lapic Radim Krčmář <rkrcmar@redhat.com> - 2016-07-01 14:50 +0200
[PATCH v1 08/11] KVM: x86: directly call recalculate_apic_map on lapic restore Radim Krčmář <rkrcmar@redhat.com> - 2016-06-30 23:00 +0200
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Andrew Honig <ahonig@google.com> |
|---|---|
| Date | 2016-07-01 00:20 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rPStr-6J4-13@gated-at.bofh.it> |
| In reply to | #1434847 |
> - > - new = kzalloc(sizeof(struct kvm_apic_map), GFP_KERNEL); > + u32 size, max_id = 255; > > mutex_lock(&kvm->arch.apic_map_lock); > > + kvm_for_each_vcpu(i, vcpu, kvm) > + if (kvm_apic_present(vcpu)) > + max_id = max(max_id, kvm_apic_id(vcpu->arch.apic)); > + > + /* kvm_apic_map_get_logical_dest() expects multiples of 16 */ > + size = round_up(max_id + 1, 16); Now that you're using the full range of apic_id values, could this calculation overflow? Perhaps max_id could be u64? > + new = kzalloc(sizeof(struct kvm_apic_map) + > + sizeof(struct kvm_lapic) * size, GFP_KERNEL); > + > if (!new) > goto out; >
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 10:50 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ2j8-4pm-9@gated-at.bofh.it> |
| In reply to | #1434876 |
On 01/07/2016 00:15, Andrew Honig wrote:
>> > + /* kvm_apic_map_get_logical_dest() expects multiples of 16 */
>> > + size = round_up(max_id + 1, 16);
> Now that you're using the full range of apic_id values, could this
> calculation overflow? Perhaps max_id could be u64?
Good point, but I wonder if it's a good idea to let userspace allocate
32 GB of memory. :)
Let's put a limit on the maximum supported APIC ID, and report it
through KVM_CHECK_EXTENSION on the new KVM_CAP_X2APIC_API capability.
If 767 is enough for Knights Landing, the allocation below fits in two
pages. If you need to make it higher, please change the allocation to
use kvm_kvzalloc and kvfree.
Last but not least...
>> > + new = kzalloc(sizeof(struct kvm_apic_map) +
>> > + sizeof(struct kvm_lapic) * size, GFP_KERNEL);
^^^^^^^^^^^^^^^^^^^^^^^^
... the sizeof here must be sizeof(struct kvm_lapic *).
Thanks,
Paolo
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-07-01 14:50 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ63o-6GX-9@gated-at.bofh.it> |
| In reply to | #1435160 |
2016-07-01 10:42+0200, Paolo Bonzini: > On 01/07/2016 00:15, Andrew Honig wrote: >>> > + /* kvm_apic_map_get_logical_dest() expects multiples of 16 */ >>> > + size = round_up(max_id + 1, 16); >> Now that you're using the full range of apic_id values, could this >> calculation overflow? Perhaps max_id could be u64? > > Good point, but I wonder if it's a good idea to let userspace allocate > 32 GB of memory. :) Yes, both could happen. I'll change it to u64 to make it future proof. > Let's put a limit on the maximum supported APIC ID, and report it > through KVM_CHECK_EXTENSION on the new KVM_CAP_X2APIC_API capability. > If 767 is enough for Knights Landing, the allocation below fits in two > pages. If you need to make it higher, please change the allocation to > use kvm_kvzalloc and kvfree. We sort of have a capability for maximum APIC ID, KVM_MAX_VCPU_ID, because VCPU ID is initial APIC ID and x2APIC ID should always be the initial APIC ID. Userspace is able to change x2APIC with LAPIC_GET/SET ioctl -- what about forbidding that? > Last but not least... > > >> > + new = kzalloc(sizeof(struct kvm_apic_map) + > >> > + sizeof(struct kvm_lapic) * size, GFP_KERNEL); > ^^^^^^^^^^^^^^^^^^^^^^^^ > ... the sizeof here must be sizeof(struct kvm_lapic *). Oops, thanks.
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 16:10 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ7iO-7C4-5@gated-at.bofh.it> |
| In reply to | #1435296 |
On 01/07/2016 14:44, Radim Krčmář wrote: > 2016-07-01 10:42+0200, Paolo Bonzini: >> On 01/07/2016 00:15, Andrew Honig wrote: >>>>> + /* kvm_apic_map_get_logical_dest() expects multiples of 16 */ >>>>> + size = round_up(max_id + 1, 16); >>> Now that you're using the full range of apic_id values, could this >>> calculation overflow? Perhaps max_id could be u64? >> >> Good point, but I wonder if it's a good idea to let userspace allocate >> 32 GB of memory. :) > > Yes, both could happen. I'll change it to u64 to make it future proof. It's not necessary to change it to u64 if you put a limit, but you can add a WARN_ON(size == 0). Also if kvm_apic_map_get_logical_dest() expects multiples of 16, it should warn whenever the invariant is not respected. >> Let's put a limit on the maximum supported APIC ID, and report it >> through KVM_CHECK_EXTENSION on the new KVM_CAP_X2APIC_API capability. >> If 767 is enough for Knights Landing, the allocation below fits in two >> pages. If you need to make it higher, please change the allocation to >> use kvm_kvzalloc and kvfree. > > We sort of have a capability for maximum APIC ID, KVM_MAX_VCPU_ID, > because VCPU ID is initial APIC ID and x2APIC ID should always be the > initial APIC ID. Should it? According to QEMU if you have e.g. 3 cores per socket one socket take 4 APIC IDs. For Knights Landing the "worst" prime factor in 288 is 3^2 so you need APIC IDs up to 288 * (4/3)^2 = 512. Paolo
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-07-01 16:40 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ7LQ-7MG-11@gated-at.bofh.it> |
| In reply to | #1435354 |
2016-07-01 16:03+0200, Paolo Bonzini: > On 01/07/2016 14:44, Radim Krčmář wrote: >> 2016-07-01 10:42+0200, Paolo Bonzini: >>> On 01/07/2016 00:15, Andrew Honig wrote: >>>>>> + /* kvm_apic_map_get_logical_dest() expects multiples of 16 */ >>>>>> + size = round_up(max_id + 1, 16); >>>> Now that you're using the full range of apic_id values, could this >>>> calculation overflow? Perhaps max_id could be u64? >>> >>> Good point, but I wonder if it's a good idea to let userspace allocate >>> 32 GB of memory. :) >> >> Yes, both could happen. I'll change it to u64 to make it future proof. > > It's not necessary to change it to u64 if you put a limit, but you can > add a WARN_ON(size == 0). Hm, to save 4 bytes and avoid a WARN_ON, I'll change it to u32 max_apic_id instead of u32 size. > Also if kvm_apic_map_get_logical_dest() expects multiples of 16, it > should warn whenever the invariant is not respected. It was to optimize the fast path ... kvm_apic_map_get_logical_dest() can handle arbitrary values, so I'll do that instead of checking or assuming an alignment. >>> Let's put a limit on the maximum supported APIC ID, and report it >>> through KVM_CHECK_EXTENSION on the new KVM_CAP_X2APIC_API capability. >>> If 767 is enough for Knights Landing, the allocation below fits in two >>> pages. If you need to make it higher, please change the allocation to >>> use kvm_kvzalloc and kvfree. >> >> We sort of have a capability for maximum APIC ID, KVM_MAX_VCPU_ID, >> because VCPU ID is initial APIC ID and x2APIC ID should always be the >> initial APIC ID. > > Should it? Yes, x2APIC ID cannot be changed in hardware and is initialized to the intitial APIC ID. Letting LAPIC_SET change x2APIC ID would allow scenarios where userspace reuses old VMs instead of building new ones after reconfiguration. I don't think it's a sensible use case and it it is currently broken, because we don't exit to userspace when changing APIC mode, so KVM would just set APIC ID to VCPU ID on any transition and userspace couldn't amend it. > According to QEMU if you have e.g. 3 cores per socket one > socket take 4 APIC IDs. For Knights Landing the "worst" prime factor in > 288 is 3^2 so you need APIC IDs up to 288 * (4/3)^2 = 512. The topology can result in sparse APIC ID and APIC ID is initialized from VCPU ID, so userspace has to pick VCPU ID accordingly.
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 17:10 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ8eR-8cq-1@gated-at.bofh.it> |
| In reply to | #1435381 |
On 01/07/2016 16:38, Radim Krčmář wrote: >> > Should it? > Yes, x2APIC ID cannot be changed in hardware and is initialized to the > intitial APIC ID. > Letting LAPIC_SET change x2APIC ID would allow scenarios where userspace > reuses old VMs instead of building new ones after reconfiguration. > I don't think it's a sensible use case and it it is currently broken, > because we don't exit to userspace when changing APIC mode, so KVM would > just set APIC ID to VCPU ID on any transition and userspace couldn't > amend it. > >> > According to QEMU if you have e.g. 3 cores per socket one >> > socket take 4 APIC IDs. For Knights Landing the "worst" prime factor in >> > 288 is 3^2 so you need APIC IDs up to 288 * (4/3)^2 = 512. > The topology can result in sparse APIC ID and APIC ID is initialized > from VCPU ID, so userspace has to pick VCPU ID accordingly. Right, I was confusing KVM_MAX_VCPUS and KVM_MAX_VCPU_ID. So the overflow case cannot happen and neither can the 32GB allocation. On the other hand, I suspect you need to bump KVM_MAX_VCPU_ID beyond its current default setting (which is equal to KVM_MAX_VCPUS), up to 511 or 1023. Thanks, Paolo
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 17:20 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ8ox-8fN-1@gated-at.bofh.it> |
| In reply to | #1435397 |
On 01/07/2016 17:06, Paolo Bonzini wrote: >>> >> > Should it? >> Yes, x2APIC ID cannot be changed in hardware and is initialized to the >> intitial APIC ID. >> Letting LAPIC_SET change x2APIC ID would allow scenarios where userspace >> reuses old VMs instead of building new ones after reconfiguration. >> I don't think it's a sensible use case and it it is currently broken, >> because we don't exit to userspace when changing APIC mode, so KVM would >> just set APIC ID to VCPU ID on any transition and userspace couldn't >> amend it. Forgot to reply about this: letting SET_LAPIC change x2APIC IDs is nonsense. In x2APIC mode + new capability disabled SET_LAPIC should ignore the id register altogether for backwards compatibility. In x2APIC mode + new capability enabled it should either ignore it, or fail if the x2APIC ID doesn't match the VCPU id. I suspect the latter is better because it would help catching the case where userspace is erroneously shifting the id left to bits 31-24. Paolo
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-07-01 18:00 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ91f-8tu-17@gated-at.bofh.it> |
| In reply to | #1435412 |
2016-07-01 17:12+0200, Paolo Bonzini: > On 01/07/2016 17:06, Paolo Bonzini wrote: >>>> >> > Should it? >>> Yes, x2APIC ID cannot be changed in hardware and is initialized to the >>> intitial APIC ID. >>> Letting LAPIC_SET change x2APIC ID would allow scenarios where userspace >>> reuses old VMs instead of building new ones after reconfiguration. >>> I don't think it's a sensible use case and it it is currently broken, >>> because we don't exit to userspace when changing APIC mode, so KVM would >>> just set APIC ID to VCPU ID on any transition and userspace couldn't >>> amend it. > > Forgot to reply about this: letting SET_LAPIC change x2APIC IDs is nonsense. > > In x2APIC mode + new capability disabled SET_LAPIC should ignore the id > register altogether for backwards compatibility. I'd still shift SET_LAPIC APIC ID to have internal APIC ID register in hardware-compatible format. > In x2APIC mode + new capability enabled it should either ignore it, or > fail if the x2APIC ID doesn't match the VCPU id. I suspect the latter > is better because it would help catching the case where userspace is > erroneously shifting the id left to bits 31-24. Yes, I'll make it EINVAL.
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 18:40 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ9DX-ug-9@gated-at.bofh.it> |
| In reply to | #1435473 |
On 01/07/2016 17:43, Radim Krčmář wrote: > > Forgot to reply about this: letting SET_LAPIC change x2APIC IDs is nonsense. > > > > In x2APIC mode + new capability disabled SET_LAPIC should ignore the id > > register altogether for backwards compatibility. > > I'd still shift SET_LAPIC APIC ID to have internal APIC ID register in > hardware-compatible format. With the capability disabled, APIC ID should always be in bits 31-24 for both GET and SET. But I think we agree, it's simpler to reason in v2 code and testcases. :) Paolo
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-07-01 17:40 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ8HV-8mD-47@gated-at.bofh.it> |
| In reply to | #1435397 |
2016-07-01 17:06+0200, Paolo Bonzini: > On 01/07/2016 16:38, Radim Krčmář wrote: > On the > other hand, I suspect you need to bump KVM_MAX_VCPU_ID beyond its > current default setting (which is equal to KVM_MAX_VCPUS), up to 511 or > 1023. Yes, thanks for pointing it out. APIC ID 1023 is reasonably low and I'm pretty sure that it cannot be surpassed with any topology of 288 VCPUs. (The limit should be 543, with 257 cores per package.)
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 09:40 +0200 |
| Subject | Re: [PATCH v1 03/11] KVM: x86: dynamic kvm_apic_map |
| Message-ID | <rQ1do-3M7-21@gated-at.bofh.it> |
| In reply to | #1434847 |
On 30/06/2016 22:54, Radim Krčmář wrote: > x2APIC supports up to 2^32-1 LAPICs, but most guest in coming years will > have slighly less VCPUs. Dynamic size saves memory at the cost of > turning one constant into a variable. > > apic_map mutex had to be moved before allocation to avoid races with cpu > hotplug. > > Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> It's important to note another change here, which is that you start using the phys_map for x2apic clustered mode. It's so important that you could make it a separate patch while keeping the phys_map static! :) Paolo
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-06-30 23:00 +0200 |
| Subject | [PATCH v1 01/11] KVM: x86: bump KVM_SOFT_MAX_VCPUS to 240 |
| Message-ID | <rPRe2-5Ou-17@gated-at.bofh.it> |
| In reply to | #1434841 |
240 has been well tested by Red Hat. Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> --- v1: new, loosely related and should have been posted long ago arch/x86/include/asm/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 7a628fb6a2c2..53d39771842b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -35,7 +35,7 @@ #include <asm/kvm_page_track.h> #define KVM_MAX_VCPUS 255 -#define KVM_SOFT_MAX_VCPUS 160 +#define KVM_SOFT_MAX_VCPUS 240 #define KVM_USER_MEM_SLOTS 509 /* memory slots that are not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 3 -- 2.9.0
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 10:50 +0200 |
| Subject | Re: [PATCH v1 01/11] KVM: x86: bump KVM_SOFT_MAX_VCPUS to 240 |
| Message-ID | <rQ2j8-4pm-7@gated-at.bofh.it> |
| In reply to | #1434848 |
On 30/06/2016 22:54, Radim Krčmář wrote: > 240 has been well tested by Red Hat. > > Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> > --- > v1: new, loosely related and should have been posted long ago > > arch/x86/include/asm/kvm_host.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 7a628fb6a2c2..53d39771842b 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -35,7 +35,7 @@ > #include <asm/kvm_page_track.h> > > #define KVM_MAX_VCPUS 255 > -#define KVM_SOFT_MAX_VCPUS 160 > +#define KVM_SOFT_MAX_VCPUS 240 > #define KVM_USER_MEM_SLOTS 509 > /* memory slots that are not exposed to userspace */ > #define KVM_PRIVATE_MEM_SLOTS 3 > Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-06-30 23:00 +0200 |
| Subject | [PATCH v1 05/11] KVM: x86: use generic function for MSI parsing |
| Message-ID | <rPRe2-5Ou-25@gated-at.bofh.it> |
| In reply to | #1434841 |
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
arch/x86/kvm/irq_comm.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index dfb4c6476877..47ad681a33fd 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -388,21 +388,16 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
kvm->arch.nr_reserved_ioapic_pins);
for (i = 0; i < nr_ioapic_pins; ++i) {
hlist_for_each_entry(entry, &table->map[i], link) {
- u32 dest_id, dest_mode;
- bool level;
+ struct kvm_lapic_irq irq;
if (entry->type != KVM_IRQ_ROUTING_MSI)
continue;
- dest_id = (entry->msi.address_lo >> 12) & 0xff;
- dest_mode = (entry->msi.address_lo >> 2) & 0x1;
- level = entry->msi.data & MSI_DATA_TRIGGER_LEVEL;
- if (level && kvm_apic_match_dest(vcpu, NULL, 0,
- dest_id, dest_mode)) {
- u32 vector = entry->msi.data & 0xff;
- __set_bit(vector,
- ioapic_handled_vectors);
- }
+ kvm_set_msi_irq(entry, &irq);
+
+ if (irq.level && kvm_apic_match_dest(vcpu, NULL, 0,
+ irq.dest_id, irq.dest_mode))
+ __set_bit(irq.vector, ioapic_handled_vectors);
}
}
srcu_read_unlock(&kvm->irq_srcu, idx);
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-06-30 23:00 +0200 |
| Subject | [PATCH v1 11/11] KVM: x86: bump MAX_VCPUS to 288 |
| Message-ID | <rPRe2-5Ou-15@gated-at.bofh.it> |
| In reply to | #1434841 |
288 is in high demand because of Knights Landing CPU. We cannot set the limit to 640k, because that would be wasting space. Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> --- arch/x86/include/asm/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 48b0ca18066c..411da14a675e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -34,7 +34,7 @@ #include <asm/asm.h> #include <asm/kvm_page_track.h> -#define KVM_MAX_VCPUS 255 +#define KVM_MAX_VCPUS 288 #define KVM_SOFT_MAX_VCPUS 240 #define KVM_USER_MEM_SLOTS 509 /* memory slots that are not exposed to userspace */ -- 2.9.0
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 10:50 +0200 |
| Subject | Re: [PATCH v1 11/11] KVM: x86: bump MAX_VCPUS to 288 |
| Message-ID | <rQ2j8-4pm-15@gated-at.bofh.it> |
| In reply to | #1434851 |
On 30/06/2016 22:54, Radim Krčmář wrote: > 288 is in high demand because of Knights Landing CPU. > We cannot set the limit to 640k, because that would be wasting space. > > Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> > --- > arch/x86/include/asm/kvm_host.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 48b0ca18066c..411da14a675e 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -34,7 +34,7 @@ > #include <asm/asm.h> > #include <asm/kvm_page_track.h> > > -#define KVM_MAX_VCPUS 255 > +#define KVM_MAX_VCPUS 288 > #define KVM_SOFT_MAX_VCPUS 240 > #define KVM_USER_MEM_SLOTS 509 > /* memory slots that are not exposed to userspace */ > Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Paolo
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-06-30 23:00 +0200 |
| Subject | [PATCH v1 09/11] KVM: x86: reset lapic base in kvm_lapic_reset |
| Message-ID | <rPRe2-5Ou-21@gated-at.bofh.it> |
| In reply to | #1434841 |
LAPIC is reset in xAPIC mode and the surrounding code expects that.
KVM never resets after initialization. This patch is just for sanity.
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
arch/x86/kvm/lapic.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 143df33f451e..46eb71c425cf 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1758,8 +1758,11 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
/* Stop the timer in case it's a reset to an active apic */
hrtimer_cancel(&apic->lapic_timer.timer);
- if (!init_event)
+ if (!init_event) {
+ kvm_lapic_set_base(vcpu, APIC_DEFAULT_PHYS_BASE |
+ MSR_IA32_APICBASE_ENABLE);
kvm_apic_set_xapic_id(apic, vcpu->vcpu_id);
+ }
kvm_apic_set_version(apic->vcpu);
for (i = 0; i < KVM_APIC_LVT_NUM; i++)
@@ -1898,9 +1901,6 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
* thinking that APIC satet has changed.
*/
vcpu->arch.apic_base = MSR_IA32_APICBASE_ENABLE;
- kvm_lapic_set_base(vcpu,
- APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE);
-
static_key_slow_inc(&apic_sw_disabled.key); /* sw disabled at reset */
kvm_lapic_reset(vcpu, false);
kvm_iodevice_init(&apic->dev, &apic_mmio_ops);
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 10:50 +0200 |
| Subject | Re: [PATCH v1 09/11] KVM: x86: reset lapic base in kvm_lapic_reset |
| Message-ID | <rQ2j8-4pm-19@gated-at.bofh.it> |
| In reply to | #1434852 |
On 30/06/2016 22:54, Radim Krčmář wrote:
> LAPIC is reset in xAPIC mode and the surrounding code expects that.
> KVM never resets after initialization. This patch is just for sanity.
>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
> arch/x86/kvm/lapic.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 143df33f451e..46eb71c425cf 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -1758,8 +1758,11 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
> /* Stop the timer in case it's a reset to an active apic */
> hrtimer_cancel(&apic->lapic_timer.timer);
>
> - if (!init_event)
> + if (!init_event) {
> + kvm_lapic_set_base(vcpu, APIC_DEFAULT_PHYS_BASE |
> + MSR_IA32_APICBASE_ENABLE);
> kvm_apic_set_xapic_id(apic, vcpu->vcpu_id);
> + }
> kvm_apic_set_version(apic->vcpu);
>
> for (i = 0; i < KVM_APIC_LVT_NUM; i++)
> @@ -1898,9 +1901,6 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
> * thinking that APIC satet has changed.
> */
> vcpu->arch.apic_base = MSR_IA32_APICBASE_ENABLE;
> - kvm_lapic_set_base(vcpu,
> - APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE);
> -
> static_key_slow_inc(&apic_sw_disabled.key); /* sw disabled at reset */
> kvm_lapic_reset(vcpu, false);
> kvm_iodevice_init(&apic->dev, &apic_mmio_ops);
>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2016-06-30 23:00 +0200 |
| Subject | [PATCH v1 02/11] KVM: x86: add kvm_apic_map_get_dest_lapic |
| Message-ID | <rPRe2-5Ou-29@gated-at.bofh.it> |
| In reply to | #1434841 |
kvm_irq_delivery_to_apic_fast and kvm_intr_is_single_vcpu_fast both
compute the interrupt destination. Factor the code.
'struct kvm_lapic **dst = NULL' had to be added to silence GCC.
GCC might complain about potential NULL access in the future, because it
missed conditions that avoided uninitialized uses of dst.
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
v1: improved comment for kvm_apic_map_get_dest_lapic() [Peter]
arch/x86/kvm/lapic.c | 241 ++++++++++++++++++++++-----------------------------
1 file changed, 103 insertions(+), 138 deletions(-)
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 22a6474af220..238b87b068db 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -671,14 +671,98 @@ static void kvm_apic_disabled_lapic_found(struct kvm *kvm)
}
}
+/* Return true if the interrupt can be handled by using *bitmap as index mask
+ * for valid destinations in *dst array.
+ * Return false if kvm_apic_map_get_dest_lapic did nothing useful.
+ * Note: we may have zero kvm_lapic destinations when we return true, which
+ * means that the interrupt should be dropped. In this case, *bitmap would be
+ * zero and *dst undefined.
+ */
+static inline bool kvm_apic_map_get_dest_lapic(struct kvm *kvm, struct kvm_lapic *src,
+ struct kvm_lapic_irq *irq, struct kvm_apic_map *map,
+ struct kvm_lapic ***dst, unsigned long *bitmap)
+{
+ int i, lowest;
+ bool x2apic_ipi;
+ u16 cid;
+
+ if (irq->shorthand == APIC_DEST_SELF) {
+ *dst = &src;
+ *bitmap = 1;
+ return true;
+ } else if (irq->shorthand)
+ return false;
+
+ x2apic_ipi = src && apic_x2apic_mode(src);
+ if (irq->dest_id == (x2apic_ipi ? X2APIC_BROADCAST : APIC_BROADCAST))
+ return false;
+
+ if (!map)
+ return false;
+
+ if (irq->dest_mode == APIC_DEST_PHYSICAL) {
+ if (irq->dest_id >= ARRAY_SIZE(map->phys_map)) {
+ *bitmap = 0;
+ } else {
+ *dst = &map->phys_map[irq->dest_id];
+ *bitmap = 1;
+ }
+ return true;
+ }
+
+ if (!kvm_apic_logical_map_valid(map))
+ return false;
+
+ apic_logical_id(map, irq->dest_id, &cid, (u16 *)bitmap);
+
+ if (cid >= ARRAY_SIZE(map->logical_map)) {
+ *bitmap = 0;
+ return true;
+ }
+
+ *dst = map->logical_map[cid];
+
+ if (!kvm_lowest_prio_delivery(irq))
+ return true;
+
+ if (!kvm_vector_hashing_enabled()) {
+ lowest = -1;
+ for_each_set_bit(i, bitmap, 16) {
+ if (!(*dst)[i])
+ continue;
+ if (lowest < 0)
+ lowest = i;
+ else if (kvm_apic_compare_prio((*dst)[i]->vcpu,
+ (*dst)[lowest]->vcpu) < 0)
+ lowest = i;
+ }
+ } else {
+ if (!*bitmap)
+ return true;
+
+ lowest = kvm_vector_to_index(irq->vector, hweight16(*bitmap),
+ bitmap, 16);
+
+ if (!(*dst)[lowest]) {
+ kvm_apic_disabled_lapic_found(kvm);
+ *bitmap = 0;
+ return true;
+ }
+ }
+
+ *bitmap = (lowest >= 0) ? 1 << lowest : 0;
+
+ return true;
+}
+
bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map)
{
struct kvm_apic_map *map;
- unsigned long bitmap = 1;
- struct kvm_lapic **dst;
+ unsigned long bitmap;
+ struct kvm_lapic **dst = NULL;
int i;
- bool ret, x2apic_ipi;
+ bool ret;
*r = -1;
@@ -687,86 +771,19 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
return true;
}
- if (irq->shorthand)
- return false;
-
- x2apic_ipi = src && apic_x2apic_mode(src);
- if (irq->dest_id == (x2apic_ipi ? X2APIC_BROADCAST : APIC_BROADCAST))
- return false;
-
- ret = true;
rcu_read_lock();
map = rcu_dereference(kvm->arch.apic_map);
- if (!map) {
- ret = false;
- goto out;
- }
-
- if (irq->dest_mode == APIC_DEST_PHYSICAL) {
- if (irq->dest_id >= ARRAY_SIZE(map->phys_map))
- goto out;
-
- dst = &map->phys_map[irq->dest_id];
- } else {
- u16 cid;
-
- if (!kvm_apic_logical_map_valid(map)) {
- ret = false;
- goto out;
+ ret = kvm_apic_map_get_dest_lapic(kvm, src, irq, map, &dst, &bitmap);
+ if (ret)
+ for_each_set_bit(i, &bitmap, 16) {
+ if (!dst[i])
+ continue;
+ if (*r < 0)
+ *r = 0;
+ *r += kvm_apic_set_irq(dst[i]->vcpu, irq, dest_map);
}
- apic_logical_id(map, irq->dest_id, &cid, (u16 *)&bitmap);
-
- if (cid >= ARRAY_SIZE(map->logical_map))
- goto out;
-
- dst = map->logical_map[cid];
-
- if (!kvm_lowest_prio_delivery(irq))
- goto set_irq;
-
- if (!kvm_vector_hashing_enabled()) {
- int l = -1;
- for_each_set_bit(i, &bitmap, 16) {
- if (!dst[i])
- continue;
- if (l < 0)
- l = i;
- else if (kvm_apic_compare_prio(dst[i]->vcpu,
- dst[l]->vcpu) < 0)
- l = i;
- }
- bitmap = (l >= 0) ? 1 << l : 0;
- } else {
- int idx;
- unsigned int dest_vcpus;
-
- dest_vcpus = hweight16(bitmap);
- if (dest_vcpus == 0)
- goto out;
-
- idx = kvm_vector_to_index(irq->vector,
- dest_vcpus, &bitmap, 16);
-
- if (!dst[idx]) {
- kvm_apic_disabled_lapic_found(kvm);
- goto out;
- }
-
- bitmap = (idx >= 0) ? 1 << idx : 0;
- }
- }
-
-set_irq:
- for_each_set_bit(i, &bitmap, 16) {
- if (!dst[i])
- continue;
- if (*r < 0)
- *r = 0;
- *r += kvm_apic_set_irq(dst[i]->vcpu, irq, dest_map);
- }
-out:
rcu_read_unlock();
return ret;
}
@@ -789,8 +806,9 @@ bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq,
struct kvm_vcpu **dest_vcpu)
{
struct kvm_apic_map *map;
+ unsigned long bitmap;
+ struct kvm_lapic **dst = NULL;
bool ret = false;
- struct kvm_lapic *dst = NULL;
if (irq->shorthand)
return false;
@@ -798,69 +816,16 @@ bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq,
rcu_read_lock();
map = rcu_dereference(kvm->arch.apic_map);
- if (!map)
- goto out;
+ if (kvm_apic_map_get_dest_lapic(kvm, NULL, irq, map, &dst, &bitmap) &&
+ hweight16(bitmap) == 1) {
+ unsigned long i = find_first_bit(&bitmap, 16);
- if (irq->dest_mode == APIC_DEST_PHYSICAL) {
- if (irq->dest_id == 0xFF)
- goto out;
-
- if (irq->dest_id >= ARRAY_SIZE(map->phys_map))
- goto out;
-
- dst = map->phys_map[irq->dest_id];
- if (dst && kvm_apic_present(dst->vcpu))
- *dest_vcpu = dst->vcpu;
- else
- goto out;
- } else {
- u16 cid;
- unsigned long bitmap = 1;
- int i, r = 0;
-
- if (!kvm_apic_logical_map_valid(map))
- goto out;
-
- apic_logical_id(map, irq->dest_id, &cid, (u16 *)&bitmap);
-
- if (cid >= ARRAY_SIZE(map->logical_map))
- goto out;
-
- if (kvm_vector_hashing_enabled() &&
- kvm_lowest_prio_delivery(irq)) {
- int idx;
- unsigned int dest_vcpus;
-
- dest_vcpus = hweight16(bitmap);
- if (dest_vcpus == 0)
- goto out;
-
- idx = kvm_vector_to_index(irq->vector, dest_vcpus,
- &bitmap, 16);
-
- dst = map->logical_map[cid][idx];
- if (!dst) {
- kvm_apic_disabled_lapic_found(kvm);
- goto out;
- }
-
- *dest_vcpu = dst->vcpu;
- } else {
- for_each_set_bit(i, &bitmap, 16) {
- dst = map->logical_map[cid][i];
- if (++r == 2)
- goto out;
- }
-
- if (dst && kvm_apic_present(dst->vcpu))
- *dest_vcpu = dst->vcpu;
- else
- goto out;
+ if (dst[i]) {
+ *dest_vcpu = dst[i]->vcpu;
+ ret = true;
}
}
- ret = true;
-out:
rcu_read_unlock();
return ret;
}
--
2.9.0
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2016-07-01 10:00 +0200 |
| Subject | Re: [PATCH v1 02/11] KVM: x86: add kvm_apic_map_get_dest_lapic |
| Message-ID | <rQ1wJ-3SM-15@gated-at.bofh.it> |
| In reply to | #1434853 |
On 30/06/2016 22:54, Radim Krčmář wrote:
> kvm_irq_delivery_to_apic_fast and kvm_intr_is_single_vcpu_fast both
> compute the interrupt destination. Factor the code.
>
> 'struct kvm_lapic **dst = NULL' had to be added to silence GCC.
> GCC might complain about potential NULL access in the future, because it
> missed conditions that avoided uninitialized uses of dst.
>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
> v1: improved comment for kvm_apic_map_get_dest_lapic() [Peter]
>
> arch/x86/kvm/lapic.c | 241 ++++++++++++++++++++++-----------------------------
> 1 file changed, 103 insertions(+), 138 deletions(-)
>
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 22a6474af220..238b87b068db 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -671,14 +671,98 @@ static void kvm_apic_disabled_lapic_found(struct kvm *kvm)
> }
> }
>
> +/* Return true if the interrupt can be handled by using *bitmap as index mask
> + * for valid destinations in *dst array.
> + * Return false if kvm_apic_map_get_dest_lapic did nothing useful.
> + * Note: we may have zero kvm_lapic destinations when we return true, which
> + * means that the interrupt should be dropped. In this case, *bitmap would be
> + * zero and *dst undefined.
> + */
> +static inline bool kvm_apic_map_get_dest_lapic(struct kvm *kvm, struct kvm_lapic *src,
> + struct kvm_lapic_irq *irq, struct kvm_apic_map *map,
> + struct kvm_lapic ***dst, unsigned long *bitmap)
> +{
> + int i, lowest;
> + bool x2apic_ipi;
> + u16 cid;
> +
> + if (irq->shorthand == APIC_DEST_SELF) {
> + *dst = &src;
This is not valid, &src dies as soon as you leave the function. You
need to pass &src into kvm_apic_map_get_dest_lapic and here do something
like
if (irq->shorthand) {
if (irq->shorthand == APIC_DEST_SELF && p_src) {
*dst = p_src;
*bitmap = 1;
return true;
}
return false;
}
If it's not too hard, I'd like to have patch 4 before this one.
Paolo
> + *bitmap = 1;
> + return true;
> + } else if (irq->shorthand)
> + return false;
> +
> + x2apic_ipi = src && apic_x2apic_mode(src);
> + if (irq->dest_id == (x2apic_ipi ? X2APIC_BROADCAST : APIC_BROADCAST))
> + return false;
> +
> + if (!map)
> + return false;
> +
> + if (irq->dest_mode == APIC_DEST_PHYSICAL) {
> + if (irq->dest_id >= ARRAY_SIZE(map->phys_map)) {
> + *bitmap = 0;
> + } else {
> + *dst = &map->phys_map[irq->dest_id];
> + *bitmap = 1;
> + }
> + return true;
> + }
> +
> + if (!kvm_apic_logical_map_valid(map))
> + return false;
> +
> + apic_logical_id(map, irq->dest_id, &cid, (u16 *)bitmap);
> +
> + if (cid >= ARRAY_SIZE(map->logical_map)) {
> + *bitmap = 0;
> + return true;
> + }
> +
> + *dst = map->logical_map[cid];
> +
> + if (!kvm_lowest_prio_delivery(irq))
> + return true;
> +
> + if (!kvm_vector_hashing_enabled()) {
> + lowest = -1;
> + for_each_set_bit(i, bitmap, 16) {
> + if (!(*dst)[i])
> + continue;
> + if (lowest < 0)
> + lowest = i;
> + else if (kvm_apic_compare_prio((*dst)[i]->vcpu,
> + (*dst)[lowest]->vcpu) < 0)
> + lowest = i;
> + }
> + } else {
> + if (!*bitmap)
> + return true;
> +
> + lowest = kvm_vector_to_index(irq->vector, hweight16(*bitmap),
> + bitmap, 16);
> +
> + if (!(*dst)[lowest]) {
> + kvm_apic_disabled_lapic_found(kvm);
> + *bitmap = 0;
> + return true;
> + }
> + }
> +
> + *bitmap = (lowest >= 0) ? 1 << lowest : 0;
> +
> + return true;
> +}
> +
> bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
> struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map)
> {
> struct kvm_apic_map *map;
> - unsigned long bitmap = 1;
> - struct kvm_lapic **dst;
> + unsigned long bitmap;
> + struct kvm_lapic **dst = NULL;
> int i;
> - bool ret, x2apic_ipi;
> + bool ret;
>
> *r = -1;
>
> @@ -687,86 +771,19 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
> return true;
> }
>
> - if (irq->shorthand)
> - return false;
> -
> - x2apic_ipi = src && apic_x2apic_mode(src);
> - if (irq->dest_id == (x2apic_ipi ? X2APIC_BROADCAST : APIC_BROADCAST))
> - return false;
> -
> - ret = true;
> rcu_read_lock();
> map = rcu_dereference(kvm->arch.apic_map);
>
> - if (!map) {
> - ret = false;
> - goto out;
> - }
> -
> - if (irq->dest_mode == APIC_DEST_PHYSICAL) {
> - if (irq->dest_id >= ARRAY_SIZE(map->phys_map))
> - goto out;
> -
> - dst = &map->phys_map[irq->dest_id];
> - } else {
> - u16 cid;
> -
> - if (!kvm_apic_logical_map_valid(map)) {
> - ret = false;
> - goto out;
> + ret = kvm_apic_map_get_dest_lapic(kvm, src, irq, map, &dst, &bitmap);
> + if (ret)
> + for_each_set_bit(i, &bitmap, 16) {
> + if (!dst[i])
> + continue;
> + if (*r < 0)
> + *r = 0;
> + *r += kvm_apic_set_irq(dst[i]->vcpu, irq, dest_map);
> }
>
> - apic_logical_id(map, irq->dest_id, &cid, (u16 *)&bitmap);
> -
> - if (cid >= ARRAY_SIZE(map->logical_map))
> - goto out;
> -
> - dst = map->logical_map[cid];
> -
> - if (!kvm_lowest_prio_delivery(irq))
> - goto set_irq;
> -
> - if (!kvm_vector_hashing_enabled()) {
> - int l = -1;
> - for_each_set_bit(i, &bitmap, 16) {
> - if (!dst[i])
> - continue;
> - if (l < 0)
> - l = i;
> - else if (kvm_apic_compare_prio(dst[i]->vcpu,
> - dst[l]->vcpu) < 0)
> - l = i;
> - }
> - bitmap = (l >= 0) ? 1 << l : 0;
> - } else {
> - int idx;
> - unsigned int dest_vcpus;
> -
> - dest_vcpus = hweight16(bitmap);
> - if (dest_vcpus == 0)
> - goto out;
> -
> - idx = kvm_vector_to_index(irq->vector,
> - dest_vcpus, &bitmap, 16);
> -
> - if (!dst[idx]) {
> - kvm_apic_disabled_lapic_found(kvm);
> - goto out;
> - }
> -
> - bitmap = (idx >= 0) ? 1 << idx : 0;
> - }
> - }
> -
> -set_irq:
> - for_each_set_bit(i, &bitmap, 16) {
> - if (!dst[i])
> - continue;
> - if (*r < 0)
> - *r = 0;
> - *r += kvm_apic_set_irq(dst[i]->vcpu, irq, dest_map);
> - }
> -out:
> rcu_read_unlock();
> return ret;
> }
> @@ -789,8 +806,9 @@ bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq,
> struct kvm_vcpu **dest_vcpu)
> {
> struct kvm_apic_map *map;
> + unsigned long bitmap;
> + struct kvm_lapic **dst = NULL;
> bool ret = false;
> - struct kvm_lapic *dst = NULL;
>
> if (irq->shorthand)
> return false;
> @@ -798,69 +816,16 @@ bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq,
> rcu_read_lock();
> map = rcu_dereference(kvm->arch.apic_map);
>
> - if (!map)
> - goto out;
> + if (kvm_apic_map_get_dest_lapic(kvm, NULL, irq, map, &dst, &bitmap) &&
> + hweight16(bitmap) == 1) {
> + unsigned long i = find_first_bit(&bitmap, 16);
>
> - if (irq->dest_mode == APIC_DEST_PHYSICAL) {
> - if (irq->dest_id == 0xFF)
> - goto out;
> -
> - if (irq->dest_id >= ARRAY_SIZE(map->phys_map))
> - goto out;
> -
> - dst = map->phys_map[irq->dest_id];
> - if (dst && kvm_apic_present(dst->vcpu))
> - *dest_vcpu = dst->vcpu;
> - else
> - goto out;
> - } else {
> - u16 cid;
> - unsigned long bitmap = 1;
> - int i, r = 0;
> -
> - if (!kvm_apic_logical_map_valid(map))
> - goto out;
> -
> - apic_logical_id(map, irq->dest_id, &cid, (u16 *)&bitmap);
> -
> - if (cid >= ARRAY_SIZE(map->logical_map))
> - goto out;
> -
> - if (kvm_vector_hashing_enabled() &&
> - kvm_lowest_prio_delivery(irq)) {
> - int idx;
> - unsigned int dest_vcpus;
> -
> - dest_vcpus = hweight16(bitmap);
> - if (dest_vcpus == 0)
> - goto out;
> -
> - idx = kvm_vector_to_index(irq->vector, dest_vcpus,
> - &bitmap, 16);
> -
> - dst = map->logical_map[cid][idx];
> - if (!dst) {
> - kvm_apic_disabled_lapic_found(kvm);
> - goto out;
> - }
> -
> - *dest_vcpu = dst->vcpu;
> - } else {
> - for_each_set_bit(i, &bitmap, 16) {
> - dst = map->logical_map[cid][i];
> - if (++r == 2)
> - goto out;
> - }
> -
> - if (dst && kvm_apic_present(dst->vcpu))
> - *dest_vcpu = dst->vcpu;
> - else
> - goto out;
> + if (dst[i]) {
> + *dest_vcpu = dst[i]->vcpu;
> + ret = true;
> }
> }
>
> - ret = true;
> -out:
> rcu_read_unlock();
> return ret;
> }
>
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | linux.kernel
csiph-web