From: Dmitry Safonov <dsafonov@virtuozzo.com>
To: <linux-kernel@vger.kernel.org>
Cc: <0x7f454c46@gmail.com>, Dmitry Safonov <dsafonov@virtuozzo.com>,
"Thomas Gleixner" <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
Andy Lutomirski <luto@kernel.org>,
"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
<x86@kernel.org>
Subject: [RFC 3/4] x86/mm: define TASK_SIZE as current->mm->task_size
Date: Fri, 30 Dec 2016 18:56:33 +0300 [thread overview]
Message-ID: <20161230155634.8692-4-dsafonov@virtuozzo.com> (raw)
In-Reply-To: <20161230155634.8692-1-dsafonov@virtuozzo.com>
Keep task's virtual address space size as mm_struct field which
exists for a long time - it's initialized in setup_new_exec()
depending on the new task's personality.
This way TASK_SIZE will always be the same as current->mm->task_size.
Previously, there could be an issue about different values of
TASK_SIZE and current->mm->task_size: e.g, a 32-bit process can unset
ADDR_LIMIT_3GB personality (with personality syscall) and
so TASK_SIZE will be 4Gb, which is larger than mm->task_size = 3Gb.
As TASK_SIZE *and* current->mm->task_size are used both in code
frequently, this difference creates a subtle situations, for example:
one can mmap addresses > 3Gb, but they will be hidden in
/proc/pid/pagemap as it checks mm->task_size.
I've moved initialization of mm->task_size earlier in setup_new_exec()
as arch_pick_mmap_layout() initializes mmap_legacy_base with
TASK_UNMAPPED_BASE, which depends on TASK_SIZE.
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
---
arch/x86/include/asm/processor.h | 17 +++++++++--------
arch/x86/um/asm/segment.h | 2 +-
arch/x86/xen/mmu.c | 4 ++--
fs/exec.c | 17 +++++++++++------
4 files changed, 23 insertions(+), 17 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index dbc7dec5fa84..47ebde614f06 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -768,10 +768,8 @@ static inline void spin_lock_prefetch(const void *x)
/*
* User space process size: 3GB (default).
*/
-#define TASK_SIZE PAGE_OFFSET
-#define TASK_SIZE_MAX TASK_SIZE
-#define STACK_TOP TASK_SIZE
-#define STACK_TOP_MAX STACK_TOP
+#define TASK_SIZE_MAX PAGE_OFFSET
+#define INIT_TASK_SIZE TASK_SIZE_MAX
#define INIT_THREAD { \
.sp0 = TOP_OF_INIT_STACK, \
@@ -817,12 +815,9 @@ static inline void spin_lock_prefetch(const void *x)
#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
0xc0000000 : 0xFFFFe000)
-#define TASK_SIZE (current->personality & ADDR_LIMIT_32BIT ? \
+#define INIT_TASK_SIZE (current->personality & ADDR_LIMIT_32BIT ? \
IA32_PAGE_OFFSET : TASK_SIZE_MAX)
-#define STACK_TOP TASK_SIZE
-#define STACK_TOP_MAX TASK_SIZE_MAX
-
#define INIT_THREAD { \
.sp0 = TOP_OF_INIT_STACK, \
.addr_limit = KERNEL_DS, \
@@ -833,6 +828,12 @@ extern unsigned long KSTK_ESP(struct task_struct *task);
#endif /* CONFIG_X86_64 */
+#define TASK_SIZE \
+ ((current->mm) ? current->mm->task_size : TASK_SIZE_MAX)
+
+#define STACK_TOP TASK_SIZE
+#define STACK_TOP_MAX TASK_SIZE_MAX
+
extern unsigned long thread_saved_pc(struct task_struct *tsk);
extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
diff --git a/arch/x86/um/asm/segment.h b/arch/x86/um/asm/segment.h
index 41dd5e1f3cd7..3a9aa9f050df 100644
--- a/arch/x86/um/asm/segment.h
+++ b/arch/x86/um/asm/segment.h
@@ -13,6 +13,6 @@ typedef struct {
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_DS MAKE_MM_SEG(~0UL)
-#define USER_DS MAKE_MM_SEG(TASK_SIZE)
+#define USER_DS MAKE_MM_SEG(TASK_SIZE_MAX)
#endif
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 7d5afdb417cc..264ca3b7be58 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -830,7 +830,7 @@ static void __xen_pgd_pin(struct mm_struct *mm, pgd_t *pgd)
#else /* CONFIG_X86_32 */
#ifdef CONFIG_X86_PAE
/* Need to make sure unshared kernel PMD is pinnable */
- xen_pin_page(mm, pgd_page(pgd[pgd_index(TASK_SIZE)]),
+ xen_pin_page(mm, pgd_page(pgd[pgd_index(TASK_SIZE_MAX)]),
PT_PMD);
#endif
xen_do_pin(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(pgd)));
@@ -949,7 +949,7 @@ static void __xen_pgd_unpin(struct mm_struct *mm, pgd_t *pgd)
#ifdef CONFIG_X86_PAE
/* Need to make sure unshared kernel PMD is unpinned */
- xen_unpin_page(mm, pgd_page(pgd[pgd_index(TASK_SIZE)]),
+ xen_unpin_page(mm, pgd_page(pgd[pgd_index(TASK_SIZE_MAX)]),
PT_PMD);
#endif
diff --git a/fs/exec.c b/fs/exec.c
index e57946610733..826b73600fc2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1303,8 +1303,19 @@ void would_dump(struct linux_binprm *bprm, struct file *file)
}
EXPORT_SYMBOL(would_dump);
+#ifndef INIT_TASK_SIZE
+#define INIT_TASK_SIZE TASK_SIZE
+#endif
+
void setup_new_exec(struct linux_binprm * bprm)
{
+
+ /* Set the new mm task size. We have to do that late because it may
+ * depend on TIF_32BIT which is only updated in flush_thread() on
+ * some architectures like powerpc
+ */
+ current->mm->task_size = INIT_TASK_SIZE;
+
arch_pick_mmap_layout(current->mm);
/* This is the point of no return */
@@ -1318,12 +1329,6 @@ void setup_new_exec(struct linux_binprm * bprm)
perf_event_exec();
__set_task_comm(current, kbasename(bprm->filename), true);
- /* Set the new mm task size. We have to do that late because it may
- * depend on TIF_32BIT which is only updated in flush_thread() on
- * some architectures like powerpc
- */
- current->mm->task_size = TASK_SIZE;
-
/* install the new credentials */
if (!uid_eq(bprm->cred->uid, current_euid()) ||
!gid_eq(bprm->cred->gid, current_egid())) {
--
2.11.0
next prev parent reply other threads:[~2016-12-30 23:33 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-30 15:56 [RFC 0/4] x86: keep TASK_SIZE in sync with mm->task_size Dmitry Safonov
2016-12-30 15:56 ` Dmitry Safonov
2016-12-30 15:56 ` Dmitry Safonov
2016-12-30 15:56 ` Dmitry Safonov
2016-12-30 15:56 ` Dmitry Safonov
2016-12-30 15:56 ` [RFC 1/4] mm: remove unused TASK_SIZE_OF() Dmitry Safonov
2016-12-30 15:56 ` Dmitry Safonov
2016-12-30 15:56 ` Dmitry Safonov
2016-12-30 15:56 ` Dmitry Safonov
2016-12-30 15:56 ` Dmitry Safonov
2016-12-31 1:36 ` Andy Lutomirski
2016-12-31 1:36 ` Andy Lutomirski
2016-12-31 1:36 ` Andy Lutomirski
2016-12-31 1:36 ` Andy Lutomirski
2017-01-02 6:57 ` Heiko Carstens
2017-01-02 6:57 ` Heiko Carstens
2017-01-02 6:57 ` Heiko Carstens
2017-01-02 6:57 ` Heiko Carstens
2017-01-02 9:53 ` Kirill A. Shutemov
2017-01-02 9:53 ` Kirill A. Shutemov
2017-01-02 9:53 ` Kirill A. Shutemov
2017-01-02 9:53 ` Kirill A. Shutemov
2017-01-05 9:51 ` David Laight
2017-01-05 9:51 ` David Laight
2017-01-05 9:51 ` David Laight
2017-01-05 9:51 ` David Laight
2017-01-05 17:54 ` Andy Lutomirski
2017-01-05 17:54 ` Andy Lutomirski
2017-01-05 17:54 ` Andy Lutomirski
2017-01-05 17:54 ` Andy Lutomirski
2016-12-30 15:56 ` [RFC 2/4] x86/thread_info: kill TIF_ADDR32 in favour of ADDR_LIMIT_32BIT Dmitry Safonov
2016-12-31 1:38 ` Andy Lutomirski
2016-12-30 15:56 ` Dmitry Safonov [this message]
2016-12-30 15:56 ` [RFC 4/4] x86/arch_prctl: add ARCH_{GET,SET}_TASK_SIZE Dmitry Safonov
2016-12-31 2:02 ` Andy Lutomirski
2016-12-31 11:10 ` Dmitry Safonov
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=20161230155634.8692-4-dsafonov@virtuozzo.com \
--to=dsafonov@virtuozzo.com \
--cc=0x7f454c46@gmail.com \
--cc=hpa@zytor.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.