kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PULL 0/2] KVM: s390: Some fixes for 6.4
@ 2023-05-04 17:16 Claudio Imbrenda
  2023-05-04 17:16 ` [GIT PULL 1/2] KVM: s390: pv: fix asynchronous teardown for small VMs Claudio Imbrenda
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Claudio Imbrenda @ 2023-05-04 17:16 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, linux-s390, frankja, borntraeger, hca, david

Hi Paolo,

just a couple of bugfixes, nothing too exceptional here.


please pull, thanks!

Claudio


The following changes since commit 8a46df7cd135fe576c18efa418cd1549e51f2732:

  KVM: s390: pci: fix virtual-physical confusion on module unload/load (2023-04-20 16:30:35 +0200)

are available in the Git repository at:

  ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git tags/kvm-s390-next-6.4-2

for you to fetch changes up to c148dc8e2fa403be501612ee409db866eeed35c0:

  KVM: s390: fix race in gmap_make_secure() (2023-05-04 18:26:27 +0200)

----------------------------------------------------------------
For 6.4

----------------------------------------------------------------
Claudio Imbrenda (2):
      KVM: s390: pv: fix asynchronous teardown for small VMs
      KVM: s390: fix race in gmap_make_secure()

 arch/s390/kernel/uv.c | 32 +++++++++++---------------------
 arch/s390/kvm/pv.c    |  5 +++++
 arch/s390/mm/gmap.c   |  7 +++++++
 3 files changed, 23 insertions(+), 21 deletions(-)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [GIT PULL 1/2] KVM: s390: pv: fix asynchronous teardown for small VMs
  2023-05-04 17:16 [GIT PULL 0/2] KVM: s390: Some fixes for 6.4 Claudio Imbrenda
@ 2023-05-04 17:16 ` Claudio Imbrenda
  2023-05-04 17:16 ` [GIT PULL 2/2] KVM: s390: fix race in gmap_make_secure() Claudio Imbrenda
  2023-05-05 10:13 ` [GIT PULL 0/2] KVM: s390: Some fixes for 6.4 Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Claudio Imbrenda @ 2023-05-04 17:16 UTC (permalink / raw)
  To: pbonzini
  Cc: kvm, linux-s390, frankja, borntraeger, hca, david, Marc Hartmayer

On machines without the Destroy Secure Configuration Fast UVC, the
topmost level of page tables is set aside and freed asynchronously
as last step of the asynchronous teardown.

Each gmap has a host_to_guest radix tree mapping host (userspace)
addresses (with 1M granularity) to gmap segment table entries (pmds).

If a guest is smaller than 2GB, the topmost level of page tables is the
segment table (i.e. there are only 2 levels). Replacing it means that
the pointers in the host_to_guest mapping would become stale and cause
all kinds of nasty issues.

This patch fixes the issue by disallowing asynchronous teardown for
guests with only 2 levels of page tables. Userspace should (and already
does) try using the normal destroy if the asynchronous one fails.

Update s390_replace_asce so it refuses to replace segment type ASCEs.
This is still needed in case the normal destroy VM fails.

Fixes: fb491d5500a7 ("KVM: s390: pv: asynchronous destroy for reboot")
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-Id: <20230421085036.52511-2-imbrenda@linux.ibm.com>
---
 arch/s390/kvm/pv.c  | 5 +++++
 arch/s390/mm/gmap.c | 7 +++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c
index e032ebbf51b9..3ce5f4351156 100644
--- a/arch/s390/kvm/pv.c
+++ b/arch/s390/kvm/pv.c
@@ -314,6 +314,11 @@ int kvm_s390_pv_set_aside(struct kvm *kvm, u16 *rc, u16 *rrc)
 	 */
 	if (kvm->arch.pv.set_aside)
 		return -EINVAL;
+
+	/* Guest with segment type ASCE, refuse to destroy asynchronously */
+	if ((kvm->arch.gmap->asce & _ASCE_TYPE_MASK) == _ASCE_TYPE_SEGMENT)
+		return -EINVAL;
+
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index 5a716bdcba05..2267cf9819b2 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -2833,6 +2833,9 @@ EXPORT_SYMBOL_GPL(s390_unlist_old_asce);
  * s390_replace_asce - Try to replace the current ASCE of a gmap with a copy
  * @gmap: the gmap whose ASCE needs to be replaced
  *
+ * If the ASCE is a SEGMENT type then this function will return -EINVAL,
+ * otherwise the pointers in the host_to_guest radix tree will keep pointing
+ * to the wrong pages, causing use-after-free and memory corruption.
  * If the allocation of the new top level page table fails, the ASCE is not
  * replaced.
  * In any case, the old ASCE is always removed from the gmap CRST list.
@@ -2847,6 +2850,10 @@ int s390_replace_asce(struct gmap *gmap)
 
 	s390_unlist_old_asce(gmap);
 
+	/* Replacing segment type ASCEs would cause serious issues */
+	if ((gmap->asce & _ASCE_TYPE_MASK) == _ASCE_TYPE_SEGMENT)
+		return -EINVAL;
+
 	page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER);
 	if (!page)
 		return -ENOMEM;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [GIT PULL 2/2] KVM: s390: fix race in gmap_make_secure()
  2023-05-04 17:16 [GIT PULL 0/2] KVM: s390: Some fixes for 6.4 Claudio Imbrenda
  2023-05-04 17:16 ` [GIT PULL 1/2] KVM: s390: pv: fix asynchronous teardown for small VMs Claudio Imbrenda
@ 2023-05-04 17:16 ` Claudio Imbrenda
  2023-05-05 10:13 ` [GIT PULL 0/2] KVM: s390: Some fixes for 6.4 Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Claudio Imbrenda @ 2023-05-04 17:16 UTC (permalink / raw)
  To: pbonzini
  Cc: kvm, linux-s390, frankja, borntraeger, hca, david, Jason Gunthorpe

Fix a potential race in gmap_make_secure() and remove the last user of
follow_page() without FOLL_GET.

The old code is locking something it doesn't have a reference to, and
as explained by Jason and David in this discussion:
https://lore.kernel.org/linux-mm/Y9J4P%2FRNvY1Ztn0Q@nvidia.com/
it can lead to all kind of bad things, including the page getting
unmapped (MADV_DONTNEED), freed, reallocated as a larger folio and the
unlock_page() would target the wrong bit.
There is also another race with the FOLL_WRITE, which could race
between the follow_page() and the get_locked_pte().

The main point is to remove the last use of follow_page() without
FOLL_GET or FOLL_PIN, removing the races can be considered a nice
bonus.

Link: https://lore.kernel.org/linux-mm/Y9J4P%2FRNvY1Ztn0Q@nvidia.com/
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Fixes: 214d9bbcd3a6 ("s390/mm: provide memory management functions for protected KVM guests")
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-Id: <20230428092753.27913-2-imbrenda@linux.ibm.com>
---
 arch/s390/kernel/uv.c | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
index 9f18a4af9c13..cb2ee06df286 100644
--- a/arch/s390/kernel/uv.c
+++ b/arch/s390/kernel/uv.c
@@ -192,21 +192,10 @@ static int expected_page_refs(struct page *page)
 	return res;
 }
 
-static int make_secure_pte(pte_t *ptep, unsigned long addr,
-			   struct page *exp_page, struct uv_cb_header *uvcb)
+static int make_page_secure(struct page *page, struct uv_cb_header *uvcb)
 {
-	pte_t entry = READ_ONCE(*ptep);
-	struct page *page;
 	int expected, cc = 0;
 
-	if (!pte_present(entry))
-		return -ENXIO;
-	if (pte_val(entry) & _PAGE_INVALID)
-		return -ENXIO;
-
-	page = pte_page(entry);
-	if (page != exp_page)
-		return -ENXIO;
 	if (PageWriteback(page))
 		return -EAGAIN;
 	expected = expected_page_refs(page);
@@ -304,17 +293,18 @@ int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb)
 		goto out;
 
 	rc = -ENXIO;
-	page = follow_page(vma, uaddr, FOLL_WRITE);
-	if (IS_ERR_OR_NULL(page))
-		goto out;
-
-	lock_page(page);
 	ptep = get_locked_pte(gmap->mm, uaddr, &ptelock);
-	if (should_export_before_import(uvcb, gmap->mm))
-		uv_convert_from_secure(page_to_phys(page));
-	rc = make_secure_pte(ptep, uaddr, page, uvcb);
+	if (pte_present(*ptep) && !(pte_val(*ptep) & _PAGE_INVALID) && pte_write(*ptep)) {
+		page = pte_page(*ptep);
+		rc = -EAGAIN;
+		if (trylock_page(page)) {
+			if (should_export_before_import(uvcb, gmap->mm))
+				uv_convert_from_secure(page_to_phys(page));
+			rc = make_page_secure(page, uvcb);
+			unlock_page(page);
+		}
+	}
 	pte_unmap_unlock(ptep, ptelock);
-	unlock_page(page);
 out:
 	mmap_read_unlock(gmap->mm);
 
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [GIT PULL 0/2] KVM: s390: Some fixes for 6.4
  2023-05-04 17:16 [GIT PULL 0/2] KVM: s390: Some fixes for 6.4 Claudio Imbrenda
  2023-05-04 17:16 ` [GIT PULL 1/2] KVM: s390: pv: fix asynchronous teardown for small VMs Claudio Imbrenda
  2023-05-04 17:16 ` [GIT PULL 2/2] KVM: s390: fix race in gmap_make_secure() Claudio Imbrenda
@ 2023-05-05 10:13 ` Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2023-05-05 10:13 UTC (permalink / raw)
  To: Claudio Imbrenda; +Cc: kvm, linux-s390, frankja, borntraeger, hca, david

On Thu, May 4, 2023 at 7:16 PM Claudio Imbrenda <imbrenda@linux.ibm.com> wrote:
>
> Hi Paolo,
>
> just a couple of bugfixes, nothing too exceptional here.
>
>
> please pull, thanks!
>
> Claudio

Done, thank you.

Paolo

>
>
> The following changes since commit 8a46df7cd135fe576c18efa418cd1549e51f2732:
>
>   KVM: s390: pci: fix virtual-physical confusion on module unload/load (2023-04-20 16:30:35 +0200)
>
> are available in the Git repository at:
>
>   ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git tags/kvm-s390-next-6.4-2
>
> for you to fetch changes up to c148dc8e2fa403be501612ee409db866eeed35c0:
>
>   KVM: s390: fix race in gmap_make_secure() (2023-05-04 18:26:27 +0200)
>
> ----------------------------------------------------------------
> For 6.4
>
> ----------------------------------------------------------------
> Claudio Imbrenda (2):
>       KVM: s390: pv: fix asynchronous teardown for small VMs
>       KVM: s390: fix race in gmap_make_secure()
>
>  arch/s390/kernel/uv.c | 32 +++++++++++---------------------
>  arch/s390/kvm/pv.c    |  5 +++++
>  arch/s390/mm/gmap.c   |  7 +++++++
>  3 files changed, 23 insertions(+), 21 deletions(-)
>


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-05-05 10:14 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-04 17:16 [GIT PULL 0/2] KVM: s390: Some fixes for 6.4 Claudio Imbrenda
2023-05-04 17:16 ` [GIT PULL 1/2] KVM: s390: pv: fix asynchronous teardown for small VMs Claudio Imbrenda
2023-05-04 17:16 ` [GIT PULL 2/2] KVM: s390: fix race in gmap_make_secure() Claudio Imbrenda
2023-05-05 10:13 ` [GIT PULL 0/2] KVM: s390: Some fixes for 6.4 Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).