Commit c0f869ff authored by David Mosberger's avatar David Mosberger

ia64: More 2.5.51/2.5.52 sync up.

parent 815ab107
......@@ -854,7 +854,7 @@ endif # ifdef include_config
# FIXME Should go into a make.lib or something
# ===========================================================================
a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS) \
a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) $(NOSTDINC_FLAGS) \
$(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
quiet_cmd_as_s_S = CPP $@
......
......@@ -41,8 +41,6 @@ core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/ arch/ia64/hp/common/ arch/ia64/hp
core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/
core-$(CONFIG_IA64_SGI_SN) += arch/ia64/sn/kernel/ \
arch/ia64/sn/io/ \
arch/ia64/sn/io/sn2/ \
arch/ia64/sn/io/sn2/pcibr/ \
arch/ia64/sn/kernel/sn2/
drivers-$(CONFIG_PCI) += arch/ia64/pci/
drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
......@@ -67,7 +65,7 @@ CLEAN_FILES += include/asm-ia64/offsets.h vmlinux.gz bootloader
prepare: include/asm-ia64/offsets.h
boot:
boot: lib/lib.a vmlinux
$(call makeboot,$@)
include/asm-ia64/offsets.h: include/asm include/linux/version.h include/config/MARKER
......
......@@ -15,7 +15,7 @@ targets-$(CONFIG_IA64_GENERIC) += bootloader
EXTRA_TARGETS += $(sort $(targets-y))
quiet_cmd_cptotop = LN $@
cmd_cptotop = ln $< $@
cmd_cptotop = ln -f $< $@
vmlinux.gz: $(obj)/vmlinux.gz $(targets-y)
$(call cmd,cptotop)
......
......@@ -91,11 +91,12 @@ ENTRY(ia64_execve)
END(ia64_execve)
/*
* sys_clone2(u64 flags, u64 ustack_base, u64 ustack_size, u64 user_tid, u64 tls)
* sys_clone2(u64 flags, u64 ustack_base, u64 ustack_size, u64 child_tidptr, u64 parent_tidptr,
* u64 tls)
*/
GLOBAL_ENTRY(sys_clone2)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
alloc r16=ar.pfs,5,2,5,0
alloc r16=ar.pfs,6,2,6,0
DO_SAVE_SWITCH_STACK
adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
mov loc0=rp
......@@ -104,9 +105,10 @@ GLOBAL_ENTRY(sys_clone2)
mov out1=in1
mov out3=in2
tbit.nz p6,p0=in0,CLONE_SETTLS_BIT
mov out4=in3 // valid only w/CLONE_SETTID and/or CLONE_CLEARTID
mov out4=in3 // child_tidptr: valid only w/CLONE_CHILD_SETTID or CLONE_CHILD_CLEARTID
;;
(p6) st8 [r2]=in4 // store TLS in r13 (tp)
(p6) st8 [r2]=in5 // store TLS in r16 for copy_thread()
mov out5=in4 // parent_tidptr: valid only w/CLONE_PARENT_SETTID
adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
dep out0=0,in0,CLONE_IDLETASK_BIT,1 // out0 = clone_flags & ~CLONE_IDLETASK
br.call.sptk.many rp=do_fork
......
......@@ -101,26 +101,15 @@ static const char *rse_hints[]={
#define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *))
/*
* The current revision of the Volume 2 (July 2000) of
* IA-64 Architecture Software Developer's Manual is wrong.
* Table 4-10 has invalid information concerning the ma field:
* Correct table is:
* bit 0 - 001 - UC
* bit 4 - 100 - UC
* bit 5 - 101 - UCE
* bit 6 - 110 - WC
* bit 7 - 111 - NatPage
*/
static const char *mem_attrib[]={
"Write Back (WB)", /* 000 */
"Uncacheable (UC)", /* 001 */
"Reserved", /* 010 */
"Reserved", /* 011 */
"Uncacheable (UC)", /* 100 */
"Uncacheable Exported (UCE)", /* 101 */
"Write Coalescing (WC)", /* 110 */
"NaTPage" /* 111 */
"WB", /* 000 */
"SW", /* 001 */
"010", /* 010 */
"011", /* 011 */
"UC", /* 100 */
"UCE", /* 101 */
"WC", /* 110 */
"NaTPage" /* 111 */
};
/*
......@@ -315,6 +304,7 @@ vm_info(char *page)
pal_vm_info_2_u_t vm_info_2;
pal_tc_info_u_t tc_info;
ia64_ptce_info_t ptce;
const char *sep;
int i, j;
s64 status;
......@@ -339,7 +329,14 @@ vm_info(char *page)
if (ia64_pal_mem_attrib(&attrib) != 0) return 0;
p += sprintf(p, "Supported memory attributes : %s\n", mem_attrib[attrib&0x7]);
p += sprintf(p, "Supported memory attributes : ");
sep = "";
for (i = 0; i < 8; i++) {
if (attrib & (1 << i)) {
p += sprintf(p, "%s%s\n", sep, mem_attrib[i]);
sep = ", ";
}
}
if ((status=ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
printk("ia64_pal_vm_page_size=%ld\n", status);
......
......@@ -383,31 +383,6 @@ copy_thread (int nr, unsigned long clone_flags,
return retval;
}
void
do_copy_regs (struct unw_frame_info *info, void *arg)
{
do_copy_task_regs(current, info, arg);
}
void
do_dump_fpu (struct unw_frame_info *info, void *arg)
{
do_dump_task_fpu(current, info, arg);
}
void
ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
{
unw_init_running(do_copy_regs, dst);
}
int
dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
{
unw_init_running(do_dump_fpu, dst);
return 1; /* f0-f31 are always valid so we always return 1 */
}
static void
do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
{
......@@ -499,36 +474,59 @@ do_dump_task_fpu (struct task_struct *task, struct unw_frame_info *info, void *a
memcpy(dst + 32, task->thread.fph, 96*16);
}
int dump_task_regs(struct task_struct *task, elf_gregset_t *regs)
void
do_copy_regs (struct unw_frame_info *info, void *arg)
{
do_copy_task_regs(current, info, arg);
}
void
do_dump_fpu (struct unw_frame_info *info, void *arg)
{
do_dump_task_fpu(current, info, arg);
}
int
dump_task_regs(struct task_struct *task, elf_gregset_t *regs)
{
struct unw_frame_info tcore_info;
if(current == task) {
if (current == task) {
unw_init_running(do_copy_regs, regs);
}
else {
memset(&tcore_info, 0, sizeof(tcore_info));
} else {
memset(&tcore_info, 0, sizeof(tcore_info));
unw_init_from_blocked_task(&tcore_info, task);
do_copy_task_regs(task, &tcore_info, regs);
}
return 1;
}
int dump_task_fpu (struct task_struct *task, elf_fpregset_t *dst)
void
ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
{
unw_init_running(do_copy_regs, dst);
}
int
dump_task_fpu (struct task_struct *task, elf_fpregset_t *dst)
{
struct unw_frame_info tcore_info;
if(current == task) {
if (current == task) {
unw_init_running(do_dump_fpu, dst);
}
else {
memset(&tcore_info, 0, sizeof(tcore_info));
} else {
memset(&tcore_info, 0, sizeof(tcore_info));
unw_init_from_blocked_task(&tcore_info, task);
do_dump_task_fpu(task, &tcore_info, dst);
}
return 1;
}
return 1;
int
dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
{
unw_init_running(do_dump_fpu, dst);
return 1; /* f0-f31 are always valid so we always return 1 */
}
asmlinkage long
......
......@@ -493,7 +493,7 @@ collect_task (struct task_list **listp, struct task_struct *p, int make_writable
/* oops, can't collect more: finish at least what we collected so far... */
return;
task_lock(p);
get_task_struct(p);
e->task = p;
e->next = *listp;
*listp = e;
......@@ -505,7 +505,7 @@ finish_task (struct task_list *list, int make_writable)
struct task_list *next = list->next;
sync_user_rbs_one_thread(list->task, make_writable);
task_unlock(list->task);
put_task_struct(list->task);
kfree(list);
return next;
}
......
......@@ -385,15 +385,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
frame = (void *) scr->pt.r12;
tramp_addr = GATE_ADDR + (ia64_sigtramp - __start_gate_section);
if (ka->sa.sa_flags & SA_ONSTACK) {
if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) {
frame = (void *) ((current->sas_ss_sp + current->sas_ss_size)
& ~(STACK_ALIGN - 1));
/*
* We need to check the memory and register stacks separately, because
* they're switched separately (memory stack is switched in the kernel,
* register stack is switched in the signal trampoline).
* We need to check for the register stack being on the signal stack
* separately, because it's switched separately (memory stack is switched
* in the kernel, register stack is switched in the signal trampoline).
*/
if (!on_sig_stack((unsigned long) frame))
frame = (void *) ((current->sas_ss_sp + current->sas_ss_size)
& ~(STACK_ALIGN - 1));
if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
}
......@@ -453,16 +452,14 @@ static long
handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset,
struct sigscratch *scr)
{
#ifdef CONFIG_IA32_SUPPORT
if (IS_IA32_PROCESS(&scr->pt)) {
/* send signal to IA-32 process */
if (!ia32_setup_frame1(sig, ka, info, oldset, &scr->pt))
return 0;
} else
#endif
/* send signal to IA-64 process */
if (!setup_frame(sig, ka, info, oldset, scr))
return 0;
/* send signal to IA-64 process */
if (!setup_frame(sig, ka, info, oldset, scr))
return 0;
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
......@@ -490,6 +487,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
siginfo_t info;
long restart = in_syscall;
long errno = scr->pt.r8;
# define ERR_CODE(c) (IS_IA32_PROCESS(&scr->pt) ? -(c) : (c))
/*
* In the ia64_leave_kernel code path, we want the common case to go fast, which
......@@ -502,7 +500,6 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
if (!oldset)
oldset = &current->blocked;
#ifdef CONFIG_IA32_SUPPORT
if (IS_IA32_PROCESS(&scr->pt)) {
if (in_syscall) {
if (errno >= 0)
......@@ -510,9 +507,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
else
errno = -errno;
}
} else
#endif
if (scr->pt.r10 != -1)
} else if (scr->pt.r10 != -1)
/*
* A system calls has to be restarted only if one of the error codes
* ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned. If r10
......@@ -531,25 +526,25 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
if (restart) {
switch (errno) {
case ERESTART_RESTARTBLOCK:
printk("ERESTART_RESTARTBLOCK: ignoring\n");
current_thread_info()->restart_block.fn = do_no_restart_syscall;
case ERESTARTNOHAND:
scr->pt.r8 = ERR_CODE(EINTR);
/* note: scr->pt.r10 is already -1 */
break;
case ERESTARTSYS:
if ((ka->sa.sa_flags & SA_RESTART) == 0) {
case ERESTARTNOHAND:
#ifdef CONFIG_IA32_SUPPORT
if (IS_IA32_PROCESS(&scr->pt))
scr->pt.r8 = -EINTR;
else
#endif
scr->pt.r8 = EINTR;
scr->pt.r8 = ERR_CODE(EINTR);
/* note: scr->pt.r10 is already -1 */
break;
}
case ERESTARTNOINTR:
#ifdef CONFIG_IA32_SUPPORT
if (IS_IA32_PROCESS(&scr->pt)) {
scr->pt.r8 = scr->pt.r1;
scr->pt.cr_iip -= 2;
} else
#endif
ia64_decrement_ip(&scr->pt);
}
}
......@@ -565,19 +560,28 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
/* Did we come from a system call? */
if (restart) {
/* Restart the system call - no handlers present */
if (errno == ERESTARTNOHAND || errno == ERESTARTSYS || errno == ERESTARTNOINTR) {
#ifdef CONFIG_IA32_SUPPORT
if (errno == ERESTARTNOHAND || errno == ERESTARTSYS || errno == ERESTARTNOINTR
|| errno == ERESTART_RESTARTBLOCK)
{
if (IS_IA32_PROCESS(&scr->pt)) {
scr->pt.r8 = scr->pt.r1;
scr->pt.cr_iip -= 2;
} else
#endif
/*
* Note: the syscall number is in r15 which is saved in pt_regs so
* all we need to do here is adjust ip so that the "break"
* instruction gets re-executed.
*/
ia64_decrement_ip(&scr->pt);
if (errno == ERESTART_RESTARTBLOCK) {
scr->pt.r8 = 0; /* x86 version of __NR_restart_syscall */
scr->pt.cr_iip -= 2;
}
} else {
/*
* Note: the syscall number is in r15 which is saved in
* pt_regs so all we need to do here is adjust ip so that
* the "break" instruction gets re-executed.
*/
ia64_decrement_ip(&scr->pt);
if (errno == ERESTART_RESTARTBLOCK) {
printk("ERESTART_RESTARTBLOCK: restarting at %lx\n", scr->pt.cr_iip);
scr->pt.r15 = __NR_restart_syscall;
}
}
}
}
return 0;
......
......@@ -12,6 +12,7 @@
#include <linux/hugetlb.h>
#include <linux/mman.h>
#include <linux/sched.h>
#include <linux/shm.h>
#include <linux/file.h> /* doh, must come after sched.h... */
#include <linux/smp.h>
#include <linux/smp_lock.h>
......
......@@ -96,13 +96,13 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
* fault.
*/
switch (handle_mm_fault(mm, vma, address, (mask & VM_WRITE) != 0)) {
case 1:
case VM_FAULT_MINOR:
++current->min_flt;
break;
case 2:
case VM_FAULT_MAJOR:
++current->maj_flt;
break;
case 0:
case VM_FAULT_SIGBUS:
/*
* We ran out of memory, or some other thing happened
* to us that made us unable to handle the page fault
......@@ -110,8 +110,10 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
*/
signal = SIGBUS;
goto bad_area;
default:
case VM_FAULT_OOM:
goto out_of_memory;
default:
BUG();
}
up_read(&mm->mmap_sem);
return;
......
......@@ -9,6 +9,7 @@
* scheduler patch
*/
#include <linux/compiler.h>
#include <linux/types.h>
#include <asm/intrinsics.h>
......
......@@ -43,6 +43,9 @@ struct thread_info {
.cpu = 0, \
.addr_limit = KERNEL_DS, \
.preempt_count = 0, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
}
/* how to get the thread information struct from C */
......
......@@ -235,7 +235,8 @@
#define __NR_epoll_create 1243
#define __NR_epoll_ctl 1244
#define __NR_epoll_wait 1245
#define __NR_semtimedop 1246
#define __NR_restart_syscall 1246
#define __NR_semtimedop 1247
#if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment