mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
To: "vernon2gm@gmail.com" <vernon2gm@gmail.com>,
	"Hansen, Dave" <dave.hansen@intel.com>,
	"kas@kernel.org" <kas@kernel.org>
Cc: "andrew+kernel@donnellan.id.au" <andrew+kernel@donnellan.id.au>,
	"rppt@kernel.org" <rppt@kernel.org>,
	"pasha.tatashin@soleen.com" <pasha.tatashin@soleen.com>,
	"yanglincheng@kylinos.cn" <yanglincheng@kylinos.cn>,
	"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
	"stable@vger.kernel.org" <stable@vger.kernel.org>,
	"david@kernel.org" <david@kernel.org>,
	"akpm@linux-foundation.org" <akpm@linux-foundation.org>,
	"mingo@redhat.com" <mingo@redhat.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-mm@kvack.org" <linux-mm@kvack.org>,
	"tj@kernel.org" <tj@kernel.org>,
	"orsonpeters@gmail.com" <orsonpeters@gmail.com>,
	"hpa@zytor.com" <hpa@zytor.com>,
	"tglx@kernel.org" <tglx@kernel.org>,
	"rmclure@linux.ibm.com" <rmclure@linux.ibm.com>,
	"bp@alien8.de" <bp@alien8.de>,
	"Yu, Yu-cheng" <yu-cheng.yu@intel.com>,
	"x86@kernel.org" <x86@kernel.org>
Subject: Re: [PATCH] x86/mm: Fix pmd_modify() dropping the dirty bit
Date: Thu, 3 Sep 2026 17:58:49 +0000	[thread overview]
Message-ID: <c15c2b17e110782d966751dbf3c487a6db837a87.camel@intel.com> (raw)
In-Reply-To: <314f11c1-ce5e-4b36-b296-0ab742550851@intel.com>

On Thu, 2026-09-03 at 07:18 -0700, Dave Hansen wrote:
> On 9/3/26 04:54, Kiryl Shutsemau wrote:
> > > Closes: https://lore.kernel.org/r/CAJxLxMUGu1-L+O_nAONOwOXnS=cNbNApCWqdthRjd76LThtSPg@mail.gmail.com/
> > > Fixes: bb3aadf7d446 ("x86/mm: Start actually marking _PAGE_SAVED_DIRTY")
> > Hm. I don't understand why would this commit explicitly exclude
> > _PAGE_DIRTY from the mask:
> > 
> > -       val &= _HPAGE_CHG_MASK;
> > +       val &= (_HPAGE_CHG_MASK & ~_PAGE_DIRTY);
> > 
> > Rick, could you comment? It doesn't look like a typo.
> 
> My guess is that it's some remnant from an earlier version of the patch.
> The asymmetry with pte_modify() vs. pmd_modify() just can't be explained
> any other way. It _might_ have been some attempt to say, "Hey
> _PAGE_DIRTY is now a part of the pgprot_t since it's part of the
> 'permissions' of a shadow stack PTE" that got abandoned.
> 
> But I don't see anything wrong with the fix at all.
> 
> It does give me pause that this has been losing user data for so long,
> but it must just be a weird combination of features that few folks use
> together (huge pages + MADV_FREE).

Oof. Looking back through the patch history, the dirty bit used to be handled
separately, such that the stripping was needed. Like this:

 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
	pteval_t _page_chg_mask_no_dirty = _PAGE_CHG_MASK & ~_PAGE_DIRTY;
 	pteval_t val = pte_val(pte), oldval = val;
	pte_t pte_result;
 
 	/*
 	 * Chop off the NX bit (if present), and add the NX portion of
 	 * the newprot (if present):
 	 */
	val &= _page_chg_mask_no_dirty;
	val |= check_pgprot(newprot) & ~_page_chg_mask_no_dirty;
 	val = flip_protnone_guard(oldval, val, PTE_PFN_MASK);

	pte_result = __pte(val);

	/*
	 * Dirty bit is not preserved above so it can be done
	 * in a special way for the shadow stack case, where it
	 * may need to set _PAGE_COW. __pte_mkdirty() will do this in
	 * the case of shadow stack.
	 */
	if (pte_dirty(pte))
		pte_result = __pte_mkdirty(pte_result, false);

	return pte_result;
 }
 
 static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
 {
	pteval_t _hpage_chg_mask_no_dirty = _HPAGE_CHG_MASK & ~_PAGE_DIRTY;
 	pmdval_t val = pmd_val(pmd), oldval = val;
	pmd_t pmd_result;

	val &= _hpage_chg_mask_no_dirty;
	val |= check_pgprot(newprot) & ~_hpage_chg_mask_no_dirty;
 	val = flip_protnone_guard(oldval, val, PHYSICAL_PMD_PAGE_MASK);


	pmd_result = __pmd(val);

	/*
	 * Dirty bit is not preserved above so it can be done
	 * in a special way for the shadow stack case, where it
	 * may need to set _PAGE_COW. __pmd_mkdirty() will do this in
	 * the case of shadow stack.
	 */
	if (pmd_dirty(pmd))
		pmd_result = __pmd_mkdirty(pmd_result, false);

	return pmd_result;
 }

The dirty bit was removed from the pte, then handled separately to share logic
in the mkdirty helpers. During development it was changed to do the necessary
adjustments depending on the dirty bit in 'val', but the mask adjustment on the
pmd_modify() side didn't get updated. So I don't remember or see any intention
for the difference.

I can't find anything back then that would have prevented it. The bug cause and
fix looks correct to me.

  parent reply	other threads:[~2026-09-03 17:58 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-03  3:16 Vernon Yang
2026-09-03  4:10 ` Andrew Morton
2026-09-03  5:24   ` Vernon Yang
2026-09-03  7:34   ` Orson Peters
2026-09-03 15:40     ` Dave Hansen
2026-09-03 11:54 ` Kiryl Shutsemau
2026-09-03 14:18   ` Dave Hansen
2026-09-03 17:21     ` Andrew Morton
2026-09-03 17:58     ` Edgecombe, Rick P [this message]
2026-09-03 18:01       ` Dave Hansen
2026-09-03 18:33         ` Edgecombe, Rick P
2026-09-03 19:25 ` [tip: x86/urgent] x86/mm: Fix userspace data loss with MADV_FREE and THP tip-bot2 for Vernon Yang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c15c2b17e110782d966751dbf3c487a6db837a87.camel@intel.com \
    --to=rick.p.edgecombe@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=andrew+kernel@donnellan.id.au \
    --cc=bp@alien8.de \
    --cc=dave.hansen@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=david@kernel.org \
    --cc=hpa@zytor.com \
    --cc=kas@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mingo@redhat.com \
    --cc=orsonpeters@gmail.com \
    --cc=pasha.tatashin@soleen.com \
    --cc=rmclure@linux.ibm.com \
    --cc=rppt@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@kernel.org \
    --cc=tj@kernel.org \
    --cc=vernon2gm@gmail.com \
    --cc=x86@kernel.org \
    --cc=yanglincheng@kylinos.cn \
    --cc=yu-cheng.yu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®