From ff89bf3bc0534aa03b5375aa906544d96911bad4 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Fri, 3 Jun 2005 05:25:00 -0700 Subject: [IA64] fix setting of sn_hub_info->shub_1_1_found Fix a bug in which shub_1_1_found is not being properly initialized or set, resulting in the improper setting of sn_hub_info->shub_1_1_found. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index e64cb8175f7..44bfc7f318c 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -222,7 +222,7 @@ void __init early_sn_setup(void) extern int platform_intr_list[]; extern nasid_t master_nasid; -static int shub_1_1_found __initdata; +static int __initdata shub_1_1_found = 0; /* * sn_check_for_wars @@ -251,7 +251,7 @@ static void __init sn_check_for_wars(void) } else { for_each_online_node(cnode) { if (is_shub_1_1(cnodeid_to_nasid(cnode))) - sn_hub_info->shub_1_1_found = 1; + shub_1_1_found = 1; } } } -- cgit v1.2.3 From ad597bd518559f59ede8d01262cdf4467e13282e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 8 Jun 2005 10:45:00 -0700 Subject: [IA64] Fill holes in FIXADDR_USER space with zero pages. This fixes an oops reported by Jason Baron. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/mm/init.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 547785e3cba..4eb2f52b87a 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -305,8 +305,9 @@ setup_gate (void) struct page *page; /* - * Map the gate page twice: once read-only to export the ELF headers etc. and once - * execute-only page to enable privilege-promotion via "epc": + * Map the gate page twice: once read-only to export the ELF + * headers etc. and once execute-only page to enable + * privilege-promotion via "epc": */ page = virt_to_page(ia64_imva(__start_gate_section)); put_kernel_page(page, GATE_ADDR, PAGE_READONLY); @@ -315,6 +316,20 @@ setup_gate (void) put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); #else put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); + /* Fill in the holes (if any) with read-only zero pages: */ + { + unsigned long addr; + + for (addr = GATE_ADDR + PAGE_SIZE; + addr < GATE_ADDR + PERCPU_PAGE_SIZE; + addr += PAGE_SIZE) + { + put_kernel_page(ZERO_PAGE(0), addr, + PAGE_READONLY); + put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE, + PAGE_READONLY); + } + } #endif ia64_patch_gate(); } -- cgit v1.2.3 From 866ba633a81c1e179038f7527809d9513160a6f7 Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Mon, 6 Jun 2005 02:04:00 -0700 Subject: [IA64] Module gp must point to valid memory Some bits of the kernel assume that gp always points to valid memory, in particular PHYSICAL_MODE_ENTER() assumes that both gp and sp are valid virtual addresses with associated physical pages. The IA64 module loader puts gp well past the end of the module, with no physical backing. Offsets on gp are still valid, but physical mode addressing breaks for modules. Ensure that gp always falls within the module body. Also ensure that gp is 8 byte aligned. Signed-off-by: Keith Owens Signed-off-by: Tony Luck --- arch/ia64/kernel/module.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index febc091c2f0..f1aca7cffd1 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -825,14 +825,16 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind * XXX Should have an arch-hook for running this after final section * addresses have been selected... */ - /* See if gp can cover the entire core module: */ - uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2; - if (mod->core_size >= MAX_LTOFF) + uint64_t gp; + if (mod->core_size > MAX_LTOFF) /* * This takes advantage of fact that SHF_ARCH_SMALL gets allocated * at the end of the module. */ - gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2; + gp = mod->core_size - MAX_LTOFF / 2; + else + gp = mod->core_size / 2; + gp = (uint64_t) mod->module_core + ((gp + 7) & -8); mod->arch.gp = gp; DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); } -- cgit v1.2.3 From 86ebacd360767f6a5cf9c8810977593dccf3f3da Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 8 Jun 2005 12:12:48 -0700 Subject: [IA64] Update comment to describe modes set in default control register. Christian Hildner pointed out that the comment did not match what the code does in cpu_init() when we set up the default control register. Patch based on suggestions from Ken Chen. Signed-off-by: Tony Luck --- arch/ia64/kernel/setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index b7e6b4cb374..d14692e0920 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -720,7 +720,8 @@ cpu_init (void) ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); /* - * Initialize default control register to defer all speculative faults. The + * Initialize default control register to defer speculative faults except + * for those arising from TLB misses, which are not deferred. The * kernel MUST NOT depend on a particular setting of these bits (in other words, * the kernel must have recovery code for all speculative accesses). Turn on * dcr.lc as per recommendation by the architecture team. Most IA-32 apps -- cgit v1.2.3 From 70aa488cff83c965c9e1850f48d82b000d0d6c1c Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Fri, 27 May 2005 23:09:00 -0700 Subject: [IA64] Extract correct break number for break.b break.b does not store the break number in cr.iim, instead it stores 0, which makes all break.b instructions look like BUG(). Extract the break number from the instruction itself. Signed-off-by: Keith Owens Signed-off-by: Tony Luck --- arch/ia64/kernel/traps.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index e82ad78081b..9bad6652d53 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -111,6 +111,24 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs) siginfo_t siginfo; int sig, code; + /* break.b always sets cr.iim to 0, which causes problems for + * debuggers. Get the real break number from the original instruction, + * but only for kernel code. User space break.b is left alone, to + * preserve the existing behaviour. All break codings have the same + * format, so there is no need to check the slot type. + */ + if (break_num == 0 && !user_mode(regs)) { + struct ia64_psr *ipsr = ia64_psr(regs); + unsigned long *bundle = (unsigned long *)regs->cr_iip; + unsigned long slot; + switch (ipsr->ri) { + case 0: slot = (bundle[0] >> 5); break; + case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break; + default: slot = (bundle[1] >> 23); break; + } + break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff); + } + /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); siginfo.si_imm = break_num; -- cgit v1.2.3