patch-2.4.4 linux/arch/ia64/ia32/binfmt_elf32.c
Next file: linux/arch/ia64/ia32/ia32_entry.S
Previous file: linux/arch/ia64/hp/hpsim_irq.c
Back to the patch index
Back to the overall index
- Lines: 140
- Date:
Thu Apr 5 12:51:47 2001
- Orig file:
v2.4.3/linux/arch/ia64/ia32/binfmt_elf32.c
- Orig date:
Thu Mar 22 09:24:58 2001
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/ia32/binfmt_elf32.c linux/arch/ia64/ia32/binfmt_elf32.c
@@ -57,28 +57,30 @@
if (page_count(page) != 1)
printk("mem_map disagrees with %p at %08lx\n", (void *) page, address);
+
pgd = pgd_offset(tsk->mm, address);
- pmd = pmd_alloc(pgd, address);
- if (!pmd) {
- __free_page(page);
- force_sig(SIGKILL, tsk);
- return 0;
- }
- pte = pte_alloc(pmd, address);
- if (!pte) {
- __free_page(page);
- force_sig(SIGKILL, tsk);
- return 0;
- }
- if (!pte_none(*pte)) {
- pte_ERROR(*pte);
- __free_page(page);
- return 0;
+
+ spin_lock(&tsk->mm->page_table_lock);
+ {
+ pmd = pmd_alloc(tsk->mm, pgd, address);
+ if (!pmd)
+ goto out;
+ pte = pte_alloc(tsk->mm, pmd, address);
+ if (!pte)
+ goto out;
+ if (!pte_none(*pte))
+ goto out;
+ flush_page_to_ram(page);
+ set_pte(pte, pte_mkwrite(mk_pte(page, PAGE_SHARED)));
}
- flush_page_to_ram(page);
- set_pte(pte, pte_mkwrite(mk_pte(page, PAGE_SHARED)));
+ spin_unlock(&tsk->mm->page_table_lock);
/* no need for flush_tlb */
return page;
+
+ out:
+ spin_unlock(&tsk->mm->page_table_lock);
+ __free_page(page);
+ return 0;
}
void ia64_elf32_init(struct pt_regs *regs)
@@ -90,12 +92,13 @@
put_shared_page(current, virt_to_page(ia32_tss), IA32_PAGE_OFFSET + PAGE_SIZE);
nr = smp_processor_id();
-
+
/* Do all the IA-32 setup here */
- current->thread.map_base = 0x40000000;
- current->thread.task_size = 0xc0000000; /* use what Linux/x86 uses... */
-
+ current->thread.map_base = 0x40000000;
+ current->thread.task_size = 0xc0000000; /* use what Linux/x86 uses... */
+ set_fs(USER_DS); /* set addr limit for new TASK_SIZE */
+
/* setup ia32 state for ia32_load_state */
current->thread.eflag = IA32_EFLAG;
@@ -124,14 +127,8 @@
: "r" ((ulong)IA32_FCR_DEFAULT));
__asm__("mov ar.fir = r0");
__asm__("mov ar.fdr = r0");
- __asm__("mov %0=ar.k0 ;;" : "=r" (current->thread.old_iob));
- __asm__("mov ar.k0=%0 ;;" :: "r"(IA32_IOBASE));
- /* TSS */
- __asm__("mov ar.k1 = %0"
- : /* no outputs */
- : "r" IA64_SEG_DESCRIPTOR(IA32_PAGE_OFFSET + PAGE_SIZE,
- 0x1FFFL, 0xBL, 1L,
- 3L, 1L, 1L, 1L));
+ current->thread.old_iob = ia64_get_kr(IA64_KR_IO_BASE);
+ ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
/* Get the segment selectors right */
regs->r16 = (__USER_DS << 16) | (__USER_DS); /* ES == DS, GS, FS are zero */
@@ -149,23 +146,10 @@
regs->r31 = IA64_SEG_DESCRIPTOR(0xc0000000L, 0x400L, 0x3L, 1L, 3L,
1L, 1L, 1L);
- /* Clear psr.ac */
+ /* Clear psr.ac */
regs->cr_ipsr &= ~IA64_PSR_AC;
regs->loadrs = 0;
- /*
- * According to the ABI %edx points to an `atexit' handler.
- * Since we don't have one we'll set it to 0 and initialize
- * all the other registers just to make things more deterministic,
- * ala the i386 implementation.
- */
- regs->r8 = 0; /* %eax */
- regs->r11 = 0; /* %ebx */
- regs->r9 = 0; /* %ecx */
- regs->r10 = 0; /* %edx */
- regs->r13 = 0; /* %ebp */
- regs->r14 = 0; /* %esi */
- regs->r15 = 0; /* %edi */
}
#undef STACK_TOP
@@ -185,9 +169,9 @@
bprm->exec += stack_base;
mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
- if (!mpnt)
- return -ENOMEM;
-
+ if (!mpnt)
+ return -ENOMEM;
+
{
mpnt->vm_mm = current->mm;
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
@@ -200,7 +184,7 @@
mpnt->vm_private_data = 0;
insert_vm_struct(current->mm, mpnt);
current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
- }
+ }
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
if (bprm->page[i]) {
@@ -208,7 +192,7 @@
}
stack_base += PAGE_SIZE;
}
-
+
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)