From patchwork Wed Jun 22 10:54:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Vrabel X-Patchwork-Id: 9192403 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 507FD6075A for ; Wed, 22 Jun 2016 10:56:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3FD382818A for ; Wed, 22 Jun 2016 10:56:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 34A12283E5; Wed, 22 Jun 2016 10:56:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 81FBE2818A for ; Wed, 22 Jun 2016 10:56:54 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bFfnt-0000O2-Sw; Wed, 22 Jun 2016 10:54:41 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bFfns-0000Nw-RN for xen-devel@lists.xenproject.org; Wed, 22 Jun 2016 10:54:40 +0000 Received: from [193.109.254.147] by server-9.bemta-14.messagelabs.com id 3C/B6-32749-07E6A675; Wed, 22 Jun 2016 10:54:40 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrPIsWRWlGSWpSXmKPExsXitHSDvW5+Xla 4wZvfQhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8aCawfZChaqV7xfY9nAeFWhi5GTQ0LAX2JT Zw87iC0skCzx7uhTRhBbRKBa4sTGl6wgtpBAmsT/da9Yuhg5OJgFlCU2PJAGCbMJ6Eg8XjKDH WKMnERv9ySwEl4BTYm3N9VAwiwCqhILr60FmyIqECxx58JzNhCbV0BQ4uTMJywgNqeAlsSxX7 +hpmtKrN+lDxJmFpCXaN46mxniABWJj2tXsUJs4pa4fXoq8wRGgVlIJs1C6J6FpHsBI/MqRvX i1KKy1CJdE72kosz0jJLcxMwcXUNDE73c1OLixPTUnMSkYr3k/NxNjMCAZACCHYwrFjofYpTk YFIS5ZVXzgoX4kvKT6nMSCzOiC8qzUktPsQow8GhJMFrkg2UEyxKTU+tSMvMAcYGTFqCg0dJh PcDSJq3uCAxtzgzHSJ1ilFRSpy3AyQhAJLIKM2Da4PF4yVGWSlhXkagQ4R4ClKLcjNLUOVfMY pzMCoJ834HmcKTmVcCN/0V0GImoMXL+tNBFpckIqSkGhgFTtr7n5lrFKbwaaqeZ7KfmPE7rSU Hyy9XLy5a2H3qocfrlqXz29b8Fw7XqNVM1ZRgLF/mZzrpyx7Vh646qtPW7motf/Bz4qTKUOEZ Wx8dO5vFsYV3kU/yio8tU2J3qiWncrEx3WvcY1d0+80tSaayPbLVnsWT66qvtLpULPp+0/TNx c6pa5YrsRRnJBpqMRcVJwIA9zjBW8ICAAA= X-Env-Sender: prvs=9743e3323=david.vrabel@citrix.com X-Msg-Ref: server-4.tower-27.messagelabs.com!1466592877!48344656!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.46; banners=-,-,- X-VirusChecked: Checked Received: (qmail 41165 invoked from network); 22 Jun 2016 10:54:38 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-4.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 22 Jun 2016 10:54:38 -0000 X-IronPort-AV: E=Sophos;i="5.26,509,1459814400"; d="scan'208";a="368921055" To: Boris Ostrovsky , David Vrabel , References: <1466525353-27751-1-git-send-email-david.vrabel@citrix.com> <57699624.4060500@oracle.com> From: David Vrabel X-Enigmail-Draft-Status: N1110 Message-ID: <576A6E6A.8030502@citrix.com> Date: Wed, 22 Jun 2016 11:54:34 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Icedove/38.5.0 MIME-Version: 1.0 In-Reply-To: <57699624.4060500@oracle.com> X-DLP: MIA2 Cc: Juergen Gross Subject: Re: [Xen-devel] [PATCHv2] x86/xen: avoid m2p lookup when setting early page table entries X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP On 21/06/16 20:31, Boris Ostrovsky wrote: > On 06/21/2016 12:09 PM, David Vrabel wrote: >> When page tables entries are set using xen_set_pte_init() during early >> boot there is no page fault handler that could handle a fault when >> performing an M2P lookup. >> >> In 64 guest (usually dom0) early_ioremap() would fault in >> xen_set_pte_init() because an M2P lookup faults because the MFN is in >> MMIO space and not mapped in the M2P. This lookup is done to see if >> the PFN in in the range used for the initial page table pages, so that >> the PTE may be set as read-only. >> >> The M2P lookup can be avoided by moving the check (and clear of RW) >> earlier when the PFN is still available. [...] >> --- a/arch/x86/xen/mmu.c >> +++ b/arch/x86/xen/mmu.c >> @@ -1562,7 +1562,7 @@ static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) >> return pte; >> } >> #else /* CONFIG_X86_64 */ >> -static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) >> +static pteval_t __init mask_rw_pte(pteval_t pte) >> { >> unsigned long pfn; >> >> @@ -1577,10 +1577,10 @@ static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) >> * page tables for mapping the p2m list, too, and page tables MUST be >> * mapped read-only. >> */ >> - pfn = pte_pfn(pte); >> + pfn = (pte & PTE_PFN_MASK) >> PAGE_SHIFT; > > Is it obvious that we are holding valid PFN at this point? It wasn't > immediately obvious to me so I wonder whether a comment stating this > would be useful here (yes, you mention it in the commit messages). I don't understand what you mean by a "valid PFN"? This is only called from xen_make_pte_init() which is for converting ptevals containing PFNs to MFNs. Did that answer your question? Would it be clearer if I just inlined the two functions like so: 8<--------------- x86/xen: avoid m2p lookup when setting early page table entries When page tables entries are set using xen_set_pte_init() during early boot there is no page fault handler that could handle a fault when performing an M2P lookup. In 64 guest (usually dom0) early_ioremap() would fault in xen_set_pte_init() because an M2P lookup faults because the MFN is in MMIO space and not mapped in the M2P. This lookup is done to see if the PFN in in the range used for the initial page table pages, so that the PTE may be set as read-only. The M2P lookup can be avoided by moving the check (and clear of RW) earlier when the PFN is still available. Signed-off-by: David Vrabel --- v3: - fold mask_rw_pte()/mask_rw_pteval() into their callers. v2: - Remove __init annotation from xen_make_pte_init() since PV_CALLEE_SAVE_REGS_THUNK always puts the thunk in .text. - mask_rw_pte() -> mask_rw_pteval() for x86-64. --- arch/x86/xen/mmu.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) @@ -1577,10 +1577,10 @@ static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) * page tables for mapping the p2m list, too, and page tables MUST be * mapped read-only. */ - pfn = pte_pfn(pte); + pfn = (pte & PTE_PFN_MASK) >> PAGE_SHIFT; if (pfn >= xen_start_info->first_p2m_pfn && pfn < xen_start_info->first_p2m_pfn + xen_start_info->nr_p2m_frames) - pte = __pte_ma(pte_val_ma(pte) & ~_PAGE_RW); + pte &= ~_PAGE_RW; return pte; } @@ -1600,13 +1600,26 @@ static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) * so always write the PTE directly and rely on Xen trapping and * emulating any updates as necessary. */ +__visible pte_t xen_make_pte_init(pteval_t pte) +{ +#ifdef CONFIG_X86_64 + pte = mask_rw_pteval(pte); +#endif + pte = pte_pfn_to_mfn(pte); + + if ((pte & PTE_PFN_MASK) >> PAGE_SHIFT == INVALID_P2M_ENTRY) + pte = 0; + + return native_make_pte(pte); +} +PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte_init); + static void __init xen_set_pte_init(pte_t *ptep, pte_t pte) { +#ifdef CONFIG_X86_32 if (pte_mfn(pte) != INVALID_P2M_ENTRY) pte = mask_rw_pte(ptep, pte); - else - pte = __pte_ma(0); - +#endif native_set_pte(ptep, pte); } @@ -2407,6 +2420,7 @@ static void __init xen_post_allocator_init(void) pv_mmu_ops.alloc_pud = xen_alloc_pud; pv_mmu_ops.release_pud = xen_release_pud; #endif + pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte); #ifdef CONFIG_X86_64 pv_mmu_ops.write_cr3 = &xen_write_cr3; @@ -2455,7 +2469,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { .pte_val = PV_CALLEE_SAVE(xen_pte_val), .pgd_val = PV_CALLEE_SAVE(xen_pgd_val), - .make_pte = PV_CALLEE_SAVE(xen_make_pte), + .make_pte = PV_CALLEE_SAVE(xen_make_pte_init), .make_pgd = PV_CALLEE_SAVE(xen_make_pgd), #ifdef CONFIG_X86_PAE diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 478a2de..bf0f78f 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1562,7 +1562,7 @@ static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) return pte; } #else /* CONFIG_X86_64 */ -static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) +static pteval_t __init mask_rw_pteval(pteval_t pte) { unsigned long pfn;