From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linutronix.de (146.0.238.70:993) by crypto-ml.lab.linutronix.de with IMAP4-SSL for ; 28 Jun 2018 19:04:06 -0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by Galois.linutronix.de with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1fYcD4-000477-5o for speck@linutronix.de; Thu, 28 Jun 2018 21:04:05 +0200 Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 0FD80AD90 for ; Thu, 28 Jun 2018 19:03:55 +0000 (UTC) Subject: [MODERATED] Re: [PATCH 4/8] L1TFv8 8 References: <20180613225434.1CDC8610FD@crypto-ml.lab.linutronix.de> <20180627155151.GB3032@dhcp22.suse.cz> From: Vlastimil Babka Message-ID: <70cd88b9-5417-48a5-d5c9-1bba4b9de91a@suse.cz> Date: Thu, 28 Jun 2018 10:05:47 +0200 MIME-Version: 1.0 In-Reply-To: <20180627155151.GB3032@dhcp22.suse.cz> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit To: speck@linutronix.de List-ID: On 06/27/2018 05:51 PM, speck for Michal Hocko wrote: > Jan Beulich has noticed that these are not correct on 32b PAE systems > because phys_addr_t is wider than unsigned long. So we need an explicit > cas for pfn_* and use phys_addr_t for other direction. I think we want > the following: > >>>From d3050e2b99e9070defcd990b7bc31a4b433367c5 Mon Sep 17 00:00:00 2001 > From: Michal Hocko > Date: Wed, 27 Jun 2018 17:46:50 +0200 > Subject: [PATCH] x86/speculation/l1tf: fix up pte->pfn conversion for PAE > > Jan has noticed that pte_pfn and co. resp. pfn_pte are incorrect for > CONFIG_PAE because phys_addr_t is wider than unsigned long and so the > pte_val reps. shift left would get truncated. Fix this up by using > proper types. > > Noticed-by: Jan Beulich > Signed-off-by: Michal Hocko Good catch. Looks good to me, and some basic printk tests on manually created and modified pte's confirm that the problem does exist and the fix works. Acked-by: Vlastimil Babka > --- > arch/x86/include/asm/pgtable.h | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h > index 6a090a76fdca..26fd42a91946 100644 > --- a/arch/x86/include/asm/pgtable.h > +++ b/arch/x86/include/asm/pgtable.h > @@ -191,21 +191,21 @@ static inline u64 protnone_mask(u64 val); > > static inline unsigned long pte_pfn(pte_t pte) > { > - unsigned long pfn = pte_val(pte); > + phys_addr_t pfn = pte_val(pte); > pfn ^= protnone_mask(pfn); > return (pfn & PTE_PFN_MASK) >> PAGE_SHIFT; > } > > static inline unsigned long pmd_pfn(pmd_t pmd) > { > - unsigned long pfn = pmd_val(pmd); > + phys_addr_t pfn = pmd_val(pmd); > pfn ^= protnone_mask(pfn); > return (pfn & pmd_pfn_mask(pmd)) >> PAGE_SHIFT; > } > > static inline unsigned long pud_pfn(pud_t pud) > { > - unsigned long pfn = pud_val(pud); > + phys_addr_t pfn = pud_val(pud); > pfn ^= protnone_mask(pfn); > return (pfn & pud_pfn_mask(pud)) >> PAGE_SHIFT; > } > @@ -555,7 +555,7 @@ static inline pgprotval_t check_pgprot(pgprot_t pgprot) > > static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) > { > - phys_addr_t pfn = page_nr << PAGE_SHIFT; > + phys_addr_t pfn = (phys_addr_t)page_nr << PAGE_SHIFT; > pfn ^= protnone_mask(pgprot_val(pgprot)); > pfn &= PTE_PFN_MASK; > return __pte(pfn | check_pgprot(pgprot)); > @@ -563,7 +563,7 @@ static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) > > static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) > { > - phys_addr_t pfn = page_nr << PAGE_SHIFT; > + phys_addr_t pfn = (phys_addr_t)page_nr << PAGE_SHIFT; > pfn ^= protnone_mask(pgprot_val(pgprot)); > pfn &= PHYSICAL_PMD_PAGE_MASK; > return __pmd(pfn | check_pgprot(pgprot)); > @@ -571,7 +571,7 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) > > static inline pud_t pfn_pud(unsigned long page_nr, pgprot_t pgprot) > { > - phys_addr_t pfn = page_nr << PAGE_SHIFT; > + phys_addr_t pfn = (phys_addr_t)page_nr << PAGE_SHIFT; > pfn ^= protnone_mask(pgprot_val(pgprot)); > pfn &= PHYSICAL_PUD_PAGE_MASK; > return __pud(pfn | check_pgprot(pgprot)); >