From nobody Sat Feb 7 12:20:01 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB2F91E1C3B for ; Tue, 7 Jan 2025 15:43:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736264635; cv=none; b=c6JLcLq5O13H/fVhixhZ8Z6gJ1m3b7qbhj+X8l0I4dNUVKsNqYe/JtAbYFKH8/XCYx6mgrLK7bPdtHmdx8IzBIafJboRLBAl1676e4bQblavzCZCvxQexpwCiJDtm4/5/r5uucQl7uceplW7W1rD7kp0V/KR/m1aOGkQJtCC/Yw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736264635; c=relaxed/simple; bh=kff/5MuiUSshICdL0Pz3Kwaact1TDCjVUg2HjOr3gSg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ek8oLQl9W8WFxagogmwFHn+Y2QPcguCIqCK3SK6lYjSDv4Qin6w8DvyhUg34luMwNkdVLpPlsWnxwAu9lABu0Pk4dpNAgN6Up0nIqtVLoPVoXQoG6GzTukBGV/ecgzys5fIRn8kbr7mBLv8HPf4xT4vMapleSuZWGiZkScLXTbE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=SQnv+BdO; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="SQnv+BdO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1736264632; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=be/xDpPjneQ7+z88xrOgXMm6ql8CC9vSv4tySFvSNk8=; b=SQnv+BdOjsYYMfAU2LTzbh9oU5RB3hydAxe09kyLYetiOA2zEWfjltjxRpParD5da54MFa PIDQow1CAtNTIJa9cnJK6EWFHIvcBAUXBaOKK91/foy7+TBFYAlyaYme6Me/N25II4esRs gC56lSS6B5yivZYLBmKTVvN+ZMxsvlA= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-342-Z0OgrVEKP1yaUdjVd0RyBw-1; Tue, 07 Jan 2025 10:43:50 -0500 X-MC-Unique: Z0OgrVEKP1yaUdjVd0RyBw-1 X-Mimecast-MFC-AGG-ID: Z0OgrVEKP1yaUdjVd0RyBw Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-385ded5e92aso2969777f8f.3 for ; Tue, 07 Jan 2025 07:43:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736264629; x=1736869429; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=be/xDpPjneQ7+z88xrOgXMm6ql8CC9vSv4tySFvSNk8=; b=LiXwsNloJIVD/03FFLfdAzquZ/rSR3jssBU093h/6RPeFpB8A4E4t1byZ8FkKNN1mg gnvY89dnyliMg9GhOSj7sds64CfGthNW2wXQIPUKRPG9G86zqCLEHwiE0CRGBL9LwvBg fcwaBSMuelYr+TngHM/oxaapIVJ6bTlZFFsxxgSYtI0u1gr8kJ1P9zlkyekeBvvSj7rv PvQHAzr1KZPNIdvJQ8+MIY9awpB7j6BbtAsuDXjY9NueOhsa7pxbR+Ij7u1DbWcHa9Bn YaSvstb47992zVcSfDYRfSi5QFVxUWmmpnxhVhjDSW8l+2/5Fy8ZWQdGK5dlo8X510vD jlqQ== X-Gm-Message-State: AOJu0YxiV3rCQC+YifdJ88fyBu1KgotqAELR6sK3Qg6AQr0Xa5Wyt4Gj DRXmY+C2yQxKG+rZVh+uHOC4YxDsosyJrnmzMw6Z1weGViFlNBnrMspACvvITmKSNTLl/JIr6OM 13wjLqchzAtAsyX1HCsdT1MRwfbJfMPh/M2Keu0LXWt/pTOcpJ6dL/Gby9qdhWsTaBNQ2+1Cufl Ih2paeME23oq/3GQOrVhCZufbmLZmgyEj5dNY3+gPksA== X-Gm-Gg: ASbGncvu8zp9VYZkfb5yvCAUHa25mPjna2Rmeuoa0j4pxJX1cmVvQevhyHe/kF/r0TD xeZSdW5BUebI97p+co8h56fiHrq8A5pyTEupVcbSvqOR2lGabUUonSa3u7PqbbYxKtB5HXH4gbY DA76725aKXyUy70lW0yeHvGCsoMXiAW3WoWyLBfSbA98dKTSR+S72CRQX9/53AS7PhyQRtjW8MA bXBBkuJJkROTcWpK5mm//JApLbpGad2PXnms7FYQRgk8n6amCxLQWumo3F49P12m/cWlFM4+Q6f DGDdHErbUq0/gC+Hu+aKC8TRhiRdssCuqe+GGFPA4g== X-Received: by 2002:a05:6000:1f88:b0:386:4034:f9a0 with SMTP id ffacd0b85a97d-38a22408cbemr49437417f8f.52.1736264629583; Tue, 07 Jan 2025 07:43:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IECHU3QXEd9DSMtt+gL3jnHOKISExr8ZSLHane3TsnWNkBR9T163eXOTOHhVFPDdEe315KvNw== X-Received: by 2002:a05:6000:1f88:b0:386:4034:f9a0 with SMTP id ffacd0b85a97d-38a22408cbemr49437388f8f.52.1736264629175; Tue, 07 Jan 2025 07:43:49 -0800 (PST) Received: from localhost (p200300cbc719170056dc6a88b509d3f3.dip0.t-ipconnect.de. [2003:cb:c719:1700:56dc:6a88:b509:d3f3]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-38a1c828d39sm52310207f8f.9.2025.01.07.07.43.47 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 07 Jan 2025 07:43:48 -0800 (PST) From: David Hildenbrand To: linux-kernel@vger.kernel.org Cc: kvm@vger.kernel.org, linux-s390@vger.kernel.org, David Hildenbrand , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Heiko Carstens , Vasily Gorbik , Alexander Gordeev , Sven Schnelle , Thomas Huth , "Matthew Wilcox (Oracle)" , stable@vger.kernel.org Subject: [PATCH v1 1/4] KVM: s390: vsie: fix some corner-cases when grabbing vsie pages Date: Tue, 7 Jan 2025 16:43:41 +0100 Message-ID: <20250107154344.1003072-2-david@redhat.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250107154344.1003072-1-david@redhat.com> References: <20250107154344.1003072-1-david@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" We try to reuse the same vsie page when re-executing the vsie with a given SCB address. The result is that we use the same shadow SCB -- residing in the vsie page -- and can avoid flushing the TLB when re-running the vsie on a CPU. So, when we allocate a fresh vsie page, or when we reuse a vsie page for a different SCB address -- reusing the shadow SCB in different context -- we set ihcpu=3D0xffff to trigger the flush. However, after we looked up the SCB address in the radix tree, but before we grabbed the vsie page by raising the refcount to 2, someone could reuse the vsie page for a different SCB address, adjusting page->index and the radix tree. In that case, we would be reusing the vsie page with a wrong page->index. Another corner case is that we might set the SCB address for a vsie page, but fail the insertion into the radix tree. Whoever would reuse that page would remove the corresponding radix tree entry -- which might now be a valid entry pointing at another page, resulting in the wrong vsie page getting removed from the radix tree. Let's handle such races better, by validating that the SCB address of a vsie page didn't change after we grabbed it (not reuse for a different SCB; the alternative would be performing another tree lookup), and by setting the SCB address to invalid until the insertion in the tree succeeded (SCB addresses are aligned to 512, so ULONG_MAX is invalid). These scenarios are rare, the effects a bit unclear, and these issues were only found by code inspection. Let's CC stable to be safe. Fixes: a3508fbe9dc6 ("KVM: s390: vsie: initial support for nested virtualiz= ation") Cc: stable@vger.kernel.org Signed-off-by: David Hildenbrand --- arch/s390/kvm/vsie.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 150b9387860ad..0fb527b33734c 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -1362,8 +1362,14 @@ static struct vsie_page *get_vsie_page(struct kvm *k= vm, unsigned long addr) page =3D radix_tree_lookup(&kvm->arch.vsie.addr_to_page, addr >> 9); rcu_read_unlock(); if (page) { - if (page_ref_inc_return(page) =3D=3D 2) - return page_to_virt(page); + if (page_ref_inc_return(page) =3D=3D 2) { + if (page->index =3D=3D addr) + return page_to_virt(page); + /* + * We raced with someone reusing + putting this vsie + * page before we grabbed it. + */ + } page_ref_dec(page); } =20 @@ -1393,15 +1399,20 @@ static struct vsie_page *get_vsie_page(struct kvm *= kvm, unsigned long addr) kvm->arch.vsie.next++; kvm->arch.vsie.next %=3D nr_vcpus; } - radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); + if (page->index !=3D ULONG_MAX) + radix_tree_delete(&kvm->arch.vsie.addr_to_page, + page->index >> 9); } - page->index =3D addr; - /* double use of the same address */ + /* Mark it as invalid until it resides in the tree. */ + page->index =3D ULONG_MAX; + + /* Double use of the same address or allocation failure. */ if (radix_tree_insert(&kvm->arch.vsie.addr_to_page, addr >> 9, page)) { page_ref_dec(page); mutex_unlock(&kvm->arch.vsie.mutex); return NULL; } + page->index =3D addr; mutex_unlock(&kvm->arch.vsie.mutex); =20 vsie_page =3D page_to_virt(page); @@ -1496,7 +1507,9 @@ void kvm_s390_vsie_destroy(struct kvm *kvm) vsie_page =3D page_to_virt(page); release_gmap_shadow(vsie_page); /* free the radix tree entry */ - radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); + if (page->index !=3D ULONG_MAX) + radix_tree_delete(&kvm->arch.vsie.addr_to_page, + page->index >> 9); __free_page(page); } kvm->arch.vsie.page_count =3D 0; --=20 2.47.1