aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorOllie Wild <aaw@google.com>2007-07-19 04:48:16 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:45 -0400
commitb6a2fea39318e43fee84fa7b0b90d68bed92d2ba (patch)
treec9c3619cb2730b5c10c7427b837146bce3d69156 /mm
parentbdf4c48af20a3b0f01671799ace345e3d49576da (diff)
mm: variable length argument support
Remove the arg+env limit of MAX_ARG_PAGES by copying the strings directly from the old mm into the new mm. We create the new mm before the binfmt code runs, and place the new stack at the very top of the address space. Once the binfmt code runs and figures out where the stack should be, we move it downwards. It is a bit peculiar in that we have one task with two mm's, one of which is inactive. [a.p.zijlstra@chello.nl: limit stack size] Signed-off-by: Ollie Wild <aaw@google.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: <linux-arch@vger.kernel.org> Cc: Hugh Dickins <hugh@veritas.com> [bunk@stusta.de: unexport bprm_mm_init] Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/mmap.c61
-rw-r--r--mm/mprotect.c2
-rw-r--r--mm/mremap.c2
3 files changed, 37 insertions, 28 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 724f342bcf89..7afc7a7cec6f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1571,33 +1571,11 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
1571} 1571}
1572#endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */ 1572#endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
1573 1573
1574#ifdef CONFIG_STACK_GROWSUP
1575int expand_stack(struct vm_area_struct *vma, unsigned long address)
1576{
1577 return expand_upwards(vma, address);
1578}
1579
1580struct vm_area_struct *
1581find_extend_vma(struct mm_struct *mm, unsigned long addr)
1582{
1583 struct vm_area_struct *vma, *prev;
1584
1585 addr &= PAGE_MASK;
1586 vma = find_vma_prev(mm, addr, &prev);
1587 if (vma && (vma->vm_start <= addr))
1588 return vma;
1589 if (!prev || expand_stack(prev, addr))
1590 return NULL;
1591 if (prev->vm_flags & VM_LOCKED) {
1592 make_pages_present(addr, prev->vm_end);
1593 }
1594 return prev;
1595}
1596#else
1597/* 1574/*
1598 * vma is the first one with address < vma->vm_start. Have to extend vma. 1575 * vma is the first one with address < vma->vm_start. Have to extend vma.
1599 */ 1576 */
1600int expand_stack(struct vm_area_struct *vma, unsigned long address) 1577static inline int expand_downwards(struct vm_area_struct *vma,
1578 unsigned long address)
1601{ 1579{
1602 int error; 1580 int error;
1603 1581
@@ -1634,6 +1612,38 @@ int expand_stack(struct vm_area_struct *vma, unsigned long address)
1634 return error; 1612 return error;
1635} 1613}
1636 1614
1615int expand_stack_downwards(struct vm_area_struct *vma, unsigned long address)
1616{
1617 return expand_downwards(vma, address);
1618}
1619
1620#ifdef CONFIG_STACK_GROWSUP
1621int expand_stack(struct vm_area_struct *vma, unsigned long address)
1622{
1623 return expand_upwards(vma, address);
1624}
1625
1626struct vm_area_struct *
1627find_extend_vma(struct mm_struct *mm, unsigned long addr)
1628{
1629 struct vm_area_struct *vma, *prev;
1630
1631 addr &= PAGE_MASK;
1632 vma = find_vma_prev(mm, addr, &prev);
1633 if (vma && (vma->vm_start <= addr))
1634 return vma;
1635 if (!prev || expand_stack(prev, addr))
1636 return NULL;
1637 if (prev->vm_flags & VM_LOCKED)
1638 make_pages_present(addr, prev->vm_end);
1639 return prev;
1640}
1641#else
1642int expand_stack(struct vm_area_struct *vma, unsigned long address)
1643{
1644 return expand_downwards(vma, address);
1645}
1646
1637struct vm_area_struct * 1647struct vm_area_struct *
1638find_extend_vma(struct mm_struct * mm, unsigned long addr) 1648find_extend_vma(struct mm_struct * mm, unsigned long addr)
1639{ 1649{
@@ -1651,9 +1661,8 @@ find_extend_vma(struct mm_struct * mm, unsigned long addr)
1651 start = vma->vm_start; 1661 start = vma->vm_start;
1652 if (expand_stack(vma, addr)) 1662 if (expand_stack(vma, addr))
1653 return NULL; 1663 return NULL;
1654 if (vma->vm_flags & VM_LOCKED) { 1664 if (vma->vm_flags & VM_LOCKED)
1655 make_pages_present(addr, start); 1665 make_pages_present(addr, start);
1656 }
1657 return vma; 1666 return vma;
1658} 1667}
1659#endif 1668#endif
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 3b8f3c0c63f3..e8346c30abec 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -128,7 +128,7 @@ static void change_protection(struct vm_area_struct *vma,
128 flush_tlb_range(vma, start, end); 128 flush_tlb_range(vma, start, end);
129} 129}
130 130
131static int 131int
132mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, 132mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
133 unsigned long start, unsigned long end, unsigned long newflags) 133 unsigned long start, unsigned long end, unsigned long newflags)
134{ 134{
diff --git a/mm/mremap.c b/mm/mremap.c
index bc7c52efc71b..8ea5c2412c6e 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -120,7 +120,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
120 120
121#define LATENCY_LIMIT (64 * PAGE_SIZE) 121#define LATENCY_LIMIT (64 * PAGE_SIZE)
122 122
123static unsigned long move_page_tables(struct vm_area_struct *vma, 123unsigned long move_page_tables(struct vm_area_struct *vma,
124 unsigned long old_addr, struct vm_area_struct *new_vma, 124 unsigned long old_addr, struct vm_area_struct *new_vma,
125 unsigned long new_addr, unsigned long len) 125 unsigned long new_addr, unsigned long len)
126{ 126{