• G
    KVM: PPC: Book3S HV: XIVE: Fix vCPU id sanity check · f54db39f
    Greg Kurz 提交于
    Commit 062cfab7 ("KVM: PPC: Book3S HV: XIVE: Make VP block size
    configurable") updated kvmppc_xive_vcpu_id_valid() in a way that
    allows userspace to trigger an assertion in skiboot and crash the host:
    
    [  696.186248988,3] XIVE[ IC 08  ] eq_blk != vp_blk (0 vs. 1) for target 0x4300008c/0
    [  696.186314757,0] Assert fail: hw/xive.c:2370:0
    [  696.186342458,0] Aborting!
    xive-kvCPU 0043 Backtrace:
     S: 0000000031e2b8f0 R: 0000000030013840   .backtrace+0x48
     S: 0000000031e2b990 R: 000000003001b2d0   ._abort+0x4c
     S: 0000000031e2ba10 R: 000000003001b34c   .assert_fail+0x34
     S: 0000000031e2ba90 R: 0000000030058984   .xive_eq_for_target.part.20+0xb0
     S: 0000000031e2bb40 R: 0000000030059fdc   .xive_setup_silent_gather+0x2c
     S: 0000000031e2bc20 R: 000000003005a334   .opal_xive_set_vp_info+0x124
     S: 0000000031e2bd20 R: 00000000300051a4   opal_entry+0x134
     --- OPAL call token: 0x8a caller R1: 0xc000001f28563850 ---
    
    XIVE maintains the interrupt context state of non-dispatched vCPUs in
    an internal VP structure. We allocate a bunch of those on startup to
    accommodate all possible vCPUs. Each VP has an id, that we derive from
    the vCPU id for efficiency:
    
    static inline u32 kvmppc_xive_vp(struct kvmppc_xive *xive, u32 server)
    {
    	return xive->vp_base + kvmppc_pack_vcpu_id(xive->kvm, server);
    }
    
    The KVM XIVE device used to allocate KVM_MAX_VCPUS VPs. This was
    limitting the number of concurrent VMs because the VP space is
    limited on the HW. Since most of the time, VMs run with a lot less
    vCPUs, commit 062cfab7 ("KVM: PPC: Book3S HV: XIVE: Make VP
    block size configurable") gave the possibility for userspace to
    tune the size of the VP block through the KVM_DEV_XIVE_NR_SERVERS
    attribute.
    
    The check in kvmppc_pack_vcpu_id() was changed from
    
    	cpu < KVM_MAX_VCPUS * xive->kvm->arch.emul_smt_mode
    
    to
    
    	cpu < xive->nr_servers * xive->kvm->arch.emul_smt_mode
    
    The previous check was based on the fact that the VP block had
    KVM_MAX_VCPUS entries and that kvmppc_pack_vcpu_id() guarantees
    that packed vCPU ids are below KVM_MAX_VCPUS. We've changed the
    size of the VP block, but kvmppc_pack_vcpu_id() has nothing to
    do with it and it certainly doesn't ensure that the packed vCPU
    ids are below xive->nr_servers. kvmppc_xive_vcpu_id_valid() might
    thus return true when the VM was configured with a non-standard
    VSMT mode, even if the packed vCPU id is higher than what we
    expect. We end up using an unallocated VP id, which confuses
    OPAL. The assert in OPAL is probably abusive and should be
    converted to a regular error that the kernel can handle, but
    we shouldn't really use broken VP ids in the first place.
    
    Fix kvmppc_xive_vcpu_id_valid() so that it checks the packed
    vCPU id is below xive->nr_servers, which is explicitly what we
    want.
    
    Fixes: 062cfab7 ("KVM: PPC: Book3S HV: XIVE: Make VP block size configurable")
    Cc: stable@vger.kernel.org # v5.5+
    Signed-off-by: NGreg Kurz <groug@kaod.org>
    Reviewed-by: NCédric Le Goater <clg@kaod.org>
    Signed-off-by: NMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/160673876747.695514.1809676603724514920.stgit@bahia.lan
    f54db39f
book3s_xive.c 58.6 KB