From patchwork Thu Jan 5 08:52:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ingo Molnar X-Patchwork-Id: 9498703 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 F417F60235 for ; Thu, 5 Jan 2017 08:55:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB64C27F85 for ; Thu, 5 Jan 2017 08:55:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E042927FA3; Thu, 5 Jan 2017 08:55:34 +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=-3.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RCVD_IN_SORBS_SPAM,T_DKIM_INVALID 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 F405327F95 for ; Thu, 5 Jan 2017 08:55:33 +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 1cP3n9-0005Wf-5s; Thu, 05 Jan 2017 08:52:59 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cP3n8-0005WZ-1M for xen-devel@lists.xenproject.org; Thu, 05 Jan 2017 08:52:58 +0000 Received: from [193.109.254.147] by server-11.bemta-6.messagelabs.com id AE/2E-25337-9690E685; Thu, 05 Jan 2017 08:52:57 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrNIsWRWlGSWpSXmKPExsVyMfTSQd0Mzrw Ig4kvJSy+b5nM5MDocfjDFZYAxijWzLyk/IoE1oz2S6IF/eEVTxa1MjUwbvToYuTiEBKYySix 8dlMVhCHRWAZq8S+rmfsXYycHBICh1gljj3RhbBjJDbdPcQIYVdK/Hu1CqiGA6hbU2JjgyXEo IlMErsO/gbrFRYwkGhY/50VxGYRUJFYsHQ9WD0bkN22xhAkLAJU8v76JDaQXmaBhYwSvT8vMk L02kh8bVwF1ssroCex/uo1ZhBbSMBTYue8X0wQcUGJkzOfsIDYzAJaEjf+vWQCmc8sIC2x/B8 HSJhTwEtictNkRpCwKNDaVwfrJzCKzELSPAtJ8yyE5gWMzKsYNYpTi8pSi3QNLfSSijLTM0py EzNzdA0NzPRyU4uLE9NTcxKTivWS83M3MQIDnwEIdjDe3BhwiFGSg0lJlNf6W26EEF9SfkplR mJxRnxRaU5q8SFGGQ4OJQneL+x5EUKCRanpqRVpmTnAGIRJS3DwKInwvgBJ8xYXJOYWZ6ZDpE 4xWnIcm7X4KRPHtGcgclfnmqdMQix5+XmpUuK8MhxADQIgDRmleXDjYGniEqOslDAvI9CBQjw FqUW5mSWo8q8YxTkYlYR5NUGm8GTmlcBtfQV0EBPQQdsDskEOKklESEk1MJa/Flr+2l++w/mO wPVYbkMvwxOvVopqzVjZZWh1ZcaLgB++a86ulve8fFEoi3Htro7+Le2Tv4UuLH0gEqy5SLmQK 7RL/Erk/Ru3bu7SffzhkcPMouJ37r5Md+1VnkuvOul5+e6agDaDx+dDGDJnrJ956fee2+WPpk +WLdOd0Hed5eY2bWm59RZKLMUZiYZazEXFiQA94OCvDgMAAA== X-Env-Sender: mingo.kernel.org@gmail.com X-Msg-Ref: server-13.tower-27.messagelabs.com!1483606376!70925328!1 X-Originating-IP: [209.85.210.193] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.1.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 12855 invoked from network); 5 Jan 2017 08:52:56 -0000 Received: from mail-wj0-f193.google.com (HELO mail-wj0-f193.google.com) (209.85.210.193) by server-13.tower-27.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 5 Jan 2017 08:52:56 -0000 Received: by mail-wj0-f193.google.com with SMTP id qs7so40695071wjc.1 for ; Thu, 05 Jan 2017 00:52:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=JmvHDazsEl8UvUxKZyRh8gjw9fodKbUVDyyGSAd8LRc=; b=FeWJoA/xweoacZyaIHPVseP3yVtYyTBcCn7WWcJCBjsnW/aErnuzeIz+KmBY7BAH2l Re/IiRhx1xUTAnXhDRNiaZS5A60kTg79leVipQubOI5hQQyxnplrSIbSrIS9+e7tmiBx AvahOaR8KWJPkc+IXtc7MLXXvkdb+Z39RcRIWiHr+jAnYjzg66e7xUJTzuwm9ovytQmZ BPtz1kxugs1VO4ie8u4cr0SU8xt0ttlr/PxpZbiton66G0bLetUXO3NxFVa3NLTtAR2T lce4M2njH/UGVQlXAfpLU4YzEOqJTKWhPf5s00W7sggQU3Ycb0quKS8NpX5MdYTUu4Ck Z8gQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition:in-reply-to:user-agent; bh=JmvHDazsEl8UvUxKZyRh8gjw9fodKbUVDyyGSAd8LRc=; b=FngzQjAMedKo//Htkrq3QLLtsBp7nV3Do8aXm+B8jo+j2Jc/TMaLy+dBpEiMa1QLT1 42szSZYq14rpZZbEXZbt3fPfsKLraikZLBFPNdbsFTFAsr+PymG34FeVHF9w/n1rXzwW CQnesprCCR0HyOMVn7CqlYTpnw+cbBvLCJwkHScDOf2QXEKXTaiayHePeubutcEqfsap 5ZsI/a4qXTlBqu/D4RrIy9LdvPekWBRbfoJqz7Ikb2i3ZJJZJc2bX9lzz4bam5HOuBqd Tu8YqLhHkcIgCe1c9HySpqCmtRDKnb72F44vCvtVSjsw1cvT3Vn/80Komfx/lYuEF1Wi TSIw== X-Gm-Message-State: AIkVDXJmBpe0I2jjYe6mIgZOISfx43ocw578W8+tmBSzoQKC4OzHzYtELSHnTVtoyx2mSQ== X-Received: by 10.194.67.67 with SMTP id l3mr66402702wjt.151.1483606375861; Thu, 05 Jan 2017 00:52:55 -0800 (PST) Received: from gmail.com (2E8B0CD5.catv.pool.telekom.hu. [46.139.12.213]) by smtp.gmail.com with ESMTPSA id 14sm99290329wmk.1.2017.01.05.00.52.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Jan 2017 00:52:55 -0800 (PST) Date: Thu, 5 Jan 2017 09:52:53 +0100 From: Ingo Molnar To: Boris Ostrovsky Message-ID: <20170105085252.GA15715@gmail.com> References: <1481215471-9639-1-git-send-email-boris.ostrovsky@oracle.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1481215471-9639-1-git-send-email-boris.ostrovsky@oracle.com> User-Agent: Mutt/1.5.24 (2015-08-30) Cc: matt@codeblueprint.co.uk, x86@kernel.org, linux-kernel@vger.kernel.org, mingo@redhat.com, hpa@zytor.com, xen-devel@lists.xenproject.org, tglx@linutronix.de Subject: Re: [Xen-devel] [PATCH] x86/head: Refactor 32-bit pgtable setup 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 * Boris Ostrovsky wrote: > The new Xen PVH entry point requires page tables to be setup by the > kernel since it is entered with paging disabled. > > Pull the common code out of head_32.S so that mk_early_pgtbl_32 can be > invoked from both the new Xen entry point and the existing startup_32 > code. > > Convert resulting common code to C. > > Signed-off-by: Boris Ostrovsky > --- > This is replacement for https://lkml.org/lkml/2016/10/14/434, with > assembly code re-written in C as requested by Ingo. > > > arch/x86/include/asm/pgtable_32.h | 32 ++++++++++ > arch/x86/kernel/head32.c | 62 +++++++++++++++++++ > arch/x86/kernel/head_32.S | 122 +++----------------------------------- > 3 files changed, 101 insertions(+), 115 deletions(-) Yeah, so (belatedly) I tried to merge this to latest upstream, via the commit below (note the slight edits to the changelog) - but 32-bit defconfig fails to build: arch/x86/kernel/head_32.S:615: Error: can't resolve `init_thread_union' {*UND* section} - `SIZEOF_PTREGS' {*UND* section} Thanks, Ingo =======================> From 071878c634fda7d9be3f015f05a89f5468e7e2e4 Mon Sep 17 00:00:00 2001 From: Boris Ostrovsky Date: Thu, 8 Dec 2016 11:44:31 -0500 Subject: [PATCH] x86/boot/32: Convert the 32-bit pgtable setup code from assembly to C The new Xen PVH entry point requires page tables to be set up by the kernel since it is entered with paging disabled. Pull the common code out of head_32.S so that mk_early_pgtbl_32() can be invoked from both the new Xen entry point and the existing startup_32() code. Convert resulting common code to C. Signed-off-by: Boris Ostrovsky Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: matt@codeblueprint.co.uk Cc: xen-devel@lists.xenproject.org Link: http://lkml.kernel.org/r/1481215471-9639-1-git-send-email-boris.ostrovsky@oracle.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pgtable_32.h | 32 ++++++++++ arch/x86/kernel/head32.c | 62 +++++++++++++++++++ arch/x86/kernel/head_32.S | 122 +++----------------------------------- 3 files changed, 101 insertions(+), 115 deletions(-) diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index b6c0b404898a..fbc73360aea0 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h @@ -27,6 +27,7 @@ struct vm_area_struct; extern pgd_t swapper_pg_dir[1024]; extern pgd_t initial_page_table[1024]; +extern pmd_t initial_pg_pmd[]; static inline void pgtable_cache_init(void) { } static inline void check_pgt_cache(void) { } @@ -75,4 +76,35 @@ do { \ #define kern_addr_valid(kaddr) (0) #endif +/* + * This is how much memory in addition to the memory covered up to + * and including _end we need mapped initially. + * We need: + * (KERNEL_IMAGE_SIZE/4096) / 1024 pages (worst case, non PAE) + * (KERNEL_IMAGE_SIZE/4096) / 512 + 4 pages (worst case for PAE) + * + * Modulo rounding, each megabyte assigned here requires a kilobyte of + * memory, which is currently unreclaimed. + * + * This should be a multiple of a page. + * + * KERNEL_IMAGE_SIZE should be greater than pa(_end) + * and small than max_low_pfn, otherwise will waste some page table entries + */ +#if PTRS_PER_PMD > 1 +#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD) +#else +#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) +#endif + +/* + * Number of possible pages in the lowmem region. + * + * We shift 2 by 31 instead of 1 by 32 to the left in order to avoid a + * gas warning about overflowing shift count when gas has been compiled + * with only a host target support using a 32-bit type for internal + * representation. + */ +#define LOWMEM_PAGES ((((2<<31) - __PAGE_OFFSET) >> PAGE_SHIFT)) + #endif /* _ASM_X86_PGTABLE_32_H */ diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index f16c55bfc090..e5fb436a6548 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c @@ -49,3 +49,65 @@ asmlinkage __visible void __init i386_start_kernel(void) start_kernel(); } + +/* + * Initialize page tables. This creates a PDE and a set of page + * tables, which are located immediately beyond __brk_base. The variable + * _brk_end is set up to point to the first "safe" location. + * Mappings are created both at virtual address 0 (identity mapping) + * and PAGE_OFFSET for up to _end. + * + * In PAE mode initial_page_table is statically defined to contain + * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3 + * entries). The identity mapping is handled by pointing two PGD entries + * to the first kernel PMD. Note the upper half of each PMD or PTE are + * always zero at this stage. + */ +void __init mk_early_pgtbl_32(void) +{ +#ifdef __pa +#undef __pa +#endif +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) + pte_t pte, *ptep; + int i; + unsigned long *ptr; + /* Enough space to fit pagetables for the low memory linear map */ + const unsigned long limit = __pa(_end) + + (PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT); +#ifdef CONFIG_X86_PAE + pmd_t pl2, *pl2p = (pmd_t *)__pa(initial_pg_pmd); +#define SET_PL2(pl2, val) { (pl2).pmd = (val); } +#else + pgd_t pl2, *pl2p = (pgd_t *)__pa(initial_page_table); +#define SET_PL2(pl2, val) { (pl2).pgd = (val); } +#endif + + ptep = (pte_t *)__pa(__brk_base); + pte.pte = PTE_IDENT_ATTR; + + while ((pte.pte & PTE_PFN_MASK) < limit) { + + SET_PL2(pl2, (unsigned long)ptep | PDE_IDENT_ATTR); + *pl2p = pl2; +#ifndef CONFIG_X86_PAE + /* Kernel PDE entry */ + *(pl2p + ((PAGE_OFFSET >> PGDIR_SHIFT))) = pl2; +#endif + for (i = 0; i < PTRS_PER_PTE; i++) { + *ptep = pte; + pte.pte += PAGE_SIZE; + ptep++; + } + + pl2p++; + } + + ptr = (unsigned long *)__pa(&max_pfn_mapped); + /* Can't use pte_pfn() since it's a call with CONFIG_PARAVIRT */ + *ptr = (pte.pte & PTE_PFN_MASK) >> PAGE_SHIFT; + + ptr = (unsigned long *)__pa(&_brk_end); + *ptr = (unsigned long)ptep + PAGE_OFFSET; +} + diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 4e8577d03372..eca1c93c38e8 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -24,6 +24,7 @@ #include #include #include +#include /* Physical address */ #define pa(X) ((X) - __PAGE_OFFSET) @@ -42,43 +43,8 @@ #define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id /* - * This is how much memory in addition to the memory covered up to - * and including _end we need mapped initially. - * We need: - * (KERNEL_IMAGE_SIZE/4096) / 1024 pages (worst case, non PAE) - * (KERNEL_IMAGE_SIZE/4096) / 512 + 4 pages (worst case for PAE) - * - * Modulo rounding, each megabyte assigned here requires a kilobyte of - * memory, which is currently unreclaimed. - * - * This should be a multiple of a page. - * - * KERNEL_IMAGE_SIZE should be greater than pa(_end) - * and small than max_low_pfn, otherwise will waste some page table entries - */ - -#if PTRS_PER_PMD > 1 -#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD) -#else -#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) -#endif - #define SIZEOF_PTREGS 17*4 -/* - * Number of possible pages in the lowmem region. - * - * We shift 2 by 31 instead of 1 by 32 to the left in order to avoid a - * gas warning about overflowing shift count when gas has been compiled - * with only a host target support using a 32-bit type for internal - * representation. - */ -LOWMEM_PAGES = (((2<<31) - __PAGE_OFFSET) >> PAGE_SHIFT) - -/* Enough space to fit pagetables for the low memory linear map */ -MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT - -/* * Worst-case size of the kernel mapping we need to make: * a relocatable kernel can live anywhere in lowmem, so we need to be able * to map all of lowmem. @@ -160,90 +126,15 @@ ENTRY(startup_32) call load_ucode_bsp #endif -/* - * Initialize page tables. This creates a PDE and a set of page - * tables, which are located immediately beyond __brk_base. The variable - * _brk_end is set up to point to the first "safe" location. - * Mappings are created both at virtual address 0 (identity mapping) - * and PAGE_OFFSET for up to _end. - */ -#ifdef CONFIG_X86_PAE - - /* - * In PAE mode initial_page_table is statically defined to contain - * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3 - * entries). The identity mapping is handled by pointing two PGD entries - * to the first kernel PMD. - * - * Note the upper half of each PMD or PTE are always zero at this stage. - */ - -#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ - - xorl %ebx,%ebx /* %ebx is kept at zero */ - - movl $pa(__brk_base), %edi - movl $pa(initial_pg_pmd), %edx - movl $PTE_IDENT_ATTR, %eax -10: - leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */ - movl %ecx,(%edx) /* Store PMD entry */ - /* Upper half already zero */ - addl $8,%edx - movl $512,%ecx -11: - stosl - xchgl %eax,%ebx - stosl - xchgl %eax,%ebx - addl $0x1000,%eax - loop 11b - - /* - * End condition: we must map up to the end + MAPPING_BEYOND_END. - */ - movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp - cmpl %ebp,%eax - jb 10b -1: - addl $__PAGE_OFFSET, %edi - movl %edi, pa(_brk_end) - shrl $12, %eax - movl %eax, pa(max_pfn_mapped) + /* Create early pagetables. */ + call mk_early_pgtbl_32 /* Do early initialization of the fixmap area */ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax +#ifdef CONFIG_X86_PAE +#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8) -#else /* Not PAE */ - -page_pde_offset = (__PAGE_OFFSET >> 20); - - movl $pa(__brk_base), %edi - movl $pa(initial_page_table), %edx - movl $PTE_IDENT_ATTR, %eax -10: - leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */ - movl %ecx,(%edx) /* Store identity PDE entry */ - movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ - addl $4,%edx - movl $1024, %ecx -11: - stosl - addl $0x1000,%eax - loop 11b - /* - * End condition: we must map up to the end + MAPPING_BEYOND_END. - */ - movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp - cmpl %ebp,%eax - jb 10b - addl $__PAGE_OFFSET, %edi - movl %edi, pa(_brk_end) - shrl $12, %eax - movl %eax, pa(max_pfn_mapped) - - /* Do early initialization of the fixmap area */ - movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax +#else movl %eax,pa(initial_page_table+0xffc) #endif @@ -666,6 +557,7 @@ ENTRY(setup_once_ref) __PAGE_ALIGNED_BSS .align PAGE_SIZE #ifdef CONFIG_X86_PAE +.globl initial_pg_pmd initial_pg_pmd: .fill 1024*KPMDS,4,0 #else