diff options
Diffstat (limited to 'arch')
106 files changed, 1597 insertions, 658 deletions
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 1d3c1398c428..52c91ccc1648 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -271,6 +271,19 @@ titan_dispatch_irqs(u64 mask) * Titan Family */ static void __init +titan_request_irq(unsigned int irq, irq_handler_t handler, + unsigned long irqflags, const char *devname, + void *dev_id) +{ + int err; + err = request_irq(irq, handler, irqflags, devname, dev_id); + if (err) { + printk("titan_request_irq for IRQ %d returned %d; ignoring\n", + irq, err); + } +} + +static void __init titan_late_init(void) { /* @@ -278,15 +291,15 @@ titan_late_init(void) * all reported to the kernel as machine checks, so the handler * is a nop so it can be called to count the individual events. */ - request_irq(63+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(63+16, titan_intr_nop, IRQF_DISABLED, "CChip Error", NULL); - request_irq(62+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(62+16, titan_intr_nop, IRQF_DISABLED, "PChip 0 H_Error", NULL); - request_irq(61+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(61+16, titan_intr_nop, IRQF_DISABLED, "PChip 1 H_Error", NULL); - request_irq(60+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(60+16, titan_intr_nop, IRQF_DISABLED, "PChip 0 C_Error", NULL); - request_irq(59+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(59+16, titan_intr_nop, IRQF_DISABLED, "PChip 1 C_Error", NULL); /* @@ -345,9 +358,9 @@ privateer_init_pci(void) * Hook a couple of extra err interrupts that the * common titan code won't. */ - request_irq(53+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(53+16, titan_intr_nop, IRQF_DISABLED, "NMI", NULL); - request_irq(50+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(50+16, titan_intr_nop, IRQF_DISABLED, "Temperature Warning", NULL); /* diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index 2edcecdea8bd..ef801563bbf5 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c @@ -9,6 +9,7 @@ */ #include <linux/clk.h> #include <linux/etherdevice.h> +#include <linux/i2c-gpio.h> #include <linux/init.h> #include <linux/linkage.h> #include <linux/platform_device.h> @@ -123,6 +124,19 @@ static struct platform_device ngw_gpio_leds = { } }; +static struct i2c_gpio_platform_data i2c_gpio_data = { + .sda_pin = GPIO_PIN_PA(6), + .scl_pin = GPIO_PIN_PA(7), +}; + +static struct platform_device i2c_gpio_device = { + .name = "i2c-gpio", + .id = 0, + .dev = { + .platform_data = &i2c_gpio_data, + }, +}; + static int __init atngw100_init(void) { unsigned i; @@ -147,6 +161,10 @@ static int __init atngw100_init(void) } platform_device_register(&ngw_gpio_leds); + at32_select_gpio(i2c_gpio_data.sda_pin, 0); + at32_select_gpio(i2c_gpio_data.scl_pin, 0); + platform_device_register(&i2c_gpio_device); + return 0; } postcore_initcall(atngw100_init); diff --git a/arch/avr32/boards/atstk1000/Kconfig b/arch/avr32/boards/atstk1000/Kconfig index 71bc7d364fb7..718578f64069 100644 --- a/arch/avr32/boards/atstk1000/Kconfig +++ b/arch/avr32/boards/atstk1000/Kconfig @@ -50,4 +50,30 @@ config BOARD_ATSTK1002_SPI1 GPIO lines and accessed through the J1 jumper block. Say "y" here to configure that SPI controller. +config BOARD_ATSTK1002_J2_LED + bool + default BOARD_ATSTK1002_J2_LED8 || BOARD_ATSTK1002_J2_RGB + +choice + prompt "LEDs connected to J2:" + depends on LEDS_GPIO && !BOARD_ATSTK1002_SW4_CUSTOM + optional + help + Select this if you have jumpered the J2 jumper block to the + LED0..LED7 amber leds, or to the RGB leds, using a ten-pin + IDC cable. A default "heartbeat" trigger is provided, but + you can of course override this. + +config BOARD_ATSTK1002_J2_LED8 + bool "LED0..LED7" + help + Select this if J2 is jumpered to LED0..LED7 amber leds. + +config BOARD_ATSTK1002_J2_RGB + bool "RGB leds" + help + Select this if J2 is jumpered to the RGB leds. + +endchoice + endif # stk 1002 diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index cb93eabb9c6c..c9981b731efa 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -11,6 +11,7 @@ #include <linux/etherdevice.h> #include <linux/init.h> #include <linux/kernel.h> +#include <linux/leds.h> #include <linux/platform_device.h> #include <linux/string.h> #include <linux/types.h> @@ -120,6 +121,65 @@ static void __init set_hw_addr(struct platform_device *pdev) clk_put(pclk); } +#ifdef CONFIG_BOARD_ATSTK1002_J2_LED + +static struct gpio_led stk_j2_led[] = { +#ifdef CONFIG_BOARD_ATSTK1002_J2_LED8 +#define LEDSTRING "J2 jumpered to LED8" + { .name = "led0:amber", .gpio = GPIO_PIN_PB( 8), }, + { .name = "led1:amber", .gpio = GPIO_PIN_PB( 9), }, + { .name = "led2:amber", .gpio = GPIO_PIN_PB(10), }, + { .name = "led3:amber", .gpio = GPIO_PIN_PB(13), }, + { .name = "led4:amber", .gpio = GPIO_PIN_PB(14), }, + { .name = "led5:amber", .gpio = GPIO_PIN_PB(15), }, + { .name = "led6:amber", .gpio = GPIO_PIN_PB(16), }, + { .name = "led7:amber", .gpio = GPIO_PIN_PB(30), + .default_trigger = "heartbeat", }, +#else /* RGB */ +#define LEDSTRING "J2 jumpered to RGB LEDs" + { .name = "r1:red", .gpio = GPIO_PIN_PB( 8), }, + { .name = "g1:green", .gpio = GPIO_PIN_PB(10), }, + { .name = "b1:blue", .gpio = GPIO_PIN_PB(14), }, + + { .name = "r2:red", .gpio = GPIO_PIN_PB( 9), + .default_trigger = "heartbeat", }, + { .name = "g2:green", .gpio = GPIO_PIN_PB(13), }, + { .name = "b2:blue", .gpio = GPIO_PIN_PB(15), + .default_trigger = "heartbeat", }, + /* PB16, PB30 unused */ +#endif +}; + +static struct gpio_led_platform_data stk_j2_led_data = { + .num_leds = ARRAY_SIZE(stk_j2_led), + .leds = stk_j2_led, +}; + +static struct platform_device stk_j2_led_dev = { + .name = "leds-gpio", + .id = 2, /* gpio block J2 */ + .dev = { + .platform_data = &stk_j2_led_data, + }, +}; + +static void setup_j2_leds(void) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(stk_j2_led); i++) + at32_select_gpio(stk_j2_led[i].gpio, AT32_GPIOF_OUTPUT); + + printk("STK1002: " LEDSTRING "\n"); + platform_device_register(&stk_j2_led_dev); +} + +#else +static void setup_j2_leds(void) +{ +} +#endif + void __init setup_board(void) { #ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM @@ -185,6 +245,8 @@ static int __init atstk1002_init(void) at32_add_device_ssc(0, ATMEL_SSC_TX); #endif + setup_j2_leds(); + return 0; } postcore_initcall(atstk1002_init); diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c index b45188f8512e..673c860ffc23 100644 --- a/arch/blackfin/kernel/init_task.c +++ b/arch/blackfin/kernel/init_task.c @@ -31,6 +31,7 @@ #include <linux/module.h> #include <linux/init_task.h> #include <linux/mqueue.h> +#include <linux/fs.h> static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 5a51dd6ab280..6a7aefe48346 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -33,6 +33,8 @@ #include <linux/user.h> #include <linux/a.out.h> #include <linux/uaccess.h> +#include <linux/fs.h> +#include <linux/err.h> #include <asm/blackfin.h> #include <asm/fixed_code.h> diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index f5e1ae3d1705..abcd14817d0e 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c @@ -37,6 +37,7 @@ #include <linux/syscalls.h> #include <linux/mman.h> #include <linux/file.h> +#include <linux/fs.h> #include <linux/uaccess.h> #include <linux/ipc.h> #include <linux/unistd.h> diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 8766bd612b47..792a8416fe10 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -31,6 +31,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/kallsyms.h> +#include <linux/fs.h> #include <asm/traps.h> #include <asm/cacheflush.h> #include <asm/blackfin.h> diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 4b41248b61ad..6b4d026a00a1 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -180,8 +180,6 @@ source "drivers/isdn/Kconfig" source "drivers/telephony/Kconfig" -source "drivers/cdrom/Kconfig" - # # input before char - char/joystick depends on it. As does USB. # diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 275673c192aa..1e74f3c5cee2 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1496,6 +1496,7 @@ sys_call_table: .long sys_signalfd .long sys_timerfd .long sys_eventfd + .long sys_fallocate syscall_table_size = (. - sys_call_table) diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index f9524933258a..f16a46e8849c 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1228,6 +1228,11 @@ menuconfig INSTRUMENTATION bool "Instrumentation Support" depends on EXPERIMENTAL default y + ---help--- + Say Y here to get to see options related to performance measurement, + debugging, and testing. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if INSTRUMENTATION diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 01f0ff0daaf4..52b932478c6d 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -51,8 +51,8 @@ cflags-y += -maccumulate-outgoing-args CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) # do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) # is .cfi_signal_frame supported too? cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c index 658834d9f92a..82b5c846a194 100644 --- a/arch/i386/boot/edd.c +++ b/arch/i386/boot/edd.c @@ -19,40 +19,12 @@ #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) -struct edd_dapa { - u8 pkt_size; - u8 rsvd; - u16 sector_cnt; - u16 buf_off, buf_seg; - u64 lba; - u64 buf_lin_addr; -}; - /* * Read the MBR (first sector) from a specific device. */ static int read_mbr(u8 devno, void *buf) { - struct edd_dapa dapa; - u16 ax, bx, cx, dx, si; - - memset(&dapa, 0, sizeof dapa); - dapa.pkt_size = sizeof(dapa); - dapa.sector_cnt = 1; - dapa.buf_off = (size_t)buf; - dapa.buf_seg = ds(); - /* dapa.lba = 0; */ - - ax = 0x4200; /* Extended Read */ - si = (size_t)&dapa; - dx = devno; - asm("pushfl; stc; int $0x13; setc %%al; popfl" - : "+a" (ax), "+S" (si), "+d" (dx) - : "m" (dapa) - : "ebx", "ecx", "edi", "memory"); - - if (!(u8)ax) - return 0; /* OK */ + u16 ax, bx, cx, dx; ax = 0x0201; /* Legacy Read, one sector */ cx = 0x0001; /* Sector 0-0-1 */ @@ -65,11 +37,10 @@ static int read_mbr(u8 devno, void *buf) return -(u8)ax; /* 0 or -1 */ } -static u32 read_mbr_sig(u8 devno, struct edd_info *ei) +static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig) { int sector_size; char *mbrbuf_ptr, *mbrbuf_end; - u32 mbrsig; u32 buf_base, mbr_base; extern char _end[]; @@ -85,15 +56,15 @@ static u32 read_mbr_sig(u8 devno, struct edd_info *ei) /* Make sure we actually have space on the heap... */ if (!(boot_params.hdr.loadflags & CAN_USE_HEAP)) - return 0; + return -1; if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr) - return 0; + return -1; if (read_mbr(devno, mbrbuf_ptr)) - return 0; + return -1; - mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET]; - return mbrsig; + *mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET]; + return 0; } static int get_edd_info(u8 devno, struct edd_info *ei) @@ -160,6 +131,7 @@ void query_edd(void) int do_edd = 1; int devno; struct edd_info ei, *edp; + u32 *mbrptr; if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) { if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip")) @@ -168,7 +140,8 @@ void query_edd(void) do_edd = 0; } - edp = (struct edd_info *)boot_params.eddbuf; + edp = boot_params.eddbuf; + mbrptr = boot_params.edd_mbr_sig_buffer; if (!do_edd) return; @@ -186,11 +159,8 @@ void query_edd(void) boot_params.eddbuf_entries++; } - if (do_mbr) { - u32 mbr_sig; - mbr_sig = read_mbr_sig(devno, &ei); - boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig; - } + if (do_mbr && !read_mbr_sig(devno, &ei, mbrptr++)) + boot_params.edd_mbr_sig_buf_entries = devno-0x80+1; } } diff --git a/arch/i386/boot/video.c b/arch/i386/boot/video.c index 958130ef0042..693f20d3102e 100644 --- a/arch/i386/boot/video.c +++ b/arch/i386/boot/video.c @@ -61,7 +61,7 @@ static void store_video_mode(void) /* Not all BIOSes are clean with respect to the top bit */ boot_params.screen_info.orig_video_mode = ax & 0x7f; - boot_params.screen_info.orig_video_page = page; + boot_params.screen_info.orig_video_page = page >> 8; } /* diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index c85598acb8fd..1b66d5c70eaf 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -11,6 +11,8 @@ #include <asm/mce.h> #include <asm/nmi.h> +#define MAX_PATCH_LEN (255-1) + #ifdef CONFIG_HOTPLUG_CPU static int smp_alt_once; @@ -148,7 +150,8 @@ static unsigned char** find_nop_table(void) #endif /* CONFIG_X86_64 */ -static void nop_out(void *insns, unsigned int len) +/* Use this to add nops to a buffer, then text_poke the whole buffer. */ +static void add_nops(void *insns, unsigned int len) { unsigned char **noptable = find_nop_table(); @@ -156,7 +159,7 @@ static void nop_out(void *insns, unsigned int len) unsigned int noplen = len; if (noplen > ASM_NOP_MAX) noplen = ASM_NOP_MAX; - text_poke(insns, noptable[noplen], noplen); + memcpy(insns, noptable[noplen], noplen); insns += noplen; len -= noplen; } @@ -174,15 +177,15 @@ extern u8 *__smp_locks[], *__smp_locks_end[]; void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { struct alt_instr *a; - u8 *instr; - int diff; + char insnbuf[MAX_PATCH_LEN]; DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); for (a = start; a < end; a++) { + u8 *instr = a->instr; BUG_ON(a->replacementlen > a->instrlen); + BUG_ON(a->instrlen > sizeof(insnbuf)); if (!boot_cpu_has(a->cpuid)) continue; - instr = a->instr; #ifdef CONFIG_X86_64 /* vsyscall code is not mapped yet. resolve it manually. */ if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) { @@ -191,9 +194,10 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) __FUNCTION__, a->instr, instr); } #endif - memcpy(instr, a->replacement, a->replacementlen); - diff = a->instrlen - a->replacementlen; - nop_out(instr + a->replacementlen, diff); + memcpy(insnbuf, a->replacement, a->replacementlen); + add_nops(insnbuf + a->replacementlen, + a->instrlen - a->replacementlen); + text_poke(instr, insnbuf, a->instrlen); } } @@ -215,16 +219,18 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) { u8 **ptr; + char insn[1]; if (noreplace_smp) return; + add_nops(insn, 1); for (ptr = start; ptr < end; ptr++) { if (*ptr < text) continue; if (*ptr > text_end) continue; - nop_out(*ptr, 1); + text_poke(*ptr, insn, 1); }; } @@ -351,6 +357,7 @@ void apply_paravirt(struct paravirt_patch_site *start, struct paravirt_patch_site *end) { struct paravirt_patch_site *p; + char insnbuf[MAX_PATCH_LEN]; if (noreplace_paravirt) return; @@ -358,13 +365,15 @@ void apply_paravirt(struct paravirt_patch_site *start, for (p = start; p < end; p++) { unsigned int used; - used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, - p->len); + BUG_ON(p->len > MAX_PATCH_LEN); + used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf, + (unsigned long)p->instr, p->len); BUG_ON(used > p->len); /* Pad the rest with nops */ - nop_out(p->instr + used, p->len - used); + add_nops(insnbuf + used, p->len - used); + text_poke(p->instr, insnbuf, p->len); } } extern struct paravirt_patch_site __start_parainstructions[], @@ -379,7 +388,7 @@ void __init alternative_instructions(void) that might execute the to be patched code. Other CPUs are not running. */ stop_nmi(); -#ifdef CONFIG_MCE +#ifdef CONFIG_X86_MCE stop_mce(); #endif @@ -417,7 +426,7 @@ void __init alternative_instructions(void) local_irq_restore(flags); restart_nmi(); -#ifdef CONFIG_MCE +#ifdef CONFIG_X86_MCE restart_mce(); #endif } diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index bfc6cb7df7e7..3d67ae18d762 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -61,8 +61,9 @@ static int enable_local_apic __initdata = 0; /* Local APIC timer verification ok */ static int local_apic_timer_verify_ok; -/* Disable local APIC timer from the kernel commandline or via dmi quirk */ -static int local_apic_timer_disabled; +/* Disable local APIC timer from the kernel commandline or via dmi quirk + or using CPU MSR check */ +int local_apic_timer_disabled; /* Local APIC timer works in C2 */ int local_apic_timer_c2_ok; EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); @@ -370,12 +371,9 @@ void __init setup_boot_APIC_clock(void) long delta, deltapm; int pm_referenced = 0; - if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN)) - local_apic_timer_disabled = 1; - /* * The local apic timer can be disabled via the kernel - * commandline or from the test above. Register the lapic + * commandline or from the CPU detection code. Register the lapic * timer as a dummy clock event source on SMP systems, so the * broadcast mechanism is used. On UP systems simply ignore it. */ @@ -1087,7 +1085,7 @@ static int __init detect_init_APIC (void) if (l & MSR_IA32_APICBASE_ENABLE) mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; - if (nmi_watchdog != NMI_NONE) + if (nmi_watchdog != NMI_NONE && nmi_watchdog != NMI_DISABLED) nmi_watchdog = NMI_LOCAL_APIC; printk(KERN_INFO "Found and enabled local APIC!\n"); diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index c7ba455d5ac7..dcf6bbb1c7c0 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -3,6 +3,7 @@ #include <linux/mm.h> #include <asm/io.h> #include <asm/processor.h> +#include <asm/apic.h> #include "cpu.h" @@ -22,6 +23,7 @@ extern void vide(void); __asm__(".align 4\nvide: ret"); +#ifdef CONFIG_X86_LOCAL_APIC #define ENABLE_C1E_MASK 0x18000000 #define CPUID_PROCESSOR_SIGNATURE 1 #define CPUID_XFAM 0x0ff00000 @@ -52,6 +54,7 @@ static __cpuinit int amd_apic_timer_broken(void) } return 0; } +#endif int force_mwait __cpuinitdata; @@ -282,8 +285,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) num_cache_leaves = 3; } +#ifdef CONFIG_X86_LOCAL_APIC if (amd_apic_timer_broken()) - set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); + local_apic_timer_disabled = 1; +#endif if (c->x86 == 0x10 && !force_mwait) clear_bit(X86_FEATURE_MWAIT, c->x86_capability); diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 32d04b083e38..705e13a30781 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -68,7 +68,8 @@ struct acpi_cpufreq_data { }; static struct acpi_cpufreq_data *drv_data[NR_CPUS]; -static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; +/* acpi_perf_data is a pointer to percpu data. */ +static struct acpi_processor_performance *acpi_perf_data; static struct cpufreq_driver acpi_cpufreq_driver; @@ -508,24 +509,14 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) * do _PDC and _PSD and find out the processor dependency for the * actual init that will happen later... */ -static int acpi_cpufreq_early_init(void) +static int __init acpi_cpufreq_early_init(void) { - struct acpi_processor_performance *data; - unsigned int i, j; - dprintk("acpi_cpufreq_early_init\n"); - for_each_possible_cpu(i) { - data = kzalloc(sizeof(struct acpi_processor_performance), - GFP_KERNEL); - if (!data) { - for_each_possible_cpu(j) { - kfree(acpi_perf_data[j]); - acpi_perf_data[j] = NULL; - } - return -ENOMEM; - } - acpi_perf_data[i] = data; + acpi_perf_data = alloc_percpu(struct acpi_processor_performance); + if (!acpi_perf_data) { + dprintk("Memory allocation error for acpi_perf_data.\n"); + return -ENOMEM; } /* Do initialization in ACPI core */ @@ -574,14 +565,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) dprintk("acpi_cpufreq_cpu_init\n"); - if (!acpi_perf_data[cpu]) - return -ENODEV; - data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); if (!data) return -ENOMEM; - data->acpi_data = acpi_perf_data[cpu]; + data->acpi_data = percpu_ptr(acpi_perf_data, cpu); drv_data[cpu] = data; if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) @@ -778,24 +766,25 @@ static struct cpufreq_driver acpi_cpufreq_driver = { static int __init acpi_cpufreq_init(void) { + int ret; + dprintk("acpi_cpufreq_init\n"); - acpi_cpufreq_early_init(); + ret = acpi_cpufreq_early_init(); + if (ret) + return ret; return cpufreq_register_driver(&acpi_cpufreq_driver); } static void __exit acpi_cpufreq_exit(void) { - unsigned int i; dprintk("acpi_cpufreq_exit\n"); cpufreq_unregister_driver(&acpi_cpufreq_driver); - for_each_possible_cpu(i) { - kfree(acpi_perf_data[i]); - acpi_perf_data[i] = NULL; - } + free_percpu(acpi_perf_data); + return; } diff --git a/arch/i386/kernel/doublefault.c b/arch/i386/kernel/doublefault.c index 265c5597efb0..40978af630e7 100644 --- a/arch/i386/kernel/doublefault.c +++ b/arch/i386/kernel/doublefault.c @@ -13,7 +13,7 @@ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE) -#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000) +#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM) static void doublefault_fn(void) { @@ -23,23 +23,23 @@ static void doublefault_fn(void) store_gdt(&gdt_desc); gdt = gdt_desc.address; - printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); if (ptr_ok(gdt)) { gdt += GDT_ENTRY_TSS << 3; tss = *(u16 *)(gdt+2); tss += *(u8 *)(gdt+4) << 16; tss += *(u8 *)(gdt+7) << 24; - printk("double fault, tss at %08lx\n", tss); + printk(KERN_EMERG "double fault, tss at %08lx\n", tss); if (ptr_ok(tss)) { struct i386_hw_tss *t = (struct i386_hw_tss *)tss; - printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp); + printk(KERN_EMERG "eip = %08lx, esp = %08lx\n", t->eip, t->esp); - printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", + printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", t->eax, t->ebx, t->ecx, t->edx); - printk("esi = %08lx, edi = %08lx\n", + printk(KERN_EMERG "esi = %08lx, edi = %08lx\n", t->esi, t->edi); } } @@ -63,6 +63,7 @@ struct tss_struct doublefault_tss __cacheline_aligned = { .cs = __KERNEL_CS, .ss = __KERNEL_DS, .ds = __USER_DS, + .fs = __KERNEL_PERCPU, .__cr3 = __pa(swapper_pg_dir) } diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 7c52b222207e..8f0382161c91 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -162,9 +162,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20); * which will be freed later */ -#ifdef CONFIG_HOTPLUG_CPU -.section .text,"ax",@progbits -#else +#ifndef CONFIG_HOTPLUG_CPU .section .init.text,"ax",@progbits #endif diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 893df8280756..4b8a8da4b2e0 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1256,12 +1256,15 @@ static struct irq_chip ioapic_chip; static void ioapic_register_intr(int irq, int vector, unsigned long trigger) { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) + trigger == IOAPIC_LEVEL) { + irq_desc[irq].status |= IRQ_LEVEL; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_fasteoi_irq, "fasteoi"); - else + } else { + irq_desc[irq].status &= ~IRQ_LEVEL; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_edge_irq, "edge"); + } set_intr_gate(vector, interrupt[irq]); } diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 99beac7f96ce..8c1c965eb2a8 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -77,7 +77,7 @@ static int __init check_nmi_watchdog(void) unsigned int *prev_nmi_count; int cpu; - if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) + if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DISABLED)) return 0; if (!atomic_read(&nmi_active)) @@ -424,7 +424,7 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, if (!!old_state == !!nmi_watchdog_enabled) return 0; - if (atomic_read(&nmi_active) < 0) { + if (atomic_read(&nmi_active) < 0 || nmi_watchdog == NMI_DISABLED) { printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); return -EIO; } diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index ea962c0667d5..739cfb207dd7 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -69,7 +69,8 @@ DEF_NATIVE(read_tsc, "rdtsc"); DEF_NATIVE(ud2a, "ud2a"); -static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned native_patch(u8 type, u16 clobbers, void *ibuf, + unsigned long addr, unsigned len) { const unsigned char *start, *end; unsigned ret; @@ -90,7 +91,7 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) #undef SITE patch_site: - ret = paravirt_patch_insns(insns, len, start, end); + ret = paravirt_patch_insns(ibuf, len, start, end); break; case PARAVIRT_PATCH(make_pgd): @@ -107,7 +108,7 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) break; default: - ret = paravirt_patch_default(type, clobbers, insns, len); + ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); break; } @@ -129,68 +130,67 @@ struct branch { u32 delta; } __attribute__((packed)); -unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, - void *site, u16 site_clobbers, +unsigned paravirt_patch_call(void *insnbuf, + const void *target, u16 tgt_clobbers, + unsigned long addr, u16 site_clobbers, unsigned len) { - unsigned char *call = site; - unsigned long delta = (unsigned long)target - (unsigned long)(call+5); - struct branch b; + struct branch *b = insnbuf; + unsigned long delta = (unsigned long)target - (addr+5); if (tgt_clobbers & ~site_clobbers) return len; /* target would clobber too much for this site */ if (len < 5) return len; /* call too long for patch site */ - b.opcode = 0xe8; /* call */ - b.delta = delta; - BUILD_BUG_ON(sizeof(b) != 5); - text_poke(call, (unsigned char *)&b, 5); + b->opcode = 0xe8; /* call */ + b->delta = delta; + BUILD_BUG_ON(sizeof(*b) != 5); return 5; } -unsigned paravirt_patch_jmp(void *target, void *site, unsigned len) +unsigned paravirt_patch_jmp(const void *target, void *insnbuf, + unsigned long addr, unsigned len) { - unsigned char *jmp = site; - unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5); - struct branch b; + struct branch *b = insnbuf; + unsigned long delta = (unsigned long)target - (addr+5); if (len < 5) return len; /* call too long for patch site */ - b.opcode = 0xe9; /* jmp */ - b.delta = delta; - text_poke(jmp, (unsigned char *)&b, 5); + b->opcode = 0xe9; /* jmp */ + b->delta = delta; return 5; } -unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len) +unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len) { void *opfunc = *((void **)¶virt_ops + type); unsigned ret; if (opfunc == NULL) /* If there's no function, patch it with a ud2a (BUG) */ - ret = paravirt_patch_insns(site, len, start_ud2a, end_ud2a); + ret = paravirt_patch_insns(insnbuf, len, start_ud2a, end_ud2a); else if (opfunc == paravirt_nop) /* If the operation is a nop, then nop the callsite */ ret = paravirt_patch_nop(); else if (type == PARAVIRT_PATCH(iret) || type == PARAVIRT_PATCH(irq_enable_sysexit)) /* If operation requires a jmp, then jmp */ - ret = paravirt_patch_jmp(opfunc, site, len); + ret = paravirt_patch_jmp(opfunc, insnbuf, addr, len); else /* Otherwise call the function; assume target could clobber any caller-save reg */ - ret = paravirt_patch_call(opfunc, CLBR_ANY, - site, clobbers, len); + ret = paravirt_patch_call(insnbuf, opfunc, CLBR_ANY, + addr, clobbers, len); return ret; } -unsigned paravirt_patch_insns(void *site, unsigned len, +unsigned paravirt_patch_insns(void *insnbuf, unsigned len, const char *start, const char *end) { unsigned insn_len = end - start; @@ -198,7 +198,7 @@ unsigned paravirt_patch_insns(void *site, unsigned len, if (insn_len > len || start == NULL) insn_len = len; else - memcpy(site, start, insn_len); + memcpy(insnbuf, start, insn_len); return insn_len; } diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 72042bb7ec94..18673e0f193b 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -87,12 +87,14 @@ struct vmi_timer_ops vmi_timer_ops; #define IRQ_PATCH_INT_MASK 0 #define IRQ_PATCH_DISABLE 5 -static inline void patch_offset(unsigned char *eip, unsigned char *dest) +static inline void patch_offset(void *insnbuf, + unsigned long eip, unsigned long dest) { - *(unsigned long *)(eip+1) = dest-eip-5; + *(unsigned long *)(insnbuf+1) = dest-eip-5; } -static unsigned patch_internal(int call, unsigned len, void *insns) +static unsigned patch_internal(int call, unsigned len, void *insnbuf, + unsigned long eip) { u64 reloc; struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; @@ -100,14 +102,14 @@ static unsigned patch_internal(int call, unsigned len, void *insns) switch(rel->type) { case VMI_RELOCATION_CALL_REL: BUG_ON(len < 5); - *(char *)insns = MNEM_CALL; - patch_offset(insns, rel->eip); + *(char *)insnbuf = MNEM_CALL; + patch_offset(insnbuf, eip, (unsigned long)rel->eip); return 5; case VMI_RELOCATION_JUMP_REL: BUG_ON(len < 5); - *(char *)insns = MNEM_JMP; - patch_offset(insns, rel->eip); + *(char *)insnbuf = MNEM_JMP; + patch_offset(insnbuf, eip, (unsigned long)rel->eip); return 5; case VMI_RELOCATION_NOP: @@ -128,21 +130,26 @@ static unsigned patch_internal(int call, unsigned len, void *insns) * Apply patch if appropriate, return length of new instruction * sequence. The callee does nop padding for us. */ -static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, + unsigned long eip, unsigned len) { switch (type) { case PARAVIRT_PATCH(irq_disable): - return patch_internal(VMI_CALL_DisableInterrupts, len, insns); + return patch_internal(VMI_CALL_DisableInterrupts, len, + insns, eip); case PARAVIRT_PATCH(irq_enable): - return patch_internal(VMI_CALL_EnableInterrupts, len, insns); + return patch_internal(VMI_CALL_EnableInterrupts, len, + insns, eip); case PARAVIRT_PATCH(restore_fl): - return patch_internal(VMI_CALL_SetInterruptMask, len, insns); + return patch_internal(VMI_CALL_SetInterruptMask, len, + insns, eip); case PARAVIRT_PATCH(save_fl): - return patch_internal(VMI_CALL_GetInterruptMask, len, insns); + return patch_internal(VMI_CALL_GetInterruptMask, len, + insns, eip); case PARAVIRT_PATCH(iret): - return patch_internal(VMI_CALL_IRET, len, insns); + return patch_internal(VMI_CALL_IRET, len, insns, eip); case PARAVIRT_PATCH(irq_enable_sysexit): - return patch_internal(VMI_CALL_SYSEXIT, len, insns); + return patch_internal(VMI_CALL_SYSEXIT, len, insns, eip); default: break; } diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 8927222b3ab2..4241a74d16c8 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c @@ -82,7 +82,7 @@ static void flush_kernel_map(void *arg) struct page *p; /* High level code is not ready for clflush yet */ - if (cpu_has_clflush) { + if (0 && cpu_has_clflush) { list_for_each_entry (p, lh, lru) cache_flush_page(p); } else if (boot_cpu_data.x86_model >= 4) diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 85503deeda46..ebc6f3c66340 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -455,3 +455,26 @@ void pcibios_disable_device (struct pci_dev *dev) if (!dev->msi_enabled && pcibios_disable_irq) pcibios_disable_irq(dev); } + +struct pci_bus *pci_scan_bus_with_sysdata(int busno) +{ + struct pci_bus *bus = NULL; + struct pci_sysdata *sd; + + /* + * Allocate per-root-bus (not per bus) arch-specific data. + * TODO: leak; this memory is never freed. + * It's arguable whether it's worth the trouble to care. + */ + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) { + printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno); + return NULL; + } + sd->node = -1; + bus = pci_scan_bus(busno, &pci_root_ops, sd); + if (!bus) + kfree(sd); + + return bus; +} diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index e7306dbf6c42..c82cbf4c7226 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -25,9 +25,9 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) pci_read_config_byte(d, reg++, &subb); DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); if (busno) - pci_scan_bus(busno, &pci_root_ops, NULL); /* Bus A */ + pci_scan_bus_with_sysdata(busno); /* Bus A */ if (suba < subb) - pci_scan_bus(suba+1, &pci_root_ops, NULL); /* Bus B */ + pci_scan_bus_with_sysdata(suba+1); /* Bus B */ } pcibios_last_bus = -1; } @@ -42,7 +42,7 @@ static void __devinit pci_fixup_i450gx(struct pci_dev *d) u8 busno; pci_read_config_byte(d, 0x4a, &busno); printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", pci_name(d), busno); - pci_scan_bus(busno, &pci_root_ops, NULL); + pci_scan_bus_with_sysdata(busno); pcibios_last_bus = -1; } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx); diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index f2cb942f8281..665db063a40a 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -138,8 +138,9 @@ static void __init pirq_peer_trick(void) for(i = 1; i < 256; i++) { if (!busmap[i] || pci_find_bus(0, i)) continue; - if (pci_scan_bus(i, &pci_root_ops, NULL)) - printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i); + if (pci_scan_bus_with_sysdata(i)) + printk(KERN_INFO "PCI: Discovered primary peer " + "bus %02x [IRQ]\n", i); } pcibios_last_bus = -1; } diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 149a9588c256..5565d7016b75 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c @@ -26,7 +26,7 @@ static void __devinit pcibios_fixup_peer_bridges(void) l != 0x0000 && l != 0xffff) { DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l); printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); - pci_scan_bus(n, &pci_root_ops, NULL); + pci_scan_bus_with_sysdata(n); break; } } diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index bb1afd9e589d..1bf5816d34c8 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -82,16 +82,15 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, switch (len) { case 1: - *value = readb(mmcfg_virt_addr + reg); + *value = mmio_config_readb(mmcfg_virt_addr + reg); break; case 2: - *value = readw(mmcfg_virt_addr + reg); + *value = mmio_config_readw(mmcfg_virt_addr + reg); break; case 4: - *value = readl(mmcfg_virt_addr + reg); + *value = mmio_config_readl(mmcfg_virt_addr + reg); break; } - spin_unlock_irqrestore(&pci_config_lock, flags); return 0; @@ -116,16 +115,15 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, switch (len) { case 1: - writeb(value, mmcfg_virt_addr + reg); + mmio_config_writeb(mmcfg_virt_addr + reg, value); break; case 2: - writew(value, mmcfg_virt_addr + reg); + mmio_config_writew(mmcfg_virt_addr + reg, value); break; case 4: - writel(value, mmcfg_virt_addr + reg); + mmio_config_writel(mmcfg_virt_addr + reg, value); break; } - spin_unlock_irqrestore(&pci_config_lock, flags); return 0; diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index adbe17a38f6f..f5f165f69e0c 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c @@ -96,10 +96,14 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) pci_read_config_byte(d, reg++, &suba); pci_read_config_byte(d, reg++, &subb); DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); - if (busno) - pci_scan_bus(QUADLOCAL2BUS(quad,busno), &pci_root_ops, NULL); /* Bus A */ - if (suba < subb) - pci_scan_bus(QUADLOCAL2BUS(quad,suba+1), &pci_root_ops, NULL); /* Bus B */ + if (busno) { + /* Bus A */ + pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno)); + } + if (suba < subb) { + /* Bus B */ + pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1)); + } } pcibios_last_bus = -1; } @@ -123,8 +127,7 @@ static int __init pci_numa_init(void) continue; printk("Scanning PCI bus %d for quad %d\n", QUADLOCAL2BUS(quad,0), quad); - pci_scan_bus(QUADLOCAL2BUS(quad,0), - &pci_root_ops, NULL); + pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0)); } return 0; } diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index e58bae2076ad..8c66f275756f 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -104,3 +104,46 @@ extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, unsigned int devfn); extern int __init pci_mmcfg_arch_init(void); + +/* + * AMD Fam10h CPUs are buggy, and cannot access MMIO config space + * on their northbrige except through the * %eax register. As such, you MUST + * NOT use normal IOMEM accesses, you need to only use the magic mmio-config + * accessor functions. + * In fact just use pci_config_*, nothing else please. + */ +static inline unsigned char mmio_config_readb(void __iomem *pos) +{ + u8 val; + asm volatile("movb (%1),%%al" : "=a" (val) : "r" (pos)); + return val; +} + +static inline unsigned short mmio_config_readw(void __iomem *pos) +{ + u16 val; + asm volatile("movw (%1),%%ax" : "=a" (val) : "r" (pos)); + return val; +} + +static inline unsigned int mmio_config_readl(void __iomem *pos) +{ + u32 val; + asm volatile("movl (%1),%%eax" : "=a" (val) : "r" (pos)); + return val; +} + +static inline void mmio_config_writeb(void __iomem *pos, u8 val) +{ + asm volatile("movb %%al,(%1)" :: "a" (val), "r" (pos) : "memory"); +} + +static inline void mmio_config_writew(void __iomem *pos, u16 val) +{ + asm volatile("movw %%ax,(%1)" :: "a" (val), "r" (pos) : "memory"); +} + +static inline void mmio_config_writel(void __iomem *pos, u32 val) +{ + asm volatile("movl %%eax,(%1)" :: "a" (val), "r" (pos) : "memory"); +} diff --git a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c index f1b486d4190b..8ecb1c722594 100644 --- a/arch/i386/pci/visws.c +++ b/arch/i386/pci/visws.c @@ -101,8 +101,8 @@ static int __init pcibios_init(void) "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0); raw_pci_ops = &pci_direct_conf1; - pci_scan_bus(pci_bus0, &pci_root_ops, NULL); - pci_scan_bus(pci_bus1, &pci_root_ops, NULL); + pci_scan_bus_with_sysdata(pci_bus0); + pci_scan_bus_with_sysdata(pci_bus1); pci_fixup_irqs(visws_swizzle, visws_map_irq); pcibios_resource_survey(); return 0; diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c index 9a8c1181c001..f0c37511d8da 100644 --- a/arch/i386/xen/enlighten.c +++ b/arch/i386/xen/enlighten.c @@ -842,7 +842,8 @@ void __init xen_setup_vcpu_info_placement(void) } } -static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len) { char *start, *end, *reloc; unsigned ret; @@ -869,7 +870,7 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) if (start == NULL || (end-start) > len) goto default_patch; - ret = paravirt_patch_insns(insns, len, start, end); + ret = paravirt_patch_insns(insnbuf, len, start, end); /* Note: because reloc is assigned from something that appears to be an array, gcc assumes it's non-null, @@ -877,8 +878,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) end. */ if (reloc > start && reloc < end) { int reloc_off = reloc - start; - long *relocp = (long *)(insns + reloc_off); - long delta = start - (char *)insns; + long *relocp = (long *)(insnbuf + reloc_off); + long delta = start - (char *)addr; *relocp += delta; } @@ -886,7 +887,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) default_patch: default: - ret = paravirt_patch_default(type, clobbers, insns, len); + ret = paravirt_patch_default(type, clobbers, insnbuf, + addr, len); break; } diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 21aa4fc5f8ef..8c39913d1729 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -327,17 +327,7 @@ config FORCE_CPEI_RETARGET This option it useful to enable this feature on older BIOS's as well. You can also enable this by using boot command line option force_cpei=1. -config PREEMPT - bool "Preemptible Kernel" - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - This allows applications to run more reliably even when the system is - under load. - - Say Y here if you are building a kernel for a desktop, embedded - or real-time system. Say N if you are unsure. +source "kernel/Kconfig.preempt" source "mm/Kconfig" diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig index 9eb48c0927b0..6dd8655664f3 100644 --- a/arch/ia64/configs/bigsur_defconfig +++ b/arch/ia64/configs/bigsur_defconfig @@ -42,7 +42,7 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_SLAB=y +CONFIG_SLUB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 3a9ed951db08..e86fbd39c795 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig @@ -43,7 +43,7 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_SLAB=y +CONFIG_SLUB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set diff --git a/arch/ia64/configs/sim_defconfig b/arch/ia64/configs/sim_defconfig index c420d9f3df98..546a772f438e 100644 --- a/arch/ia64/configs/sim_defconfig +++ b/arch/ia64/configs/sim_defconfig @@ -43,7 +43,7 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_SLAB=y +CONFIG_SLUB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 4c9ffc47bc7a..9aecfceeb38c 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -46,7 +46,7 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_SLAB=y +CONFIG_SLUB=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 3dbb3987df27..797acf9066c1 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -53,7 +53,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y +CONFIG_SLUB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 4a060fc39934..0a06b1333c95 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -48,7 +48,7 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_SLAB=y +CONFIG_SLUB=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig index 03172dc8c403..0210545e7f61 100644 --- a/arch/ia64/defconfig +++ b/arch/ia64/defconfig @@ -53,8 +53,7 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set +CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set diff --git a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S index a9bd71ac78e2..8808565491fb 100644 --- a/arch/ia64/hp/sim/boot/boot_head.S +++ b/arch/ia64/hp/sim/boot/boot_head.S @@ -26,6 +26,7 @@ GLOBAL_ENTRY(_start) movl sp = stack_mem+16384-16 bsw.1 br.call.sptk.many rp=start_bootloader +0: nop 0 /* dummy nop to make unwinding work */ END(_start) /* diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index 15c08d52f09f..8c6ec7070844 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -113,10 +113,8 @@ processor_get_freq ( saved_mask = current->cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(cpu)); - if (smp_processor_id() != cpu) { - ret = -EAGAIN; + if (smp_processor_id() != cpu) goto migrate_end; - } /* processor_get_pstate gets the instantaneous frequency */ ret = processor_get_pstate(&value); @@ -125,7 +123,7 @@ processor_get_freq ( set_cpus_allowed(current, saved_mask); printk(KERN_WARNING "get performance failed with error %d\n", ret); - ret = -EAGAIN; + ret = 0; goto migrate_end; } clock_freq = extract_clock(data, value, cpu); diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index cc3ee4ef37af..44be1c952b7c 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -33,6 +33,11 @@ void ack_bad_irq(unsigned int irq) } #ifdef CONFIG_IA64_GENERIC +ia64_vector __ia64_irq_to_vector(int irq) +{ + return irq_cfg[irq].vector; +} + unsigned int __ia64_local_vector_to_irq (ia64_vector vec) { return __get_cpu_var(vector_irq)[vec]; diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index ff28620cb992..63b73f3d4c9f 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -2018,22 +2018,26 @@ ia64_mca_late_init(void) if (cpe_vector >= 0) { /* If platform supports CPEI, enable the irq. */ - cpe_poll_enabled = 0; - for (irq = 0; irq < NR_IRQS; ++irq) - if (irq_to_vector(irq) == cpe_vector) { - desc = irq_desc + irq; - desc->status |= IRQ_PER_CPU; - setup_irq(irq, &mca_cpe_irqaction); - ia64_cpe_irq = irq; - } - ia64_mca_register_cpev(cpe_vector); - IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__); - } else { - /* If platform doesn't support CPEI, get the timer going. */ - if (cpe_poll_enabled) { - ia64_mca_cpe_poll(0UL); - IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __FUNCTION__); + irq = local_vector_to_irq(cpe_vector); + if (irq > 0) { + cpe_poll_enabled = 0; + desc = irq_desc + irq; + desc->status |= IRQ_PER_CPU; + setup_irq(irq, &mca_cpe_irqaction); + ia64_cpe_irq = irq; + ia64_mca_register_cpev(cpe_vector); + IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", + __FUNCTION__); + return 0; } + printk(KERN_ERR "%s: Failed to find irq for CPE " + "interrupt handler, vector %d\n", + __FUNCTION__, cpe_vector); + } + /* If platform doesn't support CPEI, get the timer going. */ + if (cpe_poll_enabled) { + ia64_mca_cpe_poll(0UL); + IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __FUNCTION__); } } #endif diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 4158906c45aa..c613fc0e91cc 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -198,9 +198,13 @@ default_idle (void) { local_irq_enable(); while (!need_resched()) { - if (can_do_pal_halt) - safe_halt(); - else + if (can_do_pal_halt) { + local_irq_disable(); + if (!need_resched()) { + safe_halt(); + } + local_irq_enable(); + } else cpu_relax(); } } diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 00f803246948..122444a97897 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -951,10 +951,14 @@ access_uarea (struct task_struct *child, unsigned long addr, return 0; case PT_CR_IPSR: - if (write_access) - pt->cr_ipsr = ((*data & IPSR_MASK) + if (write_access) { + unsigned long tmp = *data; + /* psr.ri==3 is a reserved value: SDM 2:25 */ + if ((tmp & IA64_PSR_RI) == IA64_PSR_RI) + tmp &= ~IA64_PSR_RI; + pt->cr_ipsr = ((tmp & IPSR_MASK) | (pt->cr_ipsr & ~IPSR_MASK)); - else + } else *data = (pt->cr_ipsr & IPSR_MASK); return 0; diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index cd9a37a552c3..407efea04bf5 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -389,6 +389,13 @@ early_console_setup (char *cmdline) if (!efi_setup_pcdp_console(cmdline)) earlycons++; #endif +#ifdef CONFIG_HP_SIMSERIAL_CONSOLE + { + extern struct console hpsim_cons; + register_console(&hpsim_cons); + earlycons++; + } +#endif return (earlycons) ? 0 : -1; } diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 83e80677de70..00232b4357ba 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -20,6 +20,8 @@ PHDRS { code PT_LOAD; percpu PT_LOAD; data PT_LOAD; + note PT_NOTE; + unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */ } SECTIONS { @@ -62,6 +64,9 @@ SECTIONS /* Read-only data */ + NOTES :code :note /* put .notes in text and mark in PT_NOTE */ + code_continues : {} :code /* switch back to regular program... */ + /* Exception table */ . = ALIGN(16); __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) @@ -99,7 +104,8 @@ SECTIONS __start_unwind = .; *(.IA_64.unwind*) __end_unwind = .; - } + } :code :unwind + code_continues2 : {} : code RODATA @@ -276,10 +282,6 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /* These must appear regardless of . */ - /* Discard them for now since Intel SoftSDV cannot handle them. - .comment 0 : { *(.comment) } - .note 0 : { *(.note) } - */ /DISCARD/ : { *(.comment) } /DISCARD/ : { *(.note) } } diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 73ccb6010c05..9150ffaff9e8 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -112,11 +112,17 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re down_read(&mm->mmap_sem); vma = find_vma_prev(mm, address, &prev_vma); - if (!vma) + if (!vma && !prev_vma ) goto bad_area; - /* find_vma_prev() returns vma such that address < vma->vm_end or NULL */ - if (address < vma->vm_start) + /* + * find_vma_prev() returns vma such that address < vma->vm_end or NULL + * + * May find no vma, but could be that the last vm area is the + * register backing store that needs to expand upwards, in + * this case vma will be null, but prev_vma will ne non-null + */ + if (( !vma && prev_vma ) || (address < vma->vm_start) ) goto check_expansion; good_area: @@ -172,6 +178,8 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re check_expansion: if (!(prev_vma && (prev_vma->vm_flags & VM_GROWSUP) && (address == prev_vma->vm_end))) { + if (!vma) + goto bad_area; if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start) diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 7f6d2360a262..360047389449 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -256,6 +256,13 @@ struct irq_chip irq_type_sn = { .set_affinity = sn_set_affinity_irq }; +ia64_vector sn_irq_to_vector(int irq) +{ + if (irq >= IA64_NUM_VECTORS) + return 0; + return (ia64_vector)irq; +} + unsigned int sn_local_vector_to_irq(u8 vector) { return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector)); @@ -398,7 +405,10 @@ sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info) struct sn_pcibus_provider *pci_provider; pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type]; - if (pci_provider && pci_provider->force_interrupt) + + /* Don't force an interrupt if the irq has been disabled */ + if (!(irq_desc[sn_irq_info->irq_irq].status & IRQ_DISABLED) && + pci_provider && pci_provider->force_interrupt) (*pci_provider->force_interrupt)(sn_irq_info); } diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c index b732644788db..13761bf160c4 100644 --- a/arch/powerpc/boot/flatdevtree.c +++ b/arch/powerpc/boot/flatdevtree.c @@ -134,20 +134,6 @@ static char *ft_next(struct ft_cxt *cxt, char *p, struct ft_atom *ret) #define HDR_SIZE _ALIGN(sizeof(struct boot_param_header), 8) #define EXPAND_INCR 1024 /* alloc this much extra when expanding */ -/* See if the regions are in the standard order and non-overlapping */ -static int ft_ordered(struct ft_cxt *cxt) -{ - char *p = (char *)cxt->bph + HDR_SIZE; - enum ft_rgn_id r; - - for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) { - if (p > cxt->rgn[r].start) - return 0; - p = cxt->rgn[r].start + cxt->rgn[r].size; - } - return p <= (char *)cxt->bph + cxt->max_size; -} - /* Copy the tree to a newly-allocated region and put things in order */ static int ft_reorder(struct ft_cxt *cxt, int nextra) { @@ -573,10 +559,6 @@ int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size, cxt->rgn[FT_STRUCT].size = struct_size(cxt); cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings); cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size); - /* Leave as '0' to force first ft_make_space call to do a ft_reorder - * and move dt to an area allocated by realloc. - cxt->isordered = ft_ordered(cxt); - */ cxt->p = cxt->rgn[FT_STRUCT].start; cxt->str_anchor = cxt->rgn[FT_STRINGS].start; diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index d0b43df44426..ca7a197998ee 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -1,9 +1,23 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc6 -# Tue Jun 26 14:15:19 2007 +# Linux kernel version: 2.6.23-rc2 +# Tue Aug 7 19:17:26 2007 # CONFIG_PPC64=y + +# +# Processor support +# +# CONFIG_POWER4_ONLY is not set +CONFIG_POWER3=y +CONFIG_POWER4=y +CONFIG_PPC_FPU=y +CONFIG_ALTIVEC=y +CONFIG_PPC_STD_MMU=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2 CONFIG_64BIT=y CONFIG_PPC_MERGE=y CONFIG_MMU=y @@ -15,6 +29,7 @@ CONFIG_ARCH_HAS_ILOG2_U64=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y @@ -22,50 +37,32 @@ CONFIG_SYSVIPC_COMPAT=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y +CONFIG_OF=y # CONFIG_PPC_UDBG_16550 is not set # CONFIG_GENERIC_TBSYNC is not set CONFIG_AUDIT_ARCH=y CONFIG_GENERIC_BUG=y # CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_POWER4_ONLY is not set -CONFIG_POWER3=y -CONFIG_POWER4=y -CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_NATIVE is not set # CONFIG_PPC_DCR_MMIO is not set # CONFIG_PPC_OF_PLATFORM_PCI is not set -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_VIRT_CPU_ACCOUNTING=y -CONFIG_SMP=y -CONFIG_NR_CPUS=2 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 @@ -100,10 +97,6 @@ CONFIG_SLAB=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set @@ -111,12 +104,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y CONFIG_STOP_MACHINE=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_BLK_DEV_BSG=y # # IO Schedulers @@ -136,7 +126,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_PPC_MULTIPLATFORM=y # CONFIG_EMBEDDED6xx is not set -# CONFIG_APUS is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_86xx is not set # CONFIG_PPC_PSERIES is not set # CONFIG_PPC_ISERIES is not set # CONFIG_PPC_MPC52xx is not set @@ -223,6 +215,7 @@ CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y CONFIG_ARCH_MEMORY_PROBE=y # CONFIG_PPC_HAS_HASH_64K is not set # CONFIG_PPC_64K_PAGES is not set @@ -241,6 +234,7 @@ CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # @@ -365,6 +359,7 @@ CONFIG_WIRELESS_EXT=y # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -379,26 +374,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set # CONFIG_MTD is not set - -# -# Parallel port support -# +CONFIG_OF_DEVICE=y # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y @@ -411,11 +391,8 @@ CONFIG_BLK_DEV_RAM_SIZE=65535 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_BLINK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -423,6 +400,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -455,37 +433,22 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_LOWLEVEL is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set # CONFIG_MACINTOSH_DRIVERS is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# Ethernet (10 or 100Mbit) -# # CONFIG_NET_ETHERNET is not set CONFIG_MII=m CONFIG_NETDEV_1000=y -CONFIG_NETDEV_10000=y CONFIG_GELIC_NET=y +# CONFIG_NETDEV_10000 is not set # # Wireless LAN @@ -518,15 +481,7 @@ CONFIG_USB_NET_MCS7830=m # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -604,10 +559,6 @@ CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=16 - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set @@ -616,10 +567,6 @@ CONFIG_GEN_RTC=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HANGCHECK_TIMER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set @@ -628,11 +575,8 @@ CONFIG_GEN_RTC=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # @@ -657,6 +601,7 @@ CONFIG_GEN_RTC=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set @@ -691,11 +636,13 @@ CONFIG_FB_PS3_DEFAULT_SIZE_M=18 # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_LOGO=y +CONFIG_FB_LOGO_EXTRA=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y @@ -709,6 +656,8 @@ CONFIG_SOUND=y # Advanced Linux Sound Architecture # CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y # CONFIG_SND_SEQUENCER is not set # CONFIG_SND_MIXER_OSS is not set # CONFIG_SND_PCM_OSS is not set @@ -735,6 +684,12 @@ CONFIG_SND_VERBOSE_PROCFS=y # # +# ALSA PowerPC devices +# +CONFIG_SND_PS3=y +CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 + +# # USB devices # # CONFIG_SND_USB_AUDIO is not set @@ -747,13 +702,14 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_SOC is not set # -# Open Sound System +# SoC Audio support for SuperH # -# CONFIG_SOUND_PRIME is not set # -# HID Devices +# Open Sound System # +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set @@ -770,10 +726,7 @@ CONFIG_USB_HID=m # # CONFIG_USB_KBD is not set # CONFIG_USB_MOUSE is not set - -# -# USB support -# +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -803,6 +756,7 @@ CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set # # USB Device Class drivers @@ -879,31 +833,8 @@ CONFIG_USB_MON=y # # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# +# CONFIG_EDAC is not set # CONFIG_RTC_CLASS is not set # @@ -920,6 +851,11 @@ CONFIG_USB_MON=y # # +# Userspace I/O +# +# CONFIG_UIO is not set + +# # File systems # CONFIG_EXT2_FS=m @@ -948,8 +884,8 @@ CONFIG_QUOTA=y CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m # CONFIG_FUSE_FS is not set # @@ -1030,7 +966,6 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -1096,6 +1031,7 @@ CONFIG_BITREVERSE=y # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y @@ -1120,6 +1056,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set @@ -1150,10 +1087,6 @@ CONFIG_IRQSTACKS=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y @@ -1191,7 +1124,4 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# +CONFIG_CRYPTO_HW=y diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f39a72f30aad..b0cb2e662c25 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -81,6 +81,7 @@ obj-y += iomap.o endif ifeq ($(CONFIG_PPC_ISERIES),y) +CFLAGS_lparmap.s += -g0 extra-y += lparmap.s $(obj)/head_64.o: $(obj)/lparmap.s AFLAGS_head_64.o += -I$(obj) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 1448af92c6a9..171800002ede 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1672,8 +1672,9 @@ _GLOBAL(__start_initialization_multiplatform) * Are we booted from a PROM Of-type client-interface ? */ cmpldi cr0,r5,0 - bne .__boot_from_prom /* yes -> prom */ - + beq 1f + b .__boot_from_prom /* yes -> prom */ +1: /* Save parameters */ mr r31,r3 mr r30,r4 @@ -1701,7 +1702,7 @@ _GLOBAL(__start_initialization_multiplatform) bl .__mmu_off b .__after_prom_start -_STATIC(__boot_from_prom) +_INIT_STATIC(__boot_from_prom) /* Save parameters */ mr r31,r3 mr r30,r4 @@ -1768,9 +1769,10 @@ _STATIC(__after_prom_start) /* the source addr */ cmpdi r4,0 /* In some cases the loader may */ - beq .start_here_multiplatform /* have already put us at zero */ + bne 1f + b .start_here_multiplatform /* have already put us at zero */ /* so we can skip the copy. */ - LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ +1: LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ sub r5,r5,r27 li r6,0x100 /* Start offset, the first 0x100 */ @@ -1957,7 +1959,7 @@ _GLOBAL(enable_64b_mode) /* * This is where the main kernel code starts. */ -_STATIC(start_here_multiplatform) +_INIT_STATIC(start_here_multiplatform) /* get a new offset, now that the kernel has moved. */ bl .reloc_offset mr r26,r3 @@ -2019,7 +2021,7 @@ _STATIC(start_here_multiplatform) b . /* prevent speculative execution */ /* This is where all platforms converge execution */ -_STATIC(start_here_common) +_INIT_STATIC(start_here_common) /* relocation is on at this point */ /* The following code sets up the SP and TOC now that we are */ diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index e708ab7ca9e8..8533de50347d 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -301,9 +301,19 @@ _GLOBAL(_tlbie) mfspr r4,SPRN_MMUCR mfspr r5,SPRN_PID /* Get PID */ rlwimi r4,r5,0,24,31 /* Set TID */ - mtspr SPRN_MMUCR,r4 + /* We have to run the search with interrupts disabled, even critical + * and debug interrupts (in fact the only critical exceptions we have + * are debug and machine check). Otherwise an interrupt which causes + * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */ + mfmsr r5 + lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha + addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l + andc r6,r5,r6 + mtmsr r6 + mtspr SPRN_MMUCR,r4 tlbsx. r3, 0, r3 + mtmsr r5 bne 10f sync /* There are only 64 TLB entries, so r3 < 64, diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index a97e23ac1976..291ffbc360c9 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -313,6 +313,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; + dev->dma_mask = 0xffffffff; if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { /* a PCI-PCI bridge */ diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index f1789578747a..a47151e806ca 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -795,7 +795,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, #ifdef CONFIG_PPC_MM_SLICES /* We only prefault standard pages for now */ - if (unlikely(get_slice_psize(mm, ea) != mm->context.user_psize)); + if (unlikely(get_slice_psize(mm, ea) != mm->context.user_psize)) return; #endif diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index b0697017d0e8..a73d2d700973 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -69,20 +69,9 @@ static inline void slb_shadow_update(unsigned long ea, smp_wmb(); } -static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags, - unsigned long entry) +static inline void slb_shadow_clear(unsigned long entry) { - /* - * Updating the shadow buffer before writing the SLB ensures - * we don't get a stale entry here if we get preempted by PHYP - * between these two statements. - */ - slb_shadow_update(ea, flags, entry); - - asm volatile("slbmte %0,%1" : - : "r" (mk_vsid_data(ea, flags)), - "r" (mk_esid_data(ea, entry)) - : "memory" ); + get_slb_shadow()->save_area[entry].esid = 0; } void slb_flush_and_rebolt(void) @@ -100,11 +89,13 @@ void slb_flush_and_rebolt(void) vflags = SLB_VSID_KERNEL | vmalloc_llp; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); - if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) + if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) { ksp_esid_data &= ~SLB_ESID_V; - - /* Only third entry (stack) may change here so only resave that */ - slb_shadow_update(get_paca()->kstack, lflags, 2); + slb_shadow_clear(2); + } else { + /* Update stack entry; others don't change */ + slb_shadow_update(get_paca()->kstack, lflags, 2); + } /* We need to do this all in asm, so we're sure we don't touch * the stack between the slbia and rebolting it. */ @@ -235,16 +226,12 @@ void slb_initialize(void) vflags = SLB_VSID_KERNEL | vmalloc_llp; /* Invalidate the entire SLB (even slot 0) & all the ERATS */ - asm volatile("isync":::"memory"); - asm volatile("slbmte %0,%0"::"r" (0) : "memory"); - asm volatile("isync; slbia; isync":::"memory"); - create_shadowed_slbe(PAGE_OFFSET, lflags, 0); - - create_shadowed_slbe(VMALLOC_START, vflags, 1); - - /* We don't bolt the stack for the time being - we're in boot, - * so the stack is in the bolted segment. By the time it goes - * elsewhere, we'll call _switch() which will bolt in the new - * one. */ - asm volatile("isync":::"memory"); + slb_shadow_update(PAGE_OFFSET, lflags, 0); + asm volatile("isync; slbia; sync; slbmte %0,%1; isync" :: + "r" (get_slb_shadow()->save_area[0].vsid), + "r" (get_slb_shadow()->save_area[0].esid) : "memory"); + + slb_shadow_update(VMALLOC_START, vflags, 1); + + slb_flush_and_rebolt(); } diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index f833dba2a028..d5fd3909d13a 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -405,6 +405,8 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, if (len > mm->task_size) return -ENOMEM; + if (len & ((1ul << pshift) - 1)) + return -EINVAL; if (fixed && (addr & ((1ul << pshift) - 1))) return -EINVAL; if (fixed && addr > (mm->task_size - len)) diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index b39cb52c6fb9..2c8e641a739b 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -106,7 +106,6 @@ static struct of_device_id mpc832x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index b2b28a44738c..090906170a41 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -70,7 +70,6 @@ static struct of_device_id mpc832x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 0e615fd65c1f..84b58934aafd 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -113,7 +113,6 @@ static struct of_device_id mpc836x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index e8003bf00c9a..be25ecd911ba 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -142,7 +142,6 @@ static struct of_device_id mpc85xx_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 90124228b8f4..095a30304c56 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -36,7 +36,6 @@ #include <asm/spu_priv1.h> #include <asm/xmon.h> #include <asm/prom.h> -#include "spu_priv1_mmio.h" const struct spu_management_ops *spu_management_ops; EXPORT_SYMBOL_GPL(spu_management_ops); @@ -636,138 +635,6 @@ static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf) static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL); -/* Hardcoded affinity idxs for QS20 */ -#define SPES_PER_BE 8 -static int QS20_reg_idxs[SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; -static int QS20_reg_memory[SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 }; - -static struct spu *spu_lookup_reg(int node, u32 reg) -{ - struct spu *spu; - - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { - if (*(u32 *)get_property(spu_devnode(spu), "reg", NULL) == reg) - return spu; - } - return NULL; -} - -static void init_aff_QS20_harcoded(void) -{ - int node, i; - struct spu *last_spu, *spu; - u32 reg; - - for (node = 0; node < MAX_NUMNODES; node++) { - last_spu = NULL; - for (i = 0; i < SPES_PER_BE; i++) { - reg = QS20_reg_idxs[i]; - spu = spu_lookup_reg(node, reg); - if (!spu) - continue; - spu->has_mem_affinity = QS20_reg_memory[reg]; - if (last_spu) - list_add_tail(&spu->aff_list, - &last_spu->aff_list); - last_spu = spu; - } - } -} - -static int of_has_vicinity(void) -{ - struct spu* spu; - - spu = list_entry(cbe_spu_info[0].spus.next, struct spu, cbe_list); - return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; -} - -static struct spu *aff_devnode_spu(int cbe, struct device_node *dn) -{ - struct spu *spu; - - list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) - if (spu_devnode(spu) == dn) - return spu; - return NULL; -} - -static struct spu * -aff_node_next_to(int cbe, struct device_node *target, struct device_node *avoid) -{ - struct spu *spu; - const phandle *vic_handles; - int lenp, i; - - list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) { - if (spu_devnode(spu) == avoid) - continue; - vic_handles = get_property(spu_devnode(spu), "vicinity", &lenp); - for (i=0; i < (lenp / sizeof(phandle)); i++) { - if (vic_handles[i] == target->linux_phandle) - return spu; - } - } - return NULL; -} - -static void init_aff_fw_vicinity_node(int cbe) -{ - struct spu *spu, *last_spu; - struct device_node *vic_dn, *last_spu_dn; - phandle avoid_ph; - const phandle *vic_handles; - const char *name; - int lenp, i, added, mem_aff; - - last_spu = list_entry(cbe_spu_info[cbe].spus.next, struct spu, cbe_list); - avoid_ph = 0; - for (added = 1; added < cbe_spu_info[cbe].n_spus; added++) { - last_spu_dn = spu_devnode(last_spu); - vic_handles = get_property(last_spu_dn, "vicinity", &lenp); - - for (i = 0; i < (lenp / sizeof(phandle)); i++) { - if (vic_handles[i] == avoid_ph) - continue; - - vic_dn = of_find_node_by_phandle(vic_handles[i]); - if (!vic_dn) - continue; - - name = get_property(vic_dn, "name", NULL); - if (strcmp(name, "spe") == 0) { - spu = aff_devnode_spu(cbe, vic_dn); - avoid_ph = last_spu_dn->linux_phandle; - } - else { - mem_aff = strcmp(name, "mic-tm") == 0; - spu = aff_node_next_to(cbe, vic_dn, last_spu_dn); - if (!spu) - continue; - if (mem_aff) { - last_spu->has_mem_affinity = 1; - spu->has_mem_affinity = 1; - } - avoid_ph = vic_dn->linux_phandle; - } - list_add_tail(&spu->aff_list, &last_spu->aff_list); - last_spu = spu; - break; - } - } -} - -static void init_aff_fw_vicinity(void) -{ - int cbe; - - /* sets has_mem_affinity for each spu, as long as the - * spu->aff_list list, linking each spu to its neighbors - */ - for (cbe = 0; cbe < MAX_NUMNODES; cbe++) - init_aff_fw_vicinity_node(cbe); -} - static int __init init_spu_base(void) { int i, ret = 0; @@ -811,13 +678,7 @@ static int __init init_spu_base(void) mutex_unlock(&spu_full_list_mutex); spu_add_sysdev_attr(&attr_stat); - if (of_has_vicinity()) { - init_aff_fw_vicinity(); - } else { - long root = of_get_flat_dt_root(); - if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - init_aff_QS20_harcoded(); - } + spu_init_affinity(); return 0; diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 75ed50fcc3db..5eb88346181a 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -361,8 +361,171 @@ static int of_destroy_spu(struct spu *spu) return 0; } +/* Hardcoded affinity idxs for qs20 */ +#define QS20_SPES_PER_BE 8 +static int qs20_reg_idxs[QS20_SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; +static int qs20_reg_memory[QS20_SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 }; + +static struct spu *spu_lookup_reg(int node, u32 reg) +{ + struct spu *spu; + u32 *spu_reg; + + list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { + spu_reg = (u32*)of_get_property(spu_devnode(spu), "reg", NULL); + if (*spu_reg == reg) + return spu; + } + return NULL; +} + +static void init_affinity_qs20_harcoded(void) +{ + int node, i; + struct spu *last_spu, *spu; + u32 reg; + + for (node = 0; node < MAX_NUMNODES; node++) { + last_spu = NULL; + for (i = 0; i < QS20_SPES_PER_BE; i++) { + reg = qs20_reg_idxs[i]; + spu = spu_lookup_reg(node, reg); + if (!spu) + continue; + spu->has_mem_affinity = qs20_reg_memory[reg]; + if (last_spu) + list_add_tail(&spu->aff_list, + &last_spu->aff_list); + last_spu = spu; + } + } +} + +static int of_has_vicinity(void) +{ + struct spu* spu; + + spu = list_first_entry(&cbe_spu_info[0].spus, struct spu, cbe_list); + return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; +} + +static struct spu *devnode_spu(int cbe, struct device_node *dn) +{ + struct spu *spu; + + list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) + if (spu_devnode(spu) == dn) + return spu; + return NULL; +} + +static struct spu * +neighbour_spu(int cbe, struct device_node *target, struct device_node *avoid) +{ + struct spu *spu; + struct device_node *spu_dn; + const phandle *vic_handles; + int lenp, i; + + list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) { + spu_dn = spu_devnode(spu); + if (spu_dn == avoid) + continue; + vic_handles = of_get_property(spu_dn, "vicinity", &lenp); + for (i=0; i < (lenp / sizeof(phandle)); i++) { + if (vic_handles[i] == target->linux_phandle) + return spu; + } + } + return NULL; +} + +static void init_affinity_node(int cbe) +{ + struct spu *spu, *last_spu; + struct device_node *vic_dn, *last_spu_dn; + phandle avoid_ph; + const phandle *vic_handles; + const char *name; + int lenp, i, added; + + last_spu = list_first_entry(&cbe_spu_info[cbe].spus, struct spu, + cbe_list); + avoid_ph = 0; + for (added = 1; added < cbe_spu_info[cbe].n_spus; added++) { + last_spu_dn = spu_devnode(last_spu); + vic_handles = of_get_property(last_spu_dn, "vicinity", &lenp); + + /* + * Walk through each phandle in vicinity property of the spu + * (tipically two vicinity phandles per spe node) + */ + for (i = 0; i < (lenp / sizeof(phandle)); i++) { + if (vic_handles[i] == avoid_ph) + continue; + + vic_dn = of_find_node_by_phandle(vic_handles[i]); + if (!vic_dn) + continue; + + /* a neighbour might be spe, mic-tm, or bif0 */ + name = of_get_property(vic_dn, "name", NULL); + if (!name) + continue; + + if (strcmp(name, "spe") == 0) { + spu = devnode_spu(cbe, vic_dn); + avoid_ph = last_spu_dn->linux_phandle; + } else { + /* + * "mic-tm" and "bif0" nodes do not have + * vicinity property. So we need to find the + * spe which has vic_dn as neighbour, but + * skipping the one we came from (last_spu_dn) + */ + spu = neighbour_spu(cbe, vic_dn, last_spu_dn); + if (!spu) + continue; + if (!strcmp(name, "mic-tm")) { + last_spu->has_mem_affinity = 1; + spu->has_mem_affinity = 1; + } + avoid_ph = vic_dn->linux_phandle; + } + + list_add_tail(&spu->aff_list, &last_spu->aff_list); + last_spu = spu; + break; + } + } +} + +static void init_affinity_fw(void) +{ + int cbe; + + for (cbe = 0; cbe < MAX_NUMNODES; cbe++) + init_affinity_node(cbe); +} + +static int __init init_affinity(void) +{ + if (of_has_vicinity()) { + init_affinity_fw(); + } else { + long root = of_get_flat_dt_root(); + if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + init_affinity_qs20_harcoded(); + else + printk("No affinity configuration found"); + } + + return 0; +} + const struct spu_management_ops spu_management_of_ops = { .enumerate_spus = of_enumerate_spus, .create_spu = of_create_spu, .destroy_spu = of_destroy_spu, + .init_affinity = init_affinity, }; diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c index dd2c6688c8aa..027ac32cc636 100644 --- a/arch/powerpc/platforms/cell/spu_syscalls.c +++ b/arch/powerpc/platforms/cell/spu_syscalls.c @@ -45,6 +45,7 @@ asmlinkage long sys_spu_create(const char __user *name, if (owner && try_module_get(owner)) { if (flags & SPU_CREATE_AFFINITY_SPU) { neighbor = fget_light(neighbor_fd, &fput_needed); + ret = -EBADF; if (neighbor) { ret = spufs_calls.create_thread(name, flags, mode, neighbor); diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index d4fc74f7bb15..67144d1d1405 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -1,5 +1,5 @@ config PPC_PS3 - bool "Sony PS3 (incomplete)" + bool "Sony PS3" depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL select USB_ARCH_HAS_OHCI @@ -10,10 +10,10 @@ config PPC_PS3 select MEMORY_HOTPLUG help This option enables support for the Sony PS3 game console - and other platforms using the PS3 hypervisor. - Support for this platform is not yet complete, so - enabling this will not result in a bootable kernel on a - PS3 system. + and other platforms using the PS3 hypervisor. Enabling this + option will allow building otheros.bld, a kernel image suitable + for programming into flash memory, and vmlinux, a kernel image + suitable for loading via kexec. menu "PS3 Platform Options" depends on PPC_PS3 diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index 825ebb2cbc2a..ce15cada88d4 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -273,55 +273,58 @@ static int ps3stor_wait_for_completion(u64 dev_id, u64 tag, static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) { + int error = -ENODEV; int result; const u64 notification_dev_id = (u64)-1LL; const unsigned int timeout = HZ; u64 lpar; u64 tag; + void *buf; + enum ps3_notify_type { + notify_device_ready = 0, + notify_region_probe = 1, + notify_region_update = 2, + }; struct { u64 operation_code; /* must be zero */ - u64 event_mask; /* 1 = device ready */ + u64 event_mask; /* OR of 1UL << enum ps3_notify_type */ } *notify_cmd; struct { - u64 event_type; /* notify_device_ready */ + u64 event_type; /* enum ps3_notify_type */ u64 bus_id; u64 dev_id; u64 dev_type; u64 dev_port; } *notify_event; - enum { - notify_device_ready = 1 - }; pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__, __LINE__, repo->bus_id, repo->dev_id, repo->dev_type); - notify_cmd = kzalloc(512, GFP_KERNEL); - notify_event = (void *)notify_cmd; - if (!notify_cmd) + buf = kzalloc(512, GFP_KERNEL); + if (!buf) return -ENOMEM; - lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd)); + lpar = ps3_mm_phys_to_lpar(__pa(buf)); + notify_cmd = buf; + notify_event = buf; result = lv1_open_device(repo->bus_id, notification_dev_id, 0); if (result) { printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__, __LINE__, ps3_result(result)); - result = -ENODEV; goto fail_free; } /* Setup and write the request for device notification. */ - notify_cmd->operation_code = 0; /* must be zero */ - notify_cmd->event_mask = 0x01; /* device ready */ + notify_cmd->operation_code = 0; /* must be zero */ + notify_cmd->event_mask = 1UL << notify_region_probe; result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar, &tag); if (result) { printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__, ps3_result(result)); - result = -ENODEV; goto fail_close; } @@ -332,13 +335,11 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) if (result) { printk(KERN_ERR "%s:%u: write not completed %s\n", __func__, __LINE__, ps3_result(result)); - result = -ENODEV; goto fail_close; } /* Loop here processing the requested notification events. */ - result = -ENODEV; while (1) { memset(notify_event, 0, sizeof(*notify_event)); @@ -358,7 +359,7 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) break; } - if (notify_event->event_type != notify_device_ready || + if (notify_event->event_type != notify_region_probe || notify_event->bus_id != repo->bus_id) { pr_debug("%s:%u: bad notify_event: event %lu, " "dev_id %lu, dev_type %lu\n", @@ -371,7 +372,7 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) notify_event->dev_type == repo->dev_type) { pr_debug("%s:%u: device ready: dev_id %u\n", __func__, __LINE__, repo->dev_id); - result = 0; + error = 0; break; } @@ -386,9 +387,9 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) fail_close: lv1_close_device(repo->bus_id, notification_dev_id); fail_free: - kfree(notify_cmd); + kfree(buf); pr_debug(" <- %s:%u\n", __func__, __LINE__); - return result; + return error; } static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index 502d80ed982b..ac2a4b8a4c14 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -414,10 +414,16 @@ static int __init ps3_enumerate_spus(int (*fn)(void *data)) return num_resource_id; } +static int ps3_init_affinity(void) +{ + return 0; +} + const struct spu_management_ops spu_management_ps3_ops = { .enumerate_spus = ps3_enumerate_spus, .create_spu = ps3_create_spu, .destroy_spu = ps3_destroy_spu, + .init_affinity = ps3_init_affinity, }; /* spu_priv1_ops */ diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 0da55368655c..a22e1f4d94c8 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -237,9 +237,19 @@ _GLOBAL(_tlbie) mfspr r4,SPRN_MMUCR mfspr r5,SPRN_PID /* Get PID */ rlwimi r4,r5,0,24,31 /* Set TID */ - mtspr SPRN_MMUCR,r4 + /* We have to run the search with interrupts disabled, even critical + * and debug interrupts (in fact the only critical exceptions we have + * are debug and machine check). Otherwise an interrupt which causes + * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */ + mfmsr r5 + lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha + addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l + andc r6,r5,r6 + mtmsr r6 + mtspr SPRN_MMUCR,r4 tlbsx. r3, 0, r3 + mtmsr r5 bne 10f sync /* There are only 64 TLB entries, so r3 < 64, diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 098c62c29f9c..b71132166f60 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -109,10 +109,6 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. -config DEFAULT_MIGRATION_COST - int - default "1000000" - config MATHEMU bool "IEEE FPU emulation" depends on MARCH_G5 diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 8e1ea1c40128..ad4ca75c0f04 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -17,6 +17,8 @@ #include <linux/parser.h> #include <linux/sysfs.h> #include <linux/module.h> +#include <linux/seq_file.h> +#include <linux/mount.h> #include <asm/ebcdic.h> #include "hypfs.h" @@ -256,6 +258,15 @@ static int hypfs_parse_options(char *options, struct super_block *sb) return 0; } +static int hypfs_show_options(struct seq_file *s, struct vfsmount *mnt) +{ + struct hypfs_sb_info *hypfs_info = mnt->mnt_sb->s_fs_info; + + seq_printf(s, ",uid=%u", hypfs_info->uid); + seq_printf(s, ",gid=%u", hypfs_info->gid); + return 0; +} + static int hypfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root_inode; @@ -459,6 +470,7 @@ static struct file_system_type hypfs_type = { static struct super_operations hypfs_s_ops = { .statfs = simple_statfs, .drop_inode = hypfs_drop_inode, + .show_options = hypfs_show_options, }; static decl_subsys(s390, NULL, NULL); diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 9833493d8867..80b637c30203 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -76,7 +76,7 @@ static void scif_sercon_putc(int c) sci_in(&scif_port, SCxSR); sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40)); - while ((sci_in(&scif_port, SCxSR) & 0x40) == 0); + while ((sci_in(&scif_port, SCxSR) & 0x40) == 0) ; if (c == '\n') diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c index 23c5948f0124..129b2cfd18a8 100644 --- a/arch/sh/kernel/machvec.c +++ b/arch/sh/kernel/machvec.c @@ -91,6 +91,13 @@ void __init sh_mv_setup(void) (unsigned long)&__machvec_start); /* + * Sanity check for machvec section alignment. Ensure + * __initmv hasn't been misused. + */ + if (machvec_size % sizeof(struct sh_machine_vector)) + panic("machvec misaligned, invalid __initmv use?"); + + /* * If the machvec hasn't been preselected, use the first * vector (usually the only one) from .machvec.init. */ diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index 891d1d46c902..f64a2d2416d4 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c @@ -93,6 +93,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: ret = generic_ptrace_peekdata(child, addr, data); + break; /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: { diff --git a/arch/sh64/kernel/setup.c b/arch/sh64/kernel/setup.c index 53e9d20a874a..2b7264c0c6f7 100644 --- a/arch/sh64/kernel/setup.c +++ b/arch/sh64/kernel/setup.c @@ -59,10 +59,6 @@ #include <asm/setup.h> #include <asm/smp.h> -#ifdef CONFIG_VT -#include <linux/console.h> -#endif - struct screen_info screen_info; #ifdef CONFIG_BLK_DEV_RAM diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c index 0bb4a8f94276..79fc48cf54c6 100644 --- a/arch/sh64/kernel/signal.c +++ b/arch/sh64/kernel/signal.c @@ -25,7 +25,6 @@ #include <linux/ptrace.h> #include <linux/unistd.h> #include <linux/stddef.h> -#include <linux/personality.h> #include <asm/ucontext.h> #include <asm/uaccess.h> #include <asm/pgtable.h> diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index ac352eb6dff3..e2d02fd13f35 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -238,6 +238,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d sd = &dev->ofdev.dev.archdata; sd->prom_node = dp; sd->op = &dev->ofdev; + sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu; dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index a1bef07755a9..c13e6cd279ac 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -206,8 +206,7 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) #ifdef CONFIG_BLK_DEV_INITRD /* Now have to check initial ramdisk, so that bootmap does not overwrite it */ if (sparc_ramdisk_image) { - if (sparc_ramdisk_image >= (unsigned long)&_end - 2 * PAGE_SIZE) - sparc_ramdisk_image -= KERNBASE; + sparc_ramdisk_image -= KERNBASE; initrd_start = sparc_ramdisk_image + phys_base; initrd_end = initrd_start + sparc_ramdisk_size; if (initrd_end > end_of_phys_memory) { diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 4ccda77d08d6..7c89893b1fe8 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -66,7 +66,7 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) } if(!xpt) panic("Cannot map External Page Table."); - sbus->iommu = (struct iommu_struct *)iounit; + sbus->ofdev.dev.archdata.iommu = iounit; iounit->page_table = xpt; spin_lock_init(&iounit->lock); @@ -127,7 +127,7 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus *sbus) { unsigned long ret, flags; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; spin_lock_irqsave(&iounit->lock, flags); ret = iounit_get_area(iounit, (unsigned long)vaddr, len); @@ -138,7 +138,7 @@ static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) { unsigned long flags; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; /* FIXME: Cache some resolved pages - often several sg entries are to the same page */ spin_lock_irqsave(&iounit->lock, flags); @@ -153,7 +153,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) { unsigned long flags; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; spin_lock_irqsave(&iounit->lock, flags); len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT; @@ -168,7 +168,7 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_ { unsigned long flags; unsigned long vaddr, len; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; spin_lock_irqsave(&iounit->lock, flags); while (sz != 0) { @@ -211,7 +211,7 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); for_each_sbus(sbus) { - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; iopte = (iopte_t *)(iounit->page_table + i); *iopte = MKIOPTE(__pa(page)); @@ -235,7 +235,7 @@ static void iounit_unmap_dma_area(unsigned long addr, int len) static struct page *iounit_translate_dvma(unsigned long addr) { struct sbus_bus *sbus = sbus_root; /* They are all the same */ - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; int i; iopte_t *iopte; @@ -279,7 +279,7 @@ __u32 iounit_map_dma_init(struct sbus_bus *sbus, int size) unsigned long rotor, scan, limit; unsigned long flags; __u32 ret; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT; i = 0x0213; @@ -315,7 +315,7 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); __u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus) { int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT; - struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; + struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; iounit->page_table[scan] = MKIOPTE(__pa(((unsigned long)addr) & PAGE_MASK)); return vaddr + (((unsigned long)addr) & ~PAGE_MASK); diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index be042efd1ba4..52e907af9d29 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -132,7 +132,7 @@ iommu_init(int iommund, struct sbus_bus *sbus) impl, vers, iommu->page_table, (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); - sbus->iommu = iommu; + sbus->ofdev.dev.archdata.iommu = iommu; } /* This begs to be btfixup-ed by srmmu. */ @@ -166,7 +166,7 @@ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte) static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus) { - struct iommu_struct *iommu = sbus->iommu; + struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; int ioptex; iopte_t *iopte, *iopte0; unsigned int busa, busa0; @@ -291,7 +291,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus) { - struct iommu_struct *iommu = sbus->iommu; + struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; int ioptex; int i; @@ -334,7 +334,7 @@ static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, unsigned long addr, int len) { unsigned long page, end; - struct iommu_struct *iommu = sbus_root->iommu; + struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; iopte_t *iopte = iommu->page_table; iopte_t *first; int ioptex; @@ -399,7 +399,7 @@ static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, static void iommu_unmap_dma_area(unsigned long busa, int len) { - struct iommu_struct *iommu = sbus_root->iommu; + struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; iopte_t *iopte = iommu->page_table; unsigned long end; int ioptex = (busa - iommu->start) >> PAGE_SHIFT; @@ -420,7 +420,7 @@ static void iommu_unmap_dma_area(unsigned long busa, int len) static struct page *iommu_translate_dvma(unsigned long busa) { - struct iommu_struct *iommu = sbus_root->iommu; + struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; iopte_t *iopte = iommu->page_table; iopte += ((busa - iommu->start) >> PAGE_SHIFT); diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 79d60d86f6f8..005a3e72d4f2 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -268,7 +268,6 @@ static inline void sun4c_init_clean_mmu(unsigned long kernel_end) unsigned char savectx, ctx; savectx = sun4c_get_context(); - kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end); for (ctx = 0; ctx < num_contexts; ctx++) { sun4c_set_context(ctx); for (vaddr = 0; vaddr < 0x20000000; vaddr += SUN4C_REAL_PGDIR_SIZE) @@ -2064,7 +2063,6 @@ void __init sun4c_paging_init(void) unsigned long end_pfn, pages_avail; kernel_end = (unsigned long) &end; - kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4); kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end); pages_avail = 0; diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index ac18bd8e273f..63144ad476f6 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S @@ -501,7 +501,7 @@ niagara_tlb_fixup: cmp %g1, SUN4V_CHIP_NIAGARA1 be,pt %xcc, niagara_patch cmp %g1, SUN4V_CHIP_NIAGARA2 - be,pt %xcc, niagara_patch + be,pt %xcc, niagara2_patch nop call generic_patch_copyops @@ -512,6 +512,15 @@ niagara_tlb_fixup: nop ba,a,pt %xcc, 80f +niagara2_patch: + call niagara2_patch_copyops + nop + call niagara_patch_bzero + nop + call niagara2_patch_pageops + nop + + ba,a,pt %xcc, 80f niagara_patch: call niagara_patch_copyops @@ -706,12 +715,13 @@ setup_trap_table: membar #Sync + BRANCH_IF_SUN4V(o2, 1f) + /* Kill PROM timer */ sethi %hi(0x80000000), %o2 sllx %o2, 32, %o2 wr %o2, 0, %tick_cmpr - BRANCH_IF_SUN4V(o2, 1f) BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) ba,pt %xcc, 2f diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 95059c2ec414..9f22e4ff6015 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c @@ -9,6 +9,7 @@ #include <linux/list.h> #include <linux/slab.h> #include <linux/mm.h> +#include <linux/miscdevice.h> #include <asm/hypervisor.h> #include <asm/mdesc.h> @@ -836,6 +837,43 @@ void __devinit mdesc_fill_in_cpu_data(cpumask_t mask) mdesc_release(hp); } +static ssize_t mdesc_read(struct file *file, char __user *buf, + size_t len, loff_t *offp) +{ + struct mdesc_handle *hp = mdesc_grab(); + int err; + + if (!hp) + return -ENODEV; + + err = hp->handle_size; + if (len < hp->handle_size) + err = -EMSGSIZE; + else if (copy_to_user(buf, &hp->mdesc, hp->handle_size)) + err = -EFAULT; + mdesc_release(hp); + + return err; +} + +static const struct file_operations mdesc_fops = { + .read = mdesc_read, + .owner = THIS_MODULE, +}; + +static struct miscdevice mdesc_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "mdesc", + .fops = &mdesc_fops, +}; + +static int __init mdesc_misc_init(void) +{ + return misc_register(&mdesc_misc); +} + +__initcall(mdesc_misc_init); + void __init sun4v_mdesc_init(void) { struct mdesc_handle *hp; diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 9448595f9063..9533a25ce5d2 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S @@ -95,14 +95,13 @@ spitfire_startup: membar #Sync startup_continue: + mov %o0, %l0 + BRANCH_IF_SUN4V(g1, niagara_lock_tlb) + sethi %hi(0x80000000), %g2 sllx %g2, 32, %g2 wr %g2, 0, %tick_cmpr - mov %o0, %l0 - - BRANCH_IF_SUN4V(g1, niagara_lock_tlb) - /* Call OBP by hand to lock KERNBASE into i/d tlbs. * We lock 2 consequetive entries if we are 'bigkernel'. */ diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile index f95fbfa3eeb8..f095e13910bc 100644 --- a/arch/sparc64/lib/Makefile +++ b/arch/sparc64/lib/Makefile @@ -13,6 +13,8 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \ U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \ NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o NGpatch.o \ NGpage.o NGbzero.o \ + NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o NG2patch.o \ + NG2page.o \ GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o GENpatch.o \ GENpage.o GENbzero.o \ copy_in_user.o user_fixup.o memmove.o \ diff --git a/arch/sparc64/lib/NG2copy_from_user.S b/arch/sparc64/lib/NG2copy_from_user.S new file mode 100644 index 000000000000..c77ef5f22102 --- /dev/null +++ b/arch/sparc64/lib/NG2copy_from_user.S @@ -0,0 +1,40 @@ +/* NG2copy_from_user.S: Niagara-2 optimized copy from userspace. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#define EX_LD(x) \ +98: x; \ + .section .fixup; \ + .align 4; \ +99: wr %g0, ASI_AIUS, %asi;\ + retl; \ + mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ + .word 98b, 99b; \ + .text; \ + .align 4; + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#ifndef ASI_BLK_AIUS_4V +#define ASI_BLK_AIUS_4V 0x17 +#endif + +#define FUNC_NAME NG2copy_from_user +#define LOAD(type,addr,dest) type##a [addr] %asi, dest +#define LOAD_BLK(addr,dest) ldda [addr] ASI_BLK_AIUS_4V, dest +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, memcpy_user_stub; \ + nop +#endif + +#include "NG2memcpy.S" diff --git a/arch/sparc64/lib/NG2copy_to_user.S b/arch/sparc64/lib/NG2copy_to_user.S new file mode 100644 index 000000000000..4bd4093acbbd --- /dev/null +++ b/arch/sparc64/lib/NG2copy_to_user.S @@ -0,0 +1,49 @@ +/* NG2copy_to_user.S: Niagara-2 optimized copy to userspace. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#define EX_ST(x) \ +98: x; \ + .section .fixup; \ + .align 4; \ +99: wr %g0, ASI_AIUS, %asi;\ + retl; \ + mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ + .word 98b, 99b; \ + .text; \ + .align 4; + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#ifndef ASI_BLK_AIUS_4V +#define ASI_BLK_AIUS_4V 0x17 +#endif + +#ifndef ASI_BLK_INIT_QUAD_LDD_AIUS +#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 +#endif + +#define FUNC_NAME NG2copy_to_user +#define STORE(type,src,addr) type##a src, [addr] ASI_AIUS +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_AIUS +#define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_AIUS_4V +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ + /* Writing to %asi is _expensive_ so we hardcode it. + * Reading %asi to check for KERNEL_DS is comparatively + * cheap. + */ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, memcpy_user_stub; \ + nop +#endif + +#include "NG2memcpy.S" diff --git a/arch/sparc64/lib/NG2memcpy.S b/arch/sparc64/lib/NG2memcpy.S new file mode 100644 index 000000000000..0aed75653b50 --- /dev/null +++ b/arch/sparc64/lib/NG2memcpy.S @@ -0,0 +1,520 @@ +/* NG2memcpy.S: Niagara-2 optimized memcpy. + * + * Copyright (C) 2007 David S. Miller (davem@davemloft.net) + */ + +#ifdef __KERNEL__ +#include <asm/visasm.h> +#include <asm/asi.h> +#define GLOBAL_SPARE %g7 +#else +#define ASI_PNF 0x82 +#define ASI_BLK_P 0xf0 +#define ASI_BLK_INIT_QUAD_LDD_P 0xe2 +#define FPRS_FEF 0x04 +#ifdef MEMCPY_DEBUG +#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs; \ + clr %g1; clr %g2; clr %g3; subcc %g0, %g0, %g0; +#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs +#else +#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs +#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs +#endif +#define GLOBAL_SPARE %g5 +#endif + +#ifndef STORE_ASI +#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P +#else +#define STORE_ASI 0x80 /* ASI_P */ +#endif +#endif + +#ifndef EX_LD +#define EX_LD(x) x +#endif + +#ifndef EX_ST +#define EX_ST(x) x +#endif + +#ifndef EX_RETVAL +#define EX_RETVAL(x) x +#endif + +#ifndef LOAD +#define LOAD(type,addr,dest) type [addr], dest +#endif + +#ifndef LOAD_BLK +#define LOAD_BLK(addr,dest) ldda [addr] ASI_BLK_P, dest +#endif + +#ifndef STORE +#ifndef MEMCPY_DEBUG +#define STORE(type,src,addr) type src, [addr] +#else +#define STORE(type,src,addr) type##a src, [addr] 0x80 +#endif +#endif + +#ifndef STORE_BLK +#define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_P +#endif + +#ifndef STORE_INIT +#define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI +#endif + +#ifndef FUNC_NAME +#define FUNC_NAME NG2memcpy +#endif + +#ifndef PREAMBLE +#define PREAMBLE +#endif + +#ifndef XCC +#define XCC xcc +#endif + +#define FREG_FROB(x0, x1, x2, x3, x4, x5, x6, x7, x8) \ + faligndata %x0, %x1, %f0; \ + faligndata %x1, %x2, %f2; \ + faligndata %x2, %x3, %f4; \ + faligndata %x3, %x4, %f6; \ + faligndata %x4, %x5, %f8; \ + faligndata %x5, %x6, %f10; \ + faligndata %x6, %x7, %f12; \ + faligndata %x7, %x8, %f14; + +#define FREG_MOVE_1(x0) \ + fmovd %x0, %f0; +#define FREG_MOVE_2(x0, x1) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; +#define FREG_MOVE_3(x0, x1, x2) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; +#define FREG_MOVE_4(x0, x1, x2, x3) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; +#define FREG_MOVE_5(x0, x1, x2, x3, x4) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; \ + fmovd %x4, %f8; +#define FREG_MOVE_6(x0, x1, x2, x3, x4, x5) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; \ + fmovd %x4, %f8; \ + fmovd %x5, %f10; +#define FREG_MOVE_7(x0, x1, x2, x3, x4, x5, x6) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; \ + fmovd %x4, %f8; \ + fmovd %x5, %f10; \ + fmovd %x6, %f12; +#define FREG_MOVE_8(x0, x1, x2, x3, x4, x5, x6, x7) \ + fmovd %x0, %f0; \ + fmovd %x1, %f2; \ + fmovd %x2, %f4; \ + fmovd %x3, %f6; \ + fmovd %x4, %f8; \ + fmovd %x5, %f10; \ + fmovd %x6, %f12; \ + fmovd %x7, %f14; +#define FREG_LOAD_1(base, x0) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)) +#define FREG_LOAD_2(base, x0, x1) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); +#define FREG_LOAD_3(base, x0, x1, x2) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); +#define FREG_LOAD_4(base, x0, x1, x2, x3) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); \ + EX_LD(LOAD(ldd, base + 0x18, %x3)); +#define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); \ + EX_LD(LOAD(ldd, base + 0x18, %x3)); \ + EX_LD(LOAD(ldd, base + 0x20, %x4)); +#define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); \ + EX_LD(LOAD(ldd, base + 0x18, %x3)); \ + EX_LD(LOAD(ldd, base + 0x20, %x4)); \ + EX_LD(LOAD(ldd, base + 0x28, %x5)); +#define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \ + EX_LD(LOAD(ldd, base + 0x00, %x0)); \ + EX_LD(LOAD(ldd, base + 0x08, %x1)); \ + EX_LD(LOAD(ldd, base + 0x10, %x2)); \ + EX_LD(LOAD(ldd, base + 0x18, %x3)); \ + EX_LD(LOAD(ldd, base + 0x20, %x4)); \ + EX_LD(LOAD(ldd, base + 0x28, %x5)); \ + EX_LD(LOAD(ldd, base + 0x30, %x6)); + + .register %g2,#scratch + .register %g3,#scratch + + .text + .align 64 + + .globl FUNC_NAME + .type FUNC_NAME,#function +FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ + srlx %o2, 31, %g2 + cmp %g2, 0 + tne %xcc, 5 + PREAMBLE + mov %o0, GLOBAL_SPARE + cmp %o2, 0 + be,pn %XCC, 85f + or %o0, %o1, %o3 + cmp %o2, 16 + blu,a,pn %XCC, 80f + or %o3, %o2, %o3 + + /* 2 blocks (128 bytes) is the minimum we can do the block + * copy with. We need to ensure that we'll iterate at least + * once in the block copy loop. At worst we'll need to align + * the destination to a 64-byte boundary which can chew up + * to (64 - 1) bytes from the length before we perform the + * block copy loop. + * + * However, the cut-off point, performance wise, is around + * 4 64-byte blocks. + */ + cmp %o2, (4 * 64) + blu,pt %XCC, 75f + andcc %o3, 0x7, %g0 + + /* %o0: dst + * %o1: src + * %o2: len (known to be >= 128) + * + * The block copy loops can use %o4, %g2, %g3 as + * temporaries while copying the data. %o5 must + * be preserved between VISEntryHalf and VISExitHalf + */ + + LOAD(prefetch, %o1 + 0x000, #one_read) + LOAD(prefetch, %o1 + 0x040, #one_read) + LOAD(prefetch, %o1 + 0x080, #one_read) + + /* Align destination on 64-byte boundary. */ + andcc %o0, (64 - 1), %o4 + be,pt %XCC, 2f + sub %o4, 64, %o4 + sub %g0, %o4, %o4 ! bytes to align dst + sub %o2, %o4, %o2 +1: subcc %o4, 1, %o4 + EX_LD(LOAD(ldub, %o1, %g1)) + EX_ST(STORE(stb, %g1, %o0)) + add %o1, 1, %o1 + bne,pt %XCC, 1b + add %o0, 1, %o0 + +2: + /* Clobbers o5/g1/g2/g3/g7/icc/xcc. We must preserve + * o5 from here until we hit VISExitHalf. + */ + VISEntryHalf + + alignaddr %o1, %g0, %g0 + + add %o1, (64 - 1), %o4 + andn %o4, (64 - 1), %o4 + andn %o2, (64 - 1), %g1 + sub %o2, %g1, %o2 + + and %o1, (64 - 1), %g2 + add %o1, %g1, %o1 + sub %o0, %o4, %g3 + brz,pt %g2, 190f + cmp %g2, 32 + blu,a 5f + cmp %g2, 16 + cmp %g2, 48 + blu,a 4f + cmp %g2, 40 + cmp %g2, 56 + blu 170f + nop + ba,a,pt %xcc, 180f + +4: /* 32 <= low bits < 48 */ + blu 150f + nop + ba,a,pt %xcc, 160f +5: /* 0 < low bits < 32 */ + blu,a 6f + cmp %g2, 8 + cmp %g2, 24 + blu 130f + nop + ba,a,pt %xcc, 140f +6: /* 0 < low bits < 16 */ + bgeu 120f + nop + /* fall through for 0 < low bits < 8 */ +110: sub %o4, 64, %g2 + EX_LD(LOAD_BLK(%g2, %f0)) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +120: sub %o4, 56, %g2 + FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +130: sub %o4, 48, %g2 + FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_6(f20, f22, f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +140: sub %o4, 40, %g2 + FREG_LOAD_5(%g2, f0, f2, f4, f6, f8) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_5(f22, f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +150: sub %o4, 32, %g2 + FREG_LOAD_4(%g2, f0, f2, f4, f6) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_4(f24, f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +160: sub %o4, 24, %g2 + FREG_LOAD_3(%g2, f0, f2, f4) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_3(f26, f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +170: sub %o4, 16, %g2 + FREG_LOAD_2(%g2, f0, f2) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_2(f28, f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +180: sub %o4, 8, %g2 + FREG_LOAD_1(%g2, f0) +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + EX_LD(LOAD_BLK(%o4, %f16)) + FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + FREG_MOVE_1(f30) + subcc %g1, 64, %g1 + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + ba,pt %xcc, 195f + nop + +190: +1: EX_ST(STORE_INIT(%g0, %o4 + %g3)) + subcc %g1, 64, %g1 + EX_LD(LOAD_BLK(%o4, %f0)) + EX_ST(STORE_BLK(%f0, %o4 + %g3)) + add %o4, 64, %o4 + bne,pt %xcc, 1b + LOAD(prefetch, %o4 + 64, #one_read) + +195: + add %o4, %g3, %o0 + membar #Sync + + VISExitHalf + + /* %o2 contains any final bytes still needed to be copied + * over. If anything is left, we copy it one byte at a time. + */ + brz,pt %o2, 85f + sub %o0, %o1, %o3 + ba,a,pt %XCC, 90f + + .align 64 +75: /* 16 < len <= 64 */ + bne,pn %XCC, 75f + sub %o0, %o1, %o3 + +72: + andn %o2, 0xf, %o4 + and %o2, 0xf, %o2 +1: subcc %o4, 0x10, %o4 + EX_LD(LOAD(ldx, %o1, %o5)) + add %o1, 0x08, %o1 + EX_LD(LOAD(ldx, %o1, %g1)) + sub %o1, 0x08, %o1 + EX_ST(STORE(stx, %o5, %o1 + %o3)) + add %o1, 0x8, %o1 + EX_ST(STORE(stx, %g1, %o1 + %o3)) + bgu,pt %XCC, 1b + add %o1, 0x8, %o1 +73: andcc %o2, 0x8, %g0 + be,pt %XCC, 1f + nop + sub %o2, 0x8, %o2 + EX_LD(LOAD(ldx, %o1, %o5)) + EX_ST(STORE(stx, %o5, %o1 + %o3)) + add %o1, 0x8, %o1 +1: andcc %o2, 0x4, %g0 + be,pt %XCC, 1f + nop + sub %o2, 0x4, %o2 + EX_LD(LOAD(lduw, %o1, %o5)) + EX_ST(STORE(stw, %o5, %o1 + %o3)) + add %o1, 0x4, %o1 +1: cmp %o2, 0 + be,pt %XCC, 85f + nop + ba,pt %xcc, 90f + nop + +75: + andcc %o0, 0x7, %g1 + sub %g1, 0x8, %g1 + be,pn %icc, 2f + sub %g0, %g1, %g1 + sub %o2, %g1, %o2 + +1: subcc %g1, 1, %g1 + EX_LD(LOAD(ldub, %o1, %o5)) + EX_ST(STORE(stb, %o5, %o1 + %o3)) + bgu,pt %icc, 1b + add %o1, 1, %o1 + +2: add %o1, %o3, %o0 + andcc %o1, 0x7, %g1 + bne,pt %icc, 8f + sll %g1, 3, %g1 + + cmp %o2, 16 + bgeu,pt %icc, 72b + nop + ba,a,pt %xcc, 73b + +8: mov 64, %o3 + andn %o1, 0x7, %o1 + EX_LD(LOAD(ldx, %o1, %g2)) + sub %o3, %g1, %o3 + andn %o2, 0x7, %o4 + sllx %g2, %g1, %g2 +1: add %o1, 0x8, %o1 + EX_LD(LOAD(ldx, %o1, %g3)) + subcc %o4, 0x8, %o4 + srlx %g3, %o3, %o5 + or %o5, %g2, %o5 + EX_ST(STORE(stx, %o5, %o0)) + add %o0, 0x8, %o0 + bgu,pt %icc, 1b + sllx %g3, %g1, %g2 + + srl %g1, 3, %g1 + andcc %o2, 0x7, %o2 + be,pn %icc, 85f + add %o1, %g1, %o1 + ba,pt %xcc, 90f + sub %o0, %o1, %o3 + + .align 64 +80: /* 0 < len <= 16 */ + andcc %o3, 0x3, %g0 + bne,pn %XCC, 90f + sub %o0, %o1, %o3 + +1: + subcc %o2, 4, %o2 + EX_LD(LOAD(lduw, %o1, %g1)) + EX_ST(STORE(stw, %g1, %o1 + %o3)) + bgu,pt %XCC, 1b + add %o1, 4, %o1 + +85: retl + mov EX_RETVAL(GLOBAL_SPARE), %o0 + + .align 32 +90: + subcc %o2, 1, %o2 + EX_LD(LOAD(ldub, %o1, %g1)) + EX_ST(STORE(stb, %g1, %o1 + %o3)) + bgu,pt %XCC, 90b + add %o1, 1, %o1 + retl + mov EX_RETVAL(GLOBAL_SPARE), %o0 + + .size FUNC_NAME, .-FUNC_NAME diff --git a/arch/sparc64/lib/NG2page.S b/arch/sparc64/lib/NG2page.S new file mode 100644 index 000000000000..73b6b7c72cbf --- /dev/null +++ b/arch/sparc64/lib/NG2page.S @@ -0,0 +1,61 @@ +/* NG2page.S: Niagara-2 optimized clear and copy page. + * + * Copyright (C) 2007 (davem@davemloft.net) + */ + +#include <asm/asi.h> +#include <asm/page.h> +#include <asm/visasm.h> + + .text + .align 32 + + /* This is heavily simplified from the sun4u variants + * because Niagara-2 does not have any D-cache aliasing issues. + */ +NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ + prefetch [%o1 + 0x00], #one_read + prefetch [%o1 + 0x40], #one_read + VISEntryHalf + set PAGE_SIZE, %g7 + sub %o0, %o1, %g3 +1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P + subcc %g7, 64, %g7 + ldda [%o1] ASI_BLK_P, %f0 + stda %f0, [%o1 + %g3] ASI_BLK_P + add %o1, 64, %o1 + bne,pt %xcc, 1b + prefetch [%o1 + 0x40], #one_read + membar #Sync + VISExitHalf + retl + nop + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define NG_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl niagara2_patch_pageops + .type niagara2_patch_pageops,#function +niagara2_patch_pageops: + NG_DO_PATCH(copy_user_page, NG2copy_user_page) + NG_DO_PATCH(_clear_page, NGclear_page) + NG_DO_PATCH(clear_user_page, NGclear_user_page) + retl + nop + .size niagara2_patch_pageops,.-niagara2_patch_pageops diff --git a/arch/sparc64/lib/NG2patch.S b/arch/sparc64/lib/NG2patch.S new file mode 100644 index 000000000000..28c36f06a6d1 --- /dev/null +++ b/arch/sparc64/lib/NG2patch.S @@ -0,0 +1,33 @@ +/* NG2patch.S: Patch Ultra-I routines with Niagara-2 variant. + * + * Copyright (C) 2007 David S. Miller <davem@davemloft.net> + */ + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define NG_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl niagara2_patch_copyops + .type niagara2_patch_copyops,#function +niagara2_patch_copyops: + NG_DO_PATCH(memcpy, NG2memcpy) + NG_DO_PATCH(___copy_from_user, NG2copy_from_user) + NG_DO_PATCH(___copy_to_user, NG2copy_to_user) + retl + nop + .size niagara2_patch_copyops,.-niagara2_patch_copyops diff --git a/arch/sparc64/lib/NGpage.S b/arch/sparc64/lib/NGpage.S index 8ce3a0c9c537..428920de05ba 100644 --- a/arch/sparc64/lib/NGpage.S +++ b/arch/sparc64/lib/NGpage.S @@ -45,6 +45,7 @@ NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ retl nop + .globl NGclear_page, NGclear_user_page NGclear_page: /* %o0=dest */ NGclear_user_page: /* %o0=dest, %o1=vaddr */ mov 8, %g1 diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 128561d3e876..b024e4a86895 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -57,8 +57,8 @@ cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) cflags-y += -maccumulate-outgoing-args # do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,) # is .cfi_signal_frame supported too? cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S index 1312bfaff306..9fd8030cc54f 100644 --- a/arch/x86_64/boot/compressed/head.S +++ b/arch/x86_64/boot/compressed/head.S @@ -195,6 +195,11 @@ ENTRY(startup_64) movl %eax, %ds movl %eax, %es movl %eax, %ss + movl %eax, %fs + movl %eax, %gs + lldt %ax + movl $0x20, %eax + ltr %ax /* Compute the decompressed kernel start address. It is where * we were loaded at aligned to a 2M boundary. %rbp contains the @@ -295,6 +300,8 @@ gdt: .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x00af9a000000ffff /* __KERNEL_CS */ .quad 0x00cf92000000ffff /* __KERNEL_DS */ + .quad 0x0080890000000000 /* TS descriptor */ + .quad 0x0000000000000000 /* TS continued */ gdt_end: .bss /* Stack for uncompression */ diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 900ff38d68de..925758dbca0c 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -791,10 +791,8 @@ static void setup_APIC_timer(unsigned int clocks) /* wait for irq slice */ if (hpet_address && hpet_use_timer) { - int trigger = hpet_readl(HPET_T0_CMP); - while (hpet_readl(HPET_COUNTER) >= trigger) - /* do nothing */ ; - while (hpet_readl(HPET_COUNTER) < trigger) + u32 trigger = hpet_readl(HPET_T0_CMP); + while (hpet_readl(HPET_T0_CMP) == trigger) /* do nothing */ ; } else { int c1, c2; diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index e89abcdbdde8..b6167fe3330e 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -345,8 +345,7 @@ NEXT_PAGE(level2_kernel_pgt) /* 40MB kernel mapping. The kernel code cannot be bigger than that. When you change this change KERNEL_TEXT_SIZE in page.h too. */ /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, - KERNEL_TEXT_SIZE/PMD_SIZE) + PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE) /* Module mapping starts here */ .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0 diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 050141c0602b..f57f8b901912 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -800,12 +800,15 @@ static struct irq_chip ioapic_chip; static void ioapic_register_intr(int irq, unsigned long trigger) { - if (trigger) + if (trigger) { + irq_desc[irq].status |= IRQ_LEVEL; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_fasteoi_irq, "fasteoi"); - else + } else { + irq_desc[irq].status &= ~IRQ_LEVEL; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_edge_irq, "edge"); + } } static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index cb8ee9d02f86..0ec6d2ddb931 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -85,7 +85,7 @@ int __init check_nmi_watchdog (void) int *counts; int cpu; - if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) + if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DISABLED)) return 0; if (!atomic_read(&nmi_active)) @@ -442,7 +442,7 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, if (!!old_state == !!nmi_watchdog_enabled) return 0; - if (atomic_read(&nmi_active) < 0) { + if (atomic_read(&nmi_active) < 0 || nmi_watchdog == NMI_DISABLED) { printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); return -EIO; } diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index ba16c968ca3f..71da01e73f03 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -367,16 +367,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) pdev = to_pci_dev(dev); - /* is the device behind a bridge? */ - if (unlikely(pdev->bus->parent)) - pbus = pdev->bus->parent; - else - pbus = pdev->bus; + pbus = pdev->bus; + + /* is the device behind a bridge? Look for the root bus */ + while (pbus->parent) + pbus = pbus->parent; tbl = pci_iommu(pbus); - BUG_ON(pdev->bus->parent && - (tbl->it_busno != pdev->bus->parent->number)); + BUG_ON(tbl && (tbl->it_busno != pbus->number)); return tbl; } diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index 05d745ede561..29711445c818 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c @@ -82,6 +82,10 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, if (dma_mask == 0) dma_mask = DMA_32BIT_MASK; + /* Device not DMA able */ + if (dev->dma_mask == NULL) + return NULL; + /* Don't invoke OOM killer */ gfp |= __GFP_NORETRY; diff --git a/arch/x86_64/lib/memcpy.S b/arch/x86_64/lib/memcpy.S index 0ea0ddc875a7..c22981fa2f3a 100644 --- a/arch/x86_64/lib/memcpy.S +++ b/arch/x86_64/lib/memcpy.S @@ -124,6 +124,8 @@ ENDPROC(__memcpy) .quad memcpy .quad 1b .byte X86_FEATURE_REP_GOOD - .byte .Lfinal - memcpy + /* Replace only beginning, memcpy is used to apply alternatives, so it + * is silly to overwrite itself with nops - reboot is only outcome... */ + .byte 2b - 1b .byte 2b - 1b .previous diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 7e161c698af4..10b9809ce821 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -75,7 +75,8 @@ static void flush_kernel_map(void *arg) /* When clflush is available always use it because it is much cheaper than WBINVD. */ - if (!cpu_has_clflush) + /* clflush is still broken. Disable for now. */ + if (1 || !cpu_has_clflush) asm volatile("wbinvd" ::: "memory"); else list_for_each_entry(pg, l, lru) { void *adr = page_address(pg); diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 65d82736987e..4095e4d66a1d 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -66,13 +66,13 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, switch (len) { case 1: - *value = readb(addr + reg); + *value = mmio_config_readb(addr + reg); break; case 2: - *value = readw(addr + reg); + *value = mmio_config_readw(addr + reg); break; case 4: - *value = readl(addr + reg); + *value = mmio_config_readl(addr + reg); break; } @@ -94,13 +94,13 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, switch (len) { case 1: - writeb(value, addr + reg); + mmio_config_writeb(addr + reg, value); break; case 2: - writew(value, addr + reg); + mmio_config_writew(addr + reg, value); break; case 4: - writel(value, addr + reg); + mmio_config_writel(addr + reg, value); break; } diff --git a/arch/x86_64/vdso/.gitignore b/arch/x86_64/vdso/.gitignore new file mode 100644 index 000000000000..f8b69d84238e --- /dev/null +++ b/arch/x86_64/vdso/.gitignore @@ -0,0 +1 @@ +vdso.lds |