From nobody Fri Oct 2 12:21:44 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 6B69145FFB3 for ; Fri, 31 Jul 2026 16:43:54 +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=1785516236; cv=none; b=iPyPysv8j0tSUp9mtR2dQ4DueR7s+Q/lLIYsETTUJVKTK/y4ukgBkIdtiexCUp0LoVliu/72x3Ja/cUXQO2EpjAViHmWZfHi5MMuJ32jJB7Z5v65ebTa9DX/ESiz+3EVN+5E1xDHM099G5hiE2gXTsDURyY/5ZFKMXCr1sQ4mLA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785516236; c=relaxed/simple; bh=04S1gzKFN2BK4RzlrOHQobVEGSqWLyPeu4/lGaAgilE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=C2Hbo4NpP+rBo46YAATVU7jJZdvvyU/eAzwWishV6zDfjJjVEsxzJUOGIN+XCGpkjrSF3x4JzyPD4EGjw9Z/p9FQlXwZ7b4Q7QRhoBPC7BZpoWiIujOnY/qg+AXy6ogU5PzalwyUNQk7gjxslnRkrKpgpQ92mEZjuEcVltk4Xq0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=Tr5ucZnr; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=Z+FaFEU9; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="Tr5ucZnr"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="Z+FaFEU9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1785516233; 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=VBHFLJxPt4apj6AE6jTX9tz6JkNc6fSnqMXU7ny6bKM=; b=Tr5ucZnrhSBDQ5AMzIL/s45An7zdvRtOJnfNT1YM/M3i4j/ks7TA3SNECy7oHOYGZc6hw2 JqEE9dR3qosB4E64HDG6w0ZJpOrGX8rdc1bm1nHJ4G59aanC6djD3+BptjSiSnxmVMYl4r oOARmoyNlz8wQu4e+9dxQ6Sas2U6HK8= Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-454-3J-wPV5aPca3pJOsBPbooA-1; Fri, 31 Jul 2026 12:43:48 -0400 X-MC-Unique: 3J-wPV5aPca3pJOsBPbooA-1 X-Mimecast-MFC-AGG-ID: 3J-wPV5aPca3pJOsBPbooA_1785516227 Received: by mail-ed1-f70.google.com with SMTP id 4fb4d7f45d1cf-698aa8bd688so1362465a12.0 for ; Fri, 31 Jul 2026 09:43:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1785516227; x=1786121027; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VBHFLJxPt4apj6AE6jTX9tz6JkNc6fSnqMXU7ny6bKM=; b=Z+FaFEU93OqDL/AhvReT9Neyl2KZ7ZMDSanAz5yDXvljd+We7QmdxdUu/wei6WmNgT wnopHr9jk6G17VktXHQp6/eYwhEv8ogdV4GCczzYuZRUaryhbgGnGjDVV40IVkwoT7Oj sMS0wKS1QHLCY7mY3XIP2I3zy2QZ2OuvFBZHGwLnwqDa6qPdnt2uMoD2qQy0Q6JocMXJ sfDZmwXX59PbYiMmDWdD6+Tn5EwXKf75YYRNtUkvvftGdumXC5PrAr1v7bVDKYIi3A4R qHA2lhNNtymh3QnrVxhcCHHFpwYl4yY6EbRRWJn3ow6SBGFjntSYtOf/+/LoD6IPczZQ bVnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785516227; x=1786121027; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=VBHFLJxPt4apj6AE6jTX9tz6JkNc6fSnqMXU7ny6bKM=; b=CosJfemNdiZC0Jm+tg75HFdtTEtKWC+OXU0DslFR2a4VwbwvFd8zifa54JF3OPemny iOz/VzDpKVcTydDw1owEC2DlcO3T1zyjhe7GDea+2y8QEFnNswGvn8pVU/3o5COueW4e nedF/WghK3XLtOEBUyQ6QDeTBrB5CUWvyOR2wsX5TCwCZ8RQnWmLNKmJU5wHbHvT41pc l/OtupawbrtuS4Se+9wI/WP0elPsUAgY6dD8tUSxTv20aiRwCHi5C2LiG1+auWyh0UyT EVMyOqvuvLI2ZsP+VJe4z9OrpKmkxMc8/3yNysdF5JFxWjFECA1m3wV0CvUlGAQ/eUVK VqRg== X-Gm-Message-State: AOJu0YzUxOwDD1wgHf70kxzuKHEM68iT0ohOlJImC7b+4YpI4Gp51+Z7 SJRZmUiYZjkAJIWnlrCcpiEYP3hAdDoReeaa5WdQB8x4GMhlElJiyH4bwF/mL6uHz7LlowIXGsm WJNtQROXqPLORuAxX0ieklfqHglb+fQOBfszmZcq2PMB4BtT0Eei4zZJEst4NqTql2Mx4unCA7v Fqf0fUln9YiFdC/cn2fNkDot4Q8lePoldZiPZujs+EjtPaM4IIow== X-Gm-Gg: AR+sD10GJxnCbsYgsYun+0JlPRCUKFmsgEzypIiR7oFj0faIHz6SI8/ZkYmLUbY10cH QVLFREq0al4IamkQV4jZEVMtXN6BSVU+iSjk03N13e35Q7A9ok19V7jNikf/8tsyM4BXNOD+OO6 uv8CRILY2MSBPrl45I8yiHfG56GMETBSh/kLj0b0MHmvAafBclISS449rjR8wW/IqgWpOhYTrst IjzjxRfBokdOgyW0n+kgW5/H5S6oaSShbP22PfdEBKvx9KubU2BV6gJZOH3GUXGjSVtea7oV0I/ hb37/7wFfqgqk7x23KdmEBzAw4ONJZ03sLZVhUxglljrxJG2tffUeZKlOIlOx3sAQ2ecRvSahO6 xZHwZBRG4d0LqKPket9yFESnrm5Hc9P8njyxCBBvHqUNFfnNg9Ge9a9PemoQMFjW/utltO0AsMq A2oyU= X-Received: by 2002:a05:6402:4491:b0:6a0:47:71a3 with SMTP id 4fb4d7f45d1cf-6a0a7d09735mr241970a12.20.1785516226776; Fri, 31 Jul 2026 09:43:46 -0700 (PDT) X-Received: by 2002:a05:6402:4491:b0:6a0:47:71a3 with SMTP id 4fb4d7f45d1cf-6a0a7d09735mr241946a12.20.1785516226373; Fri, 31 Jul 2026 09:43:46 -0700 (PDT) Received: from [192.168.10.48] ([151.95.34.92]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a09c655626sm2907232a12.22.2026.07.31.09.43.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jul 2026 09:43:45 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Boris Brezillon , Thomas Zimmermann , David Hildenbrand , Michal Hocko , Sergio Lopez , Christian Koenig , Huang Rui , bcm-kernel-feedback-list@broadcom.com, dri-devel@lists.freedesktop.org, linux-mm@kvack.org Subject: [PATCH RFT 1/3] mm: export variants of vmf_insert_pfn* for use with pfn_mkwrite() Date: Fri, 31 Jul 2026 18:43:39 +0200 Message-ID: <20260731164341.1109827-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260731164341.1109827-1-pbonzini@redhat.com> References: <20260731164341.1109827-1-pbonzini@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" Right now, users of .pfn_mkwrite() have no way to create a PTE that has gone through maybe_mkwrite(). Because vma_set_page_prot() will have cleared the writable PTE bit, users of fixup_user_fault() will see a read-only PTE and have no clue that the page needs a *second* fault to reach its final status. Handling this in fixup_user_fault() is problematic: the information about the presence of *_mkwrite is only recorded in vma->vm_page_prot, which is an opaque pgprot_t, therefore only follow_pfnmap_start() knows how to retrieve it. There are actually some preexisting functions that suggest how this is supposed to be handled, namely vmf_insert_page_mkwrite() and vmf_insert_pfn_pmd(). Adjust mm/memory.c to export two more functions: vmf_insert_pfn_mkwrite() for the common case where vma->vm_page_prot is okay, and __vmf_insert_pfn_prot() when really all parameters are needed. This makes it possible to fix drivers that use .pfn_mkwrite together with vmf_insert_pfn() and vmf_insert_pfn_prot(). Signed-off-by: Paolo Bonzini Tested-by: Sergio Lopez --- include/linux/mm.h | 4 +++ mm/huge_memory.c | 2 +- mm/memory.c | 75 +++++++++++++++++++++++++++++++++------------- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 34c79b5fcb9b..33c7de36b214 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -4551,6 +4551,10 @@ vm_fault_t vmf_insert_pfn(struct vm_area_struct *vma= , unsigned long addr, unsigned long pfn); vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long a= ddr, unsigned long pfn, pgprot_t pgprot); +vm_fault_t vmf_insert_pfn_mkwrite(struct vm_area_struct *vma, unsigned lon= g addr, + unsigned long pfn, bool write); +vm_fault_t __vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long= addr, + unsigned long pfn, pgprot_t pgprot, bool mkwrite); vm_fault_t vmf_insert_mixed(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma, diff --git a/mm/huge_memory.c b/mm/huge_memory.c index b5d1e9d4463d..2f4dcaa819b7 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1615,7 +1615,7 @@ static vm_fault_t insert_pmd(struct vm_area_struct *v= ma, unsigned long addr, * @pfn: pfn to insert * @write: whether it's a write fault * - * Insert a pmd size pfn. See vmf_insert_pfn() for additional info. + * Insert a pmd size pfn. See vmf_insert_pfn_mkwrite() for additional info. * * Return: vm_fault_t value. */ diff --git a/mm/memory.c b/mm/memory.c index 40997a26846f..7b950be8f511 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2718,6 +2718,34 @@ static vm_fault_t insert_pfn(struct vm_area_struct *= vma, unsigned long addr, return VM_FAULT_NOPAGE; } =20 +vm_fault_t __vmf_insert_pfn_prot(struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn, pgprot_t pgprot, + bool mkwrite) +{ + /* + * Technically, architectures with pte_special can avoid all these + * restrictions (same for remap_pfn_range). However we would like + * consistency in testing and feature parity among all, so we should + * try to keep these invariants in place for everybody. + */ + BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))); + BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) =3D=3D + (VM_PFNMAP|VM_MIXEDMAP)); + BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags)); + BUG_ON((vma->vm_flags & VM_MIXEDMAP) && pfn_valid(pfn)); + + if (addr < vma->vm_start || addr >=3D vma->vm_end) + return VM_FAULT_SIGBUS; + + if (!pfn_modify_allowed(pfn, pgprot)) + return VM_FAULT_SIGBUS; + + pfnmap_setup_cachemode_pfn(pfn, &pgprot); + + return insert_pfn(vma, addr, pfn, pgprot, mkwrite); +} +EXPORT_SYMBOL(__vmf_insert_pfn_prot); + /** * vmf_insert_pfn_prot - insert single pfn into user vma with specified pg= prot * @vma: user vma to map to @@ -2754,27 +2782,7 @@ static vm_fault_t insert_pfn(struct vm_area_struct *= vma, unsigned long addr, vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long a= ddr, unsigned long pfn, pgprot_t pgprot) { - /* - * Technically, architectures with pte_special can avoid all these - * restrictions (same for remap_pfn_range). However we would like - * consistency in testing and feature parity among all, so we should - * try to keep these invariants in place for everybody. - */ - BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))); - BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) =3D=3D - (VM_PFNMAP|VM_MIXEDMAP)); - BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags)); - BUG_ON((vma->vm_flags & VM_MIXEDMAP) && pfn_valid(pfn)); - - if (addr < vma->vm_start || addr >=3D vma->vm_end) - return VM_FAULT_SIGBUS; - - if (!pfn_modify_allowed(pfn, pgprot)) - return VM_FAULT_SIGBUS; - - pfnmap_setup_cachemode_pfn(pfn, &pgprot); - - return insert_pfn(vma, addr, pfn, pgprot, false); + return __vmf_insert_pfn_prot(vma, addr, pfn, pgprot, false); } EXPORT_SYMBOL(vmf_insert_pfn_prot); =20 @@ -2805,6 +2813,31 @@ vm_fault_t vmf_insert_pfn(struct vm_area_struct *vma= , unsigned long addr, } EXPORT_SYMBOL(vmf_insert_pfn); =20 +/** + * vmf_insert_pfn_mkwrite - insert single pfn into user vma, possibly writ= able + * @vma: user vma to map to + * @addr: target user address of this page + * @pfn: source kernel pfn + * @write: whether the PTE should be installed writable + * + * Like vmf_insert_pfn(), except that @write allows installing a writable + * PTE even when @vma is under write notification, i.e. when it has a + * .page_mkwrite() or .pfn_mkwrite() callback and vma_set_page_prot() has + * therefore cleared the write bit from @vma->vm_page_prot. + * + * Note that neither of these callbacks is invoked, so the caller must + * itself do whatever they would have done if @write is true. + * + * Context: Process context. May allocate using %GFP_KERNEL. + * Return: vm_fault_t value. + */ +vm_fault_t vmf_insert_pfn_mkwrite(struct vm_area_struct *vma, unsigned lon= g addr, + unsigned long pfn, bool write) +{ + return __vmf_insert_pfn_prot(vma, addr, pfn, vma->vm_page_prot, write); +} +EXPORT_SYMBOL(vmf_insert_pfn_mkwrite); + static bool vm_mixed_ok(struct vm_area_struct *vma, unsigned long pfn, bool mkwrite) { --=20 2.55.0 From nobody Fri Oct 2 12:21:44 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.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 9ADE745FFA0 for ; Fri, 31 Jul 2026 16:43:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785516235; cv=none; b=OQtlhyWb8AR8MF1BfqBy588QskoSmFES4tPrUMh+0XBieIinHvOQO5ZDCBMXUNYF2g0TQEwmkVoc7t/iKxT7CO5Gn7FnWvDi46Myuwwm+Ls4KzSvZrRzpz2YkHRKwGBU0kUdLbbWzPe7e+lXjMfgXezpgpzEFK7eRWJNVtN0Luw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785516235; c=relaxed/simple; bh=dDHSTOzfodwH41AG8mWGo0E+iIXJYN7gqzY27YFcp3Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CERX5YBDDMoIAgbaUWsGqvO2bk4pQf9f6FOCOLULw+mG2IajCN+f+LKvbaKe495vUfuJygXDnFCVX+XPWgmGWEpK8rL7dKxIPVhkUc8ccZ5A1sYntuWob6ykDcG6jKYo7A1Rd/8OU9/RBBzyGtqPOfQka8VIugFiFg1o4KxJb8I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=B6FrsRmQ; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=NWPeVabh; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="B6FrsRmQ"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="NWPeVabh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1785516232; 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=+ltyqZW5ZfqrwkkeZqLpjTnozgkU+0DHxMfwj6ZzMkA=; b=B6FrsRmQSzL74EZVS3n8K9/ho+i7Hi4du2O9OedyktruTtPpajK/gx59LbJaMQ7wdgolgr n45jJ3L7x4WkHfcJntHBv1VuQQklPv2wFc+nB+DR5U5q9krsFghLSRwG7PswmFN/j4rwcR nxl6N6gpM0n5uQ3ZKQlyR8N3ayb3Wxk= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-321-Q32aQ5YqP9iqotvSq5leFw-1; Fri, 31 Jul 2026 12:43:51 -0400 X-MC-Unique: Q32aQ5YqP9iqotvSq5leFw-1 X-Mimecast-MFC-AGG-ID: Q32aQ5YqP9iqotvSq5leFw_1785516230 Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-c15d4224f9dso96562366b.3 for ; Fri, 31 Jul 2026 09:43:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1785516230; x=1786121030; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+ltyqZW5ZfqrwkkeZqLpjTnozgkU+0DHxMfwj6ZzMkA=; b=NWPeVabh4o/ZBbeqqe1VfwQY5p+QG7tqA9FXu3C4MG76tLS5E0IbAyJ3bgVBa1BYul b89f2fMNAf3PE8WGkge3ZWXoF5me46XeG3EaGIA/w6ozDdM3wT8Fi6N2ow6VHSG5/ip/ IJbIbJ2pEqVdMSJ6nFe/amiVrY1U7TgV4g+1Af+JntNDo3oMV5zHFQ9QrBqmNVBQOFgQ honBL7v0+dmsVXUOTUDLi3jLdS1id+rMDWhIrkiedDdnnbVN8i4pTr8W+Dc5IptCv9Eo WQpeA5FvfPso4N4/o1QOFGu2NaBellySCRVBufhKhDLHr2jb+IrNwyb+GqF7C4ulB7/6 57gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785516230; x=1786121030; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=+ltyqZW5ZfqrwkkeZqLpjTnozgkU+0DHxMfwj6ZzMkA=; b=Sllv0uUY1JiwvUtFyxGNn5dv/pYArQdqiiqUQbi0RutsgkLPkSyE8qGigZQcnAOZeB m+eqJ0INL+8cmeK8ZuyZXAodrfP/nyl8IBk1e/HUjPS4AbJ67UyI/TwAIIZxhGGuEwXX VD4UjFbRdNu6RA4ceCQLdterF9esuJ0sFMejwU4y7lGn6xBgsDeougKnM4rQZ6hYJ/0y B+R8ksM+j5RkGEqnkaxVVxud3kT08Pp+Rvm/a81dWZMS3thUWmhhjoqQ544+PFWGCeAa MKjlgfQNvcJK5cRkUS9o/bDYYmJYIqftBQ36igUlHGS/GTgicTMrYY2myytz2Wfhjb4z 1j4w== X-Gm-Message-State: AOJu0YwkJ3v+C0cIc+/mEN+FUbJzKpwPdvIP8rfeH8AHsTuV8Ktv8wd8 uNnZEsdOtPd6r//rwCzc65xZ746a8/vp07O4WjhN/cOr6D0ypaD+aXZA9a/X8MQdItXDHYmjgdA +3qhv2yMhioYH1kUWIQ9IWkH/lsnR6v7cVDpoMwbakmmpa4FNVV2m2ej3p+H2l6KC2fEz/3hZ8S rNB9IGOYDV9eXyq7DRVOA0DYLQ3+0z0xZBLCv7fuRtv96MAWnYKg== X-Gm-Gg: AR+sD11uM+/xX32pWNA/c/5W65JrgaOzQCpfN0D2xrwezDOzWTXxtWUL6Lwl715oHXA CVLV6cXFmtIYKsTk1sAEUSh2V69Fl8OQtYoy47lj0hLc+MYOqnAekOs1KZO5tMb4HSUG4zKnhJ3 Z05GdPz7C5af868n1a04K5rEXbAJhTwj25YQOulSyKMp0WwN3SPqVU63x6X6pGbSHMfarXZjc3g qM7dlx1EFK7b9NZh7iT7/vYTNd65EV4u5IWO9ZSak159QyRdp/AfV1WRGlYXNq1KD69twkik05p C3bPyD5/0NFaAT2By/yBSTqFVjlVUQwe3E0JTAPmGt0f+SnQWsXWkNrx5sAEuojch6FROcSfr59 v3gSnrSF16/ojbEyPJ/6q08qqLu5w7fzTpaaU88OnNoldjpZeVqEqMPeWDWNjrTs+KDkSVwPdl5 4dnH0= X-Received: by 2002:a17:907:d1f:b0:c1f:17f6:2a74 with SMTP id a640c23a62f3a-c1fe7fc540fmr36349266b.9.1785516230009; Fri, 31 Jul 2026 09:43:50 -0700 (PDT) X-Received: by 2002:a17:907:d1f:b0:c1f:17f6:2a74 with SMTP id a640c23a62f3a-c1fe7fc540fmr36346066b.9.1785516229473; Fri, 31 Jul 2026 09:43:49 -0700 (PDT) Received: from [192.168.10.48] ([151.95.34.92]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c1fd4537761sm215223766b.52.2026.07.31.09.43.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jul 2026 09:43:48 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Boris Brezillon , Thomas Zimmermann , David Hildenbrand , Michal Hocko , Sergio Lopez , Christian Koenig , Huang Rui , bcm-kernel-feedback-list@broadcom.com, dri-devel@lists.freedesktop.org, linux-mm@kvack.org Subject: [PATCH RFT 2/3] drm/shmem_helper: use vmf_insert_pfn_mkwrite() Date: Fri, 31 Jul 2026 18:43:40 +0200 Message-ID: <20260731164341.1109827-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260731164341.1109827-1-pbonzini@redhat.com> References: <20260731164341.1109827-1-pbonzini@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" This ensures that KVM or VFIO correctly see a writable PTE when they request one. Otherwise, a guest write to an unpopulated PTE from a mapping backed by a DRM GEM BO triggers a VM exit with EFAULT. The code actually is simpler, because the same logic already applied to the hugepage mapping case using vmf_insert_pfn_pmd(). Reported-by: Sergio Lopez Link: https://lore.kernel.org/kvm/20260729072044.25796-1-slp@redhat.com/ Fixes: 28e3918179aa ("drm/gem-shmem: Track folio accessed/dirty status in m= map") Signed-off-by: Paolo Bonzini Reviewed-by: Boris Brezillon Tested-by: Sergio Lopez --- drivers/gpu/drm/drm_gem_shmem_helper.c | 38 ++++++++++++++------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_g= em_shmem_helper.c index c989459eb215..33a14f558276 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -589,11 +589,25 @@ static void drm_gem_shmem_record_mkwrite(struct vm_fa= ult *vmf) folio_mark_dirty(page_folio(shmem->pages[page_offset])); } =20 +/* + * Because the vm_ops have a .pfn_mkwrite() callback, vma_set_page_prot() + * has cleared the write bit from vma->vm_page_prot. vmf_insert_pfn() + * would install a read-only entry even for a write fault, relying on a + * second fault to reach .pfn_mkwrite() and upgrade it, but that second + * fault never happens for fixup_user_fault() callers that directly + * walk the page tables with follow_pfnmap_start(). To ensure that + * they don't see the read-only entry, pass FAULT_FLAG_WRITE info down + * to install a writable entry right away. Because .pfn_mkwrite() is + * not invoked, record the write afterwards. + */ static vm_fault_t try_insert_pfn(struct vm_fault *vmf, unsigned int order, unsigned long pfn) { + bool write =3D vmf->flags & FAULT_FLAG_WRITE; + vm_fault_t ret =3D VM_FAULT_FALLBACK; + if (!order) { - return vmf_insert_pfn(vmf->vma, vmf->address, pfn); + ret =3D vmf_insert_pfn_mkwrite(vmf->vma, vmf->address, pfn, write); #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP } else if (order =3D=3D PMD_ORDER) { unsigned long paddr =3D pfn << PAGE_SHIFT; @@ -601,27 +615,15 @@ static vm_fault_t try_insert_pfn(struct vm_fault *vmf= , unsigned int order, =20 if (aligned && folio_test_pmd_mappable(page_folio(pfn_to_page(pfn)))) { - vm_fault_t ret; - pfn &=3D PMD_MASK >> PAGE_SHIFT; - - /* Unlike PTEs which are automatically upgraded to - * writeable entries, the PMD upgrades go through - * .huge_fault(). Make sure we pass the "write" info - * along in that case. - * This also means we have to record the write fault - * here, instead of in .pfn_mkwrite(). - */ - ret =3D vmf_insert_pfn_pmd(vmf, pfn, - vmf->flags & FAULT_FLAG_WRITE); - if (ret =3D=3D VM_FAULT_NOPAGE && (vmf->flags & FAULT_FLAG_WRITE)) - drm_gem_shmem_record_mkwrite(vmf); - - return ret; + ret =3D vmf_insert_pfn_pmd(vmf, pfn, write); } #endif } - return VM_FAULT_FALLBACK; + + if (ret =3D=3D VM_FAULT_NOPAGE && write) + drm_gem_shmem_record_mkwrite(vmf); + return ret; } =20 static vm_fault_t drm_gem_shmem_any_fault(struct vm_fault *vmf, unsigned i= nt order) --=20 2.55.0 From nobody Fri Oct 2 12:21:44 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 7D4F245FFD1 for ; Fri, 31 Jul 2026 16:43:56 +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=1785516238; cv=none; b=Nw/5N77j5896QtEl2z65rtju/hmtmbuilQFwMSYl3ZxsA59Vm4iZu+L9V/Rh2MiuqPMdvLywKU7vNzeiRziXvfvOVuxYpM4NMiwQIWmPknHskA6gqf8kBPIpUUPcIHsr2DKwD5qkTlFssxJeZFoJv4soAD792TCbgMeA7oaRWFg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785516238; c=relaxed/simple; bh=A45rtVuI2v+Zs4TW0iC+h2We1+nvtl6ZE/yluKW9Tsk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UjtdrcnjsBg+HEvMd47YaMUEeKoE2ly6Zm0bZegQ2cbYzRt9FDB1EIreH6CC4Ge4atVLlVSM6FFBpN3P3E0IaDHzffS0cMqO++VCNfnY8Fix8yptOOipFcuDplGCLYGb5Y58Kbjh0K8p6OFIXqa3Vcsb0TMvahHfYA22XuwJ9zg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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=B2lG9ztx; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=EBdEqYYm; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine 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="B2lG9ztx"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="EBdEqYYm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1785516235; 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=rKIuXVAQxBinLsqe2l2r/I0mxnjKp1xskcVhmjIrGQo=; b=B2lG9ztxVtGSZjJbFaaWiyLZ4gxxU+wvDymLAyx73Eh2NnPNRpnZ8cu91H7uMTXRVaKzAJ VJyzaL8wiIhoYZjbdircAn7L04CoYWClsdV7eK7JxrASTk5NyiN3DpD5c8f15Q8Y/S89fu Pux8XJBmrYeGPpjYTPZBU/nSLUhU6Hw= Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-138-y0FxAryKNmmax5NBxq07eg-1; Fri, 31 Jul 2026 12:43:53 -0400 X-MC-Unique: y0FxAryKNmmax5NBxq07eg-1 X-Mimecast-MFC-AGG-ID: y0FxAryKNmmax5NBxq07eg_1785516233 Received: by mail-ed1-f69.google.com with SMTP id 4fb4d7f45d1cf-69c2f98aa9fso1450373a12.2 for ; Fri, 31 Jul 2026 09:43:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1785516233; x=1786121033; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=rKIuXVAQxBinLsqe2l2r/I0mxnjKp1xskcVhmjIrGQo=; b=EBdEqYYmQDnxUVUSYkqi5ON0HhBsoDrYbzWE3J4M6v0qm+BUkIDZcogs6YG3AyzseR GL6Bi2LmTa5CiGgf3m7IFBYq91Q+5Z2Rjcyj7EyVN26wkcsOk+hJ7L+iKowdyMf3a99p cfY3dSPLpcPMaVqhknRI2S35gLYRCxY5gUX84kiAqtFX0NaiaeyiV/uugKzK20xzE7R8 5Q3ge211S7rlSx2qMTNA/GBYtSL8LjN2yh9DGVBW+pn7H/gGD04YDWmHObW3TqkOpMkG Ja5mVAMKgXNfhBK4d5mB1QzX1VFB6kdwksRyWFJhOzoJfIyqV722cHilrm/OUvwYk2mo g5WA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785516233; x=1786121033; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=rKIuXVAQxBinLsqe2l2r/I0mxnjKp1xskcVhmjIrGQo=; b=BkFgpBVk6pLf+w7nBKtJKJmocYxcmC9PMDCitVW+js/7N36+hikhs39Otk4Xw25sZY vE6CLOAqaUR7BFi6aaJbLVtXCEaTiupAZ+NFceJKOVvxXOtfnazy7y72ILZe+XOH2vZf Z9pGKzfXCEIzKSWPWSVl1NHvnzeNd1GXQnoS4GGr5yJT6hydhU07RdVC0O1w1gGu6pIB RkyHJUn1yKDj2E+PqSpzj0NvWkjeqIEUcv8O9N1xuhDsPDDS3wdRlvr9GFOdV2vX2n+R GdVZGnCA2CXYomaVl+8xAfmgLKt3xu3jKo+stmJ8cxWyklnSMRNvsHGt52KGXYr5rKci TuxA== X-Gm-Message-State: AOJu0YzavzivY0UU194yQk6XIVqF9m9HZuVGgPObjWmZbsbt3kSdWmW9 dIr/ncioYBfWh4uoWPlUUFlj5TRPjNADNcX4bBCUvsODYlnsPARPrUVIet0+2Ip30xnrkhiWNnJ GLILm8zDhwKKh6CL1g1qPd8fcfAgxRpKO5dzy8QvLQTnSIpvgI+8SaLPqTE5MvsDOnBSduNTFyZ 9NFtClztEi64PQf880jJiViLZ6PIXL/NaoC5dDJowMs2w8n5jcIA== X-Gm-Gg: AR+sD13UnUI/MYSG7ar5zEA7Ldkdia6TkaaOouTsTWiUzYjlDSSlui0rhmA+2Mg96nr KO6YKDx34B9qfTeqqDHkaNruRnkehcYsLrwLqYV2UrtxcCmsCeq7YqBBZPZcWcamgiNoGeRktTV ZmFelOZVFfpPGWKIQuq2jRJBkZwtXrD4nl+mOwvCBg6SsipPNxS7T8uDq6WWsq1vCeXrktLKvGR 5vWzQDdVnr4KMKbFS4B8HbI0fmjleynKOcVZScU2z1u5ESykhC1oQdp3qmO5kY5NzwikDS54eFj itCrY2yrvJ3OZUiV7Ai4zYAeLHgdlxLEDrzjNNaSYK/xZ4vdkQdVPxyASzdqGaz6XKeaSEQpc+0 wkMj2VA3pyDfIAxTcLrOjpmbb6ov4sxOBPQ1Gqid+wNBCjaSUeiXeLmBPEt+2NL1yoSSNfPRnBu gcccQ= X-Received: by 2002:a05:6402:548a:b0:6a0:923a:cfe7 with SMTP id 4fb4d7f45d1cf-6a0a7cf5cf6mr192246a12.37.1785516232618; Fri, 31 Jul 2026 09:43:52 -0700 (PDT) X-Received: by 2002:a05:6402:548a:b0:6a0:923a:cfe7 with SMTP id 4fb4d7f45d1cf-6a0a7cf5cf6mr192219a12.37.1785516232159; Fri, 31 Jul 2026 09:43:52 -0700 (PDT) Received: from [192.168.10.48] ([151.95.34.92]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a09c5a0556sm2582577a12.5.2026.07.31.09.43.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jul 2026 09:43:51 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Boris Brezillon , Thomas Zimmermann , David Hildenbrand , Michal Hocko , Sergio Lopez , Christian Koenig , Huang Rui , bcm-kernel-feedback-list@broadcom.com, dri-devel@lists.freedesktop.org, linux-mm@kvack.org Subject: [PATCH RFT 3/3] drm/ttm, drm/vmwgfx: directly create writable PTEs when mkwrite is in use Date: Fri, 31 Jul 2026 18:43:41 +0200 Message-ID: <20260731164341.1109827-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260731164341.1109827-1-pbonzini@redhat.com> References: <20260731164341.1109827-1-pbonzini@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" This ensures that fixup_user_fault() users see a writable PTE when they request one. The flip side is that vmw_bo_vm_fault() now has to record by hand the write fault, because .pfn_mkwrite() is not invoked. Prefaulting works as before because only the first entry comes out writable, while the following ones still end up executing the .pfn_mkwrite() callback. Signed-off-by: Paolo Bonzini Tested-by: Sergio Lopez --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 3 +- drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 42 ++++++++++++---------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_v= m.c index a80510489c45..ef27a2d7afc0 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -263,7 +263,8 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vm= f, * at arbitrary times while the data is mmap'ed. * See vmf_insert_pfn_prot() for a discussion. */ - ret =3D vmf_insert_pfn_prot(vma, address, pfn, prot); + ret =3D __vmf_insert_pfn_prot(vma, address, pfn, prot, + i =3D=3D 0 && !!(vmf->flags & FAULT_FLAG_WRITE)); =20 /* Never error on prefaulted PTEs */ if (unlikely((ret & VM_FAULT_ERROR))) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/v= mwgfx/vmwgfx_page_dirty.c index 45561bc1c9ef..2cc490e7d758 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c @@ -398,15 +398,33 @@ void vmw_bo_dirty_clear_res(struct vmw_resource *res) dirty->end =3D res_start; } =20 +static vm_fault_t vmw_bo_dirty_mkwrite(struct vm_fault *vmf, struct ttm_bu= ffer_object *bo) +{ + unsigned long page_offset; + struct vmw_bo *vbo =3D to_vmw_bo(&bo->base); + + page_offset =3D vmf->pgoff - drm_vma_node_start(&bo->base.vma_node); + if (unlikely(page_offset >=3D PFN_UP(bo->resource->size))) + return VM_FAULT_SIGBUS; + + if (vbo->dirty && vbo->dirty->method =3D=3D VMW_BO_DIRTY_MKWRITE && + !test_bit(page_offset, &vbo->dirty->bitmap[0])) { + struct vmw_bo_dirty *dirty =3D vbo->dirty; + + __set_bit(page_offset, &dirty->bitmap[0]); + dirty->start =3D min(dirty->start, page_offset); + dirty->end =3D max(dirty->end, page_offset + 1); + } + return 0; +} + vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf) { struct vm_area_struct *vma =3D vmf->vma; struct ttm_buffer_object *bo =3D (struct ttm_buffer_object *) vma->vm_private_data; vm_fault_t ret; - unsigned long page_offset; unsigned int save_flags; - struct vmw_bo *vbo =3D to_vmw_bo(&bo->base); =20 /* * mkwrite() doesn't handle the VM_FAULT_RETRY return value correctly. @@ -419,22 +437,7 @@ vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf) if (ret) return ret; =20 - page_offset =3D vmf->pgoff - drm_vma_node_start(&bo->base.vma_node); - if (unlikely(page_offset >=3D PFN_UP(bo->resource->size))) { - ret =3D VM_FAULT_SIGBUS; - goto out_unlock; - } - - if (vbo->dirty && vbo->dirty->method =3D=3D VMW_BO_DIRTY_MKWRITE && - !test_bit(page_offset, &vbo->dirty->bitmap[0])) { - struct vmw_bo_dirty *dirty =3D vbo->dirty; - - __set_bit(page_offset, &dirty->bitmap[0]); - dirty->start =3D min(dirty->start, page_offset); - dirty->end =3D max(dirty->end, page_offset + 1); - } - -out_unlock: + ret =3D vmw_bo_dirty_mkwrite(vmf, bo); dma_resv_unlock(bo->base.resv); return ret; } @@ -484,6 +487,9 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf) prot =3D vm_get_page_prot(vma->vm_flags); =20 ret =3D ttm_bo_vm_fault_reserved(vmf, prot, num_prefault); + if (ret =3D=3D VM_FAULT_NOPAGE && (vmf->flags & FAULT_FLAG_WRITE)) + WARN_ON_ONCE(vmw_bo_dirty_mkwrite(vmf, bo)); + if (ret =3D=3D VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) return ret; =20 --=20 2.55.0