Commit 2b5f799d authored by David Mosberger's avatar David Mosberger

ia64: Sync with 2.5.71.

parent 84a2f00e
......@@ -55,6 +55,9 @@ struct disk_stat {
#include "../kernel/fw-emu.c"
/* This needs to be defined because lib/string.c:strlcat() calls it in case of error... */
asm (".global printk; printk = 0");
/*
* Set a break point on this function so that symbols are available to set breakpoints in
* the kernel being debugged.
......
......@@ -1902,22 +1902,26 @@ acpi_sba_ioc_add(struct acpi_device *device)
struct ioc *ioc;
acpi_status status;
u64 hpa, length;
struct acpi_device_info dev_info;
struct acpi_buffer buffer;
struct acpi_device_info *dev_info;
status = hp_acpi_csr_space(device->handle, &hpa, &length);
if (ACPI_FAILURE(status))
return 1;
status = acpi_get_object_info(device->handle, &dev_info);
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
status = acpi_get_object_info(device->handle, &buffer);
if (ACPI_FAILURE(status))
return 1;
dev_info = buffer.pointer;
/*
* For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI
* root bridges, and its CSR space includes the IOC function.
*/
if (strncmp("HWP0001", dev_info.hardware_id, 7) == 0)
if (strncmp("HWP0001", dev_info->hardware_id.value, 7) == 0)
hpa += ZX1_IOC_OFFSET;
ACPI_MEM_FREE(dev_info);
ioc = ioc_init(hpa, device->handle);
if (!ioc)
......
......@@ -44,14 +44,8 @@ ENTRY(ia32_clone)
br.call.sptk.many rp=do_fork
.ret0: .restore sp
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
mov r2=-1000
adds r3=IA64_TASK_PID_OFFSET,r8
;;
cmp.leu p6,p0=r8,r2
mov ar.pfs=loc1
mov rp=loc0
;;
(p6) ld4 r8=[r3]
br.ret.sptk.many rp
END(ia32_clone)
......@@ -183,14 +177,8 @@ GLOBAL_ENTRY(sys32_fork)
br.call.sptk.few rp=do_fork
.ret5: .restore sp
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
mov r2=-1000
adds r3=IA64_TASK_PID_OFFSET,r8
;;
cmp.leu p6,p0=r8,r2
mov ar.pfs=loc1
mov rp=loc0
;;
(p6) ld4 r8=[r3]
br.ret.sptk.many rp
END(sys32_fork)
......
......@@ -19,18 +19,28 @@ obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_SMP) += smp.o smpboot.o
obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
# The gate DSO image is built using a special linker script.
targets += gate.so gate-syms.o
AFLAGS_gate.lds.o += -P -C -U$(ARCH)
arch/ia64/kernel/gate.lds.s: %.s: %.S scripts FORCE
$(call if_changed_dep,as_s_S)
$(obj)/gate.so: $(src)/gate.lds.s $(obj)/gate.o
$(CC) -nostdlib -shared -s -Wl,-soname=linux-gate.so.1 \
-o $@ -Wl,-T,$^
extra-y += gate.so
quiet_cmd_gate = GATE $@
cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1
$(obj)/gate.so: $(src)/gate.lds.s $(obj)/gate.o FORCE
$(call if_changed,gate)
$(obj)/built-in.o: $(obj)/gate-syms.o
$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
$(obj)/gate-syms.o: $(src)/gate.lds.s $(obj)/gate.o
$(CC) -nostdlib -r -o $@ -Wl,-T,$^
extra-y += gate-syms.o
GATECFLAGS_gate-syms.o = -r
$(obj)/gate-syms.o: $(src)/gate.lds.s $(obj)/gate.o FORCE
$(call if_changed,gate)
# gate-data.o contains the gate DSO image as data in section .data.gate.
# We must build gate.so before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin
$(obj)/gate-data.o: $(obj)/gate.so
......@@ -116,14 +116,8 @@ GLOBAL_ENTRY(sys_clone2)
br.call.sptk.many rp=do_fork
.ret1: .restore sp
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
mov r2=-1000
adds r3=IA64_TASK_PID_OFFSET,r8
;;
cmp.leu p6,p0=r8,r2
mov ar.pfs=loc1
mov rp=loc0
;;
(p6) ld4 r8=[r3]
br.ret.sptk.many rp
END(sys_clone2)
......@@ -151,14 +145,8 @@ GLOBAL_ENTRY(sys_clone)
br.call.sptk.many rp=do_fork
.ret2: .restore sp
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
mov r2=-1000
adds r3=IA64_TASK_PID_OFFSET,r8
;;
cmp.leu p6,p0=r8,r2
mov ar.pfs=loc1
mov rp=loc0
;;
(p6) ld4 r8=[r3]
br.ret.sptk.many rp
END(sys_clone)
......
......@@ -14,6 +14,7 @@
#define SW(f) (IA64_SWITCH_STACK_##f##_OFFSET)
#define PT_REGS_SAVES(off) \
.unwabi 3, 'i'; \
.unwabi @svr4, 'i'; \
.fframe IA64_PT_REGS_SIZE+16+(off); \
.spillsp rp, PT(CR_IIP)+16+(off); \
......
......@@ -171,7 +171,8 @@ END(__kernel_syscall_via_epc)
*/
#define SIGTRAMP_SAVES \
.unwabi @svr4, 's'; /* mark this as a sigtramp handler (saves scratch regs) */ \
.unwabi 3, 's'; /* mark this as a sigtramp handler (saves scratch regs) */ \
.unwabi @svr4, 's'; /* backwards compatibility with old unwinders (remove in v2.7) */ \
.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF; \
.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF; \
.savesp pr, PR_OFF+SIGCONTEXT_OFF; \
......
......@@ -65,7 +65,7 @@
/*
* Controller mappings for all interrupt sources:
*/
irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
irq_desc_t _irq_desc[NR_IRQS] __cacheline_aligned = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.handler = &no_irq_type,
......@@ -235,7 +235,6 @@ int handle_IRQ_event(unsigned int irq,
{
int status = 1; /* Force the "do bottom halves" bit */
int retval = 0;
struct irqaction *first_action = action;
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();
......@@ -248,30 +247,88 @@ int handle_IRQ_event(unsigned int irq,
if (status & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
if (retval != 1) {
static int count = 100;
if (count) {
count--;
if (retval) {
printk("irq event %d: bogus retval mask %x\n",
irq, retval);
} else {
printk("irq %d: nobody cared!\n", irq);
}
dump_stack();
printk("handlers:\n");
action = first_action;
do {
printk("[<%p>]", action->handler);
print_symbol(" (%s)",
(unsigned long)action->handler);
printk("\n");
action = action->next;
} while (action);
}
return retval;
}
static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
{
struct irqaction *action;
if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
printk(KERN_ERR "irq event %d: bogus return value %x\n",
irq, action_ret);
} else {
printk(KERN_ERR "irq %d: nobody cared!\n", irq);
}
dump_stack();
printk(KERN_ERR "handlers:\n");
action = desc->action;
do {
printk(KERN_ERR "[<%p>]", action->handler);
print_symbol(" (%s)",
(unsigned long)action->handler);
printk("\n");
action = action->next;
} while (action);
}
static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
{
static int count = 100;
if (count) {
count--;
__report_bad_irq(irq, desc, action_ret);
}
}
static int noirqdebug;
static int __init noirqdebug_setup(char *str)
{
noirqdebug = 1;
printk("IRQ lockup detection disabled\n");
return 1;
}
__setup("noirqdebug", noirqdebug_setup);
/*
* If 99,900 of the previous 100,000 interrupts have not been handled then
* assume that the IRQ is stuck in some manner. Drop a diagnostic and try to
* turn the IRQ off.
*
* (The other 100-of-100,000 interrupts may have been a correctly-functioning
* device sharing an IRQ with the failing one)
*
* Called under desc->lock
*/
static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret)
{
if (action_ret != IRQ_HANDLED) {
desc->irqs_unhandled++;
if (action_ret != IRQ_NONE)
report_bad_irq(irq, desc, action_ret);
}
return status;
desc->irq_count++;
if (desc->irq_count < 100000)
return;
desc->irq_count = 0;
if (desc->irqs_unhandled > 99900) {
/*
* The interrupt is stuck
*/
__report_bad_irq(irq, desc, action_ret);
/*
* Now kill the IRQ
*/
printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
desc->status |= IRQ_DISABLED;
desc->handler->disable(irq);
}
desc->irqs_unhandled = 0;
}
/*
......@@ -380,21 +437,24 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
* 0 return value means that this irq is already being
* handled by some other CPU. (or is disabled)
*/
int cpu;
irq_desc_t *desc = irq_desc(irq);
struct irqaction * action;
irqreturn_t action_ret;
unsigned int status;
int cpu;
irq_enter();
cpu = smp_processor_id();
cpu = smp_processor_id(); /* for CONFIG_PREEMPT, this must come after irq_enter()! */
kstat_cpu(cpu).irqs[irq]++;
if (desc->status & IRQ_PER_CPU) {
/* no locking required for CPU-local interrupts: */
desc->handler->ack(irq);
handle_IRQ_event(irq, regs, desc->action);
action_ret = handle_IRQ_event(irq, regs, desc->action);
desc->handler->end(irq);
if (!noirqdebug)
note_interrupt(irq, desc, action_ret);
} else {
spin_lock(&desc->lock);
desc->handler->ack(irq);
......@@ -438,9 +498,10 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
*/
for (;;) {
spin_unlock(&desc->lock);
handle_IRQ_event(irq, regs, action);
action_ret = handle_IRQ_event(irq, regs, action);
spin_lock(&desc->lock);
if (!noirqdebug)
note_interrupt(irq, desc, action_ret);
if (!(desc->status & IRQ_PENDING))
break;
desc->status &= ~IRQ_PENDING;
......
......@@ -863,7 +863,8 @@ module_arch_cleanup (struct module *mod)
}
#ifdef CONFIG_SMP
void percpu_modcopy(void *pcpudst, const void *src, unsigned long size)
void
percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
{
unsigned int i;
for (i = 0; i < NR_CPUS; i++)
......
......@@ -352,10 +352,10 @@ static struct task_struct * __init
fork_by_hand (void)
{
/*
* don't care about the eip and regs settings since we'll never reschedule the
* Don't care about the IP and regs settings since we'll never reschedule the
* forked task.
*/
return do_fork(CLONE_VM|CLONE_IDLETASK, 0, 0, 0, NULL, NULL);
return copy_process(CLONE_VM|CLONE_IDLETASK, 0, 0, 0, NULL, NULL);
}
static int __init
......@@ -370,6 +370,7 @@ do_boot_cpu (int sapicid, int cpu)
idle = fork_by_hand();
if (IS_ERR(idle))
panic("failed fork for CPU %d", cpu);
wake_up_forked_process(idle);
/*
* We remove it from the pidhash and the runqueue
......
......@@ -825,7 +825,7 @@ desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave
static inline void
desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr)
{
if (abi == 0 && context == 'i') {
if (abi == 3 && context == 'i') {
sr->flags |= UNW_FLAG_INTERRUPT_FRAME;
UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __FUNCTION__);
}
......
......@@ -70,6 +70,26 @@ check_pgt_cache (void)
}
}
void
update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte)
{
unsigned long addr;
struct page *page;
if (!pte_exec(pte))
return; /* not an executable page... */
page = pte_page(pte);
/* don't use VADDR: it may not be mapped on this CPU (or may have just been flushed): */
addr = (unsigned long) page_address(page);
if (test_bit(PG_arch_1, &page->flags))
return; /* i-cache is already coherent with d-cache */
flush_icache_range(addr, addr + PAGE_SIZE);
set_bit(PG_arch_1, &page->flags); /* mark page as clean */
}
inline void
ia64_set_rbs_bot (void)
{
......
......@@ -128,4 +128,11 @@ compat_ptr (compat_uptr_t uptr)
return (void *) (unsigned long) uptr;
}
static __inline__ void *
compat_alloc_user_space (long len)
{
struct pt_regs *regs = ia64_task_regs(current);
return (void *) ((regs->r12 & -16) - len);
}
#endif /* _ASM_IA64_COMPAT_H */
......@@ -158,29 +158,4 @@ pte_free_kernel (pte_t *pte)
extern void check_pgt_cache (void);
/*
* IA-64 doesn't have any external MMU info: the page tables contain all the necessary
* information. However, we use this macro to take care of any (delayed) i-cache flushing
* that may be necessary.
*/
static inline void
update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte)
{
unsigned long addr;
struct page *page;
if (!pte_exec(pte))
return; /* not an executable page... */
page = pte_page(pte);
/* don't use VADDR: it may not be mapped on this CPU (or may have just been flushed): */
addr = (unsigned long) page_address(page);
if (test_bit(PG_arch_1, &page->flags))
return; /* i-cache is already coherent with d-cache */
flush_icache_range(addr, addr + PAGE_SIZE);
set_bit(PG_arch_1, &page->flags); /* mark page as clean */
}
#endif /* _ASM_IA64_PGALLOC_H */
......@@ -461,6 +461,13 @@ extern struct page *zero_page_memmap_ptr;
typedef pte_t *pte_addr_t;
/*
* IA-64 doesn't have any external MMU info: the page tables contain all the necessary
* information. However, we use this routine to take care of any (delayed) i-cache
* flushing that may be necessary.
*/
extern void update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte);
# ifdef CONFIG_VIRTUAL_MEM_MAP
/* arch mem_map init routine is needed due to holes in a virtual mem_map */
# define __HAVE_ARCH_MEMMAP_INIT
......
......@@ -23,11 +23,11 @@ extern void xor_ia64_5(unsigned long, unsigned long *, unsigned long *,
unsigned long *, unsigned long *, unsigned long *);
static struct xor_block_template xor_block_ia64 = {
name: "ia64",
do_2: xor_ia64_2,
do_3: xor_ia64_3,
do_4: xor_ia64_4,
do_5: xor_ia64_5,
.name = "ia64",
.do_2 = xor_ia64_2,
.do_3 = xor_ia64_3,
.do_4 = xor_ia64_4,
.do_5 = xor_ia64_5,
};
#define XOR_TRY_TEMPLATES xor_speed(&xor_block_ia64)
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