On Mon, Sep 06, 2021, Paolo Bonzini wrote: > On 03/09/21 23:15, Eduardo Habkost wrote: > > - Increases KVM_MAX_VCPU_ID from 1023 to 4096. ... > > Eduardo Habkost (3): > > kvm: x86: Set KVM_MAX_VCPU_ID to 4*KVM_MAX_VCPUS ... > > kvm: x86: Increase MAX_VCPUS to 1024 > > kvm: x86: Increase KVM_SOFT_MAX_VCPUS to 710 > > > > arch/x86/include/asm/kvm_host.h | 18 +++++++++++++++--- > > 1 file changed, 15 insertions(+), 3 deletions(-) > > > > Queued, thanks. Before we commit to this, can we sort out the off-by-one mess that is KVM_MAX_VCPU_ID? As Eduardo pointed out[*], Juergen's commit 76b4f357d0e7 ("x86/kvm: fix vcpu-id indexed array sizes") _shouldn't_ be necessary because kvm_vm_ioctl_create_vcpu() rejects attempts to create id==KVM_MAX_VCPU_ID if (id >= KVM_MAX_VCPU_ID) return -EINVAL; which aligns with the docs for KVM_CREATE_VCPU: The vcpu id is an integer in the range [0, max_vcpu_id) but the fix is "needed" because rtc_irq_eoi_tracking_reset() does bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID + 1); and now we have this DECLARE_BITMAP(map, KVM_MAX_VCPU_ID + 1); u8 vectors[KVM_MAX_VCPU_ID + 1]; which is wrong as well. The "right" fix would have been to change rtc_irq_eoi_tracking_reset(), but that looks all kinds of wrong on the surface. Non-x86 really mucks it up because generic code does: #ifndef KVM_MAX_VCPU_ID #define KVM_MAX_VCPU_ID KVM_MAX_VCPUS #endif which means pretty much everything else can create more vCPUs than vCPU IDs. Maybe fix KVM's internal KVM_MAX_VCPU_ID so that it's incluse, and handle the backwards compability mess in KVM_CAP_MAX_VCPU_ID? Then have the max ID for x86 be (4*KVM_MAX_VCPUS - 1). E.g. something like: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e5d5c5ed7dd4..2e5c8081f72b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4061,7 +4061,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) r = KVM_MAX_VCPUS; break; case KVM_CAP_MAX_VCPU_ID: - r = KVM_MAX_VCPU_ID; + /* KVM's ABI is stupid. */ + r = KVM_MAX_VCPU_ID - 1; break; case KVM_CAP_PV_MMU: /* obsolete */ r = 0; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b50dbe269f4b..ba46c42a4a6f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3460,7 +3460,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) struct kvm_vcpu *vcpu; struct page *page; - if (id >= KVM_MAX_VCPU_ID) + if (id > KVM_MAX_VCPU_ID) return -EINVAL; mutex_lock(&kvm->lock); 17:23:40 ✔ ~/go/src/kernel.org/host $ gdd diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index caaa0f592d8e..0292d8a5ce5e 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -434,7 +434,7 @@ extern int kvmppc_h_logical_ci_store(struct kvm_vcpu *vcpu); #define SPLIT_HACK_OFFS 0xfb000000 /* - * This packs a VCPU ID from the [0..KVM_MAX_VCPU_ID) space down to the + * This packs a VCPU ID from the [0..KVM_MAX_VCPU_ID] space down to the * [0..KVM_MAX_VCPUS) space, using knowledge of the guest's core stride * (but not its actual threading mode, which is not available) to avoid * collisions. diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 9f52f282b1aa..beeebace8d1c 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -33,11 +33,11 @@ #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE #include <asm/kvm_book3s_asm.h> /* for MAX_SMT_THREADS */ -#define KVM_MAX_VCPU_ID (MAX_SMT_THREADS * KVM_MAX_VCORES) +#define KVM_MAX_VCPU_ID (MAX_SMT_THREADS * KVM_MAX_VCORES) - 1 #define KVM_MAX_NESTED_GUESTS KVMPPC_NR_LPIDS #else -#define KVM_MAX_VCPU_ID KVM_MAX_VCPUS +#define KVM_MAX_VCPU_ID KVM_MAX_VCPUS - 1 #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ #define __KVM_HAVE_ARCH_INTC_INITIALIZED diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e5d5c5ed7dd4..5c20c0bd4db6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4061,7 +4061,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) r = KVM_MAX_VCPUS; break; case KVM_CAP_MAX_VCPU_ID: - r = KVM_MAX_VCPU_ID; + /* KVM's ABI is stupid. */ + r = KVM_MAX_VCPU_ID + 1; break; case KVM_CAP_PV_MMU: /* obsolete */ r = 0; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ae7735b490b4..37ef972caf4b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -40,7 +40,7 @@ #include <linux/kvm_dirty_ring.h> #ifndef KVM_MAX_VCPU_ID -#define KVM_MAX_VCPU_ID KVM_MAX_VCPUS +#define KVM_MAX_VCPU_ID KVM_MAX_VCPUS - 1 #endif /* diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b50dbe269f4b..ba46c42a4a6f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3460,7 +3460,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) struct kvm_vcpu *vcpu; struct page *page; - if (id >= KVM_MAX_VCPU_ID) + if (id > KVM_MAX_VCPU_ID) return -EINVAL; mutex_lock(&kvm->lock);