diff options
Diffstat (limited to 'arch')
130 files changed, 1463 insertions, 1855 deletions
diff --git a/arch/alpha/include/asm/fcntl.h b/arch/alpha/include/asm/fcntl.h index 25da0017ec87..21b1117a0c61 100644 --- a/arch/alpha/include/asm/fcntl.h +++ b/arch/alpha/include/asm/fcntl.h | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #ifndef _ALPHA_FCNTL_H | 1 | #ifndef _ALPHA_FCNTL_H |
| 2 | #define _ALPHA_FCNTL_H | 2 | #define _ALPHA_FCNTL_H |
| 3 | 3 | ||
| 4 | /* open/fcntl - O_SYNC is only implemented on blocks devices and on files | ||
| 5 | located on an ext2 file system */ | ||
| 6 | #define O_CREAT 01000 /* not fcntl */ | 4 | #define O_CREAT 01000 /* not fcntl */ |
| 7 | #define O_TRUNC 02000 /* not fcntl */ | 5 | #define O_TRUNC 02000 /* not fcntl */ |
| 8 | #define O_EXCL 04000 /* not fcntl */ | 6 | #define O_EXCL 04000 /* not fcntl */ |
| @@ -10,13 +8,28 @@ | |||
| 10 | 8 | ||
| 11 | #define O_NONBLOCK 00004 | 9 | #define O_NONBLOCK 00004 |
| 12 | #define O_APPEND 00010 | 10 | #define O_APPEND 00010 |
| 13 | #define O_SYNC 040000 | 11 | #define O_DSYNC 040000 /* used to be O_SYNC, see below */ |
| 14 | #define O_DIRECTORY 0100000 /* must be a directory */ | 12 | #define O_DIRECTORY 0100000 /* must be a directory */ |
| 15 | #define O_NOFOLLOW 0200000 /* don't follow links */ | 13 | #define O_NOFOLLOW 0200000 /* don't follow links */ |
| 16 | #define O_LARGEFILE 0400000 /* will be set by the kernel on every open */ | 14 | #define O_LARGEFILE 0400000 /* will be set by the kernel on every open */ |
| 17 | #define O_DIRECT 02000000 /* direct disk access - should check with OSF/1 */ | 15 | #define O_DIRECT 02000000 /* direct disk access - should check with OSF/1 */ |
| 18 | #define O_NOATIME 04000000 | 16 | #define O_NOATIME 04000000 |
| 19 | #define O_CLOEXEC 010000000 /* set close_on_exec */ | 17 | #define O_CLOEXEC 010000000 /* set close_on_exec */ |
| 18 | /* | ||
| 19 | * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using | ||
| 20 | * the O_SYNC flag. We continue to use the existing numerical value | ||
| 21 | * for O_DSYNC semantics now, but using the correct symbolic name for it. | ||
| 22 | * This new value is used to request true Posix O_SYNC semantics. It is | ||
| 23 | * defined in this strange way to make sure applications compiled against | ||
| 24 | * new headers get at least O_DSYNC semantics on older kernels. | ||
| 25 | * | ||
| 26 | * This has the nice side-effect that we can simply test for O_DSYNC | ||
| 27 | * wherever we do not care if O_DSYNC or O_SYNC is used. | ||
| 28 | * | ||
| 29 | * Note: __O_SYNC must never be used directly. | ||
| 30 | */ | ||
| 31 | #define __O_SYNC 020000000 | ||
| 32 | #define O_SYNC (__O_SYNC|O_DSYNC) | ||
| 20 | 33 | ||
| 21 | #define F_GETLK 7 | 34 | #define F_GETLK 7 |
| 22 | #define F_SETLK 8 | 35 | #define F_SETLK 8 |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 9a3334ae282e..62619f25132f 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
| @@ -178,25 +178,18 @@ SYSCALL_DEFINE6(osf_mmap, unsigned long, addr, unsigned long, len, | |||
| 178 | unsigned long, prot, unsigned long, flags, unsigned long, fd, | 178 | unsigned long, prot, unsigned long, flags, unsigned long, fd, |
| 179 | unsigned long, off) | 179 | unsigned long, off) |
| 180 | { | 180 | { |
| 181 | struct file *file = NULL; | 181 | unsigned long ret = -EINVAL; |
| 182 | unsigned long ret = -EBADF; | ||
| 183 | 182 | ||
| 184 | #if 0 | 183 | #if 0 |
| 185 | if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED)) | 184 | if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED)) |
| 186 | printk("%s: unimplemented OSF mmap flags %04lx\n", | 185 | printk("%s: unimplemented OSF mmap flags %04lx\n", |
| 187 | current->comm, flags); | 186 | current->comm, flags); |
| 188 | #endif | 187 | #endif |
| 189 | if (!(flags & MAP_ANONYMOUS)) { | 188 | if ((off + PAGE_ALIGN(len)) < off) |
| 190 | file = fget(fd); | 189 | goto out; |
| 191 | if (!file) | 190 | if (off & ~PAGE_MASK) |
| 192 | goto out; | 191 | goto out; |
| 193 | } | 192 | ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); |
| 194 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 195 | down_write(¤t->mm->mmap_sem); | ||
| 196 | ret = do_mmap(file, addr, len, prot, flags, off); | ||
| 197 | up_write(¤t->mm->mmap_sem); | ||
| 198 | if (file) | ||
| 199 | fput(file); | ||
| 200 | out: | 193 | out: |
| 201 | return ret; | 194 | return ret; |
| 202 | } | 195 | } |
diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h index 8eebf89f5ab1..41f99c573b93 100644 --- a/arch/arm/include/asm/mman.h +++ b/arch/arm/include/asm/mman.h | |||
| @@ -1 +1,4 @@ | |||
| 1 | #include <asm-generic/mman.h> | 1 | #include <asm-generic/mman.h> |
| 2 | |||
| 3 | #define arch_mmap_check(addr, len, flags) \ | ||
| 4 | (((flags) & MAP_FIXED && (addr) < FIRST_USER_ADDRESS) ? -EINVAL : 0) | ||
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index f58c1156e779..9314a2d681f1 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
| @@ -172,7 +172,7 @@ | |||
| 172 | /* 160 */ CALL(sys_sched_get_priority_min) | 172 | /* 160 */ CALL(sys_sched_get_priority_min) |
| 173 | CALL(sys_sched_rr_get_interval) | 173 | CALL(sys_sched_rr_get_interval) |
| 174 | CALL(sys_nanosleep) | 174 | CALL(sys_nanosleep) |
| 175 | CALL(sys_arm_mremap) | 175 | CALL(sys_mremap) |
| 176 | CALL(sys_setresuid16) | 176 | CALL(sys_setresuid16) |
| 177 | /* 165 */ CALL(sys_getresuid16) | 177 | /* 165 */ CALL(sys_getresuid16) |
| 178 | CALL(sys_ni_syscall) /* vm86 */ | 178 | CALL(sys_ni_syscall) /* vm86 */ |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index f0fe95b7085d..2c1db77d7848 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
| @@ -416,12 +416,12 @@ sys_mmap2: | |||
| 416 | tst r5, #PGOFF_MASK | 416 | tst r5, #PGOFF_MASK |
| 417 | moveq r5, r5, lsr #PAGE_SHIFT - 12 | 417 | moveq r5, r5, lsr #PAGE_SHIFT - 12 |
| 418 | streq r5, [sp, #4] | 418 | streq r5, [sp, #4] |
| 419 | beq do_mmap2 | 419 | beq sys_mmap_pgoff |
| 420 | mov r0, #-EINVAL | 420 | mov r0, #-EINVAL |
| 421 | mov pc, lr | 421 | mov pc, lr |
| 422 | #else | 422 | #else |
| 423 | str r5, [sp, #4] | 423 | str r5, [sp, #4] |
| 424 | b do_mmap2 | 424 | b sys_mmap_pgoff |
| 425 | #endif | 425 | #endif |
| 426 | ENDPROC(sys_mmap2) | 426 | ENDPROC(sys_mmap2) |
| 427 | 427 | ||
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 78ecaac65206..ae4027bd01bd 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
| @@ -28,41 +28,6 @@ | |||
| 28 | #include <linux/ipc.h> | 28 | #include <linux/ipc.h> |
| 29 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
| 30 | 30 | ||
| 31 | extern unsigned long do_mremap(unsigned long addr, unsigned long old_len, | ||
| 32 | unsigned long new_len, unsigned long flags, | ||
| 33 | unsigned long new_addr); | ||
| 34 | |||
| 35 | /* common code for old and new mmaps */ | ||
| 36 | inline long do_mmap2( | ||
| 37 | unsigned long addr, unsigned long len, | ||
| 38 | unsigned long prot, unsigned long flags, | ||
| 39 | unsigned long fd, unsigned long pgoff) | ||
| 40 | { | ||
| 41 | int error = -EINVAL; | ||
| 42 | struct file * file = NULL; | ||
| 43 | |||
| 44 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 45 | |||
| 46 | if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS) | ||
| 47 | goto out; | ||
| 48 | |||
| 49 | error = -EBADF; | ||
| 50 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 51 | file = fget(fd); | ||
| 52 | if (!file) | ||
| 53 | goto out; | ||
| 54 | } | ||
| 55 | |||
| 56 | down_write(¤t->mm->mmap_sem); | ||
| 57 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 58 | up_write(¤t->mm->mmap_sem); | ||
| 59 | |||
| 60 | if (file) | ||
| 61 | fput(file); | ||
| 62 | out: | ||
| 63 | return error; | ||
| 64 | } | ||
| 65 | |||
| 66 | struct mmap_arg_struct { | 31 | struct mmap_arg_struct { |
| 67 | unsigned long addr; | 32 | unsigned long addr; |
| 68 | unsigned long len; | 33 | unsigned long len; |
| @@ -84,29 +49,11 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) | |||
| 84 | if (a.offset & ~PAGE_MASK) | 49 | if (a.offset & ~PAGE_MASK) |
| 85 | goto out; | 50 | goto out; |
| 86 | 51 | ||
| 87 | error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); | 52 | error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); |
| 88 | out: | 53 | out: |
| 89 | return error; | 54 | return error; |
| 90 | } | 55 | } |
| 91 | 56 | ||
| 92 | asmlinkage unsigned long | ||
| 93 | sys_arm_mremap(unsigned long addr, unsigned long old_len, | ||
| 94 | unsigned long new_len, unsigned long flags, | ||
| 95 | unsigned long new_addr) | ||
| 96 | { | ||
| 97 | unsigned long ret = -EINVAL; | ||
| 98 | |||
| 99 | if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS) | ||
| 100 | goto out; | ||
| 101 | |||
| 102 | down_write(¤t->mm->mmap_sem); | ||
| 103 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | ||
| 104 | up_write(¤t->mm->mmap_sem); | ||
| 105 | |||
| 106 | out: | ||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* | 57 | /* |
| 111 | * Perform the select(nd, in, out, ex, tv) and mmap() system | 58 | * Perform the select(nd, in, out, ex, tv) and mmap() system |
| 112 | * calls. | 59 | * calls. |
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index d140abca690a..f780086befd7 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig | |||
| @@ -3,6 +3,30 @@ if ARCH_MSM | |||
| 3 | comment "MSM Board Type" | 3 | comment "MSM Board Type" |
| 4 | depends on ARCH_MSM | 4 | depends on ARCH_MSM |
| 5 | 5 | ||
| 6 | config MSM_DEBUG_UART | ||
| 7 | int | ||
| 8 | default 1 if MSM_DEBUG_UART1 | ||
| 9 | default 2 if MSM_DEBUG_UART2 | ||
| 10 | default 3 if MSM_DEBUG_UART3 | ||
| 11 | |||
| 12 | choice | ||
| 13 | prompt "Debug UART" | ||
| 14 | |||
| 15 | default MSM_DEBUG_UART_NONE | ||
| 16 | |||
| 17 | config MSM_DEBUG_UART_NONE | ||
| 18 | bool "None" | ||
| 19 | |||
| 20 | config MSM_DEBUG_UART1 | ||
| 21 | bool "UART1" | ||
| 22 | |||
| 23 | config MSM_DEBUG_UART2 | ||
| 24 | bool "UART2" | ||
| 25 | |||
| 26 | config MSM_DEBUG_UART3 | ||
| 27 | bool "UART3" | ||
| 28 | endchoice | ||
| 29 | |||
| 6 | config MACH_HALIBUT | 30 | config MACH_HALIBUT |
| 7 | depends on ARCH_MSM | 31 | depends on ARCH_MSM |
| 8 | default y | 32 | default y |
| @@ -10,4 +34,10 @@ config MACH_HALIBUT | |||
| 10 | help | 34 | help |
| 11 | Support for the Qualcomm SURF7201A eval board. | 35 | Support for the Qualcomm SURF7201A eval board. |
| 12 | 36 | ||
| 37 | config MACH_TROUT | ||
| 38 | default y | ||
| 39 | bool "HTC Dream (aka trout)" | ||
| 40 | help | ||
| 41 | Support for the HTC Dream, T-Mobile G1, Android ADP1 devices. | ||
| 42 | |||
| 13 | endif | 43 | endif |
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 1aa47001aa3b..91e6f5c95dc1 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile | |||
| @@ -6,3 +6,4 @@ obj-y += clock.o clock-7x01a.o | |||
| 6 | 6 | ||
| 7 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o | 7 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o |
| 8 | 8 | ||
| 9 | obj-$(CONFIG_MACH_TROUT) += board-dream.o | ||
diff --git a/arch/arm/mach-msm/board-dream.c b/arch/arm/mach-msm/board-dream.c new file mode 100644 index 000000000000..21afa8513168 --- /dev/null +++ b/arch/arm/mach-msm/board-dream.c | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | /* linux/arch/arm/mach-msm/board-dream.c | ||
| 2 | * | ||
| 3 | * Copyright (C) 2009 Google, Inc. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | |||
| 21 | #include <asm/mach-types.h> | ||
| 22 | #include <asm/mach/arch.h> | ||
| 23 | #include <asm/mach/map.h> | ||
| 24 | #include <asm/setup.h> | ||
| 25 | |||
| 26 | #include <mach/board.h> | ||
| 27 | #include <mach/hardware.h> | ||
| 28 | #include <mach/msm_iomap.h> | ||
| 29 | |||
| 30 | #include "devices.h" | ||
| 31 | #include "board-dream.h" | ||
| 32 | |||
| 33 | static struct platform_device *devices[] __initdata = { | ||
| 34 | &msm_device_uart3, | ||
| 35 | &msm_device_smd, | ||
| 36 | &msm_device_nand, | ||
| 37 | &msm_device_hsusb, | ||
| 38 | &msm_device_i2c, | ||
| 39 | }; | ||
| 40 | |||
| 41 | extern struct sys_timer msm_timer; | ||
| 42 | |||
| 43 | static void __init trout_init_irq(void) | ||
| 44 | { | ||
| 45 | msm_init_irq(); | ||
| 46 | } | ||
| 47 | |||
| 48 | static void __init trout_fixup(struct machine_desc *desc, struct tag *tags, | ||
| 49 | char **cmdline, struct meminfo *mi) | ||
| 50 | { | ||
| 51 | mi->nr_banks = 1; | ||
| 52 | mi->bank[0].start = PHYS_OFFSET; | ||
| 53 | mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); | ||
| 54 | mi->bank[0].size = (101*1024*1024); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void __init trout_init(void) | ||
| 58 | { | ||
| 59 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 60 | } | ||
| 61 | |||
| 62 | static struct map_desc trout_io_desc[] __initdata = { | ||
| 63 | { | ||
| 64 | .virtual = TROUT_CPLD_BASE, | ||
| 65 | .pfn = __phys_to_pfn(TROUT_CPLD_START), | ||
| 66 | .length = TROUT_CPLD_SIZE, | ||
| 67 | .type = MT_DEVICE_NONSHARED | ||
| 68 | } | ||
| 69 | }; | ||
| 70 | |||
| 71 | static void __init trout_map_io(void) | ||
| 72 | { | ||
| 73 | msm_map_common_io(); | ||
| 74 | iotable_init(trout_io_desc, ARRAY_SIZE(trout_io_desc)); | ||
| 75 | |||
| 76 | #ifdef CONFIG_MSM_DEBUG_UART3 | ||
| 77 | /* route UART3 to the "H2W" extended usb connector */ | ||
| 78 | writeb(0x80, TROUT_CPLD_BASE + 0x00); | ||
| 79 | #endif | ||
| 80 | |||
| 81 | msm_clock_init(); | ||
| 82 | } | ||
| 83 | |||
| 84 | MACHINE_START(TROUT, "HTC Dream") | ||
| 85 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 86 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 87 | .boot_params = 0x10000100, | ||
| 88 | .fixup = trout_fixup, | ||
| 89 | .map_io = trout_map_io, | ||
| 90 | .init_irq = trout_init_irq, | ||
| 91 | .init_machine = trout_init, | ||
| 92 | .timer = &msm_timer, | ||
| 93 | MACHINE_END | ||
diff --git a/arch/arm/mach-msm/board-dream.h b/arch/arm/mach-msm/board-dream.h new file mode 100644 index 000000000000..4f345a5a0a61 --- /dev/null +++ b/arch/arm/mach-msm/board-dream.h | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | |||
| 2 | #define TROUT_CPLD_BASE 0xE8100000 | ||
| 3 | #define TROUT_CPLD_START 0x98000000 | ||
| 4 | #define TROUT_CPLD_SIZE SZ_4K | ||
| 5 | |||
diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S index 1db3c97dbc49..d48747ebcd3d 100644 --- a/arch/arm/mach-msm/include/mach/debug-macro.S +++ b/arch/arm/mach-msm/include/mach/debug-macro.S | |||
| @@ -14,15 +14,18 @@ | |||
| 14 | * | 14 | * |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | |||
| 18 | |||
| 17 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
| 18 | #include <mach/msm_iomap.h> | 20 | #include <mach/msm_iomap.h> |
| 19 | 21 | ||
| 22 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 20 | .macro addruart,rx | 23 | .macro addruart,rx |
| 21 | @ see if the MMU is enabled and select appropriate base address | 24 | @ see if the MMU is enabled and select appropriate base address |
| 22 | mrc p15, 0, \rx, c1, c0 | 25 | mrc p15, 0, \rx, c1, c0 |
| 23 | tst \rx, #1 | 26 | tst \rx, #1 |
| 24 | ldreq \rx, =MSM_UART1_PHYS | 27 | ldreq \rx, =MSM_DEBUG_UART_PHYS |
| 25 | movne \rx, #0 | 28 | ldrne \rx, =MSM_DEBUG_UART_BASE |
| 26 | .endm | 29 | .endm |
| 27 | 30 | ||
| 28 | .macro senduart,rd,rx | 31 | .macro senduart,rd,rx |
| @@ -32,13 +35,20 @@ | |||
| 32 | 35 | ||
| 33 | .macro waituart,rd,rx | 36 | .macro waituart,rd,rx |
| 34 | @ wait for TX_READY | 37 | @ wait for TX_READY |
| 35 | teq \rx, #0 | 38 | 1001: ldr \rd, [\rx, #0x08] |
| 36 | bne 2f | ||
| 37 | 1: ldr \rd, [\rx, #0x08] | ||
| 38 | tst \rd, #0x04 | 39 | tst \rd, #0x04 |
| 39 | beq 1b | 40 | beq 1001b |
| 40 | 2: | 41 | .endm |
| 42 | #else | ||
| 43 | .macro addruart,rx | ||
| 44 | .endm | ||
| 45 | |||
| 46 | .macro senduart,rd,rx | ||
| 47 | .endm | ||
| 48 | |||
| 49 | .macro waituart,rd,rx | ||
| 41 | .endm | 50 | .endm |
| 51 | #endif | ||
| 42 | 52 | ||
| 43 | .macro busyuart,rd,rx | 53 | .macro busyuart,rd,rx |
| 44 | .endm | 54 | .endm |
diff --git a/arch/arm/mach-msm/include/mach/mmc.h b/arch/arm/mach-msm/include/mach/mmc.h new file mode 100644 index 000000000000..0ecf25426284 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/mmc.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/include/asm/mach/mmc.h | ||
| 3 | */ | ||
| 4 | #ifndef ASMARM_MACH_MMC_H | ||
| 5 | #define ASMARM_MACH_MMC_H | ||
| 6 | |||
| 7 | #include <linux/mmc/host.h> | ||
| 8 | #include <linux/mmc/card.h> | ||
| 9 | #include <linux/mmc/sdio_func.h> | ||
| 10 | |||
| 11 | struct embedded_sdio_data { | ||
| 12 | struct sdio_cis cis; | ||
| 13 | struct sdio_cccr cccr; | ||
| 14 | struct sdio_embedded_func *funcs; | ||
| 15 | int num_funcs; | ||
| 16 | }; | ||
| 17 | |||
| 18 | struct mmc_platform_data { | ||
| 19 | unsigned int ocr_mask; /* available voltages */ | ||
| 20 | u32 (*translate_vdd)(struct device *, unsigned int); | ||
| 21 | unsigned int (*status)(struct device *); | ||
| 22 | struct embedded_sdio_data *embedded_sdio; | ||
| 23 | int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id); | ||
| 24 | }; | ||
| 25 | |||
| 26 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 2f7b4c8620d9..9dae1a98c77a 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h | |||
| @@ -84,6 +84,18 @@ | |||
| 84 | #define MSM_UART3_PHYS 0xA9C00000 | 84 | #define MSM_UART3_PHYS 0xA9C00000 |
| 85 | #define MSM_UART3_SIZE SZ_4K | 85 | #define MSM_UART3_SIZE SZ_4K |
| 86 | 86 | ||
| 87 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 88 | #define MSM_DEBUG_UART_BASE 0xE1000000 | ||
| 89 | #if CONFIG_MSM_DEBUG_UART == 1 | ||
| 90 | #define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS | ||
| 91 | #elif CONFIG_MSM_DEBUG_UART == 2 | ||
| 92 | #define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS | ||
| 93 | #elif CONFIG_MSM_DEBUG_UART == 3 | ||
| 94 | #define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS | ||
| 95 | #endif | ||
| 96 | #define MSM_DEBUG_UART_SIZE SZ_4K | ||
| 97 | #endif | ||
| 98 | |||
| 87 | #define MSM_SDC1_PHYS 0xA0400000 | 99 | #define MSM_SDC1_PHYS 0xA0400000 |
| 88 | #define MSM_SDC1_SIZE SZ_4K | 100 | #define MSM_SDC1_SIZE SZ_4K |
| 89 | 101 | ||
diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h index 026e8955ace9..d94292c29d8e 100644 --- a/arch/arm/mach-msm/include/mach/uncompress.h +++ b/arch/arm/mach-msm/include/mach/uncompress.h | |||
| @@ -16,9 +16,16 @@ | |||
| 16 | #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H | 16 | #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H |
| 17 | 17 | ||
| 18 | #include "hardware.h" | 18 | #include "hardware.h" |
| 19 | #include "linux/io.h" | ||
| 20 | #include "mach/msm_iomap.h" | ||
| 19 | 21 | ||
| 20 | static void putc(int c) | 22 | static void putc(int c) |
| 21 | { | 23 | { |
| 24 | #if defined(MSM_DEBUG_UART_PHYS) | ||
| 25 | unsigned base = MSM_DEBUG_UART_PHYS; | ||
| 26 | while (!(readl(base + 0x08) & 0x04)) ; | ||
| 27 | writel(c, base + 0x0c); | ||
| 28 | #endif | ||
| 22 | } | 29 | } |
| 23 | 30 | ||
| 24 | static inline void flush(void) | 31 | static inline void flush(void) |
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 6e7692ff6f2c..1c5e7dac086f 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c | |||
| @@ -42,6 +42,9 @@ static struct map_desc msm_io_desc[] __initdata = { | |||
| 42 | MSM_DEVICE(GPIO1), | 42 | MSM_DEVICE(GPIO1), |
| 43 | MSM_DEVICE(GPIO2), | 43 | MSM_DEVICE(GPIO2), |
| 44 | MSM_DEVICE(CLK_CTL), | 44 | MSM_DEVICE(CLK_CTL), |
| 45 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 46 | MSM_DEVICE(DEBUG_UART), | ||
| 47 | #endif | ||
| 45 | { | 48 | { |
| 46 | .virtual = (unsigned long) MSM_SHARED_RAM_BASE, | 49 | .virtual = (unsigned long) MSM_SHARED_RAM_BASE, |
| 47 | .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), | 50 | .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), |
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 2b7996401b0f..f5abc51c5a07 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c | |||
| @@ -54,7 +54,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 54 | * We enforce the MAP_FIXED case. | 54 | * We enforce the MAP_FIXED case. |
| 55 | */ | 55 | */ |
| 56 | if (flags & MAP_FIXED) { | 56 | if (flags & MAP_FIXED) { |
| 57 | if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1)) | 57 | if (aliasing && flags & MAP_SHARED && |
| 58 | (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) | ||
| 58 | return -EINVAL; | 59 | return -EINVAL; |
| 59 | return addr; | 60 | return addr; |
| 60 | } | 61 | } |
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 4cbca9da1505..996cbac6932c 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile | |||
| @@ -9,6 +9,7 @@ obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o | |||
| 9 | obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o | 9 | obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o |
| 10 | obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o | 10 | obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o |
| 11 | obj-$(CONFIG_MXC_PWM) += pwm.o | 11 | obj-$(CONFIG_MXC_PWM) += pwm.o |
| 12 | obj-$(CONFIG_USB_EHCI_MXC) += ehci.o | ||
| 12 | obj-$(CONFIG_MXC_ULPI) += ulpi.o | 13 | obj-$(CONFIG_MXC_ULPI) += ulpi.o |
| 13 | obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o | 14 | obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o |
| 14 | obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o | 15 | obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o |
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c new file mode 100644 index 000000000000..41599be882e8 --- /dev/null +++ b/arch/arm/plat-mxc/ehci.c | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
| 11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 12 | * for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software Foundation, | ||
| 16 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | |||
| 22 | #include <mach/hardware.h> | ||
| 23 | #include <mach/mxc_ehci.h> | ||
| 24 | |||
| 25 | #define USBCTRL_OTGBASE_OFFSET 0x600 | ||
| 26 | |||
| 27 | #define MX31_OTG_SIC_SHIFT 29 | ||
| 28 | #define MX31_OTG_SIC_MASK (0xf << MX31_OTG_SIC_SHIFT) | ||
| 29 | #define MX31_OTG_PM_BIT (1 << 24) | ||
| 30 | |||
| 31 | #define MX31_H2_SIC_SHIFT 21 | ||
| 32 | #define MX31_H2_SIC_MASK (0xf << MX31_H2_SIC_SHIFT) | ||
| 33 | #define MX31_H2_PM_BIT (1 << 16) | ||
| 34 | #define MX31_H2_DT_BIT (1 << 5) | ||
| 35 | |||
| 36 | #define MX31_H1_SIC_SHIFT 13 | ||
| 37 | #define MX31_H1_SIC_MASK (0xf << MX31_H1_SIC_SHIFT) | ||
| 38 | #define MX31_H1_PM_BIT (1 << 8) | ||
| 39 | #define MX31_H1_DT_BIT (1 << 4) | ||
| 40 | |||
| 41 | int mxc_set_usbcontrol(int port, unsigned int flags) | ||
| 42 | { | ||
| 43 | unsigned int v; | ||
| 44 | |||
| 45 | if (cpu_is_mx31()) { | ||
| 46 | v = readl(IO_ADDRESS(MX31_OTG_BASE_ADDR + | ||
| 47 | USBCTRL_OTGBASE_OFFSET)); | ||
| 48 | |||
| 49 | switch (port) { | ||
| 50 | case 0: /* OTG port */ | ||
| 51 | v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); | ||
| 52 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
| 53 | << MX31_OTG_SIC_SHIFT; | ||
| 54 | if (flags & MXC_EHCI_POWER_PINS_ENABLED) | ||
| 55 | v |= MX31_OTG_PM_BIT; | ||
| 56 | |||
| 57 | break; | ||
| 58 | case 1: /* H1 port */ | ||
| 59 | v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT); | ||
| 60 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
| 61 | << MX31_H1_SIC_SHIFT; | ||
| 62 | if (flags & MXC_EHCI_POWER_PINS_ENABLED) | ||
| 63 | v |= MX31_H1_PM_BIT; | ||
| 64 | |||
| 65 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
| 66 | v |= MX31_H1_DT_BIT; | ||
| 67 | |||
| 68 | break; | ||
| 69 | case 2: /* H2 port */ | ||
| 70 | v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT); | ||
| 71 | v |= (flags & MXC_EHCI_INTERFACE_MASK) | ||
| 72 | << MX31_H2_SIC_SHIFT; | ||
| 73 | if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) | ||
| 74 | v |= MX31_H2_PM_BIT; | ||
| 75 | |||
| 76 | if (!(flags & MXC_EHCI_TTL_ENABLED)) | ||
| 77 | v |= MX31_H2_DT_BIT; | ||
| 78 | |||
| 79 | break; | ||
| 80 | } | ||
| 81 | |||
| 82 | writel(v, IO_ADDRESS(MX31_OTG_BASE_ADDR + | ||
| 83 | USBCTRL_OTGBASE_OFFSET)); | ||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | printk(KERN_WARNING | ||
| 88 | "%s() unable to setup USBCONTROL for this CPU\n", __func__); | ||
| 89 | return -EINVAL; | ||
| 90 | } | ||
| 91 | EXPORT_SYMBOL(mxc_set_usbcontrol); | ||
| 92 | |||
diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h new file mode 100644 index 000000000000..8f796239393e --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | #ifndef __INCLUDE_ASM_ARCH_MXC_EHCI_H | ||
| 2 | #define __INCLUDE_ASM_ARCH_MXC_EHCI_H | ||
| 3 | |||
| 4 | /* values for portsc field */ | ||
| 5 | #define MXC_EHCI_PHY_LOW_POWER_SUSPEND (1 << 23) | ||
| 6 | #define MXC_EHCI_FORCE_FS (1 << 24) | ||
| 7 | #define MXC_EHCI_UTMI_8BIT (0 << 28) | ||
| 8 | #define MXC_EHCI_UTMI_16BIT (1 << 28) | ||
| 9 | #define MXC_EHCI_SERIAL (1 << 29) | ||
| 10 | #define MXC_EHCI_MODE_UTMI (0 << 30) | ||
| 11 | #define MXC_EHCI_MODE_PHILIPS (1 << 30) | ||
| 12 | #define MXC_EHCI_MODE_ULPI (2 << 30) | ||
| 13 | #define MXC_EHCI_MODE_SERIAL (3 << 30) | ||
| 14 | |||
| 15 | /* values for flags field */ | ||
| 16 | #define MXC_EHCI_INTERFACE_DIFF_UNI (0 << 0) | ||
| 17 | #define MXC_EHCI_INTERFACE_DIFF_BI (1 << 0) | ||
| 18 | #define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0) | ||
| 19 | #define MXC_EHCI_INTERFACE_SINGLE_BI (3 << 0) | ||
| 20 | #define MXC_EHCI_INTERFACE_MASK (0xf) | ||
| 21 | |||
| 22 | #define MXC_EHCI_POWER_PINS_ENABLED (1 << 5) | ||
| 23 | #define MXC_EHCI_TTL_ENABLED (1 << 6) | ||
| 24 | |||
| 25 | struct mxc_usbh_platform_data { | ||
| 26 | int (*init)(struct platform_device *pdev); | ||
| 27 | int (*exit)(struct platform_device *pdev); | ||
| 28 | |||
| 29 | unsigned int portsc; | ||
| 30 | unsigned int flags; | ||
| 31 | struct otg_transceiver *otg; | ||
| 32 | }; | ||
| 33 | |||
| 34 | int mxc_set_usbcontrol(int port, unsigned int flags); | ||
| 35 | |||
| 36 | #endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */ | ||
| 37 | |||
diff --git a/arch/avr32/include/asm/syscalls.h b/arch/avr32/include/asm/syscalls.h index 483d666c27c0..66a197266637 100644 --- a/arch/avr32/include/asm/syscalls.h +++ b/arch/avr32/include/asm/syscalls.h | |||
| @@ -29,10 +29,6 @@ asmlinkage int sys_sigaltstack(const stack_t __user *, stack_t __user *, | |||
| 29 | struct pt_regs *); | 29 | struct pt_regs *); |
| 30 | asmlinkage int sys_rt_sigreturn(struct pt_regs *); | 30 | asmlinkage int sys_rt_sigreturn(struct pt_regs *); |
| 31 | 31 | ||
| 32 | /* kernel/sys_avr32.c */ | ||
| 33 | asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long, | ||
| 34 | unsigned long, unsigned long, off_t); | ||
| 35 | |||
| 36 | /* mm/cache.c */ | 32 | /* mm/cache.c */ |
| 37 | asmlinkage int sys_cacheflush(int, void __user *, size_t); | 33 | asmlinkage int sys_cacheflush(int, void __user *, size_t); |
| 38 | 34 | ||
diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c index 5d2daeaf356f..459349b5ed5a 100644 --- a/arch/avr32/kernel/sys_avr32.c +++ b/arch/avr32/kernel/sys_avr32.c | |||
| @@ -5,39 +5,8 @@ | |||
| 5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
| 6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
| 7 | */ | 7 | */ |
| 8 | #include <linux/errno.h> | ||
| 9 | #include <linux/fs.h> | ||
| 10 | #include <linux/file.h> | ||
| 11 | #include <linux/mm.h> | ||
| 12 | #include <linux/unistd.h> | 8 | #include <linux/unistd.h> |
| 13 | 9 | ||
| 14 | #include <asm/mman.h> | ||
| 15 | #include <asm/uaccess.h> | ||
| 16 | #include <asm/syscalls.h> | ||
| 17 | |||
| 18 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 19 | unsigned long prot, unsigned long flags, | ||
| 20 | unsigned long fd, off_t offset) | ||
| 21 | { | ||
| 22 | int error = -EBADF; | ||
| 23 | struct file *file = NULL; | ||
| 24 | |||
| 25 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 26 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 27 | file = fget(fd); | ||
| 28 | if (!file) | ||
| 29 | return error; | ||
| 30 | } | ||
| 31 | |||
| 32 | down_write(¤t->mm->mmap_sem); | ||
| 33 | error = do_mmap_pgoff(file, addr, len, prot, flags, offset); | ||
| 34 | up_write(¤t->mm->mmap_sem); | ||
| 35 | |||
| 36 | if (file) | ||
| 37 | fput(file); | ||
| 38 | return error; | ||
| 39 | } | ||
| 40 | |||
| 41 | int kernel_execve(const char *file, char **argv, char **envp) | 10 | int kernel_execve(const char *file, char **argv, char **envp) |
| 42 | { | 11 | { |
| 43 | register long scno asm("r8") = __NR_execve; | 12 | register long scno asm("r8") = __NR_execve; |
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S index f7244cd02fbb..0447a3e2ba64 100644 --- a/arch/avr32/kernel/syscall-stubs.S +++ b/arch/avr32/kernel/syscall-stubs.S | |||
| @@ -61,7 +61,7 @@ __sys_execve: | |||
| 61 | __sys_mmap2: | 61 | __sys_mmap2: |
| 62 | pushm lr | 62 | pushm lr |
| 63 | st.w --sp, ARG6 | 63 | st.w --sp, ARG6 |
| 64 | call sys_mmap2 | 64 | call sys_mmap_pgoff |
| 65 | sub sp, -4 | 65 | sub sp, -4 |
| 66 | popm pc | 66 | popm pc |
| 67 | 67 | ||
diff --git a/arch/blackfin/include/asm/fcntl.h b/arch/blackfin/include/asm/fcntl.h index 8727b2b382f1..251c911d59c1 100644 --- a/arch/blackfin/include/asm/fcntl.h +++ b/arch/blackfin/include/asm/fcntl.h | |||
| @@ -7,8 +7,6 @@ | |||
| 7 | #ifndef _BFIN_FCNTL_H | 7 | #ifndef _BFIN_FCNTL_H |
| 8 | #define _BFIN_FCNTL_H | 8 | #define _BFIN_FCNTL_H |
| 9 | 9 | ||
| 10 | /* open/fcntl - O_SYNC is only implemented on blocks devices and on files | ||
| 11 | located on an ext2 file system */ | ||
| 12 | #define O_DIRECTORY 040000 /* must be a directory */ | 10 | #define O_DIRECTORY 040000 /* must be a directory */ |
| 13 | #define O_NOFOLLOW 0100000 /* don't follow links */ | 11 | #define O_NOFOLLOW 0100000 /* don't follow links */ |
| 14 | #define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ | 12 | #define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ |
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index afcef129d4e8..2e7f8e10bf87 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c | |||
| @@ -22,39 +22,6 @@ | |||
| 22 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
| 23 | #include <asm/dma.h> | 23 | #include <asm/dma.h> |
| 24 | 24 | ||
| 25 | /* common code for old and new mmaps */ | ||
| 26 | static inline long | ||
| 27 | do_mmap2(unsigned long addr, unsigned long len, | ||
| 28 | unsigned long prot, unsigned long flags, | ||
| 29 | unsigned long fd, unsigned long pgoff) | ||
| 30 | { | ||
| 31 | int error = -EBADF; | ||
| 32 | struct file *file = NULL; | ||
| 33 | |||
| 34 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 35 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 36 | file = fget(fd); | ||
| 37 | if (!file) | ||
| 38 | goto out; | ||
| 39 | } | ||
| 40 | |||
| 41 | down_write(¤t->mm->mmap_sem); | ||
| 42 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 43 | up_write(¤t->mm->mmap_sem); | ||
| 44 | |||
| 45 | if (file) | ||
| 46 | fput(file); | ||
| 47 | out: | ||
| 48 | return error; | ||
| 49 | } | ||
| 50 | |||
| 51 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 52 | unsigned long prot, unsigned long flags, | ||
| 53 | unsigned long fd, unsigned long pgoff) | ||
| 54 | { | ||
| 55 | return do_mmap2(addr, len, prot, flags, fd, pgoff); | ||
| 56 | } | ||
| 57 | |||
| 58 | asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) | 25 | asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) |
| 59 | { | 26 | { |
| 60 | return sram_alloc_with_lsl(size, flags); | 27 | return sram_alloc_with_lsl(size, flags); |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index a50637a8b9bd..f3f8bb46b517 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
| @@ -1422,7 +1422,7 @@ ENTRY(_sys_call_table) | |||
| 1422 | .long _sys_ni_syscall /* streams2 */ | 1422 | .long _sys_ni_syscall /* streams2 */ |
| 1423 | .long _sys_vfork /* 190 */ | 1423 | .long _sys_vfork /* 190 */ |
| 1424 | .long _sys_getrlimit | 1424 | .long _sys_getrlimit |
| 1425 | .long _sys_mmap2 | 1425 | .long _sys_mmap_pgoff |
| 1426 | .long _sys_truncate64 | 1426 | .long _sys_truncate64 |
| 1427 | .long _sys_ftruncate64 | 1427 | .long _sys_ftruncate64 |
| 1428 | .long _sys_stat64 /* 195 */ | 1428 | .long _sys_stat64 /* 195 */ |
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c index 2ad962c7e88e..c2bbb1ac98a9 100644 --- a/arch/cris/kernel/sys_cris.c +++ b/arch/cris/kernel/sys_cris.c | |||
| @@ -26,31 +26,6 @@ | |||
| 26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
| 27 | #include <asm/segment.h> | 27 | #include <asm/segment.h> |
| 28 | 28 | ||
| 29 | /* common code for old and new mmaps */ | ||
| 30 | static inline long | ||
| 31 | do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, | ||
| 32 | unsigned long flags, unsigned long fd, unsigned long pgoff) | ||
| 33 | { | ||
| 34 | int error = -EBADF; | ||
| 35 | struct file * file = NULL; | ||
| 36 | |||
| 37 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 38 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 39 | file = fget(fd); | ||
| 40 | if (!file) | ||
| 41 | goto out; | ||
| 42 | } | ||
| 43 | |||
| 44 | down_write(¤t->mm->mmap_sem); | ||
| 45 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 46 | up_write(¤t->mm->mmap_sem); | ||
| 47 | |||
| 48 | if (file) | ||
| 49 | fput(file); | ||
| 50 | out: | ||
| 51 | return error; | ||
| 52 | } | ||
| 53 | |||
| 54 | asmlinkage unsigned long old_mmap(unsigned long __user *args) | 29 | asmlinkage unsigned long old_mmap(unsigned long __user *args) |
| 55 | { | 30 | { |
| 56 | unsigned long buffer[6]; | 31 | unsigned long buffer[6]; |
| @@ -63,7 +38,7 @@ asmlinkage unsigned long old_mmap(unsigned long __user *args) | |||
| 63 | if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */ | 38 | if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */ |
| 64 | goto out; | 39 | goto out; |
| 65 | 40 | ||
| 66 | err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3], | 41 | err = sys_mmap_pgoff(buffer[0], buffer[1], buffer[2], buffer[3], |
| 67 | buffer[4], buffer[5] >> PAGE_SHIFT); | 42 | buffer[4], buffer[5] >> PAGE_SHIFT); |
| 68 | out: | 43 | out: |
| 69 | return err; | 44 | return err; |
| @@ -73,7 +48,8 @@ asmlinkage long | |||
| 73 | sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, | 48 | sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, |
| 74 | unsigned long flags, unsigned long fd, unsigned long pgoff) | 49 | unsigned long flags, unsigned long fd, unsigned long pgoff) |
| 75 | { | 50 | { |
| 76 | return do_mmap2(addr, len, prot, flags, fd, pgoff); | 51 | /* bug(?): 8Kb pages here */ |
| 52 | return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); | ||
| 77 | } | 53 | } |
| 78 | 54 | ||
| 79 | /* | 55 | /* |
diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c index 2b6b5289cdcc..1d3d4c9e2521 100644 --- a/arch/frv/kernel/sys_frv.c +++ b/arch/frv/kernel/sys_frv.c | |||
| @@ -31,9 +31,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | |||
| 31 | unsigned long prot, unsigned long flags, | 31 | unsigned long prot, unsigned long flags, |
| 32 | unsigned long fd, unsigned long pgoff) | 32 | unsigned long fd, unsigned long pgoff) |
| 33 | { | 33 | { |
| 34 | int error = -EBADF; | ||
| 35 | struct file * file = NULL; | ||
| 36 | |||
| 37 | /* As with sparc32, make sure the shift for mmap2 is constant | 34 | /* As with sparc32, make sure the shift for mmap2 is constant |
| 38 | (12), no matter what PAGE_SIZE we have.... */ | 35 | (12), no matter what PAGE_SIZE we have.... */ |
| 39 | 36 | ||
| @@ -41,69 +38,10 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | |||
| 41 | trying to map something we can't */ | 38 | trying to map something we can't */ |
| 42 | if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1)) | 39 | if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1)) |
| 43 | return -EINVAL; | 40 | return -EINVAL; |
| 44 | pgoff >>= PAGE_SHIFT - 12; | ||
| 45 | |||
| 46 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 47 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 48 | file = fget(fd); | ||
| 49 | if (!file) | ||
| 50 | goto out; | ||
| 51 | } | ||
| 52 | |||
| 53 | down_write(¤t->mm->mmap_sem); | ||
| 54 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 55 | up_write(¤t->mm->mmap_sem); | ||
| 56 | |||
| 57 | if (file) | ||
| 58 | fput(file); | ||
| 59 | out: | ||
| 60 | return error; | ||
| 61 | } | ||
| 62 | |||
| 63 | #if 0 /* DAVIDM - do we want this */ | ||
| 64 | struct mmap_arg_struct64 { | ||
| 65 | __u32 addr; | ||
| 66 | __u32 len; | ||
| 67 | __u32 prot; | ||
| 68 | __u32 flags; | ||
| 69 | __u64 offset; /* 64 bits */ | ||
| 70 | __u32 fd; | ||
| 71 | }; | ||
| 72 | |||
| 73 | asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) | ||
| 74 | { | ||
| 75 | int error = -EFAULT; | ||
| 76 | struct file * file = NULL; | ||
| 77 | struct mmap_arg_struct64 a; | ||
| 78 | unsigned long pgoff; | ||
| 79 | |||
| 80 | if (copy_from_user(&a, arg, sizeof(a))) | ||
| 81 | return -EFAULT; | ||
| 82 | |||
| 83 | if ((long)a.offset & ~PAGE_MASK) | ||
| 84 | return -EINVAL; | ||
| 85 | |||
| 86 | pgoff = a.offset >> PAGE_SHIFT; | ||
| 87 | if ((a.offset >> PAGE_SHIFT) != pgoff) | ||
| 88 | return -EINVAL; | ||
| 89 | |||
| 90 | if (!(a.flags & MAP_ANONYMOUS)) { | ||
| 91 | error = -EBADF; | ||
| 92 | file = fget(a.fd); | ||
| 93 | if (!file) | ||
| 94 | goto out; | ||
| 95 | } | ||
| 96 | a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 97 | 41 | ||
| 98 | down_write(¤t->mm->mmap_sem); | 42 | return sys_mmap_pgoff(addr, len, prot, flags, fd, |
| 99 | error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); | 43 | pgoff >> (PAGE_SHIFT - 12)); |
| 100 | up_write(¤t->mm->mmap_sem); | ||
| 101 | if (file) | ||
| 102 | fput(file); | ||
| 103 | out: | ||
| 104 | return error; | ||
| 105 | } | 44 | } |
| 106 | #endif | ||
| 107 | 45 | ||
| 108 | /* | 46 | /* |
| 109 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. | 47 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. |
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index 8cb5d73a0e35..b5969db0ca10 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c | |||
| @@ -26,39 +26,6 @@ | |||
| 26 | #include <asm/traps.h> | 26 | #include <asm/traps.h> |
| 27 | #include <asm/unistd.h> | 27 | #include <asm/unistd.h> |
| 28 | 28 | ||
| 29 | /* common code for old and new mmaps */ | ||
| 30 | static inline long do_mmap2( | ||
| 31 | unsigned long addr, unsigned long len, | ||
| 32 | unsigned long prot, unsigned long flags, | ||
| 33 | unsigned long fd, unsigned long pgoff) | ||
| 34 | { | ||
| 35 | int error = -EBADF; | ||
| 36 | struct file * file = NULL; | ||
| 37 | |||
| 38 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 39 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 40 | file = fget(fd); | ||
| 41 | if (!file) | ||
| 42 | goto out; | ||
| 43 | } | ||
| 44 | |||
| 45 | down_write(¤t->mm->mmap_sem); | ||
| 46 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 47 | up_write(¤t->mm->mmap_sem); | ||
| 48 | |||
| 49 | if (file) | ||
| 50 | fput(file); | ||
| 51 | out: | ||
| 52 | return error; | ||
| 53 | } | ||
| 54 | |||
| 55 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 56 | unsigned long prot, unsigned long flags, | ||
| 57 | unsigned long fd, unsigned long pgoff) | ||
| 58 | { | ||
| 59 | return do_mmap2(addr, len, prot, flags, fd, pgoff); | ||
| 60 | } | ||
| 61 | |||
| 62 | /* | 29 | /* |
| 63 | * Perform the select(nd, in, out, ex, tv) and mmap() system | 30 | * Perform the select(nd, in, out, ex, tv) and mmap() system |
| 64 | * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to | 31 | * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to |
| @@ -87,57 +54,11 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg) | |||
| 87 | if (a.offset & ~PAGE_MASK) | 54 | if (a.offset & ~PAGE_MASK) |
| 88 | goto out; | 55 | goto out; |
| 89 | 56 | ||
| 90 | a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | 57 | error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, |
| 91 | 58 | a.offset >> PAGE_SHIFT); | |
| 92 | error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); | ||
| 93 | out: | ||
| 94 | return error; | ||
| 95 | } | ||
| 96 | |||
| 97 | #if 0 /* DAVIDM - do we want this */ | ||
| 98 | struct mmap_arg_struct64 { | ||
| 99 | __u32 addr; | ||
| 100 | __u32 len; | ||
| 101 | __u32 prot; | ||
| 102 | __u32 flags; | ||
| 103 | __u64 offset; /* 64 bits */ | ||
| 104 | __u32 fd; | ||
| 105 | }; | ||
| 106 | |||
| 107 | asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) | ||
| 108 | { | ||
| 109 | int error = -EFAULT; | ||
| 110 | struct file * file = NULL; | ||
| 111 | struct mmap_arg_struct64 a; | ||
| 112 | unsigned long pgoff; | ||
| 113 | |||
| 114 | if (copy_from_user(&a, arg, sizeof(a))) | ||
| 115 | return -EFAULT; | ||
| 116 | |||
| 117 | if ((long)a.offset & ~PAGE_MASK) | ||
| 118 | return -EINVAL; | ||
| 119 | |||
| 120 | pgoff = a.offset >> PAGE_SHIFT; | ||
| 121 | if ((a.offset >> PAGE_SHIFT) != pgoff) | ||
| 122 | return -EINVAL; | ||
| 123 | |||
| 124 | if (!(a.flags & MAP_ANONYMOUS)) { | ||
| 125 | error = -EBADF; | ||
| 126 | file = fget(a.fd); | ||
| 127 | if (!file) | ||
| 128 | goto out; | ||
| 129 | } | ||
| 130 | a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 131 | |||
| 132 | down_write(¤t->mm->mmap_sem); | ||
| 133 | error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); | ||
| 134 | up_write(¤t->mm->mmap_sem); | ||
| 135 | if (file) | ||
| 136 | fput(file); | ||
| 137 | out: | 59 | out: |
| 138 | return error; | 60 | return error; |
| 139 | } | 61 | } |
| 140 | #endif | ||
| 141 | 62 | ||
| 142 | struct sel_arg_struct { | 63 | struct sel_arg_struct { |
| 143 | unsigned long n; | 64 | unsigned long n; |
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S index 4eb67faac633..2d69881eda6a 100644 --- a/arch/h8300/kernel/syscalls.S +++ b/arch/h8300/kernel/syscalls.S | |||
| @@ -206,7 +206,7 @@ SYMBOL_NAME_LABEL(sys_call_table) | |||
| 206 | .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ | 206 | .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ |
| 207 | .long SYMBOL_NAME(sys_vfork) /* 190 */ | 207 | .long SYMBOL_NAME(sys_vfork) /* 190 */ |
| 208 | .long SYMBOL_NAME(sys_getrlimit) | 208 | .long SYMBOL_NAME(sys_getrlimit) |
| 209 | .long SYMBOL_NAME(sys_mmap2) | 209 | .long SYMBOL_NAME(sys_mmap_pgoff) |
| 210 | .long SYMBOL_NAME(sys_truncate64) | 210 | .long SYMBOL_NAME(sys_truncate64) |
| 211 | .long SYMBOL_NAME(sys_ftruncate64) | 211 | .long SYMBOL_NAME(sys_ftruncate64) |
| 212 | .long SYMBOL_NAME(sys_stat64) /* 195 */ | 212 | .long SYMBOL_NAME(sys_stat64) /* 195 */ |
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 429ec968c9ee..045b746b9808 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
| @@ -858,6 +858,9 @@ ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot | |||
| 858 | 858 | ||
| 859 | prot = get_prot32(prot); | 859 | prot = get_prot32(prot); |
| 860 | 860 | ||
| 861 | if (flags & MAP_HUGETLB) | ||
| 862 | return -ENOMEM; | ||
| 863 | |||
| 861 | #if PAGE_SHIFT > IA32_PAGE_SHIFT | 864 | #if PAGE_SHIFT > IA32_PAGE_SHIFT |
| 862 | mutex_lock(&ia32_mmap_mutex); | 865 | mutex_lock(&ia32_mmap_mutex); |
| 863 | { | 866 | { |
diff --git a/arch/ia64/include/asm/xen/hypervisor.h b/arch/ia64/include/asm/xen/hypervisor.h index 88afb54501e4..67455c2ed2b1 100644 --- a/arch/ia64/include/asm/xen/hypervisor.h +++ b/arch/ia64/include/asm/xen/hypervisor.h | |||
| @@ -37,35 +37,9 @@ | |||
| 37 | #include <xen/interface/xen.h> | 37 | #include <xen/interface/xen.h> |
| 38 | #include <xen/interface/version.h> /* to compile feature.c */ | 38 | #include <xen/interface/version.h> /* to compile feature.c */ |
| 39 | #include <xen/features.h> /* to comiple xen-netfront.c */ | 39 | #include <xen/features.h> /* to comiple xen-netfront.c */ |
| 40 | #include <xen/xen.h> | ||
| 40 | #include <asm/xen/hypercall.h> | 41 | #include <asm/xen/hypercall.h> |
| 41 | 42 | ||
| 42 | /* xen_domain_type is set before executing any C code by early_xen_setup */ | ||
| 43 | enum xen_domain_type { | ||
| 44 | XEN_NATIVE, /* running on bare hardware */ | ||
| 45 | XEN_PV_DOMAIN, /* running in a PV domain */ | ||
| 46 | XEN_HVM_DOMAIN, /* running in a Xen hvm domain*/ | ||
| 47 | }; | ||
| 48 | |||
| 49 | #ifdef CONFIG_XEN | ||
| 50 | extern enum xen_domain_type xen_domain_type; | ||
| 51 | #else | ||
| 52 | #define xen_domain_type XEN_NATIVE | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #define xen_domain() (xen_domain_type != XEN_NATIVE) | ||
| 56 | #define xen_pv_domain() (xen_domain() && \ | ||
| 57 | xen_domain_type == XEN_PV_DOMAIN) | ||
| 58 | #define xen_hvm_domain() (xen_domain() && \ | ||
| 59 | xen_domain_type == XEN_HVM_DOMAIN) | ||
| 60 | |||
| 61 | #ifdef CONFIG_XEN_DOM0 | ||
| 62 | #define xen_initial_domain() (xen_pv_domain() && \ | ||
| 63 | (xen_start_info->flags & SIF_INITDOMAIN)) | ||
| 64 | #else | ||
| 65 | #define xen_initial_domain() (0) | ||
| 66 | #endif | ||
| 67 | |||
| 68 | |||
| 69 | #ifdef CONFIG_XEN | 43 | #ifdef CONFIG_XEN |
| 70 | extern struct shared_info *HYPERVISOR_shared_info; | 44 | extern struct shared_info *HYPERVISOR_shared_info; |
| 71 | extern struct start_info *xen_start_info; | 45 | extern struct start_info *xen_start_info; |
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index 92ed83f34036..609d50056a6c 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c | |||
| @@ -100,51 +100,7 @@ sys_getpagesize (void) | |||
| 100 | asmlinkage unsigned long | 100 | asmlinkage unsigned long |
| 101 | ia64_brk (unsigned long brk) | 101 | ia64_brk (unsigned long brk) |
| 102 | { | 102 | { |
| 103 | unsigned long rlim, retval, newbrk, oldbrk; | 103 | unsigned long retval = sys_brk(brk); |
| 104 | struct mm_struct *mm = current->mm; | ||
| 105 | |||
| 106 | /* | ||
| 107 | * Most of this replicates the code in sys_brk() except for an additional safety | ||
| 108 | * check and the clearing of r8. However, we can't call sys_brk() because we need | ||
| 109 | * to acquire the mmap_sem before we can do the test... | ||
| 110 | */ | ||
| 111 | down_write(&mm->mmap_sem); | ||
| 112 | |||
| 113 | if (brk < mm->end_code) | ||
| 114 | goto out; | ||
| 115 | newbrk = PAGE_ALIGN(brk); | ||
| 116 | oldbrk = PAGE_ALIGN(mm->brk); | ||
| 117 | if (oldbrk == newbrk) | ||
| 118 | goto set_brk; | ||
| 119 | |||
| 120 | /* Always allow shrinking brk. */ | ||
| 121 | if (brk <= mm->brk) { | ||
| 122 | if (!do_munmap(mm, newbrk, oldbrk-newbrk)) | ||
| 123 | goto set_brk; | ||
| 124 | goto out; | ||
| 125 | } | ||
| 126 | |||
| 127 | /* Check against unimplemented/unmapped addresses: */ | ||
| 128 | if ((newbrk - oldbrk) > RGN_MAP_LIMIT || REGION_OFFSET(newbrk) > RGN_MAP_LIMIT) | ||
| 129 | goto out; | ||
| 130 | |||
| 131 | /* Check against rlimit.. */ | ||
| 132 | rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; | ||
| 133 | if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) | ||
| 134 | goto out; | ||
| 135 | |||
| 136 | /* Check against existing mmap mappings. */ | ||
| 137 | if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) | ||
| 138 | goto out; | ||
| 139 | |||
| 140 | /* Ok, looks good - let it rip. */ | ||
| 141 | if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) | ||
| 142 | goto out; | ||
| 143 | set_brk: | ||
| 144 | mm->brk = brk; | ||
| 145 | out: | ||
| 146 | retval = mm->brk; | ||
| 147 | up_write(&mm->mmap_sem); | ||
| 148 | force_successful_syscall_return(); | 104 | force_successful_syscall_return(); |
| 149 | return retval; | 105 | return retval; |
| 150 | } | 106 | } |
| @@ -185,39 +141,6 @@ int ia64_mmap_check(unsigned long addr, unsigned long len, | |||
| 185 | return 0; | 141 | return 0; |
| 186 | } | 142 | } |
| 187 | 143 | ||
| 188 | static inline unsigned long | ||
| 189 | do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff) | ||
| 190 | { | ||
| 191 | struct file *file = NULL; | ||
| 192 | |||
| 193 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 194 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 195 | file = fget(fd); | ||
| 196 | if (!file) | ||
| 197 | return -EBADF; | ||
| 198 | |||
| 199 | if (!file->f_op || !file->f_op->mmap) { | ||
| 200 | addr = -ENODEV; | ||
| 201 | goto out; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | /* Careful about overflows.. */ | ||
| 206 | len = PAGE_ALIGN(len); | ||
| 207 | if (!len || len > TASK_SIZE) { | ||
| 208 | addr = -EINVAL; | ||
| 209 | goto out; | ||
| 210 | } | ||
| 211 | |||
| 212 | down_write(¤t->mm->mmap_sem); | ||
| 213 | addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 214 | up_write(¤t->mm->mmap_sem); | ||
| 215 | |||
| 216 | out: if (file) | ||
| 217 | fput(file); | ||
| 218 | return addr; | ||
| 219 | } | ||
| 220 | |||
| 221 | /* | 144 | /* |
| 222 | * mmap2() is like mmap() except that the offset is expressed in units | 145 | * mmap2() is like mmap() except that the offset is expressed in units |
| 223 | * of PAGE_SIZE (instead of bytes). This allows to mmap2() (pieces | 146 | * of PAGE_SIZE (instead of bytes). This allows to mmap2() (pieces |
| @@ -226,7 +149,7 @@ out: if (file) | |||
| 226 | asmlinkage unsigned long | 149 | asmlinkage unsigned long |
| 227 | sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff) | 150 | sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff) |
| 228 | { | 151 | { |
| 229 | addr = do_mmap2(addr, len, prot, flags, fd, pgoff); | 152 | addr = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); |
| 230 | if (!IS_ERR((void *) addr)) | 153 | if (!IS_ERR((void *) addr)) |
| 231 | force_successful_syscall_return(); | 154 | force_successful_syscall_return(); |
| 232 | return addr; | 155 | return addr; |
| @@ -238,7 +161,7 @@ sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, lo | |||
| 238 | if (offset_in_page(off) != 0) | 161 | if (offset_in_page(off) != 0) |
| 239 | return -EINVAL; | 162 | return -EINVAL; |
| 240 | 163 | ||
| 241 | addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); | 164 | addr = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); |
| 242 | if (!IS_ERR((void *) addr)) | 165 | if (!IS_ERR((void *) addr)) |
| 243 | force_successful_syscall_return(); | 166 | force_successful_syscall_return(); |
| 244 | return addr; | 167 | return addr; |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index c0fca2c1c858..df639db779f9 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
| @@ -131,6 +131,7 @@ alloc_pci_controller (int seg) | |||
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | struct pci_root_info { | 133 | struct pci_root_info { |
| 134 | struct acpi_device *bridge; | ||
| 134 | struct pci_controller *controller; | 135 | struct pci_controller *controller; |
| 135 | char *name; | 136 | char *name; |
| 136 | }; | 137 | }; |
| @@ -297,9 +298,20 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | |||
| 297 | window->offset = offset; | 298 | window->offset = offset; |
| 298 | 299 | ||
| 299 | if (insert_resource(root, &window->resource)) { | 300 | if (insert_resource(root, &window->resource)) { |
| 300 | printk(KERN_ERR "alloc 0x%llx-0x%llx from %s for %s failed\n", | 301 | dev_err(&info->bridge->dev, |
| 301 | window->resource.start, window->resource.end, | 302 | "can't allocate host bridge window %pR\n", |
| 302 | root->name, info->name); | 303 | &window->resource); |
| 304 | } else { | ||
| 305 | if (offset) | ||
| 306 | dev_info(&info->bridge->dev, "host bridge window %pR " | ||
| 307 | "(PCI address [%#llx-%#llx])\n", | ||
| 308 | &window->resource, | ||
| 309 | window->resource.start - offset, | ||
| 310 | window->resource.end - offset); | ||
| 311 | else | ||
| 312 | dev_info(&info->bridge->dev, | ||
| 313 | "host bridge window %pR\n", | ||
| 314 | &window->resource); | ||
| 303 | } | 315 | } |
| 304 | 316 | ||
| 305 | return AE_OK; | 317 | return AE_OK; |
| @@ -319,8 +331,9 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl) | |||
| 319 | (res->end - res->start < 16)) | 331 | (res->end - res->start < 16)) |
| 320 | continue; | 332 | continue; |
| 321 | if (j >= PCI_BUS_NUM_RESOURCES) { | 333 | if (j >= PCI_BUS_NUM_RESOURCES) { |
| 322 | printk("Ignoring range [%#llx-%#llx] (%lx)\n", | 334 | dev_warn(&bus->dev, |
| 323 | res->start, res->end, res->flags); | 335 | "ignoring host bridge window %pR (no space)\n", |
| 336 | res); | ||
| 324 | continue; | 337 | continue; |
| 325 | } | 338 | } |
| 326 | bus->resource[j++] = res; | 339 | bus->resource[j++] = res; |
| @@ -364,6 +377,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
| 364 | goto out3; | 377 | goto out3; |
| 365 | 378 | ||
| 366 | sprintf(name, "PCI Bus %04x:%02x", domain, bus); | 379 | sprintf(name, "PCI Bus %04x:%02x", domain, bus); |
| 380 | info.bridge = device; | ||
| 367 | info.controller = controller; | 381 | info.controller = controller; |
| 368 | info.name = name; | 382 | info.name = name; |
| 369 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, | 383 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, |
| @@ -720,9 +734,6 @@ int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) | |||
| 720 | return ret; | 734 | return ret; |
| 721 | } | 735 | } |
| 722 | 736 | ||
| 723 | /* It's defined in drivers/pci/pci.c */ | ||
| 724 | extern u8 pci_cache_line_size; | ||
| 725 | |||
| 726 | /** | 737 | /** |
| 727 | * set_pci_cacheline_size - determine cacheline size for PCI devices | 738 | * set_pci_cacheline_size - determine cacheline size for PCI devices |
| 728 | * | 739 | * |
| @@ -731,7 +742,7 @@ extern u8 pci_cache_line_size; | |||
| 731 | * | 742 | * |
| 732 | * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). | 743 | * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). |
| 733 | */ | 744 | */ |
| 734 | static void __init set_pci_cacheline_size(void) | 745 | static void __init set_pci_dfl_cacheline_size(void) |
| 735 | { | 746 | { |
| 736 | unsigned long levels, unique_caches; | 747 | unsigned long levels, unique_caches; |
| 737 | long status; | 748 | long status; |
| @@ -751,7 +762,7 @@ static void __init set_pci_cacheline_size(void) | |||
| 751 | "(status=%ld)\n", __func__, status); | 762 | "(status=%ld)\n", __func__, status); |
| 752 | return; | 763 | return; |
| 753 | } | 764 | } |
| 754 | pci_cache_line_size = (1 << cci.pcci_line_size) / 4; | 765 | pci_dfl_cache_line_size = (1 << cci.pcci_line_size) / 4; |
| 755 | } | 766 | } |
| 756 | 767 | ||
| 757 | u64 ia64_dma_get_required_mask(struct device *dev) | 768 | u64 ia64_dma_get_required_mask(struct device *dev) |
| @@ -782,7 +793,7 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask); | |||
| 782 | 793 | ||
| 783 | static int __init pcibios_init(void) | 794 | static int __init pcibios_init(void) |
| 784 | { | 795 | { |
| 785 | set_pci_cacheline_size(); | 796 | set_pci_dfl_cacheline_size(); |
| 786 | return 0; | 797 | return 0; |
| 787 | } | 798 | } |
| 788 | 799 | ||
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c index 305ac852bbed..d3c865c5a6ba 100644 --- a/arch/m32r/kernel/sys_m32r.c +++ b/arch/m32r/kernel/sys_m32r.c | |||
| @@ -76,30 +76,6 @@ asmlinkage int sys_tas(int __user *addr) | |||
| 76 | return oldval; | 76 | return oldval; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 80 | unsigned long prot, unsigned long flags, | ||
| 81 | unsigned long fd, unsigned long pgoff) | ||
| 82 | { | ||
| 83 | int error = -EBADF; | ||
| 84 | struct file *file = NULL; | ||
| 85 | |||
| 86 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 87 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 88 | file = fget(fd); | ||
| 89 | if (!file) | ||
| 90 | goto out; | ||
| 91 | } | ||
| 92 | |||
| 93 | down_write(¤t->mm->mmap_sem); | ||
| 94 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 95 | up_write(¤t->mm->mmap_sem); | ||
| 96 | |||
| 97 | if (file) | ||
| 98 | fput(file); | ||
| 99 | out: | ||
| 100 | return error; | ||
| 101 | } | ||
| 102 | |||
| 103 | /* | 79 | /* |
| 104 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. | 80 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. |
| 105 | * | 81 | * |
diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S index aa3bf4cfab37..60536e271233 100644 --- a/arch/m32r/kernel/syscall_table.S +++ b/arch/m32r/kernel/syscall_table.S | |||
| @@ -191,7 +191,7 @@ ENTRY(sys_call_table) | |||
| 191 | .long sys_ni_syscall /* streams2 */ | 191 | .long sys_ni_syscall /* streams2 */ |
| 192 | .long sys_vfork /* 190 */ | 192 | .long sys_vfork /* 190 */ |
| 193 | .long sys_getrlimit | 193 | .long sys_getrlimit |
| 194 | .long sys_mmap2 | 194 | .long sys_mmap_pgoff |
| 195 | .long sys_truncate64 | 195 | .long sys_truncate64 |
| 196 | .long sys_ftruncate64 | 196 | .long sys_ftruncate64 |
| 197 | .long sys_stat64 /* 195 */ | 197 | .long sys_stat64 /* 195 */ |
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 7deb402bfc75..218f441de667 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c | |||
| @@ -29,37 +29,16 @@ | |||
| 29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
| 30 | #include <asm/unistd.h> | 30 | #include <asm/unistd.h> |
| 31 | 31 | ||
| 32 | /* common code for old and new mmaps */ | ||
| 33 | static inline long do_mmap2( | ||
| 34 | unsigned long addr, unsigned long len, | ||
| 35 | unsigned long prot, unsigned long flags, | ||
| 36 | unsigned long fd, unsigned long pgoff) | ||
| 37 | { | ||
| 38 | int error = -EBADF; | ||
| 39 | struct file * file = NULL; | ||
| 40 | |||
| 41 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 42 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 43 | file = fget(fd); | ||
| 44 | if (!file) | ||
| 45 | goto out; | ||
| 46 | } | ||
| 47 | |||
| 48 | down_write(¤t->mm->mmap_sem); | ||
| 49 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 50 | up_write(¤t->mm->mmap_sem); | ||
| 51 | |||
| 52 | if (file) | ||
| 53 | fput(file); | ||
| 54 | out: | ||
| 55 | return error; | ||
| 56 | } | ||
| 57 | |||
| 58 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | 32 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, |
| 59 | unsigned long prot, unsigned long flags, | 33 | unsigned long prot, unsigned long flags, |
| 60 | unsigned long fd, unsigned long pgoff) | 34 | unsigned long fd, unsigned long pgoff) |
| 61 | { | 35 | { |
| 62 | return do_mmap2(addr, len, prot, flags, fd, pgoff); | 36 | /* |
| 37 | * This is wrong for sun3 - there PAGE_SIZE is 8Kb, | ||
| 38 | * so we need to shift the argument down by 1; m68k mmap64(3) | ||
| 39 | * (in libc) expects the last argument of mmap2 in 4Kb units. | ||
| 40 | */ | ||
| 41 | return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); | ||
| 63 | } | 42 | } |
| 64 | 43 | ||
| 65 | /* | 44 | /* |
| @@ -90,57 +69,11 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) | |||
| 90 | if (a.offset & ~PAGE_MASK) | 69 | if (a.offset & ~PAGE_MASK) |
| 91 | goto out; | 70 | goto out; |
| 92 | 71 | ||
| 93 | a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | 72 | error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, |
| 94 | 73 | a.offset >> PAGE_SHIFT); | |
| 95 | error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); | ||
| 96 | out: | ||
| 97 | return error; | ||
| 98 | } | ||
| 99 | |||
| 100 | #if 0 | ||
| 101 | struct mmap_arg_struct64 { | ||
| 102 | __u32 addr; | ||
| 103 | __u32 len; | ||
| 104 | __u32 prot; | ||
| 105 | __u32 flags; | ||
| 106 | __u64 offset; /* 64 bits */ | ||
| 107 | __u32 fd; | ||
| 108 | }; | ||
| 109 | |||
| 110 | asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) | ||
| 111 | { | ||
| 112 | int error = -EFAULT; | ||
| 113 | struct file * file = NULL; | ||
| 114 | struct mmap_arg_struct64 a; | ||
| 115 | unsigned long pgoff; | ||
| 116 | |||
| 117 | if (copy_from_user(&a, arg, sizeof(a))) | ||
| 118 | return -EFAULT; | ||
| 119 | |||
| 120 | if ((long)a.offset & ~PAGE_MASK) | ||
| 121 | return -EINVAL; | ||
| 122 | |||
| 123 | pgoff = a.offset >> PAGE_SHIFT; | ||
| 124 | if ((a.offset >> PAGE_SHIFT) != pgoff) | ||
| 125 | return -EINVAL; | ||
| 126 | |||
| 127 | if (!(a.flags & MAP_ANONYMOUS)) { | ||
| 128 | error = -EBADF; | ||
| 129 | file = fget(a.fd); | ||
| 130 | if (!file) | ||
| 131 | goto out; | ||
| 132 | } | ||
| 133 | a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 134 | |||
| 135 | down_write(¤t->mm->mmap_sem); | ||
| 136 | error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); | ||
| 137 | up_write(¤t->mm->mmap_sem); | ||
| 138 | if (file) | ||
| 139 | fput(file); | ||
| 140 | out: | 74 | out: |
| 141 | return error; | 75 | return error; |
| 142 | } | 76 | } |
| 143 | #endif | ||
| 144 | 77 | ||
| 145 | struct sel_arg_struct { | 78 | struct sel_arg_struct { |
| 146 | unsigned long n; | 79 | unsigned long n; |
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c index efdd090778a3..b67cbc735a9b 100644 --- a/arch/m68knommu/kernel/sys_m68k.c +++ b/arch/m68knommu/kernel/sys_m68k.c | |||
| @@ -27,39 +27,6 @@ | |||
| 27 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
| 28 | #include <asm/unistd.h> | 28 | #include <asm/unistd.h> |
| 29 | 29 | ||
| 30 | /* common code for old and new mmaps */ | ||
| 31 | static inline long do_mmap2( | ||
| 32 | unsigned long addr, unsigned long len, | ||
| 33 | unsigned long prot, unsigned long flags, | ||
| 34 | unsigned long fd, unsigned long pgoff) | ||
| 35 | { | ||
| 36 | int error = -EBADF; | ||
| 37 | struct file * file = NULL; | ||
| 38 | |||
| 39 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 40 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 41 | file = fget(fd); | ||
| 42 | if (!file) | ||
| 43 | goto out; | ||
| 44 | } | ||
| 45 | |||
| 46 | down_write(¤t->mm->mmap_sem); | ||
| 47 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 48 | up_write(¤t->mm->mmap_sem); | ||
| 49 | |||
| 50 | if (file) | ||
| 51 | fput(file); | ||
| 52 | out: | ||
| 53 | return error; | ||
| 54 | } | ||
| 55 | |||
| 56 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 57 | unsigned long prot, unsigned long flags, | ||
| 58 | unsigned long fd, unsigned long pgoff) | ||
| 59 | { | ||
| 60 | return do_mmap2(addr, len, prot, flags, fd, pgoff); | ||
| 61 | } | ||
| 62 | |||
| 63 | /* | 30 | /* |
| 64 | * Perform the select(nd, in, out, ex, tv) and mmap() system | 31 | * Perform the select(nd, in, out, ex, tv) and mmap() system |
| 65 | * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to | 32 | * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to |
| @@ -88,9 +55,8 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg) | |||
| 88 | if (a.offset & ~PAGE_MASK) | 55 | if (a.offset & ~PAGE_MASK) |
| 89 | goto out; | 56 | goto out; |
| 90 | 57 | ||
| 91 | a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | 58 | error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, |
| 92 | 59 | a.offset >> PAGE_SHIFT); | |
| 93 | error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); | ||
| 94 | out: | 60 | out: |
| 95 | return error; | 61 | return error; |
| 96 | } | 62 | } |
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index 23535cc415ae..486837efa3d7 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68knommu/kernel/syscalltable.S | |||
| @@ -210,7 +210,7 @@ ENTRY(sys_call_table) | |||
| 210 | .long sys_ni_syscall /* streams2 */ | 210 | .long sys_ni_syscall /* streams2 */ |
| 211 | .long sys_vfork /* 190 */ | 211 | .long sys_vfork /* 190 */ |
| 212 | .long sys_getrlimit | 212 | .long sys_getrlimit |
| 213 | .long sys_mmap2 | 213 | .long sys_mmap_pgoff |
| 214 | .long sys_truncate64 | 214 | .long sys_truncate64 |
| 215 | .long sys_ftruncate64 | 215 | .long sys_ftruncate64 |
| 216 | .long sys_stat64 /* 195 */ | 216 | .long sys_stat64 /* 195 */ |
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index 07cabed4b947..9f3c205fb75b 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c | |||
| @@ -62,46 +62,14 @@ out: | |||
| 62 | return error; | 62 | return error; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | asmlinkage long | ||
| 66 | sys_mmap2(unsigned long addr, unsigned long len, | ||
| 67 | unsigned long prot, unsigned long flags, | ||
| 68 | unsigned long fd, unsigned long pgoff) | ||
| 69 | { | ||
| 70 | struct file *file = NULL; | ||
| 71 | int ret = -EBADF; | ||
| 72 | |||
| 73 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 74 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 75 | file = fget(fd); | ||
| 76 | if (!file) { | ||
| 77 | printk(KERN_INFO "no fd in mmap\r\n"); | ||
| 78 | goto out; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | down_write(¤t->mm->mmap_sem); | ||
| 83 | ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 84 | up_write(¤t->mm->mmap_sem); | ||
| 85 | if (file) | ||
| 86 | fput(file); | ||
| 87 | out: | ||
| 88 | return ret; | ||
| 89 | } | ||
| 90 | |||
| 91 | asmlinkage long sys_mmap(unsigned long addr, unsigned long len, | 65 | asmlinkage long sys_mmap(unsigned long addr, unsigned long len, |
| 92 | unsigned long prot, unsigned long flags, | 66 | unsigned long prot, unsigned long flags, |
| 93 | unsigned long fd, off_t pgoff) | 67 | unsigned long fd, off_t pgoff) |
| 94 | { | 68 | { |
| 95 | int err = -EINVAL; | 69 | if (pgoff & ~PAGE_MASK) |
| 96 | 70 | return -EINVAL; | |
| 97 | if (pgoff & ~PAGE_MASK) { | ||
| 98 | printk(KERN_INFO "no pagemask in mmap\r\n"); | ||
| 99 | goto out; | ||
| 100 | } | ||
| 101 | 71 | ||
| 102 | err = sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); | 72 | return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); |
| 103 | out: | ||
| 104 | return err; | ||
| 105 | } | 73 | } |
| 106 | 74 | ||
| 107 | /* | 75 | /* |
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index c1ab1dc10898..b96f365ea6b1 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S | |||
| @@ -196,7 +196,7 @@ ENTRY(sys_call_table) | |||
| 196 | .long sys_ni_syscall /* reserved for streams2 */ | 196 | .long sys_ni_syscall /* reserved for streams2 */ |
| 197 | .long sys_vfork /* 190 */ | 197 | .long sys_vfork /* 190 */ |
| 198 | .long sys_getrlimit | 198 | .long sys_getrlimit |
| 199 | .long sys_mmap2 /* mmap2 */ | 199 | .long sys_mmap_pgoff /* mmap2 */ |
| 200 | .long sys_truncate64 | 200 | .long sys_truncate64 |
| 201 | .long sys_ftruncate64 | 201 | .long sys_ftruncate64 |
| 202 | .long sys_stat64 /* 195 */ | 202 | .long sys_stat64 /* 195 */ |
diff --git a/arch/mips/include/asm/fcntl.h b/arch/mips/include/asm/fcntl.h index 2a52333a062d..7c6681aa2ab8 100644 --- a/arch/mips/include/asm/fcntl.h +++ b/arch/mips/include/asm/fcntl.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | #define O_APPEND 0x0008 | 12 | #define O_APPEND 0x0008 |
| 13 | #define O_SYNC 0x0010 | 13 | #define O_DSYNC 0x0010 /* used to be O_SYNC, see below */ |
| 14 | #define O_NONBLOCK 0x0080 | 14 | #define O_NONBLOCK 0x0080 |
| 15 | #define O_CREAT 0x0100 /* not fcntl */ | 15 | #define O_CREAT 0x0100 /* not fcntl */ |
| 16 | #define O_TRUNC 0x0200 /* not fcntl */ | 16 | #define O_TRUNC 0x0200 /* not fcntl */ |
| @@ -18,6 +18,21 @@ | |||
| 18 | #define O_NOCTTY 0x0800 /* not fcntl */ | 18 | #define O_NOCTTY 0x0800 /* not fcntl */ |
| 19 | #define FASYNC 0x1000 /* fcntl, for BSD compatibility */ | 19 | #define FASYNC 0x1000 /* fcntl, for BSD compatibility */ |
| 20 | #define O_LARGEFILE 0x2000 /* allow large file opens */ | 20 | #define O_LARGEFILE 0x2000 /* allow large file opens */ |
| 21 | /* | ||
| 22 | * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using | ||
| 23 | * the O_SYNC flag. We continue to use the existing numerical value | ||
| 24 | * for O_DSYNC semantics now, but using the correct symbolic name for it. | ||
| 25 | * This new value is used to request true Posix O_SYNC semantics. It is | ||
| 26 | * defined in this strange way to make sure applications compiled against | ||
| 27 | * new headers get at least O_DSYNC semantics on older kernels. | ||
| 28 | * | ||
| 29 | * This has the nice side-effect that we can simply test for O_DSYNC | ||
| 30 | * wherever we do not care if O_DSYNC or O_SYNC is used. | ||
| 31 | * | ||
| 32 | * Note: __O_SYNC must never be used directly. | ||
| 33 | */ | ||
| 34 | #define __O_SYNC 0x4000 | ||
| 35 | #define O_SYNC (__O_SYNC|O_DSYNC) | ||
| 21 | #define O_DIRECT 0x8000 /* direct disk access hint */ | 36 | #define O_DIRECT 0x8000 /* direct disk access hint */ |
| 22 | 37 | ||
| 23 | #define F_GETLK 14 | 38 | #define F_GETLK 14 |
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index ad4e017ed2f3..80e2ba694bab 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c | |||
| @@ -82,6 +82,7 @@ static int sp_stopping; | |||
| 82 | #define MTSP_O_SHLOCK 0x0010 | 82 | #define MTSP_O_SHLOCK 0x0010 |
| 83 | #define MTSP_O_EXLOCK 0x0020 | 83 | #define MTSP_O_EXLOCK 0x0020 |
| 84 | #define MTSP_O_ASYNC 0x0040 | 84 | #define MTSP_O_ASYNC 0x0040 |
| 85 | /* XXX: check which of these is actually O_SYNC vs O_DSYNC */ | ||
| 85 | #define MTSP_O_FSYNC O_SYNC | 86 | #define MTSP_O_FSYNC O_SYNC |
| 86 | #define MTSP_O_NOFOLLOW 0x0100 | 87 | #define MTSP_O_NOFOLLOW 0x0100 |
| 87 | #define MTSP_O_SYNC 0x0080 | 88 | #define MTSP_O_SYNC 0x0080 |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 1a2793efdc4e..f042563c924f 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
| @@ -67,28 +67,13 @@ SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len, | |||
| 67 | unsigned long, prot, unsigned long, flags, unsigned long, fd, | 67 | unsigned long, prot, unsigned long, flags, unsigned long, fd, |
| 68 | unsigned long, pgoff) | 68 | unsigned long, pgoff) |
| 69 | { | 69 | { |
| 70 | struct file * file = NULL; | ||
| 71 | unsigned long error; | 70 | unsigned long error; |
| 72 | 71 | ||
| 73 | error = -EINVAL; | 72 | error = -EINVAL; |
| 74 | if (pgoff & (~PAGE_MASK >> 12)) | 73 | if (pgoff & (~PAGE_MASK >> 12)) |
| 75 | goto out; | 74 | goto out; |
| 76 | pgoff >>= PAGE_SHIFT-12; | 75 | error = sys_mmap_pgoff(addr, len, prot, flags, fd, |
| 77 | 76 | pgoff >> (PAGE_SHIFT-12)); | |
| 78 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 79 | error = -EBADF; | ||
| 80 | file = fget(fd); | ||
| 81 | if (!file) | ||
| 82 | goto out; | ||
| 83 | } | ||
| 84 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 85 | |||
| 86 | down_write(¤t->mm->mmap_sem); | ||
| 87 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 88 | up_write(¤t->mm->mmap_sem); | ||
| 89 | if (file) | ||
| 90 | fput(file); | ||
| 91 | |||
| 92 | out: | 77 | out: |
| 93 | return error; | 78 | return error; |
| 94 | } | 79 | } |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index fe0d79805603..3f7f466190b4 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
| @@ -93,7 +93,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 93 | * We do not accept a shared mapping if it would violate | 93 | * We do not accept a shared mapping if it would violate |
| 94 | * cache aliasing constraints. | 94 | * cache aliasing constraints. |
| 95 | */ | 95 | */ |
| 96 | if ((flags & MAP_SHARED) && (addr & shm_align_mask)) | 96 | if ((flags & MAP_SHARED) && |
| 97 | ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask)) | ||
| 97 | return -EINVAL; | 98 | return -EINVAL; |
| 98 | return addr; | 99 | return addr; |
| 99 | } | 100 | } |
| @@ -129,31 +130,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 129 | } | 130 | } |
| 130 | } | 131 | } |
| 131 | 132 | ||
| 132 | /* common code for old and new mmaps */ | ||
| 133 | static inline unsigned long | ||
| 134 | do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, | ||
| 135 | unsigned long flags, unsigned long fd, unsigned long pgoff) | ||
| 136 | { | ||
| 137 | unsigned long error = -EBADF; | ||
| 138 | struct file * file = NULL; | ||
| 139 | |||
| 140 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 141 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 142 | file = fget(fd); | ||
| 143 | if (!file) | ||
| 144 | goto out; | ||
| 145 | } | ||
| 146 | |||
| 147 | down_write(¤t->mm->mmap_sem); | ||
| 148 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 149 | up_write(¤t->mm->mmap_sem); | ||
| 150 | |||
| 151 | if (file) | ||
| 152 | fput(file); | ||
| 153 | out: | ||
| 154 | return error; | ||
| 155 | } | ||
| 156 | |||
| 157 | SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, | 133 | SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, |
| 158 | unsigned long, prot, unsigned long, flags, unsigned long, | 134 | unsigned long, prot, unsigned long, flags, unsigned long, |
| 159 | fd, off_t, offset) | 135 | fd, off_t, offset) |
| @@ -164,7 +140,7 @@ SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, | |||
| 164 | if (offset & ~PAGE_MASK) | 140 | if (offset & ~PAGE_MASK) |
| 165 | goto out; | 141 | goto out; |
| 166 | 142 | ||
| 167 | result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | 143 | result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); |
| 168 | 144 | ||
| 169 | out: | 145 | out: |
| 170 | return result; | 146 | return result; |
| @@ -177,7 +153,7 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len, | |||
| 177 | if (pgoff & (~PAGE_MASK >> 12)) | 153 | if (pgoff & (~PAGE_MASK >> 12)) |
| 178 | return -EINVAL; | 154 | return -EINVAL; |
| 179 | 155 | ||
| 180 | return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12)); | 156 | return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12)); |
| 181 | } | 157 | } |
| 182 | 158 | ||
| 183 | save_static_function(sys_fork); | 159 | save_static_function(sys_fork); |
diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c index 7c92f79b6480..e94ef158f980 100644 --- a/arch/mips/loongson/common/mem.c +++ b/arch/mips/loongson/common/mem.c | |||
| @@ -26,7 +26,7 @@ void __init prom_init_memory(void) | |||
| 26 | /* override of arch/mips/mm/cache.c: __uncached_access */ | 26 | /* override of arch/mips/mm/cache.c: __uncached_access */ |
| 27 | int __uncached_access(struct file *file, unsigned long addr) | 27 | int __uncached_access(struct file *file, unsigned long addr) |
| 28 | { | 28 | { |
| 29 | if (file->f_flags & O_SYNC) | 29 | if (file->f_flags & O_DSYNC) |
| 30 | return 1; | 30 | return 1; |
| 31 | 31 | ||
| 32 | return addr >= __pa(high_memory) || | 32 | return addr >= __pa(high_memory) || |
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 694d51f523d1..102b2dfa542a 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
| @@ -194,7 +194,7 @@ void __devinit cpu_cache_init(void) | |||
| 194 | 194 | ||
| 195 | int __weak __uncached_access(struct file *file, unsigned long addr) | 195 | int __weak __uncached_access(struct file *file, unsigned long addr) |
| 196 | { | 196 | { |
| 197 | if (file->f_flags & O_SYNC) | 197 | if (file->f_flags & O_DSYNC) |
| 198 | return 1; | 198 | return 1; |
| 199 | 199 | ||
| 200 | return addr >= __pa(high_memory); | 200 | return addr >= __pa(high_memory); |
diff --git a/arch/mn10300/include/asm/mman.h b/arch/mn10300/include/asm/mman.h index 8eebf89f5ab1..db5c53da73ce 100644 --- a/arch/mn10300/include/asm/mman.h +++ b/arch/mn10300/include/asm/mman.h | |||
| @@ -1 +1,6 @@ | |||
| 1 | #include <asm-generic/mman.h> | 1 | #include <asm-generic/mman.h> |
| 2 | |||
| 3 | #define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */ | ||
| 4 | |||
| 5 | #define arch_mmap_check(addr, len, flags) \ | ||
| 6 | (((flags) & MAP_FIXED && (addr) < MIN_MAP_ADDR) ? -EINVAL : 0) | ||
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index a94e7ea3faa6..c9ee6c009d79 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S | |||
| @@ -578,7 +578,7 @@ ENTRY(sys_call_table) | |||
| 578 | .long sys_ni_syscall /* reserved for streams2 */ | 578 | .long sys_ni_syscall /* reserved for streams2 */ |
| 579 | .long sys_vfork /* 190 */ | 579 | .long sys_vfork /* 190 */ |
| 580 | .long sys_getrlimit | 580 | .long sys_getrlimit |
| 581 | .long sys_mmap2 | 581 | .long sys_mmap_pgoff |
| 582 | .long sys_truncate64 | 582 | .long sys_truncate64 |
| 583 | .long sys_ftruncate64 | 583 | .long sys_ftruncate64 |
| 584 | .long sys_stat64 /* 195 */ | 584 | .long sys_stat64 /* 195 */ |
diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c index 8ca5af00334c..17cc6ce04e84 100644 --- a/arch/mn10300/kernel/sys_mn10300.c +++ b/arch/mn10300/kernel/sys_mn10300.c | |||
| @@ -23,47 +23,13 @@ | |||
| 23 | 23 | ||
| 24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
| 25 | 25 | ||
| 26 | #define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */ | ||
| 27 | |||
| 28 | /* | ||
| 29 | * memory mapping syscall | ||
| 30 | */ | ||
| 31 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 32 | unsigned long prot, unsigned long flags, | ||
| 33 | unsigned long fd, unsigned long pgoff) | ||
| 34 | { | ||
| 35 | struct file *file = NULL; | ||
| 36 | long error = -EINVAL; | ||
| 37 | |||
| 38 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 39 | |||
| 40 | if (flags & MAP_FIXED && addr < MIN_MAP_ADDR) | ||
| 41 | goto out; | ||
| 42 | |||
| 43 | error = -EBADF; | ||
| 44 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 45 | file = fget(fd); | ||
| 46 | if (!file) | ||
| 47 | goto out; | ||
| 48 | } | ||
| 49 | |||
| 50 | down_write(¤t->mm->mmap_sem); | ||
| 51 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 52 | up_write(¤t->mm->mmap_sem); | ||
| 53 | |||
| 54 | if (file) | ||
| 55 | fput(file); | ||
| 56 | out: | ||
| 57 | return error; | ||
| 58 | } | ||
| 59 | |||
| 60 | asmlinkage long old_mmap(unsigned long addr, unsigned long len, | 26 | asmlinkage long old_mmap(unsigned long addr, unsigned long len, |
| 61 | unsigned long prot, unsigned long flags, | 27 | unsigned long prot, unsigned long flags, |
| 62 | unsigned long fd, unsigned long offset) | 28 | unsigned long fd, unsigned long offset) |
| 63 | { | 29 | { |
| 64 | if (offset & ~PAGE_MASK) | 30 | if (offset & ~PAGE_MASK) |
| 65 | return -EINVAL; | 31 | return -EINVAL; |
| 66 | return sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | 32 | return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); |
| 67 | } | 33 | } |
| 68 | 34 | ||
| 69 | struct sel_arg_struct { | 35 | struct sel_arg_struct { |
diff --git a/arch/parisc/include/asm/fcntl.h b/arch/parisc/include/asm/fcntl.h index 1e1c824764ee..f357fc693c89 100644 --- a/arch/parisc/include/asm/fcntl.h +++ b/arch/parisc/include/asm/fcntl.h | |||
| @@ -1,14 +1,13 @@ | |||
| 1 | #ifndef _PARISC_FCNTL_H | 1 | #ifndef _PARISC_FCNTL_H |
| 2 | #define _PARISC_FCNTL_H | 2 | #define _PARISC_FCNTL_H |
| 3 | 3 | ||
| 4 | /* open/fcntl - O_SYNC is only implemented on blocks devices and on files | ||
| 5 | located on an ext2 file system */ | ||
| 6 | #define O_APPEND 000000010 | 4 | #define O_APPEND 000000010 |
| 7 | #define O_BLKSEEK 000000100 /* HPUX only */ | 5 | #define O_BLKSEEK 000000100 /* HPUX only */ |
| 8 | #define O_CREAT 000000400 /* not fcntl */ | 6 | #define O_CREAT 000000400 /* not fcntl */ |
| 9 | #define O_EXCL 000002000 /* not fcntl */ | 7 | #define O_EXCL 000002000 /* not fcntl */ |
| 10 | #define O_LARGEFILE 000004000 | 8 | #define O_LARGEFILE 000004000 |
| 11 | #define O_SYNC 000100000 | 9 | #define __O_SYNC 000100000 |
| 10 | #define O_SYNC (__O_SYNC|O_DSYNC) | ||
| 12 | #define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ | 11 | #define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */ |
| 13 | #define O_NOCTTY 000400000 /* not fcntl */ | 12 | #define O_NOCTTY 000400000 /* not fcntl */ |
| 14 | #define O_DSYNC 001000000 /* HPUX only */ | 13 | #define O_DSYNC 001000000 /* HPUX only */ |
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 71b31957c8f1..9147391afb03 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
| @@ -110,37 +110,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 110 | return addr; | 110 | return addr; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static unsigned long do_mmap2(unsigned long addr, unsigned long len, | ||
| 114 | unsigned long prot, unsigned long flags, unsigned long fd, | ||
| 115 | unsigned long pgoff) | ||
| 116 | { | ||
| 117 | struct file * file = NULL; | ||
| 118 | unsigned long error = -EBADF; | ||
| 119 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 120 | file = fget(fd); | ||
| 121 | if (!file) | ||
| 122 | goto out; | ||
| 123 | } | ||
| 124 | |||
| 125 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 126 | |||
| 127 | down_write(¤t->mm->mmap_sem); | ||
| 128 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 129 | up_write(¤t->mm->mmap_sem); | ||
| 130 | |||
| 131 | if (file != NULL) | ||
| 132 | fput(file); | ||
| 133 | out: | ||
| 134 | return error; | ||
| 135 | } | ||
| 136 | |||
| 137 | asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, | 113 | asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, |
| 138 | unsigned long prot, unsigned long flags, unsigned long fd, | 114 | unsigned long prot, unsigned long flags, unsigned long fd, |
| 139 | unsigned long pgoff) | 115 | unsigned long pgoff) |
| 140 | { | 116 | { |
| 141 | /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE | 117 | /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE |
| 142 | we have. */ | 118 | we have. */ |
| 143 | return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12)); | 119 | return sys_mmap_pgoff(addr, len, prot, flags, fd, |
| 120 | pgoff >> (PAGE_SHIFT - 12)); | ||
| 144 | } | 121 | } |
| 145 | 122 | ||
| 146 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, | 123 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, |
| @@ -148,7 +125,8 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, | |||
| 148 | unsigned long offset) | 125 | unsigned long offset) |
| 149 | { | 126 | { |
| 150 | if (!(offset & ~PAGE_MASK)) { | 127 | if (!(offset & ~PAGE_MASK)) { |
| 151 | return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | 128 | return sys_mmap_pgoff(addr, len, prot, flags, fd, |
| 129 | offset >> PAGE_SHIFT); | ||
| 152 | } else { | 130 | } else { |
| 153 | return -EINVAL; | 131 | return -EINVAL; |
| 154 | } | 132 | } |
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index c04832c4a02e..3370e62e43d4 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c | |||
| @@ -140,7 +140,6 @@ static inline unsigned long do_mmap2(unsigned long addr, size_t len, | |||
| 140 | unsigned long prot, unsigned long flags, | 140 | unsigned long prot, unsigned long flags, |
| 141 | unsigned long fd, unsigned long off, int shift) | 141 | unsigned long fd, unsigned long off, int shift) |
| 142 | { | 142 | { |
| 143 | struct file * file = NULL; | ||
| 144 | unsigned long ret = -EINVAL; | 143 | unsigned long ret = -EINVAL; |
| 145 | 144 | ||
| 146 | if (!arch_validate_prot(prot)) | 145 | if (!arch_validate_prot(prot)) |
| @@ -151,20 +150,8 @@ static inline unsigned long do_mmap2(unsigned long addr, size_t len, | |||
| 151 | goto out; | 150 | goto out; |
| 152 | off >>= shift; | 151 | off >>= shift; |
| 153 | } | 152 | } |
| 154 | |||
| 155 | ret = -EBADF; | ||
| 156 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 157 | if (!(file = fget(fd))) | ||
| 158 | goto out; | ||
| 159 | } | ||
| 160 | |||
| 161 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 162 | 153 | ||
| 163 | down_write(¤t->mm->mmap_sem); | 154 | ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off); |
| 164 | ret = do_mmap_pgoff(file, addr, len, prot, flags, off); | ||
| 165 | up_write(¤t->mm->mmap_sem); | ||
| 166 | if (file) | ||
| 167 | fput(file); | ||
| 168 | out: | 155 | out: |
| 169 | return ret; | 156 | return ret; |
| 170 | } | 157 | } |
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 25c31d681402..22c9e557bb22 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
| @@ -624,38 +624,6 @@ struct mmap_arg_struct_emu31 { | |||
| 624 | u32 offset; | 624 | u32 offset; |
| 625 | }; | 625 | }; |
| 626 | 626 | ||
| 627 | /* common code for old and new mmaps */ | ||
| 628 | static inline long do_mmap2( | ||
| 629 | unsigned long addr, unsigned long len, | ||
| 630 | unsigned long prot, unsigned long flags, | ||
| 631 | unsigned long fd, unsigned long pgoff) | ||
| 632 | { | ||
| 633 | struct file * file = NULL; | ||
| 634 | unsigned long error = -EBADF; | ||
| 635 | |||
| 636 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 637 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 638 | file = fget(fd); | ||
| 639 | if (!file) | ||
| 640 | goto out; | ||
| 641 | } | ||
| 642 | |||
| 643 | down_write(¤t->mm->mmap_sem); | ||
| 644 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 645 | if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) { | ||
| 646 | /* Result is out of bounds. */ | ||
| 647 | do_munmap(current->mm, addr, len); | ||
| 648 | error = -ENOMEM; | ||
| 649 | } | ||
| 650 | up_write(¤t->mm->mmap_sem); | ||
| 651 | |||
| 652 | if (file) | ||
| 653 | fput(file); | ||
| 654 | out: | ||
| 655 | return error; | ||
| 656 | } | ||
| 657 | |||
| 658 | |||
| 659 | asmlinkage unsigned long | 627 | asmlinkage unsigned long |
| 660 | old32_mmap(struct mmap_arg_struct_emu31 __user *arg) | 628 | old32_mmap(struct mmap_arg_struct_emu31 __user *arg) |
| 661 | { | 629 | { |
| @@ -669,7 +637,8 @@ old32_mmap(struct mmap_arg_struct_emu31 __user *arg) | |||
| 669 | if (a.offset & ~PAGE_MASK) | 637 | if (a.offset & ~PAGE_MASK) |
| 670 | goto out; | 638 | goto out; |
| 671 | 639 | ||
| 672 | error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); | 640 | error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, |
| 641 | a.offset >> PAGE_SHIFT); | ||
| 673 | out: | 642 | out: |
| 674 | return error; | 643 | return error; |
| 675 | } | 644 | } |
| @@ -682,7 +651,7 @@ sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) | |||
| 682 | 651 | ||
| 683 | if (copy_from_user(&a, arg, sizeof(a))) | 652 | if (copy_from_user(&a, arg, sizeof(a))) |
| 684 | goto out; | 653 | goto out; |
| 685 | error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); | 654 | error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); |
| 686 | out: | 655 | out: |
| 687 | return error; | 656 | return error; |
| 688 | } | 657 | } |
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index e9d94f61d500..86a74c9c9e63 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c | |||
| @@ -32,32 +32,6 @@ | |||
| 32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
| 33 | #include "entry.h" | 33 | #include "entry.h" |
| 34 | 34 | ||
| 35 | /* common code for old and new mmaps */ | ||
| 36 | static inline long do_mmap2( | ||
| 37 | unsigned long addr, unsigned long len, | ||
| 38 | unsigned long prot, unsigned long flags, | ||
| 39 | unsigned long fd, unsigned long pgoff) | ||
| 40 | { | ||
| 41 | long error = -EBADF; | ||
| 42 | struct file * file = NULL; | ||
| 43 | |||
| 44 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 45 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 46 | file = fget(fd); | ||
| 47 | if (!file) | ||
| 48 | goto out; | ||
| 49 | } | ||
| 50 | |||
| 51 | down_write(¤t->mm->mmap_sem); | ||
| 52 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 53 | up_write(¤t->mm->mmap_sem); | ||
| 54 | |||
| 55 | if (file) | ||
| 56 | fput(file); | ||
| 57 | out: | ||
| 58 | return error; | ||
| 59 | } | ||
| 60 | |||
| 61 | /* | 35 | /* |
| 62 | * Perform the select(nd, in, out, ex, tv) and mmap() system | 36 | * Perform the select(nd, in, out, ex, tv) and mmap() system |
| 63 | * calls. Linux for S/390 isn't able to handle more than 5 | 37 | * calls. Linux for S/390 isn't able to handle more than 5 |
| @@ -81,7 +55,7 @@ SYSCALL_DEFINE1(mmap2, struct mmap_arg_struct __user *, arg) | |||
| 81 | 55 | ||
| 82 | if (copy_from_user(&a, arg, sizeof(a))) | 56 | if (copy_from_user(&a, arg, sizeof(a))) |
| 83 | goto out; | 57 | goto out; |
| 84 | error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); | 58 | error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); |
| 85 | out: | 59 | out: |
| 86 | return error; | 60 | return error; |
| 87 | } | 61 | } |
| @@ -98,7 +72,7 @@ SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct __user *, arg) | |||
| 98 | if (a.offset & ~PAGE_MASK) | 72 | if (a.offset & ~PAGE_MASK) |
| 99 | goto out; | 73 | goto out; |
| 100 | 74 | ||
| 101 | error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); | 75 | error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); |
| 102 | out: | 76 | out: |
| 103 | return error; | 77 | return error; |
| 104 | } | 78 | } |
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c index 001249469866..856ed68a58e6 100644 --- a/arch/score/kernel/sys_score.c +++ b/arch/score/kernel/sys_score.c | |||
| @@ -36,34 +36,16 @@ asmlinkage long | |||
| 36 | sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, | 36 | sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, |
| 37 | unsigned long flags, unsigned long fd, unsigned long pgoff) | 37 | unsigned long flags, unsigned long fd, unsigned long pgoff) |
| 38 | { | 38 | { |
| 39 | int error = -EBADF; | 39 | return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); |
| 40 | struct file *file = NULL; | ||
| 41 | |||
| 42 | if (pgoff & (~PAGE_MASK >> 12)) | ||
| 43 | return -EINVAL; | ||
| 44 | |||
| 45 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 46 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 47 | file = fget(fd); | ||
| 48 | if (!file) | ||
| 49 | return error; | ||
| 50 | } | ||
| 51 | |||
| 52 | down_write(¤t->mm->mmap_sem); | ||
| 53 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 54 | up_write(¤t->mm->mmap_sem); | ||
| 55 | |||
| 56 | if (file) | ||
| 57 | fput(file); | ||
| 58 | |||
| 59 | return error; | ||
| 60 | } | 40 | } |
| 61 | 41 | ||
| 62 | asmlinkage long | 42 | asmlinkage long |
| 63 | sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, | 43 | sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, |
| 64 | unsigned long flags, unsigned long fd, off_t pgoff) | 44 | unsigned long flags, unsigned long fd, off_t offset) |
| 65 | { | 45 | { |
| 66 | return sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); | 46 | if (unlikely(offset & ~PAGE_MASK)) |
| 47 | return -EINVAL; | ||
| 48 | return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | ||
| 67 | } | 49 | } |
| 68 | 50 | ||
| 69 | asmlinkage long | 51 | asmlinkage long |
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 8aa5d1ceaf14..71399cde03b5 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c | |||
| @@ -28,37 +28,13 @@ | |||
| 28 | #include <asm/cacheflush.h> | 28 | #include <asm/cacheflush.h> |
| 29 | #include <asm/cachectl.h> | 29 | #include <asm/cachectl.h> |
| 30 | 30 | ||
| 31 | static inline long | ||
| 32 | do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, | ||
| 33 | unsigned long flags, int fd, unsigned long pgoff) | ||
| 34 | { | ||
| 35 | int error = -EBADF; | ||
| 36 | struct file *file = NULL; | ||
| 37 | |||
| 38 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 39 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 40 | file = fget(fd); | ||
| 41 | if (!file) | ||
| 42 | goto out; | ||
| 43 | } | ||
| 44 | |||
| 45 | down_write(¤t->mm->mmap_sem); | ||
| 46 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 47 | up_write(¤t->mm->mmap_sem); | ||
| 48 | |||
| 49 | if (file) | ||
| 50 | fput(file); | ||
| 51 | out: | ||
| 52 | return error; | ||
| 53 | } | ||
| 54 | |||
| 55 | asmlinkage int old_mmap(unsigned long addr, unsigned long len, | 31 | asmlinkage int old_mmap(unsigned long addr, unsigned long len, |
| 56 | unsigned long prot, unsigned long flags, | 32 | unsigned long prot, unsigned long flags, |
| 57 | int fd, unsigned long off) | 33 | int fd, unsigned long off) |
| 58 | { | 34 | { |
| 59 | if (off & ~PAGE_MASK) | 35 | if (off & ~PAGE_MASK) |
| 60 | return -EINVAL; | 36 | return -EINVAL; |
| 61 | return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT); | 37 | return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT); |
| 62 | } | 38 | } |
| 63 | 39 | ||
| 64 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | 40 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, |
| @@ -74,7 +50,7 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | |||
| 74 | 50 | ||
| 75 | pgoff >>= PAGE_SHIFT - 12; | 51 | pgoff >>= PAGE_SHIFT - 12; |
| 76 | 52 | ||
| 77 | return do_mmap2(addr, len, prot, flags, fd, pgoff); | 53 | return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); |
| 78 | } | 54 | } |
| 79 | 55 | ||
| 80 | /* | 56 | /* |
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c index d2984fa42d3d..afeb710ec5c3 100644 --- a/arch/sh/mm/mmap.c +++ b/arch/sh/mm/mmap.c | |||
| @@ -54,7 +54,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 54 | /* We do not accept a shared mapping if it would violate | 54 | /* We do not accept a shared mapping if it would violate |
| 55 | * cache aliasing constraints. | 55 | * cache aliasing constraints. |
| 56 | */ | 56 | */ |
| 57 | if ((flags & MAP_SHARED) && (addr & shm_align_mask)) | 57 | if ((flags & MAP_SHARED) && |
| 58 | ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask)) | ||
| 58 | return -EINVAL; | 59 | return -EINVAL; |
| 59 | return addr; | 60 | return addr; |
| 60 | } | 61 | } |
diff --git a/arch/sparc/include/asm/fcntl.h b/arch/sparc/include/asm/fcntl.h index d4d9c9d852c3..3b9cfb39175e 100644 --- a/arch/sparc/include/asm/fcntl.h +++ b/arch/sparc/include/asm/fcntl.h | |||
| @@ -1,14 +1,12 @@ | |||
| 1 | #ifndef _SPARC_FCNTL_H | 1 | #ifndef _SPARC_FCNTL_H |
| 2 | #define _SPARC_FCNTL_H | 2 | #define _SPARC_FCNTL_H |
| 3 | 3 | ||
| 4 | /* open/fcntl - O_SYNC is only implemented on blocks devices and on files | ||
| 5 | located on an ext2 file system */ | ||
| 6 | #define O_APPEND 0x0008 | 4 | #define O_APPEND 0x0008 |
| 7 | #define FASYNC 0x0040 /* fcntl, for BSD compatibility */ | 5 | #define FASYNC 0x0040 /* fcntl, for BSD compatibility */ |
| 8 | #define O_CREAT 0x0200 /* not fcntl */ | 6 | #define O_CREAT 0x0200 /* not fcntl */ |
| 9 | #define O_TRUNC 0x0400 /* not fcntl */ | 7 | #define O_TRUNC 0x0400 /* not fcntl */ |
| 10 | #define O_EXCL 0x0800 /* not fcntl */ | 8 | #define O_EXCL 0x0800 /* not fcntl */ |
| 11 | #define O_SYNC 0x2000 | 9 | #define O_DSYNC 0x2000 /* used to be O_SYNC, see below */ |
| 12 | #define O_NONBLOCK 0x4000 | 10 | #define O_NONBLOCK 0x4000 |
| 13 | #if defined(__sparc__) && defined(__arch64__) | 11 | #if defined(__sparc__) && defined(__arch64__) |
| 14 | #define O_NDELAY 0x0004 | 12 | #define O_NDELAY 0x0004 |
| @@ -20,6 +18,21 @@ | |||
| 20 | #define O_DIRECT 0x100000 /* direct disk access hint */ | 18 | #define O_DIRECT 0x100000 /* direct disk access hint */ |
| 21 | #define O_NOATIME 0x200000 | 19 | #define O_NOATIME 0x200000 |
| 22 | #define O_CLOEXEC 0x400000 | 20 | #define O_CLOEXEC 0x400000 |
| 21 | /* | ||
| 22 | * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using | ||
| 23 | * the O_SYNC flag. We continue to use the existing numerical value | ||
| 24 | * for O_DSYNC semantics now, but using the correct symbolic name for it. | ||
| 25 | * This new value is used to request true Posix O_SYNC semantics. It is | ||
| 26 | * defined in this strange way to make sure applications compiled against | ||
| 27 | * new headers get at least O_DSYNC semantics on older kernels. | ||
| 28 | * | ||
| 29 | * This has the nice side-effect that we can simply test for O_DSYNC | ||
| 30 | * wherever we do not care if O_DSYNC or O_SYNC is used. | ||
| 31 | * | ||
| 32 | * Note: __O_SYNC must never be used directly. | ||
| 33 | */ | ||
| 34 | #define __O_SYNC 0x800000 | ||
| 35 | #define O_SYNC (__O_SYNC|O_DSYNC) | ||
| 23 | 36 | ||
| 24 | #define F_GETOWN 5 /* for sockets. */ | 37 | #define F_GETOWN 5 /* for sockets. */ |
| 25 | #define F_SETOWN 6 /* for sockets. */ | 38 | #define F_SETOWN 6 /* for sockets. */ |
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index b63e51c3c3ee..b0576df6ec83 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h | |||
| @@ -16,8 +16,6 @@ | |||
| 16 | 16 | ||
| 17 | #define PCI_IRQ_NONE 0xffffffff | 17 | #define PCI_IRQ_NONE 0xffffffff |
| 18 | 18 | ||
| 19 | #define PCI_CACHE_LINE_BYTES 64 | ||
| 20 | |||
| 21 | static inline void pcibios_set_master(struct pci_dev *dev) | 19 | static inline void pcibios_set_master(struct pci_dev *dev) |
| 22 | { | 20 | { |
| 23 | /* No special bus mastering setup handling */ | 21 | /* No special bus mastering setup handling */ |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c68648662802..b85374f7cf94 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
| @@ -1081,3 +1081,10 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar, | |||
| 1081 | *start = rp->start - offset; | 1081 | *start = rp->start - offset; |
| 1082 | *end = rp->end - offset; | 1082 | *end = rp->end - offset; |
| 1083 | } | 1083 | } |
| 1084 | |||
| 1085 | static int __init pcibios_init(void) | ||
| 1086 | { | ||
| 1087 | pci_dfl_cache_line_size = 64 >> 2; | ||
| 1088 | return 0; | ||
| 1089 | } | ||
| 1090 | subsys_initcall(pcibios_init); | ||
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 00abe87e5b51..dc0ac197e7e2 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c | |||
| @@ -564,28 +564,6 @@ asmlinkage long sparc32_open(const char __user *filename, | |||
| 564 | return do_sys_open(AT_FDCWD, filename, flags, mode); | 564 | return do_sys_open(AT_FDCWD, filename, flags, mode); |
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | extern unsigned long do_mremap(unsigned long addr, | ||
| 568 | unsigned long old_len, unsigned long new_len, | ||
| 569 | unsigned long flags, unsigned long new_addr); | ||
| 570 | |||
| 571 | asmlinkage unsigned long sys32_mremap(unsigned long addr, | ||
| 572 | unsigned long old_len, unsigned long new_len, | ||
| 573 | unsigned long flags, u32 __new_addr) | ||
| 574 | { | ||
| 575 | unsigned long ret = -EINVAL; | ||
| 576 | unsigned long new_addr = __new_addr; | ||
| 577 | |||
| 578 | if (unlikely(sparc_mmap_check(addr, old_len))) | ||
| 579 | goto out; | ||
| 580 | if (unlikely(sparc_mmap_check(new_addr, new_len))) | ||
| 581 | goto out; | ||
| 582 | down_write(¤t->mm->mmap_sem); | ||
| 583 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | ||
| 584 | up_write(¤t->mm->mmap_sem); | ||
| 585 | out: | ||
| 586 | return ret; | ||
| 587 | } | ||
| 588 | |||
| 589 | long sys32_lookup_dcookie(unsigned long cookie_high, | 567 | long sys32_lookup_dcookie(unsigned long cookie_high, |
| 590 | unsigned long cookie_low, | 568 | unsigned long cookie_low, |
| 591 | char __user *buf, size_t len) | 569 | char __user *buf, size_t len) |
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 03035c852a43..3a82e65d8db2 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c | |||
| @@ -45,7 +45,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi | |||
| 45 | /* We do not accept a shared mapping if it would violate | 45 | /* We do not accept a shared mapping if it would violate |
| 46 | * cache aliasing constraints. | 46 | * cache aliasing constraints. |
| 47 | */ | 47 | */ |
| 48 | if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1))) | 48 | if ((flags & MAP_SHARED) && |
| 49 | ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) | ||
| 49 | return -EINVAL; | 50 | return -EINVAL; |
| 50 | return addr; | 51 | return addr; |
| 51 | } | 52 | } |
| @@ -79,15 +80,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi | |||
| 79 | } | 80 | } |
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | asmlinkage unsigned long sparc_brk(unsigned long brk) | ||
| 83 | { | ||
| 84 | if(ARCH_SUN4C) { | ||
| 85 | if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000)) | ||
| 86 | return current->mm->brk; | ||
| 87 | } | ||
| 88 | return sys_brk(brk); | ||
| 89 | } | ||
| 90 | |||
| 91 | /* | 83 | /* |
| 92 | * sys_pipe() is the normal C calling standard for creating | 84 | * sys_pipe() is the normal C calling standard for creating |
| 93 | * a pipe. It's not the way unix traditionally does this, though. | 85 | * a pipe. It's not the way unix traditionally does this, though. |
| @@ -234,31 +226,6 @@ int sparc_mmap_check(unsigned long addr, unsigned long len) | |||
| 234 | } | 226 | } |
| 235 | 227 | ||
| 236 | /* Linux version of mmap */ | 228 | /* Linux version of mmap */ |
| 237 | static unsigned long do_mmap2(unsigned long addr, unsigned long len, | ||
| 238 | unsigned long prot, unsigned long flags, unsigned long fd, | ||
| 239 | unsigned long pgoff) | ||
| 240 | { | ||
| 241 | struct file * file = NULL; | ||
| 242 | unsigned long retval = -EBADF; | ||
| 243 | |||
| 244 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 245 | file = fget(fd); | ||
| 246 | if (!file) | ||
| 247 | goto out; | ||
| 248 | } | ||
| 249 | |||
| 250 | len = PAGE_ALIGN(len); | ||
| 251 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 252 | |||
| 253 | down_write(¤t->mm->mmap_sem); | ||
| 254 | retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 255 | up_write(¤t->mm->mmap_sem); | ||
| 256 | |||
| 257 | if (file) | ||
| 258 | fput(file); | ||
| 259 | out: | ||
| 260 | return retval; | ||
| 261 | } | ||
| 262 | 229 | ||
| 263 | asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, | 230 | asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, |
| 264 | unsigned long prot, unsigned long flags, unsigned long fd, | 231 | unsigned long prot, unsigned long flags, unsigned long fd, |
| @@ -266,14 +233,16 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, | |||
| 266 | { | 233 | { |
| 267 | /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE | 234 | /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE |
| 268 | we have. */ | 235 | we have. */ |
| 269 | return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12)); | 236 | return sys_mmap_pgoff(addr, len, prot, flags, fd, |
| 237 | pgoff >> (PAGE_SHIFT - 12)); | ||
| 270 | } | 238 | } |
| 271 | 239 | ||
| 272 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, | 240 | asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, |
| 273 | unsigned long prot, unsigned long flags, unsigned long fd, | 241 | unsigned long prot, unsigned long flags, unsigned long fd, |
| 274 | unsigned long off) | 242 | unsigned long off) |
| 275 | { | 243 | { |
| 276 | return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); | 244 | /* no alignment check? */ |
| 245 | return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); | ||
| 277 | } | 246 | } |
| 278 | 247 | ||
| 279 | long sparc_remap_file_pages(unsigned long start, unsigned long size, | 248 | long sparc_remap_file_pages(unsigned long start, unsigned long size, |
| @@ -287,27 +256,6 @@ long sparc_remap_file_pages(unsigned long start, unsigned long size, | |||
| 287 | (pgoff >> (PAGE_SHIFT - 12)), flags); | 256 | (pgoff >> (PAGE_SHIFT - 12)), flags); |
| 288 | } | 257 | } |
| 289 | 258 | ||
| 290 | extern unsigned long do_mremap(unsigned long addr, | ||
| 291 | unsigned long old_len, unsigned long new_len, | ||
| 292 | unsigned long flags, unsigned long new_addr); | ||
| 293 | |||
| 294 | asmlinkage unsigned long sparc_mremap(unsigned long addr, | ||
| 295 | unsigned long old_len, unsigned long new_len, | ||
| 296 | unsigned long flags, unsigned long new_addr) | ||
| 297 | { | ||
| 298 | unsigned long ret = -EINVAL; | ||
| 299 | |||
| 300 | if (unlikely(sparc_mmap_check(addr, old_len))) | ||
| 301 | goto out; | ||
| 302 | if (unlikely(sparc_mmap_check(new_addr, new_len))) | ||
| 303 | goto out; | ||
| 304 | down_write(¤t->mm->mmap_sem); | ||
| 305 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | ||
| 306 | up_write(¤t->mm->mmap_sem); | ||
| 307 | out: | ||
| 308 | return ret; | ||
| 309 | } | ||
| 310 | |||
| 311 | /* we come to here via sys_nis_syscall so it can setup the regs argument */ | 259 | /* we come to here via sys_nis_syscall so it can setup the regs argument */ |
| 312 | asmlinkage unsigned long | 260 | asmlinkage unsigned long |
| 313 | c_sys_nis_syscall (struct pt_regs *regs) | 261 | c_sys_nis_syscall (struct pt_regs *regs) |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index e2d102447a43..cfa0e19abe3b 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
| @@ -317,10 +317,14 @@ bottomup: | |||
| 317 | unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) | 317 | unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) |
| 318 | { | 318 | { |
| 319 | unsigned long align_goal, addr = -ENOMEM; | 319 | unsigned long align_goal, addr = -ENOMEM; |
| 320 | unsigned long (*get_area)(struct file *, unsigned long, | ||
| 321 | unsigned long, unsigned long, unsigned long); | ||
| 322 | |||
| 323 | get_area = current->mm->get_unmapped_area; | ||
| 320 | 324 | ||
| 321 | if (flags & MAP_FIXED) { | 325 | if (flags & MAP_FIXED) { |
| 322 | /* Ok, don't mess with it. */ | 326 | /* Ok, don't mess with it. */ |
| 323 | return get_unmapped_area(NULL, orig_addr, len, pgoff, flags); | 327 | return get_area(NULL, orig_addr, len, pgoff, flags); |
| 324 | } | 328 | } |
| 325 | flags &= ~MAP_SHARED; | 329 | flags &= ~MAP_SHARED; |
| 326 | 330 | ||
| @@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u | |||
| 333 | align_goal = (64UL * 1024); | 337 | align_goal = (64UL * 1024); |
| 334 | 338 | ||
| 335 | do { | 339 | do { |
| 336 | addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); | 340 | addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); |
| 337 | if (!(addr & ~PAGE_MASK)) { | 341 | if (!(addr & ~PAGE_MASK)) { |
| 338 | addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); | 342 | addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); |
| 339 | break; | 343 | break; |
| @@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u | |||
| 351 | * be obtained. | 355 | * be obtained. |
| 352 | */ | 356 | */ |
| 353 | if (addr & ~PAGE_MASK) | 357 | if (addr & ~PAGE_MASK) |
| 354 | addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags); | 358 | addr = get_area(NULL, orig_addr, len, pgoff, flags); |
| 355 | 359 | ||
| 356 | return addr; | 360 | return addr; |
| 357 | } | 361 | } |
| @@ -399,18 +403,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
| 399 | } | 403 | } |
| 400 | } | 404 | } |
| 401 | 405 | ||
| 402 | SYSCALL_DEFINE1(sparc_brk, unsigned long, brk) | ||
| 403 | { | ||
| 404 | /* People could try to be nasty and use ta 0x6d in 32bit programs */ | ||
| 405 | if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32) | ||
| 406 | return current->mm->brk; | ||
| 407 | |||
| 408 | if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk))) | ||
| 409 | return current->mm->brk; | ||
| 410 | |||
| 411 | return sys_brk(brk); | ||
| 412 | } | ||
| 413 | |||
| 414 | /* | 406 | /* |
| 415 | * sys_pipe() is the normal C calling standard for creating | 407 | * sys_pipe() is the normal C calling standard for creating |
| 416 | * a pipe. It's not the way unix traditionally does this, though. | 408 | * a pipe. It's not the way unix traditionally does this, though. |
| @@ -568,23 +560,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, | |||
| 568 | unsigned long, prot, unsigned long, flags, unsigned long, fd, | 560 | unsigned long, prot, unsigned long, flags, unsigned long, fd, |
| 569 | unsigned long, off) | 561 | unsigned long, off) |
| 570 | { | 562 | { |
| 571 | struct file * file = NULL; | 563 | unsigned long retval = -EINVAL; |
| 572 | unsigned long retval = -EBADF; | ||
| 573 | |||
| 574 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 575 | file = fget(fd); | ||
| 576 | if (!file) | ||
| 577 | goto out; | ||
| 578 | } | ||
| 579 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 580 | len = PAGE_ALIGN(len); | ||
| 581 | 564 | ||
| 582 | down_write(¤t->mm->mmap_sem); | 565 | if ((off + PAGE_ALIGN(len)) < off) |
| 583 | retval = do_mmap(file, addr, len, prot, flags, off); | 566 | goto out; |
| 584 | up_write(¤t->mm->mmap_sem); | 567 | if (off & ~PAGE_MASK) |
| 585 | 568 | goto out; | |
| 586 | if (file) | 569 | retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); |
| 587 | fput(file); | ||
| 588 | out: | 570 | out: |
| 589 | return retval; | 571 | return retval; |
| 590 | } | 572 | } |
| @@ -614,12 +596,6 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len, | |||
| 614 | 596 | ||
| 615 | if (test_thread_flag(TIF_32BIT)) | 597 | if (test_thread_flag(TIF_32BIT)) |
| 616 | goto out; | 598 | goto out; |
| 617 | if (unlikely(new_len >= VA_EXCLUDE_START)) | ||
| 618 | goto out; | ||
| 619 | if (unlikely(sparc_mmap_check(addr, old_len))) | ||
| 620 | goto out; | ||
| 621 | if (unlikely(sparc_mmap_check(new_addr, new_len))) | ||
| 622 | goto out; | ||
| 623 | 599 | ||
| 624 | down_write(¤t->mm->mmap_sem); | 600 | down_write(¤t->mm->mmap_sem); |
| 625 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | 601 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); |
diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index a63c5d2d9849..d2f999ae2b85 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | struct new_utsname; | 9 | struct new_utsname; |
| 10 | 10 | ||
| 11 | extern asmlinkage unsigned long sys_getpagesize(void); | 11 | extern asmlinkage unsigned long sys_getpagesize(void); |
| 12 | extern asmlinkage unsigned long sparc_brk(unsigned long brk); | ||
| 13 | extern asmlinkage long sparc_pipe(struct pt_regs *regs); | 12 | extern asmlinkage long sparc_pipe(struct pt_regs *regs); |
| 14 | extern asmlinkage long sys_ipc(unsigned int call, int first, | 13 | extern asmlinkage long sys_ipc(unsigned int call, int first, |
| 15 | unsigned long second, | 14 | unsigned long second, |
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index ceb1530f8aa6..801fc8e5a0e8 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S | |||
| @@ -19,7 +19,7 @@ sys_call_table: | |||
| 19 | /*0*/ .long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write | 19 | /*0*/ .long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write |
| 20 | /*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link | 20 | /*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link |
| 21 | /*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod | 21 | /*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod |
| 22 | /*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek | 22 | /*15*/ .long sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys_lseek |
| 23 | /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 | 23 | /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 |
| 24 | /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause | 24 | /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause |
| 25 | /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice | 25 | /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice |
| @@ -67,7 +67,7 @@ sys_call_table: | |||
| 67 | /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall | 67 | /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall |
| 68 | /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler | 68 | /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler |
| 69 | /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep | 69 | /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep |
| 70 | /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl | 70 | /*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl |
| 71 | /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep | 71 | /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep |
| 72 | /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun | 72 | /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun |
| 73 | /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy | 73 | /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy |
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index cc8e7862e95a..e575b46bd7a9 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
| @@ -21,7 +21,7 @@ sys_call_table32: | |||
| 21 | /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write | 21 | /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write |
| 22 | /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link | 22 | /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link |
| 23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod | 23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod |
| 24 | /*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek | 24 | /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek |
| 25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 | 25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 |
| 26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause | 26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause |
| 27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice | 27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice |
| @@ -68,7 +68,7 @@ sys_call_table32: | |||
| 68 | .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall | 68 | .word compat_sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall |
| 69 | /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler | 69 | /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler |
| 70 | .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep | 70 | .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep |
| 71 | /*250*/ .word sys32_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl | 71 | /*250*/ .word sys_mremap, compat_sys_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl |
| 72 | .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep | 72 | .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep |
| 73 | /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun | 73 | /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun |
| 74 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy | 74 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy |
| @@ -96,7 +96,7 @@ sys_call_table: | |||
| 96 | /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write | 96 | /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write |
| 97 | /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link | 97 | /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link |
| 98 | /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod | 98 | /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod |
| 99 | /*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek | 99 | /*15*/ .word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek |
| 100 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid | 100 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid |
| 101 | /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall | 101 | /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall |
| 102 | /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice | 102 | /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice |
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index a4625c7b2bf9..cccab850c27e 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "linux/mm.h" | 8 | #include "linux/mm.h" |
| 9 | #include "linux/sched.h" | 9 | #include "linux/sched.h" |
| 10 | #include "linux/utsname.h" | 10 | #include "linux/utsname.h" |
| 11 | #include "linux/syscalls.h" | ||
| 11 | #include "asm/current.h" | 12 | #include "asm/current.h" |
| 12 | #include "asm/mman.h" | 13 | #include "asm/mman.h" |
| 13 | #include "asm/uaccess.h" | 14 | #include "asm/uaccess.h" |
| @@ -37,31 +38,6 @@ long sys_vfork(void) | |||
| 37 | return ret; | 38 | return ret; |
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | /* common code for old and new mmaps */ | ||
| 41 | long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 42 | unsigned long prot, unsigned long flags, | ||
| 43 | unsigned long fd, unsigned long pgoff) | ||
| 44 | { | ||
| 45 | long error = -EBADF; | ||
| 46 | struct file * file = NULL; | ||
| 47 | |||
| 48 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 49 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 50 | file = fget(fd); | ||
| 51 | if (!file) | ||
| 52 | goto out; | ||
| 53 | } | ||
| 54 | |||
| 55 | down_write(¤t->mm->mmap_sem); | ||
| 56 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 57 | up_write(¤t->mm->mmap_sem); | ||
| 58 | |||
| 59 | if (file) | ||
| 60 | fput(file); | ||
| 61 | out: | ||
| 62 | return error; | ||
| 63 | } | ||
| 64 | |||
| 65 | long old_mmap(unsigned long addr, unsigned long len, | 41 | long old_mmap(unsigned long addr, unsigned long len, |
| 66 | unsigned long prot, unsigned long flags, | 42 | unsigned long prot, unsigned long flags, |
| 67 | unsigned long fd, unsigned long offset) | 43 | unsigned long fd, unsigned long offset) |
| @@ -70,7 +46,7 @@ long old_mmap(unsigned long addr, unsigned long len, | |||
| 70 | if (offset & ~PAGE_MASK) | 46 | if (offset & ~PAGE_MASK) |
| 71 | goto out; | 47 | goto out; |
| 72 | 48 | ||
| 73 | err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | 49 | err = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); |
| 74 | out: | 50 | out: |
| 75 | return err; | 51 | return err; |
| 76 | } | 52 | } |
diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h index 905698197e35..e7787679e317 100644 --- a/arch/um/sys-i386/shared/sysdep/syscalls.h +++ b/arch/um/sys-i386/shared/sysdep/syscalls.h | |||
| @@ -20,7 +20,3 @@ extern syscall_handler_t *sys_call_table[]; | |||
| 20 | #define EXECUTE_SYSCALL(syscall, regs) \ | 20 | #define EXECUTE_SYSCALL(syscall, regs) \ |
| 21 | ((long (*)(struct syscall_args)) \ | 21 | ((long (*)(struct syscall_args)) \ |
| 22 | (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) | 22 | (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) |
| 23 | |||
| 24 | extern long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 25 | unsigned long prot, unsigned long flags, | ||
| 26 | unsigned long fd, unsigned long pgoff); | ||
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 731318e5ac1d..bc01e3ebfeb2 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
| @@ -187,8 +187,8 @@ config HAVE_MMIOTRACE_SUPPORT | |||
| 187 | def_bool y | 187 | def_bool y |
| 188 | 188 | ||
| 189 | config X86_DECODER_SELFTEST | 189 | config X86_DECODER_SELFTEST |
| 190 | bool "x86 instruction decoder selftest" | 190 | bool "x86 instruction decoder selftest" |
| 191 | depends on DEBUG_KERNEL | 191 | depends on DEBUG_KERNEL && KPROBES |
| 192 | ---help--- | 192 | ---help--- |
| 193 | Perform x86 instruction decoder selftests at build time. | 193 | Perform x86 instruction decoder selftests at build time. |
| 194 | This option is useful for checking the sanity of x86 instruction | 194 | This option is useful for checking the sanity of x86 instruction |
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 4eefdca9832b..53147ad85b96 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
| @@ -696,7 +696,7 @@ ia32_sys_call_table: | |||
| 696 | .quad quiet_ni_syscall /* streams2 */ | 696 | .quad quiet_ni_syscall /* streams2 */ |
| 697 | .quad stub32_vfork /* 190 */ | 697 | .quad stub32_vfork /* 190 */ |
| 698 | .quad compat_sys_getrlimit | 698 | .quad compat_sys_getrlimit |
| 699 | .quad sys32_mmap2 | 699 | .quad sys_mmap_pgoff |
| 700 | .quad sys32_truncate64 | 700 | .quad sys32_truncate64 |
| 701 | .quad sys32_ftruncate64 | 701 | .quad sys32_ftruncate64 |
| 702 | .quad sys32_stat64 /* 195 */ | 702 | .quad sys32_stat64 /* 195 */ |
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index df82c0e48ded..422572c77923 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c | |||
| @@ -155,9 +155,6 @@ struct mmap_arg_struct { | |||
| 155 | asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg) | 155 | asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg) |
| 156 | { | 156 | { |
| 157 | struct mmap_arg_struct a; | 157 | struct mmap_arg_struct a; |
| 158 | struct file *file = NULL; | ||
| 159 | unsigned long retval; | ||
| 160 | struct mm_struct *mm ; | ||
| 161 | 158 | ||
| 162 | if (copy_from_user(&a, arg, sizeof(a))) | 159 | if (copy_from_user(&a, arg, sizeof(a))) |
| 163 | return -EFAULT; | 160 | return -EFAULT; |
| @@ -165,22 +162,8 @@ asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg) | |||
| 165 | if (a.offset & ~PAGE_MASK) | 162 | if (a.offset & ~PAGE_MASK) |
| 166 | return -EINVAL; | 163 | return -EINVAL; |
| 167 | 164 | ||
| 168 | if (!(a.flags & MAP_ANONYMOUS)) { | 165 | return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, |
| 169 | file = fget(a.fd); | ||
| 170 | if (!file) | ||
| 171 | return -EBADF; | ||
| 172 | } | ||
| 173 | |||
| 174 | mm = current->mm; | ||
| 175 | down_write(&mm->mmap_sem); | ||
| 176 | retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, | ||
| 177 | a.offset>>PAGE_SHIFT); | 166 | a.offset>>PAGE_SHIFT); |
| 178 | if (file) | ||
| 179 | fput(file); | ||
| 180 | |||
| 181 | up_write(&mm->mmap_sem); | ||
| 182 | |||
| 183 | return retval; | ||
| 184 | } | 167 | } |
| 185 | 168 | ||
| 186 | asmlinkage long sys32_mprotect(unsigned long start, size_t len, | 169 | asmlinkage long sys32_mprotect(unsigned long start, size_t len, |
| @@ -483,30 +466,6 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, | |||
| 483 | return ret; | 466 | return ret; |
| 484 | } | 467 | } |
| 485 | 468 | ||
| 486 | asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, | ||
| 487 | unsigned long prot, unsigned long flags, | ||
| 488 | unsigned long fd, unsigned long pgoff) | ||
| 489 | { | ||
| 490 | struct mm_struct *mm = current->mm; | ||
| 491 | unsigned long error; | ||
| 492 | struct file *file = NULL; | ||
| 493 | |||
| 494 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 495 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 496 | file = fget(fd); | ||
| 497 | if (!file) | ||
| 498 | return -EBADF; | ||
| 499 | } | ||
| 500 | |||
| 501 | down_write(&mm->mmap_sem); | ||
| 502 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 503 | up_write(&mm->mmap_sem); | ||
| 504 | |||
| 505 | if (file) | ||
| 506 | fput(file); | ||
| 507 | return error; | ||
| 508 | } | ||
| 509 | |||
| 510 | asmlinkage long sys32_olduname(struct oldold_utsname __user *name) | 469 | asmlinkage long sys32_olduname(struct oldold_utsname __user *name) |
| 511 | { | 470 | { |
| 512 | char *arch = "x86_64"; | 471 | char *arch = "x86_64"; |
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h index 84786fb9a23b..4d817f9e6e77 100644 --- a/arch/x86/include/asm/amd_iommu_proto.h +++ b/arch/x86/include/asm/amd_iommu_proto.h | |||
| @@ -28,7 +28,9 @@ extern void amd_iommu_flush_all_domains(void); | |||
| 28 | extern void amd_iommu_flush_all_devices(void); | 28 | extern void amd_iommu_flush_all_devices(void); |
| 29 | extern void amd_iommu_apply_erratum_63(u16 devid); | 29 | extern void amd_iommu_apply_erratum_63(u16 devid); |
| 30 | extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); | 30 | extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); |
| 31 | 31 | extern int amd_iommu_init_devices(void); | |
| 32 | extern void amd_iommu_uninit_devices(void); | ||
| 33 | extern void amd_iommu_init_notifier(void); | ||
| 32 | #ifndef CONFIG_AMD_IOMMU_STATS | 34 | #ifndef CONFIG_AMD_IOMMU_STATS |
| 33 | 35 | ||
| 34 | static inline void amd_iommu_stats_init(void) { } | 36 | static inline void amd_iommu_stats_init(void) { } |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index b399988eee3a..b4bf9a942ed0 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
| @@ -118,11 +118,27 @@ extern int __init pcibios_init(void); | |||
| 118 | 118 | ||
| 119 | /* pci-mmconfig.c */ | 119 | /* pci-mmconfig.c */ |
| 120 | 120 | ||
| 121 | /* "PCI MMCONFIG %04x [bus %02x-%02x]" */ | ||
| 122 | #define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2) | ||
| 123 | |||
| 124 | struct pci_mmcfg_region { | ||
| 125 | struct list_head list; | ||
| 126 | struct resource res; | ||
| 127 | u64 address; | ||
| 128 | char __iomem *virt; | ||
| 129 | u16 segment; | ||
| 130 | u8 start_bus; | ||
| 131 | u8 end_bus; | ||
| 132 | char name[PCI_MMCFG_RESOURCE_NAME_LEN]; | ||
| 133 | }; | ||
| 134 | |||
| 121 | extern int __init pci_mmcfg_arch_init(void); | 135 | extern int __init pci_mmcfg_arch_init(void); |
| 122 | extern void __init pci_mmcfg_arch_free(void); | 136 | extern void __init pci_mmcfg_arch_free(void); |
| 137 | extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); | ||
| 138 | |||
| 139 | extern struct list_head pci_mmcfg_list; | ||
| 123 | 140 | ||
| 124 | extern struct acpi_mcfg_allocation *pci_mmcfg_config; | 141 | #define PCI_MMCFG_BUS_OFFSET(bus) ((bus) << 20) |
| 125 | extern int pci_mmcfg_config_num; | ||
| 126 | 142 | ||
| 127 | /* | 143 | /* |
| 128 | * AMD Fam10h CPUs are buggy, and cannot access MMIO config space | 144 | * AMD Fam10h CPUs are buggy, and cannot access MMIO config space |
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h index 9af9decb38c3..4a5a089e1c62 100644 --- a/arch/x86/include/asm/sys_ia32.h +++ b/arch/x86/include/asm/sys_ia32.h | |||
| @@ -57,9 +57,6 @@ asmlinkage long sys32_pwrite(unsigned int, char __user *, u32, u32, u32); | |||
| 57 | asmlinkage long sys32_personality(unsigned long); | 57 | asmlinkage long sys32_personality(unsigned long); |
| 58 | asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32); | 58 | asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32); |
| 59 | 59 | ||
| 60 | asmlinkage long sys32_mmap2(unsigned long, unsigned long, unsigned long, | ||
| 61 | unsigned long, unsigned long, unsigned long); | ||
| 62 | |||
| 63 | struct oldold_utsname; | 60 | struct oldold_utsname; |
| 64 | struct old_utsname; | 61 | struct old_utsname; |
| 65 | asmlinkage long sys32_olduname(struct oldold_utsname __user *); | 62 | asmlinkage long sys32_olduname(struct oldold_utsname __user *); |
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 372b76edd63f..1bb6e395881c 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h | |||
| @@ -55,8 +55,6 @@ struct sel_arg_struct; | |||
| 55 | struct oldold_utsname; | 55 | struct oldold_utsname; |
| 56 | struct old_utsname; | 56 | struct old_utsname; |
| 57 | 57 | ||
| 58 | asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long, | ||
| 59 | unsigned long, unsigned long, unsigned long); | ||
| 60 | asmlinkage int old_mmap(struct mmap_arg_struct __user *); | 58 | asmlinkage int old_mmap(struct mmap_arg_struct __user *); |
| 61 | asmlinkage int old_select(struct sel_arg_struct __user *); | 59 | asmlinkage int old_select(struct sel_arg_struct __user *); |
| 62 | asmlinkage int sys_ipc(uint, int, int, int, void __user *, long); | 60 | asmlinkage int sys_ipc(uint, int, int, int, void __user *, long); |
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 022a84386de8..ecb544e65382 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h | |||
| @@ -23,6 +23,7 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
| 23 | struct tss_struct; | 23 | struct tss_struct; |
| 24 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | 24 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, |
| 25 | struct tss_struct *tss); | 25 | struct tss_struct *tss); |
| 26 | extern void show_regs_common(void); | ||
| 26 | 27 | ||
| 27 | #ifdef CONFIG_X86_32 | 28 | #ifdef CONFIG_X86_32 |
| 28 | 29 | ||
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index d5b7e90c0edf..396ff4cc8ed4 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h | |||
| @@ -37,31 +37,4 @@ | |||
| 37 | extern struct shared_info *HYPERVISOR_shared_info; | 37 | extern struct shared_info *HYPERVISOR_shared_info; |
| 38 | extern struct start_info *xen_start_info; | 38 | extern struct start_info *xen_start_info; |
| 39 | 39 | ||
| 40 | enum xen_domain_type { | ||
| 41 | XEN_NATIVE, /* running on bare hardware */ | ||
| 42 | XEN_PV_DOMAIN, /* running in a PV domain */ | ||
| 43 | XEN_HVM_DOMAIN, /* running in a Xen hvm domain */ | ||
| 44 | }; | ||
| 45 | |||
| 46 | #ifdef CONFIG_XEN | ||
| 47 | extern enum xen_domain_type xen_domain_type; | ||
| 48 | #else | ||
| 49 | #define xen_domain_type XEN_NATIVE | ||
| 50 | #endif | ||
| 51 | |||
| 52 | #define xen_domain() (xen_domain_type != XEN_NATIVE) | ||
| 53 | #define xen_pv_domain() (xen_domain() && \ | ||
| 54 | xen_domain_type == XEN_PV_DOMAIN) | ||
| 55 | #define xen_hvm_domain() (xen_domain() && \ | ||
| 56 | xen_domain_type == XEN_HVM_DOMAIN) | ||
| 57 | |||
| 58 | #ifdef CONFIG_XEN_DOM0 | ||
| 59 | #include <xen/interface/xen.h> | ||
| 60 | |||
| 61 | #define xen_initial_domain() (xen_pv_domain() && \ | ||
| 62 | xen_start_info->flags & SIF_INITDOMAIN) | ||
| 63 | #else /* !CONFIG_XEN_DOM0 */ | ||
| 64 | #define xen_initial_domain() (0) | ||
| 65 | #endif /* CONFIG_XEN_DOM0 */ | ||
| 66 | |||
| 67 | #endif /* _ASM_X86_XEN_HYPERVISOR_H */ | 40 | #endif /* _ASM_X86_XEN_HYPERVISOR_H */ |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 1c0fb4d4ad55..b990b5cc9541 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
| @@ -166,6 +166,43 @@ static void iommu_uninit_device(struct device *dev) | |||
| 166 | { | 166 | { |
| 167 | kfree(dev->archdata.iommu); | 167 | kfree(dev->archdata.iommu); |
| 168 | } | 168 | } |
| 169 | |||
| 170 | void __init amd_iommu_uninit_devices(void) | ||
| 171 | { | ||
| 172 | struct pci_dev *pdev = NULL; | ||
| 173 | |||
| 174 | for_each_pci_dev(pdev) { | ||
| 175 | |||
| 176 | if (!check_device(&pdev->dev)) | ||
| 177 | continue; | ||
| 178 | |||
| 179 | iommu_uninit_device(&pdev->dev); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | int __init amd_iommu_init_devices(void) | ||
| 184 | { | ||
| 185 | struct pci_dev *pdev = NULL; | ||
| 186 | int ret = 0; | ||
| 187 | |||
| 188 | for_each_pci_dev(pdev) { | ||
| 189 | |||
| 190 | if (!check_device(&pdev->dev)) | ||
| 191 | continue; | ||
| 192 | |||
| 193 | ret = iommu_init_device(&pdev->dev); | ||
| 194 | if (ret) | ||
| 195 | goto out_free; | ||
| 196 | } | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | |||
| 200 | out_free: | ||
| 201 | |||
| 202 | amd_iommu_uninit_devices(); | ||
| 203 | |||
| 204 | return ret; | ||
| 205 | } | ||
| 169 | #ifdef CONFIG_AMD_IOMMU_STATS | 206 | #ifdef CONFIG_AMD_IOMMU_STATS |
| 170 | 207 | ||
| 171 | /* | 208 | /* |
| @@ -1587,6 +1624,11 @@ static struct notifier_block device_nb = { | |||
| 1587 | .notifier_call = device_change_notifier, | 1624 | .notifier_call = device_change_notifier, |
| 1588 | }; | 1625 | }; |
| 1589 | 1626 | ||
| 1627 | void amd_iommu_init_notifier(void) | ||
| 1628 | { | ||
| 1629 | bus_register_notifier(&pci_bus_type, &device_nb); | ||
| 1630 | } | ||
| 1631 | |||
| 1590 | /***************************************************************************** | 1632 | /***************************************************************************** |
| 1591 | * | 1633 | * |
| 1592 | * The next functions belong to the dma_ops mapping/unmapping code. | 1634 | * The next functions belong to the dma_ops mapping/unmapping code. |
| @@ -2145,8 +2187,6 @@ static void prealloc_protection_domains(void) | |||
| 2145 | if (!check_device(&dev->dev)) | 2187 | if (!check_device(&dev->dev)) |
| 2146 | continue; | 2188 | continue; |
| 2147 | 2189 | ||
| 2148 | iommu_init_device(&dev->dev); | ||
| 2149 | |||
| 2150 | /* Is there already any domain for it? */ | 2190 | /* Is there already any domain for it? */ |
| 2151 | if (domain_for_device(&dev->dev)) | 2191 | if (domain_for_device(&dev->dev)) |
| 2152 | continue; | 2192 | continue; |
| @@ -2215,8 +2255,6 @@ int __init amd_iommu_init_dma_ops(void) | |||
| 2215 | 2255 | ||
| 2216 | register_iommu(&amd_iommu_ops); | 2256 | register_iommu(&amd_iommu_ops); |
| 2217 | 2257 | ||
| 2218 | bus_register_notifier(&pci_bus_type, &device_nb); | ||
| 2219 | |||
| 2220 | amd_iommu_stats_init(); | 2258 | amd_iommu_stats_init(); |
| 2221 | 2259 | ||
| 2222 | return 0; | 2260 | return 0; |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 7ffc39965233..1dca9c34eaeb 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
| @@ -1274,6 +1274,10 @@ static int __init amd_iommu_init(void) | |||
| 1274 | if (ret) | 1274 | if (ret) |
| 1275 | goto free; | 1275 | goto free; |
| 1276 | 1276 | ||
| 1277 | ret = amd_iommu_init_devices(); | ||
| 1278 | if (ret) | ||
| 1279 | goto free; | ||
| 1280 | |||
| 1277 | if (iommu_pass_through) | 1281 | if (iommu_pass_through) |
| 1278 | ret = amd_iommu_init_passthrough(); | 1282 | ret = amd_iommu_init_passthrough(); |
| 1279 | else | 1283 | else |
| @@ -1281,6 +1285,8 @@ static int __init amd_iommu_init(void) | |||
| 1281 | if (ret) | 1285 | if (ret) |
| 1282 | goto free; | 1286 | goto free; |
| 1283 | 1287 | ||
| 1288 | amd_iommu_init_notifier(); | ||
| 1289 | |||
| 1284 | enable_iommus(); | 1290 | enable_iommus(); |
| 1285 | 1291 | ||
| 1286 | if (iommu_pass_through) | 1292 | if (iommu_pass_through) |
| @@ -1296,6 +1302,9 @@ out: | |||
| 1296 | return ret; | 1302 | return ret; |
| 1297 | 1303 | ||
| 1298 | free: | 1304 | free: |
| 1305 | |||
| 1306 | amd_iommu_uninit_devices(); | ||
| 1307 | |||
| 1299 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, | 1308 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, |
| 1300 | get_order(MAX_DOMAIN_ID/8)); | 1309 | get_order(MAX_DOMAIN_ID/8)); |
| 1301 | 1310 | ||
| @@ -1336,6 +1345,9 @@ void __init amd_iommu_detect(void) | |||
| 1336 | iommu_detected = 1; | 1345 | iommu_detected = 1; |
| 1337 | amd_iommu_detected = 1; | 1346 | amd_iommu_detected = 1; |
| 1338 | x86_init.iommu.iommu_init = amd_iommu_init; | 1347 | x86_init.iommu.iommu_init = amd_iommu_init; |
| 1348 | |||
| 1349 | /* Make sure ACS will be enabled */ | ||
| 1350 | pci_request_acs(); | ||
| 1339 | } | 1351 | } |
| 1340 | } | 1352 | } |
| 1341 | 1353 | ||
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index d9acc3bee0f4..e31b9ffe25f5 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c | |||
| @@ -127,7 +127,7 @@ static u32 noop_apic_read(u32 reg) | |||
| 127 | 127 | ||
| 128 | static void noop_apic_write(u32 reg, u32 v) | 128 | static void noop_apic_write(u32 reg, u32 v) |
| 129 | { | 129 | { |
| 130 | WARN_ON_ONCE((cpu_has_apic || !disable_apic)); | 130 | WARN_ON_ONCE(cpu_has_apic && !disable_apic); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | struct apic apic_noop = { | 133 | struct apic apic_noop = { |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index e85f8fb7f8e7..dd2b5f264643 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
| @@ -27,6 +27,9 @@ | |||
| 27 | * | 27 | * |
| 28 | * http://www.unisys.com | 28 | * http://www.unisys.com |
| 29 | */ | 29 | */ |
| 30 | |||
| 31 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 32 | |||
| 30 | #include <linux/notifier.h> | 33 | #include <linux/notifier.h> |
| 31 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
| 32 | #include <linux/cpumask.h> | 35 | #include <linux/cpumask.h> |
| @@ -223,9 +226,9 @@ static int parse_unisys_oem(char *oemptr) | |||
| 223 | mip_addr = val; | 226 | mip_addr = val; |
| 224 | mip = (struct mip_reg *)val; | 227 | mip = (struct mip_reg *)val; |
| 225 | mip_reg = __va(mip); | 228 | mip_reg = __va(mip); |
| 226 | pr_debug("es7000_mipcfg: host_reg = 0x%lx \n", | 229 | pr_debug("host_reg = 0x%lx\n", |
| 227 | (unsigned long)host_reg); | 230 | (unsigned long)host_reg); |
| 228 | pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n", | 231 | pr_debug("mip_reg = 0x%lx\n", |
| 229 | (unsigned long)mip_reg); | 232 | (unsigned long)mip_reg); |
| 230 | success++; | 233 | success++; |
| 231 | break; | 234 | break; |
| @@ -401,7 +404,7 @@ static void es7000_enable_apic_mode(void) | |||
| 401 | if (!es7000_plat) | 404 | if (!es7000_plat) |
| 402 | return; | 405 | return; |
| 403 | 406 | ||
| 404 | printk(KERN_INFO "ES7000: Enabling APIC mode.\n"); | 407 | pr_info("Enabling APIC mode.\n"); |
| 405 | memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); | 408 | memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); |
| 406 | es7000_mip_reg.off_0x00 = MIP_SW_APIC; | 409 | es7000_mip_reg.off_0x00 = MIP_SW_APIC; |
| 407 | es7000_mip_reg.off_0x38 = MIP_VALID; | 410 | es7000_mip_reg.off_0x38 = MIP_VALID; |
| @@ -514,8 +517,7 @@ static void es7000_setup_apic_routing(void) | |||
| 514 | { | 517 | { |
| 515 | int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); | 518 | int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); |
| 516 | 519 | ||
| 517 | printk(KERN_INFO | 520 | pr_info("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", |
| 518 | "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", | ||
| 519 | (apic_version[apic] == 0x14) ? | 521 | (apic_version[apic] == 0x14) ? |
| 520 | "Physical Cluster" : "Logical Cluster", | 522 | "Physical Cluster" : "Logical Cluster", |
| 521 | nr_ioapics, cpumask_bits(es7000_target_cpus())[0]); | 523 | nr_ioapics, cpumask_bits(es7000_target_cpus())[0]); |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 8b581d3905cb..d2e7c77c1ea4 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
| @@ -764,14 +764,15 @@ static struct freq_attr *acpi_cpufreq_attr[] = { | |||
| 764 | }; | 764 | }; |
| 765 | 765 | ||
| 766 | static struct cpufreq_driver acpi_cpufreq_driver = { | 766 | static struct cpufreq_driver acpi_cpufreq_driver = { |
| 767 | .verify = acpi_cpufreq_verify, | 767 | .verify = acpi_cpufreq_verify, |
| 768 | .target = acpi_cpufreq_target, | 768 | .target = acpi_cpufreq_target, |
| 769 | .init = acpi_cpufreq_cpu_init, | 769 | .bios_limit = acpi_processor_get_bios_limit, |
| 770 | .exit = acpi_cpufreq_cpu_exit, | 770 | .init = acpi_cpufreq_cpu_init, |
| 771 | .resume = acpi_cpufreq_resume, | 771 | .exit = acpi_cpufreq_cpu_exit, |
| 772 | .name = "acpi-cpufreq", | 772 | .resume = acpi_cpufreq_resume, |
| 773 | .owner = THIS_MODULE, | 773 | .name = "acpi-cpufreq", |
| 774 | .attr = acpi_cpufreq_attr, | 774 | .owner = THIS_MODULE, |
| 775 | .attr = acpi_cpufreq_attr, | ||
| 775 | }; | 776 | }; |
| 776 | 777 | ||
| 777 | static int __init acpi_cpufreq_init(void) | 778 | static int __init acpi_cpufreq_init(void) |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c index f10dea409f40..cb01dac267d3 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c | |||
| @@ -164,7 +164,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /* cpuinfo and default policy values */ | 166 | /* cpuinfo and default policy values */ |
| 167 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 167 | policy->cpuinfo.transition_latency = 200000; |
| 168 | policy->cur = busfreq * max_multiplier; | 168 | policy->cur = busfreq * max_multiplier; |
| 169 | 169 | ||
| 170 | result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio); | 170 | result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio); |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index d47c775eb0ab..9a97116f89e5 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c | |||
| @@ -714,14 +714,17 @@ static struct freq_attr *powernow_table_attr[] = { | |||
| 714 | }; | 714 | }; |
| 715 | 715 | ||
| 716 | static struct cpufreq_driver powernow_driver = { | 716 | static struct cpufreq_driver powernow_driver = { |
| 717 | .verify = powernow_verify, | 717 | .verify = powernow_verify, |
| 718 | .target = powernow_target, | 718 | .target = powernow_target, |
| 719 | .get = powernow_get, | 719 | .get = powernow_get, |
| 720 | .init = powernow_cpu_init, | 720 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
| 721 | .exit = powernow_cpu_exit, | 721 | .bios_limit = acpi_processor_get_bios_limit, |
| 722 | .name = "powernow-k7", | 722 | #endif |
| 723 | .owner = THIS_MODULE, | 723 | .init = powernow_cpu_init, |
| 724 | .attr = powernow_table_attr, | 724 | .exit = powernow_cpu_exit, |
| 725 | .name = "powernow-k7", | ||
| 726 | .owner = THIS_MODULE, | ||
| 727 | .attr = powernow_table_attr, | ||
| 725 | }; | 728 | }; |
| 726 | 729 | ||
| 727 | static int __init powernow_init(void) | 730 | static int __init powernow_init(void) |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 3f12dabeab52..a9df9441a9a2 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -1118,7 +1118,7 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, | |||
| 1118 | static int powernowk8_target(struct cpufreq_policy *pol, | 1118 | static int powernowk8_target(struct cpufreq_policy *pol, |
| 1119 | unsigned targfreq, unsigned relation) | 1119 | unsigned targfreq, unsigned relation) |
| 1120 | { | 1120 | { |
| 1121 | cpumask_t oldmask; | 1121 | cpumask_var_t oldmask; |
| 1122 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1122 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
| 1123 | u32 checkfid; | 1123 | u32 checkfid; |
| 1124 | u32 checkvid; | 1124 | u32 checkvid; |
| @@ -1131,9 +1131,13 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
| 1131 | checkfid = data->currfid; | 1131 | checkfid = data->currfid; |
| 1132 | checkvid = data->currvid; | 1132 | checkvid = data->currvid; |
| 1133 | 1133 | ||
| 1134 | /* only run on specific CPU from here on */ | 1134 | /* only run on specific CPU from here on. */ |
| 1135 | oldmask = current->cpus_allowed; | 1135 | /* This is poor form: use a workqueue or smp_call_function_single */ |
| 1136 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu)); | 1136 | if (!alloc_cpumask_var(&oldmask, GFP_KERNEL)) |
| 1137 | return -ENOMEM; | ||
| 1138 | |||
| 1139 | cpumask_copy(oldmask, tsk_cpumask(current)); | ||
| 1140 | set_cpus_allowed_ptr(current, cpumask_of(pol->cpu)); | ||
| 1137 | 1141 | ||
| 1138 | if (smp_processor_id() != pol->cpu) { | 1142 | if (smp_processor_id() != pol->cpu) { |
| 1139 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); | 1143 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); |
| @@ -1193,7 +1197,8 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
| 1193 | ret = 0; | 1197 | ret = 0; |
| 1194 | 1198 | ||
| 1195 | err_out: | 1199 | err_out: |
| 1196 | set_cpus_allowed_ptr(current, &oldmask); | 1200 | set_cpus_allowed_ptr(current, oldmask); |
| 1201 | free_cpumask_var(oldmask); | ||
| 1197 | return ret; | 1202 | return ret; |
| 1198 | } | 1203 | } |
| 1199 | 1204 | ||
| @@ -1393,14 +1398,15 @@ static struct freq_attr *powernow_k8_attr[] = { | |||
| 1393 | }; | 1398 | }; |
| 1394 | 1399 | ||
| 1395 | static struct cpufreq_driver cpufreq_amd64_driver = { | 1400 | static struct cpufreq_driver cpufreq_amd64_driver = { |
| 1396 | .verify = powernowk8_verify, | 1401 | .verify = powernowk8_verify, |
| 1397 | .target = powernowk8_target, | 1402 | .target = powernowk8_target, |
| 1398 | .init = powernowk8_cpu_init, | 1403 | .bios_limit = acpi_processor_get_bios_limit, |
| 1399 | .exit = __devexit_p(powernowk8_cpu_exit), | 1404 | .init = powernowk8_cpu_init, |
| 1400 | .get = powernowk8_get, | 1405 | .exit = __devexit_p(powernowk8_cpu_exit), |
| 1401 | .name = "powernow-k8", | 1406 | .get = powernowk8_get, |
| 1402 | .owner = THIS_MODULE, | 1407 | .name = "powernow-k8", |
| 1403 | .attr = powernow_k8_attr, | 1408 | .owner = THIS_MODULE, |
| 1409 | .attr = powernow_k8_attr, | ||
| 1404 | }; | 1410 | }; |
| 1405 | 1411 | ||
| 1406 | /* driver entry point for init */ | 1412 | /* driver entry point for init */ |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index 3ae5a7a3a500..2ce8e0b5cc54 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | |||
| @@ -39,7 +39,7 @@ static struct pci_dev *speedstep_chipset_dev; | |||
| 39 | 39 | ||
| 40 | /* speedstep_processor | 40 | /* speedstep_processor |
| 41 | */ | 41 | */ |
| 42 | static unsigned int speedstep_processor; | 42 | static enum speedstep_processor speedstep_processor; |
| 43 | 43 | ||
| 44 | static u32 pmbase; | 44 | static u32 pmbase; |
| 45 | 45 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c index f4c290b8482f..ad0083abfa23 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c | |||
| @@ -34,7 +34,7 @@ static int relaxed_check; | |||
| 34 | * GET PROCESSOR CORE SPEED IN KHZ * | 34 | * GET PROCESSOR CORE SPEED IN KHZ * |
| 35 | *********************************************************************/ | 35 | *********************************************************************/ |
| 36 | 36 | ||
| 37 | static unsigned int pentium3_get_frequency(unsigned int processor) | 37 | static unsigned int pentium3_get_frequency(enum speedstep_processor processor) |
| 38 | { | 38 | { |
| 39 | /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ | 39 | /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ |
| 40 | struct { | 40 | struct { |
| @@ -227,7 +227,7 @@ static unsigned int pentium4_get_frequency(void) | |||
| 227 | 227 | ||
| 228 | 228 | ||
| 229 | /* Warning: may get called from smp_call_function_single. */ | 229 | /* Warning: may get called from smp_call_function_single. */ |
| 230 | unsigned int speedstep_get_frequency(unsigned int processor) | 230 | unsigned int speedstep_get_frequency(enum speedstep_processor processor) |
| 231 | { | 231 | { |
| 232 | switch (processor) { | 232 | switch (processor) { |
| 233 | case SPEEDSTEP_CPU_PCORE: | 233 | case SPEEDSTEP_CPU_PCORE: |
| @@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor); | |||
| 380 | * DETECT SPEEDSTEP SPEEDS * | 380 | * DETECT SPEEDSTEP SPEEDS * |
| 381 | *********************************************************************/ | 381 | *********************************************************************/ |
| 382 | 382 | ||
| 383 | unsigned int speedstep_get_freqs(unsigned int processor, | 383 | unsigned int speedstep_get_freqs(enum speedstep_processor processor, |
| 384 | unsigned int *low_speed, | 384 | unsigned int *low_speed, |
| 385 | unsigned int *high_speed, | 385 | unsigned int *high_speed, |
| 386 | unsigned int *transition_latency, | 386 | unsigned int *transition_latency, |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h index 2b6c04e5a304..70d9cea1219d 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h | |||
| @@ -11,18 +11,18 @@ | |||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | /* processors */ | 13 | /* processors */ |
| 14 | 14 | enum speedstep_processor { | |
| 15 | #define SPEEDSTEP_CPU_PIII_C_EARLY 0x00000001 /* Coppermine core */ | 15 | SPEEDSTEP_CPU_PIII_C_EARLY = 0x00000001, /* Coppermine core */ |
| 16 | #define SPEEDSTEP_CPU_PIII_C 0x00000002 /* Coppermine core */ | 16 | SPEEDSTEP_CPU_PIII_C = 0x00000002, /* Coppermine core */ |
| 17 | #define SPEEDSTEP_CPU_PIII_T 0x00000003 /* Tualatin core */ | 17 | SPEEDSTEP_CPU_PIII_T = 0x00000003, /* Tualatin core */ |
| 18 | #define SPEEDSTEP_CPU_P4M 0x00000004 /* P4-M */ | 18 | SPEEDSTEP_CPU_P4M = 0x00000004, /* P4-M */ |
| 19 | |||
| 20 | /* the following processors are not speedstep-capable and are not auto-detected | 19 | /* the following processors are not speedstep-capable and are not auto-detected |
| 21 | * in speedstep_detect_processor(). However, their speed can be detected using | 20 | * in speedstep_detect_processor(). However, their speed can be detected using |
| 22 | * the speedstep_get_frequency() call. */ | 21 | * the speedstep_get_frequency() call. */ |
| 23 | #define SPEEDSTEP_CPU_PM 0xFFFFFF03 /* Pentium M */ | 22 | SPEEDSTEP_CPU_PM = 0xFFFFFF03, /* Pentium M */ |
| 24 | #define SPEEDSTEP_CPU_P4D 0xFFFFFF04 /* desktop P4 */ | 23 | SPEEDSTEP_CPU_P4D = 0xFFFFFF04, /* desktop P4 */ |
| 25 | #define SPEEDSTEP_CPU_PCORE 0xFFFFFF05 /* Core */ | 24 | SPEEDSTEP_CPU_PCORE = 0xFFFFFF05, /* Core */ |
| 25 | }; | ||
| 26 | 26 | ||
| 27 | /* speedstep states -- only two of them */ | 27 | /* speedstep states -- only two of them */ |
| 28 | 28 | ||
| @@ -31,10 +31,10 @@ | |||
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | /* detect a speedstep-capable processor */ | 33 | /* detect a speedstep-capable processor */ |
| 34 | extern unsigned int speedstep_detect_processor (void); | 34 | extern enum speedstep_processor speedstep_detect_processor(void); |
| 35 | 35 | ||
| 36 | /* detect the current speed (in khz) of the processor */ | 36 | /* detect the current speed (in khz) of the processor */ |
| 37 | extern unsigned int speedstep_get_frequency(unsigned int processor); | 37 | extern unsigned int speedstep_get_frequency(enum speedstep_processor processor); |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | /* detect the low and high speeds of the processor. The callback | 40 | /* detect the low and high speeds of the processor. The callback |
| @@ -42,7 +42,7 @@ extern unsigned int speedstep_get_frequency(unsigned int processor); | |||
| 42 | * SPEEDSTEP_LOW; the second argument is zero so that no | 42 | * SPEEDSTEP_LOW; the second argument is zero so that no |
| 43 | * cpufreq_notify_transition calls are initiated. | 43 | * cpufreq_notify_transition calls are initiated. |
| 44 | */ | 44 | */ |
| 45 | extern unsigned int speedstep_get_freqs(unsigned int processor, | 45 | extern unsigned int speedstep_get_freqs(enum speedstep_processor processor, |
| 46 | unsigned int *low_speed, | 46 | unsigned int *low_speed, |
| 47 | unsigned int *high_speed, | 47 | unsigned int *high_speed, |
| 48 | unsigned int *transition_latency, | 48 | unsigned int *transition_latency, |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c index befea088e4f5..04d73c114e49 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c | |||
| @@ -35,7 +35,7 @@ static int smi_cmd; | |||
| 35 | static unsigned int smi_sig; | 35 | static unsigned int smi_sig; |
| 36 | 36 | ||
| 37 | /* info about the processor */ | 37 | /* info about the processor */ |
| 38 | static unsigned int speedstep_processor; | 38 | static enum speedstep_processor speedstep_processor; |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * There are only two frequency states for each processor. Values | 41 | * There are only two frequency states for each processor. Values |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index d7ebf25d10ed..a8aacd4b513c 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -1388,13 +1388,14 @@ static void __mcheck_cpu_init_timer(void) | |||
| 1388 | struct timer_list *t = &__get_cpu_var(mce_timer); | 1388 | struct timer_list *t = &__get_cpu_var(mce_timer); |
| 1389 | int *n = &__get_cpu_var(mce_next_interval); | 1389 | int *n = &__get_cpu_var(mce_next_interval); |
| 1390 | 1390 | ||
| 1391 | setup_timer(t, mce_start_timer, smp_processor_id()); | ||
| 1392 | |||
| 1391 | if (mce_ignore_ce) | 1393 | if (mce_ignore_ce) |
| 1392 | return; | 1394 | return; |
| 1393 | 1395 | ||
| 1394 | *n = check_interval * HZ; | 1396 | *n = check_interval * HZ; |
| 1395 | if (!*n) | 1397 | if (!*n) |
| 1396 | return; | 1398 | return; |
| 1397 | setup_timer(t, mce_start_timer, smp_processor_id()); | ||
| 1398 | t->expires = round_jiffies(jiffies + *n); | 1399 | t->expires = round_jiffies(jiffies + *n); |
| 1399 | add_timer_on(t, smp_processor_id()); | 1400 | add_timer_on(t, smp_processor_id()); |
| 1400 | } | 1401 | } |
| @@ -1928,7 +1929,7 @@ error2: | |||
| 1928 | sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr); | 1929 | sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr); |
| 1929 | error: | 1930 | error: |
| 1930 | while (--i >= 0) | 1931 | while (--i >= 0) |
| 1931 | sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[i].attr); | 1932 | sysdev_remove_file(&per_cpu(mce_dev, cpu), mce_attrs[i]); |
| 1932 | 1933 | ||
| 1933 | sysdev_unregister(&per_cpu(mce_dev, cpu)); | 1934 | sysdev_unregister(&per_cpu(mce_dev, cpu)); |
| 1934 | 1935 | ||
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index ab1a8a89b984..45506d5dd8df 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -1632,6 +1632,7 @@ static void intel_pmu_drain_bts_buffer(struct cpu_hw_events *cpuc) | |||
| 1632 | 1632 | ||
| 1633 | data.period = event->hw.last_period; | 1633 | data.period = event->hw.last_period; |
| 1634 | data.addr = 0; | 1634 | data.addr = 0; |
| 1635 | data.raw = NULL; | ||
| 1635 | regs.ip = 0; | 1636 | regs.ip = 0; |
| 1636 | 1637 | ||
| 1637 | /* | 1638 | /* |
| @@ -1749,6 +1750,7 @@ static int p6_pmu_handle_irq(struct pt_regs *regs) | |||
| 1749 | u64 val; | 1750 | u64 val; |
| 1750 | 1751 | ||
| 1751 | data.addr = 0; | 1752 | data.addr = 0; |
| 1753 | data.raw = NULL; | ||
| 1752 | 1754 | ||
| 1753 | cpuc = &__get_cpu_var(cpu_hw_events); | 1755 | cpuc = &__get_cpu_var(cpu_hw_events); |
| 1754 | 1756 | ||
| @@ -1794,6 +1796,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
| 1794 | u64 ack, status; | 1796 | u64 ack, status; |
| 1795 | 1797 | ||
| 1796 | data.addr = 0; | 1798 | data.addr = 0; |
| 1799 | data.raw = NULL; | ||
| 1797 | 1800 | ||
| 1798 | cpuc = &__get_cpu_var(cpu_hw_events); | 1801 | cpuc = &__get_cpu_var(cpu_hw_events); |
| 1799 | 1802 | ||
| @@ -1857,6 +1860,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs) | |||
| 1857 | u64 val; | 1860 | u64 val; |
| 1858 | 1861 | ||
| 1859 | data.addr = 0; | 1862 | data.addr = 0; |
| 1863 | data.raw = NULL; | ||
| 1860 | 1864 | ||
| 1861 | cpuc = &__get_cpu_var(cpu_hw_events); | 1865 | cpuc = &__get_cpu_var(cpu_hw_events); |
| 1862 | 1866 | ||
| @@ -2062,12 +2066,6 @@ static __init int p6_pmu_init(void) | |||
| 2062 | 2066 | ||
| 2063 | x86_pmu = p6_pmu; | 2067 | x86_pmu = p6_pmu; |
| 2064 | 2068 | ||
| 2065 | if (!cpu_has_apic) { | ||
| 2066 | pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n"); | ||
| 2067 | pr_info("no hardware sampling interrupt available.\n"); | ||
| 2068 | x86_pmu.apic = 0; | ||
| 2069 | } | ||
| 2070 | |||
| 2071 | return 0; | 2069 | return 0; |
| 2072 | } | 2070 | } |
| 2073 | 2071 | ||
| @@ -2159,6 +2157,16 @@ static __init int amd_pmu_init(void) | |||
| 2159 | return 0; | 2157 | return 0; |
| 2160 | } | 2158 | } |
| 2161 | 2159 | ||
| 2160 | static void __init pmu_check_apic(void) | ||
| 2161 | { | ||
| 2162 | if (cpu_has_apic) | ||
| 2163 | return; | ||
| 2164 | |||
| 2165 | x86_pmu.apic = 0; | ||
| 2166 | pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n"); | ||
| 2167 | pr_info("no hardware sampling interrupt available.\n"); | ||
| 2168 | } | ||
| 2169 | |||
| 2162 | void __init init_hw_perf_events(void) | 2170 | void __init init_hw_perf_events(void) |
| 2163 | { | 2171 | { |
| 2164 | int err; | 2172 | int err; |
| @@ -2180,6 +2188,8 @@ void __init init_hw_perf_events(void) | |||
| 2180 | return; | 2188 | return; |
| 2181 | } | 2189 | } |
| 2182 | 2190 | ||
| 2191 | pmu_check_apic(); | ||
| 2192 | |||
| 2183 | pr_cont("%s PMU driver.\n", x86_pmu.name); | 2193 | pr_cont("%s PMU driver.\n", x86_pmu.name); |
| 2184 | 2194 | ||
| 2185 | if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) { | 2195 | if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) { |
| @@ -2287,7 +2297,7 @@ void callchain_store(struct perf_callchain_entry *entry, u64 ip) | |||
| 2287 | 2297 | ||
| 2288 | static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry); | 2298 | static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry); |
| 2289 | static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry); | 2299 | static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry); |
| 2290 | static DEFINE_PER_CPU(int, in_nmi_frame); | 2300 | static DEFINE_PER_CPU(int, in_ignored_frame); |
| 2291 | 2301 | ||
| 2292 | 2302 | ||
| 2293 | static void | 2303 | static void |
| @@ -2303,8 +2313,9 @@ static void backtrace_warning(void *data, char *msg) | |||
| 2303 | 2313 | ||
| 2304 | static int backtrace_stack(void *data, char *name) | 2314 | static int backtrace_stack(void *data, char *name) |
| 2305 | { | 2315 | { |
| 2306 | per_cpu(in_nmi_frame, smp_processor_id()) = | 2316 | per_cpu(in_ignored_frame, smp_processor_id()) = |
| 2307 | x86_is_stack_id(NMI_STACK, name); | 2317 | x86_is_stack_id(NMI_STACK, name) || |
| 2318 | x86_is_stack_id(DEBUG_STACK, name); | ||
| 2308 | 2319 | ||
| 2309 | return 0; | 2320 | return 0; |
| 2310 | } | 2321 | } |
| @@ -2313,7 +2324,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable) | |||
| 2313 | { | 2324 | { |
| 2314 | struct perf_callchain_entry *entry = data; | 2325 | struct perf_callchain_entry *entry = data; |
| 2315 | 2326 | ||
| 2316 | if (per_cpu(in_nmi_frame, smp_processor_id())) | 2327 | if (per_cpu(in_ignored_frame, smp_processor_id())) |
| 2317 | return; | 2328 | return; |
| 2318 | 2329 | ||
| 2319 | if (reliable) | 2330 | if (reliable) |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 8e740934bd1f..b13af53883aa 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
| @@ -103,6 +103,35 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
| 103 | return NULL; | 103 | return NULL; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static inline int | ||
| 107 | in_irq_stack(unsigned long *stack, unsigned long *irq_stack, | ||
| 108 | unsigned long *irq_stack_end) | ||
| 109 | { | ||
| 110 | return (stack >= irq_stack && stack < irq_stack_end); | ||
| 111 | } | ||
| 112 | |||
| 113 | /* | ||
| 114 | * We are returning from the irq stack and go to the previous one. | ||
| 115 | * If the previous stack is also in the irq stack, then bp in the first | ||
| 116 | * frame of the irq stack points to the previous, interrupted one. | ||
| 117 | * Otherwise we have another level of indirection: We first save | ||
| 118 | * the bp of the previous stack, then we switch the stack to the irq one | ||
| 119 | * and save a new bp that links to the previous one. | ||
| 120 | * (See save_args()) | ||
| 121 | */ | ||
| 122 | static inline unsigned long | ||
| 123 | fixup_bp_irq_link(unsigned long bp, unsigned long *stack, | ||
| 124 | unsigned long *irq_stack, unsigned long *irq_stack_end) | ||
| 125 | { | ||
| 126 | #ifdef CONFIG_FRAME_POINTER | ||
| 127 | struct stack_frame *frame = (struct stack_frame *)bp; | ||
| 128 | |||
| 129 | if (!in_irq_stack(stack, irq_stack, irq_stack_end)) | ||
| 130 | return (unsigned long)frame->next_frame; | ||
| 131 | #endif | ||
| 132 | return bp; | ||
| 133 | } | ||
| 134 | |||
| 106 | /* | 135 | /* |
| 107 | * x86-64 can have up to three kernel stacks: | 136 | * x86-64 can have up to three kernel stacks: |
| 108 | * process stack | 137 | * process stack |
| @@ -175,7 +204,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
| 175 | irq_stack = irq_stack_end - | 204 | irq_stack = irq_stack_end - |
| 176 | (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack); | 205 | (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack); |
| 177 | 206 | ||
| 178 | if (stack >= irq_stack && stack < irq_stack_end) { | 207 | if (in_irq_stack(stack, irq_stack, irq_stack_end)) { |
| 179 | if (ops->stack(data, "IRQ") < 0) | 208 | if (ops->stack(data, "IRQ") < 0) |
| 180 | break; | 209 | break; |
| 181 | bp = print_context_stack(tinfo, stack, bp, | 210 | bp = print_context_stack(tinfo, stack, bp, |
| @@ -186,6 +215,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
| 186 | * pointer (index -1 to end) in the IRQ stack: | 215 | * pointer (index -1 to end) in the IRQ stack: |
| 187 | */ | 216 | */ |
| 188 | stack = (unsigned long *) (irq_stack_end[-1]); | 217 | stack = (unsigned long *) (irq_stack_end[-1]); |
| 218 | bp = fixup_bp_irq_link(bp, stack, irq_stack, | ||
| 219 | irq_stack_end); | ||
| 189 | irq_stack_end = NULL; | 220 | irq_stack_end = NULL; |
| 190 | ops->stack(data, "EOI"); | 221 | ops->stack(data, "EOI"); |
| 191 | continue; | 222 | continue; |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 63bca794c8f9..673f693fb451 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
| @@ -1076,10 +1076,10 @@ ENTRY(\sym) | |||
| 1076 | TRACE_IRQS_OFF | 1076 | TRACE_IRQS_OFF |
| 1077 | movq %rsp,%rdi /* pt_regs pointer */ | 1077 | movq %rsp,%rdi /* pt_regs pointer */ |
| 1078 | xorl %esi,%esi /* no error code */ | 1078 | xorl %esi,%esi /* no error code */ |
| 1079 | PER_CPU(init_tss, %rbp) | 1079 | PER_CPU(init_tss, %r12) |
| 1080 | subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) | 1080 | subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12) |
| 1081 | call \do_sym | 1081 | call \do_sym |
| 1082 | addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) | 1082 | addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12) |
| 1083 | jmp paranoid_exit /* %ebx: no swapgs flag */ | 1083 | jmp paranoid_exit /* %ebx: no swapgs flag */ |
| 1084 | CFI_ENDPROC | 1084 | CFI_ENDPROC |
| 1085 | END(\sym) | 1085 | END(\sym) |
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index d42f65ac4927..05d5fec64a94 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c | |||
| @@ -362,8 +362,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, | |||
| 362 | return ret; | 362 | return ret; |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | if (bp->callback) | 365 | ret = arch_store_info(bp); |
| 366 | ret = arch_store_info(bp); | ||
| 367 | 366 | ||
| 368 | if (ret < 0) | 367 | if (ret < 0) |
| 369 | return ret; | 368 | return ret; |
| @@ -519,7 +518,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
| 519 | break; | 518 | break; |
| 520 | } | 519 | } |
| 521 | 520 | ||
| 522 | (bp->callback)(bp, args->regs); | 521 | perf_bp_event(bp, args->regs); |
| 523 | 522 | ||
| 524 | rcu_read_unlock(); | 523 | rcu_read_unlock(); |
| 525 | } | 524 | } |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 20a5b3689463..dd74fe7273b1 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
| @@ -86,9 +86,15 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) | |||
| 86 | gdb_regs[GDB_DS] = regs->ds; | 86 | gdb_regs[GDB_DS] = regs->ds; |
| 87 | gdb_regs[GDB_ES] = regs->es; | 87 | gdb_regs[GDB_ES] = regs->es; |
| 88 | gdb_regs[GDB_CS] = regs->cs; | 88 | gdb_regs[GDB_CS] = regs->cs; |
| 89 | gdb_regs[GDB_SS] = __KERNEL_DS; | ||
| 90 | gdb_regs[GDB_FS] = 0xFFFF; | 89 | gdb_regs[GDB_FS] = 0xFFFF; |
| 91 | gdb_regs[GDB_GS] = 0xFFFF; | 90 | gdb_regs[GDB_GS] = 0xFFFF; |
| 91 | if (user_mode_vm(regs)) { | ||
| 92 | gdb_regs[GDB_SS] = regs->ss; | ||
| 93 | gdb_regs[GDB_SP] = regs->sp; | ||
| 94 | } else { | ||
| 95 | gdb_regs[GDB_SS] = __KERNEL_DS; | ||
| 96 | gdb_regs[GDB_SP] = kernel_stack_pointer(regs); | ||
| 97 | } | ||
| 92 | #else | 98 | #else |
| 93 | gdb_regs[GDB_R8] = regs->r8; | 99 | gdb_regs[GDB_R8] = regs->r8; |
| 94 | gdb_regs[GDB_R9] = regs->r9; | 100 | gdb_regs[GDB_R9] = regs->r9; |
| @@ -101,8 +107,8 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) | |||
| 101 | gdb_regs32[GDB_PS] = regs->flags; | 107 | gdb_regs32[GDB_PS] = regs->flags; |
| 102 | gdb_regs32[GDB_CS] = regs->cs; | 108 | gdb_regs32[GDB_CS] = regs->cs; |
| 103 | gdb_regs32[GDB_SS] = regs->ss; | 109 | gdb_regs32[GDB_SS] = regs->ss; |
| 104 | #endif | ||
| 105 | gdb_regs[GDB_SP] = kernel_stack_pointer(regs); | 110 | gdb_regs[GDB_SP] = kernel_stack_pointer(regs); |
| 111 | #endif | ||
| 106 | } | 112 | } |
| 107 | 113 | ||
| 108 | /** | 114 | /** |
| @@ -220,8 +226,7 @@ static void kgdb_correct_hw_break(void) | |||
| 220 | dr7 |= ((breakinfo[breakno].len << 2) | | 226 | dr7 |= ((breakinfo[breakno].len << 2) | |
| 221 | breakinfo[breakno].type) << | 227 | breakinfo[breakno].type) << |
| 222 | ((breakno << 2) + 16); | 228 | ((breakno << 2) + 16); |
| 223 | if (breakno >= 0 && breakno <= 3) | 229 | set_debugreg(breakinfo[breakno].addr, breakno); |
| 224 | set_debugreg(breakinfo[breakno].addr, breakno); | ||
| 225 | 230 | ||
| 226 | } else { | 231 | } else { |
| 227 | if ((dr7 & breakbit) && !breakinfo[breakno].enabled) { | 232 | if ((dr7 & breakbit) && !breakinfo[breakno].enabled) { |
| @@ -395,7 +400,6 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, | |||
| 395 | /* set the trace bit if we're stepping */ | 400 | /* set the trace bit if we're stepping */ |
| 396 | if (remcomInBuffer[0] == 's') { | 401 | if (remcomInBuffer[0] == 's') { |
| 397 | linux_regs->flags |= X86_EFLAGS_TF; | 402 | linux_regs->flags |= X86_EFLAGS_TF; |
| 398 | kgdb_single_step = 1; | ||
| 399 | atomic_set(&kgdb_cpu_doing_single_step, | 403 | atomic_set(&kgdb_cpu_doing_single_step, |
| 400 | raw_smp_processor_id()); | 404 | raw_smp_processor_id()); |
| 401 | } | 405 | } |
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 63123d902103..37542b67c57e 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
| @@ -13,6 +13,9 @@ | |||
| 13 | * Licensed under the terms of the GNU General Public | 13 | * Licensed under the terms of the GNU General Public |
| 14 | * License version 2. See file COPYING for details. | 14 | * License version 2. See file COPYING for details. |
| 15 | */ | 15 | */ |
| 16 | |||
| 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 18 | |||
| 16 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
| 17 | #include <linux/pci_ids.h> | 20 | #include <linux/pci_ids.h> |
| 18 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
| @@ -81,7 +84,7 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) | |||
| 81 | 84 | ||
| 82 | memset(csig, 0, sizeof(*csig)); | 85 | memset(csig, 0, sizeof(*csig)); |
| 83 | rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); | 86 | rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); |
| 84 | pr_info("microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev); | 87 | pr_info("CPU%d: patch_level=0x%x\n", cpu, csig->rev); |
| 85 | return 0; | 88 | return 0; |
| 86 | } | 89 | } |
| 87 | 90 | ||
| @@ -111,8 +114,8 @@ static int get_matching_microcode(int cpu, void *mc, int rev) | |||
| 111 | 114 | ||
| 112 | /* ucode might be chipset specific -- currently we don't support this */ | 115 | /* ucode might be chipset specific -- currently we don't support this */ |
| 113 | if (mc_header->nb_dev_id || mc_header->sb_dev_id) { | 116 | if (mc_header->nb_dev_id || mc_header->sb_dev_id) { |
| 114 | pr_err(KERN_ERR "microcode: CPU%d: loading of chipset " | 117 | pr_err("CPU%d: loading of chipset specific code not yet supported\n", |
| 115 | "specific code not yet supported\n", cpu); | 118 | cpu); |
| 116 | return 0; | 119 | return 0; |
| 117 | } | 120 | } |
| 118 | 121 | ||
| @@ -141,12 +144,12 @@ static int apply_microcode_amd(int cpu) | |||
| 141 | 144 | ||
| 142 | /* check current patch id and patch's id for match */ | 145 | /* check current patch id and patch's id for match */ |
| 143 | if (rev != mc_amd->hdr.patch_id) { | 146 | if (rev != mc_amd->hdr.patch_id) { |
| 144 | pr_err("microcode: CPU%d: update failed " | 147 | pr_err("CPU%d: update failed (for patch_level=0x%x)\n", |
| 145 | "(for patch_level=0x%x)\n", cpu, mc_amd->hdr.patch_id); | 148 | cpu, mc_amd->hdr.patch_id); |
| 146 | return -1; | 149 | return -1; |
| 147 | } | 150 | } |
| 148 | 151 | ||
| 149 | pr_info("microcode: CPU%d: updated (new patch_level=0x%x)\n", cpu, rev); | 152 | pr_info("CPU%d: updated (new patch_level=0x%x)\n", cpu, rev); |
| 150 | uci->cpu_sig.rev = rev; | 153 | uci->cpu_sig.rev = rev; |
| 151 | 154 | ||
| 152 | return 0; | 155 | return 0; |
| @@ -169,15 +172,14 @@ get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size) | |||
| 169 | return NULL; | 172 | return NULL; |
| 170 | 173 | ||
| 171 | if (section_hdr[0] != UCODE_UCODE_TYPE) { | 174 | if (section_hdr[0] != UCODE_UCODE_TYPE) { |
| 172 | pr_err("microcode: error: invalid type field in " | 175 | pr_err("error: invalid type field in container file section header\n"); |
| 173 | "container file section header\n"); | ||
| 174 | return NULL; | 176 | return NULL; |
| 175 | } | 177 | } |
| 176 | 178 | ||
| 177 | total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); | 179 | total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); |
| 178 | 180 | ||
| 179 | if (total_size > size || total_size > UCODE_MAX_SIZE) { | 181 | if (total_size > size || total_size > UCODE_MAX_SIZE) { |
| 180 | pr_err("microcode: error: size mismatch\n"); | 182 | pr_err("error: size mismatch\n"); |
| 181 | return NULL; | 183 | return NULL; |
| 182 | } | 184 | } |
| 183 | 185 | ||
| @@ -206,14 +208,13 @@ static int install_equiv_cpu_table(const u8 *buf) | |||
| 206 | size = buf_pos[2]; | 208 | size = buf_pos[2]; |
| 207 | 209 | ||
| 208 | if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { | 210 | if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { |
| 209 | pr_err("microcode: error: invalid type field in " | 211 | pr_err("error: invalid type field in container file section header\n"); |
| 210 | "container file section header\n"); | ||
| 211 | return 0; | 212 | return 0; |
| 212 | } | 213 | } |
| 213 | 214 | ||
| 214 | equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); | 215 | equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); |
| 215 | if (!equiv_cpu_table) { | 216 | if (!equiv_cpu_table) { |
| 216 | pr_err("microcode: failed to allocate equivalent CPU table\n"); | 217 | pr_err("failed to allocate equivalent CPU table\n"); |
| 217 | return 0; | 218 | return 0; |
| 218 | } | 219 | } |
| 219 | 220 | ||
| @@ -246,7 +247,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) | |||
| 246 | 247 | ||
| 247 | offset = install_equiv_cpu_table(ucode_ptr); | 248 | offset = install_equiv_cpu_table(ucode_ptr); |
| 248 | if (!offset) { | 249 | if (!offset) { |
| 249 | pr_err("microcode: failed to create equivalent cpu table\n"); | 250 | pr_err("failed to create equivalent cpu table\n"); |
| 250 | return UCODE_ERROR; | 251 | return UCODE_ERROR; |
| 251 | } | 252 | } |
| 252 | 253 | ||
| @@ -277,8 +278,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) | |||
| 277 | if (!leftover) { | 278 | if (!leftover) { |
| 278 | vfree(uci->mc); | 279 | vfree(uci->mc); |
| 279 | uci->mc = new_mc; | 280 | uci->mc = new_mc; |
| 280 | pr_debug("microcode: CPU%d found a matching microcode " | 281 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
| 281 | "update with version 0x%x (current=0x%x)\n", | ||
| 282 | cpu, new_rev, uci->cpu_sig.rev); | 282 | cpu, new_rev, uci->cpu_sig.rev); |
| 283 | } else { | 283 | } else { |
| 284 | vfree(new_mc); | 284 | vfree(new_mc); |
| @@ -300,7 +300,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) | |||
| 300 | return UCODE_NFOUND; | 300 | return UCODE_NFOUND; |
| 301 | 301 | ||
| 302 | if (*(u32 *)firmware->data != UCODE_MAGIC) { | 302 | if (*(u32 *)firmware->data != UCODE_MAGIC) { |
| 303 | pr_err("microcode: invalid UCODE_MAGIC (0x%08x)\n", | 303 | pr_err("invalid UCODE_MAGIC (0x%08x)\n", |
| 304 | *(u32 *)firmware->data); | 304 | *(u32 *)firmware->data); |
| 305 | return UCODE_ERROR; | 305 | return UCODE_ERROR; |
| 306 | } | 306 | } |
| @@ -313,8 +313,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) | |||
| 313 | static enum ucode_state | 313 | static enum ucode_state |
| 314 | request_microcode_user(int cpu, const void __user *buf, size_t size) | 314 | request_microcode_user(int cpu, const void __user *buf, size_t size) |
| 315 | { | 315 | { |
| 316 | pr_info("microcode: AMD microcode update via " | 316 | pr_info("AMD microcode update via /dev/cpu/microcode not supported\n"); |
| 317 | "/dev/cpu/microcode not supported\n"); | ||
| 318 | return UCODE_ERROR; | 317 | return UCODE_ERROR; |
| 319 | } | 318 | } |
| 320 | 319 | ||
| @@ -334,14 +333,13 @@ void init_microcode_amd(struct device *device) | |||
| 334 | WARN_ON(c->x86_vendor != X86_VENDOR_AMD); | 333 | WARN_ON(c->x86_vendor != X86_VENDOR_AMD); |
| 335 | 334 | ||
| 336 | if (c->x86 < 0x10) { | 335 | if (c->x86 < 0x10) { |
| 337 | pr_warning("microcode: AMD CPU family 0x%x not supported\n", | 336 | pr_warning("AMD CPU family 0x%x not supported\n", c->x86); |
| 338 | c->x86); | ||
| 339 | return; | 337 | return; |
| 340 | } | 338 | } |
| 341 | supported_cpu = 1; | 339 | supported_cpu = 1; |
| 342 | 340 | ||
| 343 | if (request_firmware(&firmware, fw_name, device)) | 341 | if (request_firmware(&firmware, fw_name, device)) |
| 344 | pr_err("microcode: failed to load file %s\n", fw_name); | 342 | pr_err("failed to load file %s\n", fw_name); |
| 345 | } | 343 | } |
| 346 | 344 | ||
| 347 | void fini_microcode_amd(void) | 345 | void fini_microcode_amd(void) |
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index e68aae397869..844c02c65fcb 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
| @@ -70,6 +70,9 @@ | |||
| 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. | 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. |
| 71 | * Thanks to Stuart Swales for pointing out this bug. | 71 | * Thanks to Stuart Swales for pointing out this bug. |
| 72 | */ | 72 | */ |
| 73 | |||
| 74 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 75 | |||
| 73 | #include <linux/platform_device.h> | 76 | #include <linux/platform_device.h> |
| 74 | #include <linux/miscdevice.h> | 77 | #include <linux/miscdevice.h> |
| 75 | #include <linux/capability.h> | 78 | #include <linux/capability.h> |
| @@ -209,7 +212,7 @@ static ssize_t microcode_write(struct file *file, const char __user *buf, | |||
| 209 | ssize_t ret = -EINVAL; | 212 | ssize_t ret = -EINVAL; |
| 210 | 213 | ||
| 211 | if ((len >> PAGE_SHIFT) > totalram_pages) { | 214 | if ((len >> PAGE_SHIFT) > totalram_pages) { |
| 212 | pr_err("microcode: too much data (max %ld pages)\n", totalram_pages); | 215 | pr_err("too much data (max %ld pages)\n", totalram_pages); |
| 213 | return ret; | 216 | return ret; |
| 214 | } | 217 | } |
| 215 | 218 | ||
| @@ -244,7 +247,7 @@ static int __init microcode_dev_init(void) | |||
| 244 | 247 | ||
| 245 | error = misc_register(µcode_dev); | 248 | error = misc_register(µcode_dev); |
| 246 | if (error) { | 249 | if (error) { |
| 247 | pr_err("microcode: can't misc_register on minor=%d\n", MICROCODE_MINOR); | 250 | pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR); |
| 248 | return error; | 251 | return error; |
| 249 | } | 252 | } |
| 250 | 253 | ||
| @@ -359,7 +362,7 @@ static enum ucode_state microcode_resume_cpu(int cpu) | |||
| 359 | if (!uci->mc) | 362 | if (!uci->mc) |
| 360 | return UCODE_NFOUND; | 363 | return UCODE_NFOUND; |
| 361 | 364 | ||
| 362 | pr_debug("microcode: CPU%d updated upon resume\n", cpu); | 365 | pr_debug("CPU%d updated upon resume\n", cpu); |
| 363 | apply_microcode_on_target(cpu); | 366 | apply_microcode_on_target(cpu); |
| 364 | 367 | ||
| 365 | return UCODE_OK; | 368 | return UCODE_OK; |
| @@ -379,7 +382,7 @@ static enum ucode_state microcode_init_cpu(int cpu) | |||
| 379 | ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev); | 382 | ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev); |
| 380 | 383 | ||
| 381 | if (ustate == UCODE_OK) { | 384 | if (ustate == UCODE_OK) { |
| 382 | pr_debug("microcode: CPU%d updated upon init\n", cpu); | 385 | pr_debug("CPU%d updated upon init\n", cpu); |
| 383 | apply_microcode_on_target(cpu); | 386 | apply_microcode_on_target(cpu); |
| 384 | } | 387 | } |
| 385 | 388 | ||
| @@ -406,7 +409,7 @@ static int mc_sysdev_add(struct sys_device *sys_dev) | |||
| 406 | if (!cpu_online(cpu)) | 409 | if (!cpu_online(cpu)) |
| 407 | return 0; | 410 | return 0; |
| 408 | 411 | ||
| 409 | pr_debug("microcode: CPU%d added\n", cpu); | 412 | pr_debug("CPU%d added\n", cpu); |
| 410 | 413 | ||
| 411 | err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); | 414 | err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); |
| 412 | if (err) | 415 | if (err) |
| @@ -425,7 +428,7 @@ static int mc_sysdev_remove(struct sys_device *sys_dev) | |||
| 425 | if (!cpu_online(cpu)) | 428 | if (!cpu_online(cpu)) |
| 426 | return 0; | 429 | return 0; |
| 427 | 430 | ||
| 428 | pr_debug("microcode: CPU%d removed\n", cpu); | 431 | pr_debug("CPU%d removed\n", cpu); |
| 429 | microcode_fini_cpu(cpu); | 432 | microcode_fini_cpu(cpu); |
| 430 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); | 433 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); |
| 431 | return 0; | 434 | return 0; |
| @@ -473,15 +476,15 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | |||
| 473 | microcode_update_cpu(cpu); | 476 | microcode_update_cpu(cpu); |
| 474 | case CPU_DOWN_FAILED: | 477 | case CPU_DOWN_FAILED: |
| 475 | case CPU_DOWN_FAILED_FROZEN: | 478 | case CPU_DOWN_FAILED_FROZEN: |
| 476 | pr_debug("microcode: CPU%d added\n", cpu); | 479 | pr_debug("CPU%d added\n", cpu); |
| 477 | if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group)) | 480 | if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group)) |
| 478 | pr_err("microcode: Failed to create group for CPU%d\n", cpu); | 481 | pr_err("Failed to create group for CPU%d\n", cpu); |
| 479 | break; | 482 | break; |
| 480 | case CPU_DOWN_PREPARE: | 483 | case CPU_DOWN_PREPARE: |
| 481 | case CPU_DOWN_PREPARE_FROZEN: | 484 | case CPU_DOWN_PREPARE_FROZEN: |
| 482 | /* Suspend is in progress, only remove the interface */ | 485 | /* Suspend is in progress, only remove the interface */ |
| 483 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); | 486 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); |
| 484 | pr_debug("microcode: CPU%d removed\n", cpu); | 487 | pr_debug("CPU%d removed\n", cpu); |
| 485 | break; | 488 | break; |
| 486 | case CPU_DEAD: | 489 | case CPU_DEAD: |
| 487 | case CPU_UP_CANCELED_FROZEN: | 490 | case CPU_UP_CANCELED_FROZEN: |
| @@ -507,7 +510,7 @@ static int __init microcode_init(void) | |||
| 507 | microcode_ops = init_amd_microcode(); | 510 | microcode_ops = init_amd_microcode(); |
| 508 | 511 | ||
| 509 | if (!microcode_ops) { | 512 | if (!microcode_ops) { |
| 510 | pr_err("microcode: no support for this CPU vendor\n"); | 513 | pr_err("no support for this CPU vendor\n"); |
| 511 | return -ENODEV; | 514 | return -ENODEV; |
| 512 | } | 515 | } |
| 513 | 516 | ||
| @@ -541,8 +544,7 @@ static int __init microcode_init(void) | |||
| 541 | register_hotcpu_notifier(&mc_cpu_notifier); | 544 | register_hotcpu_notifier(&mc_cpu_notifier); |
| 542 | 545 | ||
| 543 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION | 546 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION |
| 544 | " <tigran@aivazian.fsnet.co.uk>," | 547 | " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n"); |
| 545 | " Peter Oruba\n"); | ||
| 546 | 548 | ||
| 547 | return 0; | 549 | return 0; |
| 548 | } | 550 | } |
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 0d334ddd0a96..ebd193e476ca 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c | |||
| @@ -70,6 +70,9 @@ | |||
| 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. | 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. |
| 71 | * Thanks to Stuart Swales for pointing out this bug. | 71 | * Thanks to Stuart Swales for pointing out this bug. |
| 72 | */ | 72 | */ |
| 73 | |||
| 74 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 75 | |||
| 73 | #include <linux/firmware.h> | 76 | #include <linux/firmware.h> |
| 74 | #include <linux/uaccess.h> | 77 | #include <linux/uaccess.h> |
| 75 | #include <linux/kernel.h> | 78 | #include <linux/kernel.h> |
| @@ -146,8 +149,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | |||
| 146 | 149 | ||
| 147 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || | 150 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || |
| 148 | cpu_has(c, X86_FEATURE_IA64)) { | 151 | cpu_has(c, X86_FEATURE_IA64)) { |
| 149 | printk(KERN_ERR "microcode: CPU%d not a capable Intel " | 152 | pr_err("CPU%d not a capable Intel processor\n", cpu_num); |
| 150 | "processor\n", cpu_num); | ||
| 151 | return -1; | 153 | return -1; |
| 152 | } | 154 | } |
| 153 | 155 | ||
| @@ -165,8 +167,8 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | |||
| 165 | /* get the current revision from MSR 0x8B */ | 167 | /* get the current revision from MSR 0x8B */ |
| 166 | rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); | 168 | rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); |
| 167 | 169 | ||
| 168 | printk(KERN_INFO "microcode: CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n", | 170 | pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n", |
| 169 | cpu_num, csig->sig, csig->pf, csig->rev); | 171 | cpu_num, csig->sig, csig->pf, csig->rev); |
| 170 | 172 | ||
| 171 | return 0; | 173 | return 0; |
| 172 | } | 174 | } |
| @@ -194,28 +196,24 @@ static int microcode_sanity_check(void *mc) | |||
| 194 | data_size = get_datasize(mc_header); | 196 | data_size = get_datasize(mc_header); |
| 195 | 197 | ||
| 196 | if (data_size + MC_HEADER_SIZE > total_size) { | 198 | if (data_size + MC_HEADER_SIZE > total_size) { |
| 197 | printk(KERN_ERR "microcode: error! " | 199 | pr_err("error! Bad data size in microcode data file\n"); |
| 198 | "Bad data size in microcode data file\n"); | ||
| 199 | return -EINVAL; | 200 | return -EINVAL; |
| 200 | } | 201 | } |
| 201 | 202 | ||
| 202 | if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { | 203 | if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { |
| 203 | printk(KERN_ERR "microcode: error! " | 204 | pr_err("error! Unknown microcode update format\n"); |
| 204 | "Unknown microcode update format\n"); | ||
| 205 | return -EINVAL; | 205 | return -EINVAL; |
| 206 | } | 206 | } |
| 207 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); | 207 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); |
| 208 | if (ext_table_size) { | 208 | if (ext_table_size) { |
| 209 | if ((ext_table_size < EXT_HEADER_SIZE) | 209 | if ((ext_table_size < EXT_HEADER_SIZE) |
| 210 | || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { | 210 | || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { |
| 211 | printk(KERN_ERR "microcode: error! " | 211 | pr_err("error! Small exttable size in microcode data file\n"); |
| 212 | "Small exttable size in microcode data file\n"); | ||
| 213 | return -EINVAL; | 212 | return -EINVAL; |
| 214 | } | 213 | } |
| 215 | ext_header = mc + MC_HEADER_SIZE + data_size; | 214 | ext_header = mc + MC_HEADER_SIZE + data_size; |
| 216 | if (ext_table_size != exttable_size(ext_header)) { | 215 | if (ext_table_size != exttable_size(ext_header)) { |
| 217 | printk(KERN_ERR "microcode: error! " | 216 | pr_err("error! Bad exttable size in microcode data file\n"); |
| 218 | "Bad exttable size in microcode data file\n"); | ||
| 219 | return -EFAULT; | 217 | return -EFAULT; |
| 220 | } | 218 | } |
| 221 | ext_sigcount = ext_header->count; | 219 | ext_sigcount = ext_header->count; |
| @@ -230,8 +228,7 @@ static int microcode_sanity_check(void *mc) | |||
| 230 | while (i--) | 228 | while (i--) |
| 231 | ext_table_sum += ext_tablep[i]; | 229 | ext_table_sum += ext_tablep[i]; |
| 232 | if (ext_table_sum) { | 230 | if (ext_table_sum) { |
| 233 | printk(KERN_WARNING "microcode: aborting, " | 231 | pr_warning("aborting, bad extended signature table checksum\n"); |
| 234 | "bad extended signature table checksum\n"); | ||
| 235 | return -EINVAL; | 232 | return -EINVAL; |
| 236 | } | 233 | } |
| 237 | } | 234 | } |
| @@ -242,7 +239,7 @@ static int microcode_sanity_check(void *mc) | |||
| 242 | while (i--) | 239 | while (i--) |
| 243 | orig_sum += ((int *)mc)[i]; | 240 | orig_sum += ((int *)mc)[i]; |
| 244 | if (orig_sum) { | 241 | if (orig_sum) { |
| 245 | printk(KERN_ERR "microcode: aborting, bad checksum\n"); | 242 | pr_err("aborting, bad checksum\n"); |
| 246 | return -EINVAL; | 243 | return -EINVAL; |
| 247 | } | 244 | } |
| 248 | if (!ext_table_size) | 245 | if (!ext_table_size) |
| @@ -255,7 +252,7 @@ static int microcode_sanity_check(void *mc) | |||
| 255 | - (mc_header->sig + mc_header->pf + mc_header->cksum) | 252 | - (mc_header->sig + mc_header->pf + mc_header->cksum) |
| 256 | + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); | 253 | + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); |
| 257 | if (sum) { | 254 | if (sum) { |
| 258 | printk(KERN_ERR "microcode: aborting, bad checksum\n"); | 255 | pr_err("aborting, bad checksum\n"); |
| 259 | return -EINVAL; | 256 | return -EINVAL; |
| 260 | } | 257 | } |
| 261 | } | 258 | } |
| @@ -327,13 +324,11 @@ static int apply_microcode(int cpu) | |||
| 327 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | 324 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); |
| 328 | 325 | ||
| 329 | if (val[1] != mc_intel->hdr.rev) { | 326 | if (val[1] != mc_intel->hdr.rev) { |
| 330 | printk(KERN_ERR "microcode: CPU%d update " | 327 | pr_err("CPU%d update to revision 0x%x failed\n", |
| 331 | "to revision 0x%x failed\n", | 328 | cpu_num, mc_intel->hdr.rev); |
| 332 | cpu_num, mc_intel->hdr.rev); | ||
| 333 | return -1; | 329 | return -1; |
| 334 | } | 330 | } |
| 335 | printk(KERN_INFO "microcode: CPU%d updated to revision " | 331 | pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x \n", |
| 336 | "0x%x, date = %04x-%02x-%02x \n", | ||
| 337 | cpu_num, val[1], | 332 | cpu_num, val[1], |
| 338 | mc_intel->hdr.date & 0xffff, | 333 | mc_intel->hdr.date & 0xffff, |
| 339 | mc_intel->hdr.date >> 24, | 334 | mc_intel->hdr.date >> 24, |
| @@ -362,8 +357,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
| 362 | 357 | ||
| 363 | mc_size = get_totalsize(&mc_header); | 358 | mc_size = get_totalsize(&mc_header); |
| 364 | if (!mc_size || mc_size > leftover) { | 359 | if (!mc_size || mc_size > leftover) { |
| 365 | printk(KERN_ERR "microcode: error!" | 360 | pr_err("error! Bad data in microcode data file\n"); |
| 366 | "Bad data in microcode data file\n"); | ||
| 367 | break; | 361 | break; |
| 368 | } | 362 | } |
| 369 | 363 | ||
| @@ -405,9 +399,8 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
| 405 | vfree(uci->mc); | 399 | vfree(uci->mc); |
| 406 | uci->mc = (struct microcode_intel *)new_mc; | 400 | uci->mc = (struct microcode_intel *)new_mc; |
| 407 | 401 | ||
| 408 | pr_debug("microcode: CPU%d found a matching microcode update with" | 402 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
| 409 | " version 0x%x (current=0x%x)\n", | 403 | cpu, new_rev, uci->cpu_sig.rev); |
| 410 | cpu, new_rev, uci->cpu_sig.rev); | ||
| 411 | out: | 404 | out: |
| 412 | return state; | 405 | return state; |
| 413 | } | 406 | } |
| @@ -429,7 +422,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) | |||
| 429 | c->x86, c->x86_model, c->x86_mask); | 422 | c->x86, c->x86_model, c->x86_mask); |
| 430 | 423 | ||
| 431 | if (request_firmware(&firmware, name, device)) { | 424 | if (request_firmware(&firmware, name, device)) { |
| 432 | pr_debug("microcode: data file %s load failed\n", name); | 425 | pr_debug("data file %s load failed\n", name); |
| 433 | return UCODE_NFOUND; | 426 | return UCODE_NFOUND; |
| 434 | } | 427 | } |
| 435 | 428 | ||
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 5e2ba634ea15..7a7bd4e3ec49 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #include <linux/clockchips.h> | 10 | #include <linux/clockchips.h> |
| 11 | #include <linux/random.h> | 11 | #include <linux/random.h> |
| 12 | #include <linux/user-return-notifier.h> | 12 | #include <linux/user-return-notifier.h> |
| 13 | #include <linux/dmi.h> | ||
| 14 | #include <linux/utsname.h> | ||
| 13 | #include <trace/events/power.h> | 15 | #include <trace/events/power.h> |
| 14 | #include <linux/hw_breakpoint.h> | 16 | #include <linux/hw_breakpoint.h> |
| 15 | #include <asm/system.h> | 17 | #include <asm/system.h> |
| @@ -90,6 +92,25 @@ void exit_thread(void) | |||
| 90 | } | 92 | } |
| 91 | } | 93 | } |
| 92 | 94 | ||
| 95 | void show_regs_common(void) | ||
| 96 | { | ||
| 97 | const char *board, *product; | ||
| 98 | |||
| 99 | board = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 100 | if (!board) | ||
| 101 | board = ""; | ||
| 102 | product = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
| 103 | if (!product) | ||
| 104 | product = ""; | ||
| 105 | |||
| 106 | printk("\n"); | ||
| 107 | printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n", | ||
| 108 | current->pid, current->comm, print_tainted(), | ||
| 109 | init_utsname()->release, | ||
| 110 | (int)strcspn(init_utsname()->version, " "), | ||
| 111 | init_utsname()->version, board, product); | ||
| 112 | } | ||
| 113 | |||
| 93 | void flush_thread(void) | 114 | void flush_thread(void) |
| 94 | { | 115 | { |
| 95 | struct task_struct *tsk = current; | 116 | struct task_struct *tsk = current; |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 075580b35682..120b88797a75 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
| 24 | #include <linux/user.h> | 24 | #include <linux/user.h> |
| 25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 26 | #include <linux/utsname.h> | ||
| 27 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
| 28 | #include <linux/reboot.h> | 27 | #include <linux/reboot.h> |
| 29 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| @@ -35,7 +34,6 @@ | |||
| 35 | #include <linux/tick.h> | 34 | #include <linux/tick.h> |
| 36 | #include <linux/percpu.h> | 35 | #include <linux/percpu.h> |
| 37 | #include <linux/prctl.h> | 36 | #include <linux/prctl.h> |
| 38 | #include <linux/dmi.h> | ||
| 39 | #include <linux/ftrace.h> | 37 | #include <linux/ftrace.h> |
| 40 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
| 41 | #include <linux/io.h> | 39 | #include <linux/io.h> |
| @@ -128,7 +126,6 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 128 | unsigned long d0, d1, d2, d3, d6, d7; | 126 | unsigned long d0, d1, d2, d3, d6, d7; |
| 129 | unsigned long sp; | 127 | unsigned long sp; |
| 130 | unsigned short ss, gs; | 128 | unsigned short ss, gs; |
| 131 | const char *board; | ||
| 132 | 129 | ||
| 133 | if (user_mode_vm(regs)) { | 130 | if (user_mode_vm(regs)) { |
| 134 | sp = regs->sp; | 131 | sp = regs->sp; |
| @@ -140,16 +137,7 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 140 | savesegment(gs, gs); | 137 | savesegment(gs, gs); |
| 141 | } | 138 | } |
| 142 | 139 | ||
| 143 | printk("\n"); | 140 | show_regs_common(); |
| 144 | |||
| 145 | board = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
| 146 | if (!board) | ||
| 147 | board = ""; | ||
| 148 | printk("Pid: %d, comm: %s %s (%s %.*s) %s\n", | ||
| 149 | task_pid_nr(current), current->comm, | ||
| 150 | print_tainted(), init_utsname()->release, | ||
| 151 | (int)strcspn(init_utsname()->version, " "), | ||
| 152 | init_utsname()->version, board); | ||
| 153 | 141 | ||
| 154 | printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", | 142 | printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", |
| 155 | (u16)regs->cs, regs->ip, regs->flags, | 143 | (u16)regs->cs, regs->ip, regs->flags, |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index c95c8f4e790a..e5ab0cd0ef36 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/user.h> | 27 | #include <linux/user.h> |
| 28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| 29 | #include <linux/utsname.h> | ||
| 30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
| 31 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 32 | #include <linux/ptrace.h> | 31 | #include <linux/ptrace.h> |
| @@ -38,7 +37,6 @@ | |||
| 38 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
| 39 | #include <linux/io.h> | 38 | #include <linux/io.h> |
| 40 | #include <linux/ftrace.h> | 39 | #include <linux/ftrace.h> |
| 41 | #include <linux/dmi.h> | ||
| 42 | 40 | ||
| 43 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
| 44 | #include <asm/system.h> | 42 | #include <asm/system.h> |
| @@ -163,18 +161,8 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 163 | unsigned long d0, d1, d2, d3, d6, d7; | 161 | unsigned long d0, d1, d2, d3, d6, d7; |
| 164 | unsigned int fsindex, gsindex; | 162 | unsigned int fsindex, gsindex; |
| 165 | unsigned int ds, cs, es; | 163 | unsigned int ds, cs, es; |
| 166 | const char *board; | 164 | |
| 167 | 165 | show_regs_common(); | |
| 168 | printk("\n"); | ||
| 169 | print_modules(); | ||
| 170 | board = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
| 171 | if (!board) | ||
| 172 | board = ""; | ||
| 173 | printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n", | ||
| 174 | current->pid, current->comm, print_tainted(), | ||
| 175 | init_utsname()->release, | ||
| 176 | (int)strcspn(init_utsname()->version, " "), | ||
| 177 | init_utsname()->version, board); | ||
| 178 | printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); | 166 | printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); |
| 179 | printk_address(regs->ip, 1); | 167 | printk_address(regs->ip, 1); |
| 180 | printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, | 168 | printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 04d182a7cfdb..7079ddaf0731 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
| @@ -555,7 +555,9 @@ static int genregs_set(struct task_struct *target, | |||
| 555 | return ret; | 555 | return ret; |
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | static void ptrace_triggered(struct perf_event *bp, void *data) | 558 | static void ptrace_triggered(struct perf_event *bp, int nmi, |
| 559 | struct perf_sample_data *data, | ||
| 560 | struct pt_regs *regs) | ||
| 559 | { | 561 | { |
| 560 | int i; | 562 | int i; |
| 561 | struct thread_struct *thread = &(current->thread); | 563 | struct thread_struct *thread = &(current->thread); |
| @@ -593,13 +595,13 @@ static unsigned long ptrace_get_dr7(struct perf_event *bp[]) | |||
| 593 | return dr7; | 595 | return dr7; |
| 594 | } | 596 | } |
| 595 | 597 | ||
| 596 | static struct perf_event * | 598 | static int |
| 597 | ptrace_modify_breakpoint(struct perf_event *bp, int len, int type, | 599 | ptrace_modify_breakpoint(struct perf_event *bp, int len, int type, |
| 598 | struct task_struct *tsk, int disabled) | 600 | struct task_struct *tsk, int disabled) |
| 599 | { | 601 | { |
| 600 | int err; | 602 | int err; |
| 601 | int gen_len, gen_type; | 603 | int gen_len, gen_type; |
| 602 | DEFINE_BREAKPOINT_ATTR(attr); | 604 | struct perf_event_attr attr; |
| 603 | 605 | ||
| 604 | /* | 606 | /* |
| 605 | * We shoud have at least an inactive breakpoint at this | 607 | * We shoud have at least an inactive breakpoint at this |
| @@ -607,18 +609,18 @@ ptrace_modify_breakpoint(struct perf_event *bp, int len, int type, | |||
| 607 | * written the address register first | 609 | * written the address register first |
| 608 | */ | 610 | */ |
| 609 | if (!bp) | 611 | if (!bp) |
| 610 | return ERR_PTR(-EINVAL); | 612 | return -EINVAL; |
| 611 | 613 | ||
| 612 | err = arch_bp_generic_fields(len, type, &gen_len, &gen_type); | 614 | err = arch_bp_generic_fields(len, type, &gen_len, &gen_type); |
| 613 | if (err) | 615 | if (err) |
| 614 | return ERR_PTR(err); | 616 | return err; |
| 615 | 617 | ||
| 616 | attr = bp->attr; | 618 | attr = bp->attr; |
| 617 | attr.bp_len = gen_len; | 619 | attr.bp_len = gen_len; |
| 618 | attr.bp_type = gen_type; | 620 | attr.bp_type = gen_type; |
| 619 | attr.disabled = disabled; | 621 | attr.disabled = disabled; |
| 620 | 622 | ||
| 621 | return modify_user_hw_breakpoint(bp, &attr, bp->callback, tsk); | 623 | return modify_user_hw_breakpoint(bp, &attr); |
| 622 | } | 624 | } |
| 623 | 625 | ||
| 624 | /* | 626 | /* |
| @@ -656,28 +658,17 @@ restore: | |||
| 656 | if (!second_pass) | 658 | if (!second_pass) |
| 657 | continue; | 659 | continue; |
| 658 | 660 | ||
| 659 | thread->ptrace_bps[i] = NULL; | 661 | rc = ptrace_modify_breakpoint(bp, len, type, |
| 660 | bp = ptrace_modify_breakpoint(bp, len, type, | ||
| 661 | tsk, 1); | 662 | tsk, 1); |
| 662 | if (IS_ERR(bp)) { | 663 | if (rc) |
| 663 | rc = PTR_ERR(bp); | ||
| 664 | thread->ptrace_bps[i] = NULL; | ||
| 665 | break; | 664 | break; |
| 666 | } | ||
| 667 | thread->ptrace_bps[i] = bp; | ||
| 668 | } | 665 | } |
| 669 | continue; | 666 | continue; |
| 670 | } | 667 | } |
| 671 | 668 | ||
| 672 | bp = ptrace_modify_breakpoint(bp, len, type, tsk, 0); | 669 | rc = ptrace_modify_breakpoint(bp, len, type, tsk, 0); |
| 673 | 670 | if (rc) | |
| 674 | /* Incorrect bp, or we have a bug in bp API */ | ||
| 675 | if (IS_ERR(bp)) { | ||
| 676 | rc = PTR_ERR(bp); | ||
| 677 | thread->ptrace_bps[i] = NULL; | ||
| 678 | break; | 671 | break; |
| 679 | } | ||
| 680 | thread->ptrace_bps[i] = bp; | ||
| 681 | } | 672 | } |
| 682 | /* | 673 | /* |
| 683 | * Make a second pass to free the remaining unused breakpoints | 674 | * Make a second pass to free the remaining unused breakpoints |
| @@ -721,9 +712,10 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, | |||
| 721 | { | 712 | { |
| 722 | struct perf_event *bp; | 713 | struct perf_event *bp; |
| 723 | struct thread_struct *t = &tsk->thread; | 714 | struct thread_struct *t = &tsk->thread; |
| 724 | DEFINE_BREAKPOINT_ATTR(attr); | 715 | struct perf_event_attr attr; |
| 725 | 716 | ||
| 726 | if (!t->ptrace_bps[nr]) { | 717 | if (!t->ptrace_bps[nr]) { |
| 718 | hw_breakpoint_init(&attr); | ||
| 727 | /* | 719 | /* |
| 728 | * Put stub len and type to register (reserve) an inactive but | 720 | * Put stub len and type to register (reserve) an inactive but |
| 729 | * correct bp | 721 | * correct bp |
| @@ -734,26 +726,32 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, | |||
| 734 | attr.disabled = 1; | 726 | attr.disabled = 1; |
| 735 | 727 | ||
| 736 | bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk); | 728 | bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk); |
| 729 | |||
| 730 | /* | ||
| 731 | * CHECKME: the previous code returned -EIO if the addr wasn't | ||
| 732 | * a valid task virtual addr. The new one will return -EINVAL in | ||
| 733 | * this case. | ||
| 734 | * -EINVAL may be what we want for in-kernel breakpoints users, | ||
| 735 | * but -EIO looks better for ptrace, since we refuse a register | ||
| 736 | * writing for the user. And anyway this is the previous | ||
| 737 | * behaviour. | ||
| 738 | */ | ||
| 739 | if (IS_ERR(bp)) | ||
| 740 | return PTR_ERR(bp); | ||
| 741 | |||
| 742 | t->ptrace_bps[nr] = bp; | ||
| 737 | } else { | 743 | } else { |
| 744 | int err; | ||
| 745 | |||
| 738 | bp = t->ptrace_bps[nr]; | 746 | bp = t->ptrace_bps[nr]; |
| 739 | t->ptrace_bps[nr] = NULL; | ||
| 740 | 747 | ||
| 741 | attr = bp->attr; | 748 | attr = bp->attr; |
| 742 | attr.bp_addr = addr; | 749 | attr.bp_addr = addr; |
| 743 | bp = modify_user_hw_breakpoint(bp, &attr, bp->callback, tsk); | 750 | err = modify_user_hw_breakpoint(bp, &attr); |
| 751 | if (err) | ||
| 752 | return err; | ||
| 744 | } | 753 | } |
| 745 | /* | ||
| 746 | * CHECKME: the previous code returned -EIO if the addr wasn't a | ||
| 747 | * valid task virtual addr. The new one will return -EINVAL in this | ||
| 748 | * case. | ||
| 749 | * -EINVAL may be what we want for in-kernel breakpoints users, but | ||
| 750 | * -EIO looks better for ptrace, since we refuse a register writing | ||
| 751 | * for the user. And anyway this is the previous behaviour. | ||
| 752 | */ | ||
| 753 | if (IS_ERR(bp)) | ||
| 754 | return PTR_ERR(bp); | ||
| 755 | 754 | ||
| 756 | t->ptrace_bps[nr] = bp; | ||
| 757 | 755 | ||
| 758 | return 0; | 756 | return 0; |
| 759 | } | 757 | } |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 2b97fc5b124e..1545bc0c9845 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
| @@ -259,6 +259,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
| 259 | DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), | 259 | DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), |
| 260 | }, | 260 | }, |
| 261 | }, | 261 | }, |
| 262 | { /* Handle problems with rebooting on ASUS P4S800 */ | ||
| 263 | .callback = set_bios_reboot, | ||
| 264 | .ident = "ASUS P4S800", | ||
| 265 | .matches = { | ||
| 266 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
| 267 | DMI_MATCH(DMI_BOARD_NAME, "P4S800"), | ||
| 268 | }, | ||
| 269 | }, | ||
| 262 | { } | 270 | { } |
| 263 | }; | 271 | }; |
| 264 | 272 | ||
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index d559af913e1f..35abcb8b00e9 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 2 | |||
| 1 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 2 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 3 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| @@ -20,9 +22,9 @@ | |||
| 20 | #include <asm/stackprotector.h> | 22 | #include <asm/stackprotector.h> |
| 21 | 23 | ||
| 22 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | 24 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS |
| 23 | # define DBG(x...) printk(KERN_DEBUG x) | 25 | # define DBG(fmt, ...) pr_dbg(fmt, ##__VA_ARGS__) |
| 24 | #else | 26 | #else |
| 25 | # define DBG(x...) | 27 | # define DBG(fmt, ...) do { if (0) pr_dbg(fmt, ##__VA_ARGS__); } while (0) |
| 26 | #endif | 28 | #endif |
| 27 | 29 | ||
| 28 | DEFINE_PER_CPU(int, cpu_number); | 30 | DEFINE_PER_CPU(int, cpu_number); |
| @@ -116,8 +118,8 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, | |||
| 116 | } else { | 118 | } else { |
| 117 | ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node), | 119 | ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node), |
| 118 | size, align, goal); | 120 | size, align, goal); |
| 119 | pr_debug("per cpu data for cpu%d %lu bytes on node%d at " | 121 | pr_debug("per cpu data for cpu%d %lu bytes on node%d at %016lx\n", |
| 120 | "%016lx\n", cpu, size, node, __pa(ptr)); | 122 | cpu, size, node, __pa(ptr)); |
| 121 | } | 123 | } |
| 122 | return ptr; | 124 | return ptr; |
| 123 | #else | 125 | #else |
| @@ -198,8 +200,7 @@ void __init setup_per_cpu_areas(void) | |||
| 198 | pcpu_cpu_distance, | 200 | pcpu_cpu_distance, |
| 199 | pcpu_fc_alloc, pcpu_fc_free); | 201 | pcpu_fc_alloc, pcpu_fc_free); |
| 200 | if (rc < 0) | 202 | if (rc < 0) |
| 201 | pr_warning("PERCPU: %s allocator failed (%d), " | 203 | pr_warning("%s allocator failed (%d), falling back to page size\n", |
| 202 | "falling back to page size\n", | ||
| 203 | pcpu_fc_names[pcpu_chosen_fc], rc); | 204 | pcpu_fc_names[pcpu_chosen_fc], rc); |
| 204 | } | 205 | } |
| 205 | if (rc < 0) | 206 | if (rc < 0) |
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c index 1884a8d12bfa..dee1ff7cba58 100644 --- a/arch/x86/kernel/sys_i386_32.c +++ b/arch/x86/kernel/sys_i386_32.c | |||
| @@ -24,31 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | #include <asm/syscalls.h> | 25 | #include <asm/syscalls.h> |
| 26 | 26 | ||
| 27 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
| 28 | unsigned long prot, unsigned long flags, | ||
| 29 | unsigned long fd, unsigned long pgoff) | ||
| 30 | { | ||
| 31 | int error = -EBADF; | ||
| 32 | struct file *file = NULL; | ||
| 33 | struct mm_struct *mm = current->mm; | ||
| 34 | |||
| 35 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 36 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 37 | file = fget(fd); | ||
| 38 | if (!file) | ||
| 39 | goto out; | ||
| 40 | } | ||
| 41 | |||
| 42 | down_write(&mm->mmap_sem); | ||
| 43 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 44 | up_write(&mm->mmap_sem); | ||
| 45 | |||
| 46 | if (file) | ||
| 47 | fput(file); | ||
| 48 | out: | ||
| 49 | return error; | ||
| 50 | } | ||
| 51 | |||
| 52 | /* | 27 | /* |
| 53 | * Perform the select(nd, in, out, ex, tv) and mmap() system | 28 | * Perform the select(nd, in, out, ex, tv) and mmap() system |
| 54 | * calls. Linux/i386 didn't use to be able to handle more than | 29 | * calls. Linux/i386 didn't use to be able to handle more than |
| @@ -77,7 +52,7 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) | |||
| 77 | if (a.offset & ~PAGE_MASK) | 52 | if (a.offset & ~PAGE_MASK) |
| 78 | goto out; | 53 | goto out; |
| 79 | 54 | ||
| 80 | err = sys_mmap2(a.addr, a.len, a.prot, a.flags, | 55 | err = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, |
| 81 | a.fd, a.offset >> PAGE_SHIFT); | 56 | a.fd, a.offset >> PAGE_SHIFT); |
| 82 | out: | 57 | out: |
| 83 | return err; | 58 | return err; |
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index 45e00eb09c3a..8aa2057efd12 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c | |||
| @@ -23,26 +23,11 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, | |||
| 23 | unsigned long, fd, unsigned long, off) | 23 | unsigned long, fd, unsigned long, off) |
| 24 | { | 24 | { |
| 25 | long error; | 25 | long error; |
| 26 | struct file *file; | ||
| 27 | |||
| 28 | error = -EINVAL; | 26 | error = -EINVAL; |
| 29 | if (off & ~PAGE_MASK) | 27 | if (off & ~PAGE_MASK) |
| 30 | goto out; | 28 | goto out; |
| 31 | 29 | ||
| 32 | error = -EBADF; | 30 | error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); |
| 33 | file = NULL; | ||
| 34 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 35 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 36 | file = fget(fd); | ||
| 37 | if (!file) | ||
| 38 | goto out; | ||
| 39 | } | ||
| 40 | down_write(¤t->mm->mmap_sem); | ||
| 41 | error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT); | ||
| 42 | up_write(¤t->mm->mmap_sem); | ||
| 43 | |||
| 44 | if (file) | ||
| 45 | fput(file); | ||
| 46 | out: | 31 | out: |
| 47 | return error; | 32 | return error; |
| 48 | } | 33 | } |
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index 70c2125d55b9..15228b5d3eb7 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S | |||
| @@ -191,7 +191,7 @@ ENTRY(sys_call_table) | |||
| 191 | .long sys_ni_syscall /* reserved for streams2 */ | 191 | .long sys_ni_syscall /* reserved for streams2 */ |
| 192 | .long ptregs_vfork /* 190 */ | 192 | .long ptregs_vfork /* 190 */ |
| 193 | .long sys_getrlimit | 193 | .long sys_getrlimit |
| 194 | .long sys_mmap2 | 194 | .long sys_mmap_pgoff |
| 195 | .long sys_truncate64 | 195 | .long sys_truncate64 |
| 196 | .long sys_ftruncate64 | 196 | .long sys_ftruncate64 |
| 197 | .long sys_stat64 /* 195 */ | 197 | .long sys_stat64 /* 195 */ |
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index fab7440c9bb2..296aba49472a 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | * Based on QEMU and Xen. | 29 | * Based on QEMU and Xen. |
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | #define pr_fmt(fmt) "pit: " fmt | ||
| 33 | |||
| 32 | #include <linux/kvm_host.h> | 34 | #include <linux/kvm_host.h> |
| 33 | 35 | ||
| 34 | #include "irq.h" | 36 | #include "irq.h" |
| @@ -262,7 +264,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) | |||
| 262 | 264 | ||
| 263 | static void destroy_pit_timer(struct kvm_timer *pt) | 265 | static void destroy_pit_timer(struct kvm_timer *pt) |
| 264 | { | 266 | { |
| 265 | pr_debug("pit: execute del timer!\n"); | 267 | pr_debug("execute del timer!\n"); |
| 266 | hrtimer_cancel(&pt->timer); | 268 | hrtimer_cancel(&pt->timer); |
| 267 | } | 269 | } |
| 268 | 270 | ||
| @@ -284,7 +286,7 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) | |||
| 284 | 286 | ||
| 285 | interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); | 287 | interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); |
| 286 | 288 | ||
| 287 | pr_debug("pit: create pit timer, interval is %llu nsec\n", interval); | 289 | pr_debug("create pit timer, interval is %llu nsec\n", interval); |
| 288 | 290 | ||
| 289 | /* TODO The new value only affected after the retriggered */ | 291 | /* TODO The new value only affected after the retriggered */ |
| 290 | hrtimer_cancel(&pt->timer); | 292 | hrtimer_cancel(&pt->timer); |
| @@ -309,7 +311,7 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val) | |||
| 309 | 311 | ||
| 310 | WARN_ON(!mutex_is_locked(&ps->lock)); | 312 | WARN_ON(!mutex_is_locked(&ps->lock)); |
| 311 | 313 | ||
| 312 | pr_debug("pit: load_count val is %d, channel is %d\n", val, channel); | 314 | pr_debug("load_count val is %d, channel is %d\n", val, channel); |
| 313 | 315 | ||
| 314 | /* | 316 | /* |
| 315 | * The largest possible initial count is 0; this is equivalent | 317 | * The largest possible initial count is 0; this is equivalent |
| @@ -395,8 +397,8 @@ static int pit_ioport_write(struct kvm_io_device *this, | |||
| 395 | mutex_lock(&pit_state->lock); | 397 | mutex_lock(&pit_state->lock); |
| 396 | 398 | ||
| 397 | if (val != 0) | 399 | if (val != 0) |
| 398 | pr_debug("pit: write addr is 0x%x, len is %d, val is 0x%x\n", | 400 | pr_debug("write addr is 0x%x, len is %d, val is 0x%x\n", |
| 399 | (unsigned int)addr, len, val); | 401 | (unsigned int)addr, len, val); |
| 400 | 402 | ||
| 401 | if (addr == 3) { | 403 | if (addr == 3) { |
| 402 | channel = val >> 6; | 404 | channel = val >> 6; |
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index a2d6472895fb..45b20e486c2f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk | 5 | inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk |
| 6 | inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt | 6 | inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt |
| 7 | quiet_cmd_inat_tables = GEN $@ | 7 | quiet_cmd_inat_tables = GEN $@ |
| 8 | cmd_inat_tables = $(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ | 8 | cmd_inat_tables = $(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ || rm -f $@ |
| 9 | 9 | ||
| 10 | $(obj)/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) | 10 | $(obj)/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) |
| 11 | $(call cmd,inat_tables) | 11 | $(call cmd,inat_tables) |
| @@ -20,7 +20,7 @@ lib-y := delay.o | |||
| 20 | lib-y += thunk_$(BITS).o | 20 | lib-y += thunk_$(BITS).o |
| 21 | lib-y += usercopy_$(BITS).o getuser.o putuser.o | 21 | lib-y += usercopy_$(BITS).o getuser.o putuser.o |
| 22 | lib-y += memcpy_$(BITS).o | 22 | lib-y += memcpy_$(BITS).o |
| 23 | lib-y += insn.o inat.o | 23 | lib-$(CONFIG_KPROBES) += insn.o inat.o |
| 24 | 24 | ||
| 25 | obj-y += msr-reg.o msr-reg-export.o | 25 | obj-y += msr-reg.o msr-reg-export.o |
| 26 | 26 | ||
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 07bcc309cfda..c0f6198565eb 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | * 2008 Pekka Paalanen <pq@iki.fi> | 5 | * 2008 Pekka Paalanen <pq@iki.fi> |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 9 | |||
| 8 | #include <linux/list.h> | 10 | #include <linux/list.h> |
| 9 | #include <linux/rculist.h> | 11 | #include <linux/rculist.h> |
| 10 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
| @@ -136,7 +138,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) | |||
| 136 | pte_t *pte = lookup_address(f->page, &level); | 138 | pte_t *pte = lookup_address(f->page, &level); |
| 137 | 139 | ||
| 138 | if (!pte) { | 140 | if (!pte) { |
| 139 | pr_err("kmmio: no pte for page 0x%08lx\n", f->page); | 141 | pr_err("no pte for page 0x%08lx\n", f->page); |
| 140 | return -1; | 142 | return -1; |
| 141 | } | 143 | } |
| 142 | 144 | ||
| @@ -148,7 +150,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) | |||
| 148 | clear_pte_presence(pte, clear, &f->old_presence); | 150 | clear_pte_presence(pte, clear, &f->old_presence); |
| 149 | break; | 151 | break; |
| 150 | default: | 152 | default: |
| 151 | pr_err("kmmio: unexpected page level 0x%x.\n", level); | 153 | pr_err("unexpected page level 0x%x.\n", level); |
| 152 | return -1; | 154 | return -1; |
| 153 | } | 155 | } |
| 154 | 156 | ||
| @@ -170,13 +172,14 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) | |||
| 170 | static int arm_kmmio_fault_page(struct kmmio_fault_page *f) | 172 | static int arm_kmmio_fault_page(struct kmmio_fault_page *f) |
| 171 | { | 173 | { |
| 172 | int ret; | 174 | int ret; |
| 173 | WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n"); | 175 | WARN_ONCE(f->armed, KERN_ERR pr_fmt("kmmio page already armed.\n")); |
| 174 | if (f->armed) { | 176 | if (f->armed) { |
| 175 | pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n", | 177 | pr_warning("double-arm: page 0x%08lx, ref %d, old %d\n", |
| 176 | f->page, f->count, !!f->old_presence); | 178 | f->page, f->count, !!f->old_presence); |
| 177 | } | 179 | } |
| 178 | ret = clear_page_presence(f, true); | 180 | ret = clear_page_presence(f, true); |
| 179 | WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page); | 181 | WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming 0x%08lx failed.\n"), |
| 182 | f->page); | ||
| 180 | f->armed = true; | 183 | f->armed = true; |
| 181 | return ret; | 184 | return ret; |
| 182 | } | 185 | } |
| @@ -240,24 +243,21 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) | |||
| 240 | * condition needs handling by do_page_fault(), the | 243 | * condition needs handling by do_page_fault(), the |
| 241 | * page really not being present is the most common. | 244 | * page really not being present is the most common. |
| 242 | */ | 245 | */ |
| 243 | pr_debug("kmmio: secondary hit for 0x%08lx CPU %d.\n", | 246 | pr_debug("secondary hit for 0x%08lx CPU %d.\n", |
| 244 | addr, smp_processor_id()); | 247 | addr, smp_processor_id()); |
| 245 | 248 | ||
| 246 | if (!faultpage->old_presence) | 249 | if (!faultpage->old_presence) |
| 247 | pr_info("kmmio: unexpected secondary hit for " | 250 | pr_info("unexpected secondary hit for address 0x%08lx on CPU %d.\n", |
| 248 | "address 0x%08lx on CPU %d.\n", addr, | 251 | addr, smp_processor_id()); |
| 249 | smp_processor_id()); | ||
| 250 | } else { | 252 | } else { |
| 251 | /* | 253 | /* |
| 252 | * Prevent overwriting already in-flight context. | 254 | * Prevent overwriting already in-flight context. |
| 253 | * This should not happen, let's hope disarming at | 255 | * This should not happen, let's hope disarming at |
| 254 | * least prevents a panic. | 256 | * least prevents a panic. |
| 255 | */ | 257 | */ |
| 256 | pr_emerg("kmmio: recursive probe hit on CPU %d, " | 258 | pr_emerg("recursive probe hit on CPU %d, for address 0x%08lx. Ignoring.\n", |
| 257 | "for address 0x%08lx. Ignoring.\n", | 259 | smp_processor_id(), addr); |
| 258 | smp_processor_id(), addr); | 260 | pr_emerg("previous hit was at 0x%08lx.\n", ctx->addr); |
| 259 | pr_emerg("kmmio: previous hit was at 0x%08lx.\n", | ||
| 260 | ctx->addr); | ||
| 261 | disarm_kmmio_fault_page(faultpage); | 261 | disarm_kmmio_fault_page(faultpage); |
| 262 | } | 262 | } |
| 263 | goto no_kmmio_ctx; | 263 | goto no_kmmio_ctx; |
| @@ -316,8 +316,8 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) | |||
| 316 | * something external causing them (f.e. using a debugger while | 316 | * something external causing them (f.e. using a debugger while |
| 317 | * mmio tracing enabled), or erroneous behaviour | 317 | * mmio tracing enabled), or erroneous behaviour |
| 318 | */ | 318 | */ |
| 319 | pr_warning("kmmio: unexpected debug trap on CPU %d.\n", | 319 | pr_warning("unexpected debug trap on CPU %d.\n", |
| 320 | smp_processor_id()); | 320 | smp_processor_id()); |
| 321 | goto out; | 321 | goto out; |
| 322 | } | 322 | } |
| 323 | 323 | ||
| @@ -425,7 +425,7 @@ int register_kmmio_probe(struct kmmio_probe *p) | |||
| 425 | list_add_rcu(&p->list, &kmmio_probes); | 425 | list_add_rcu(&p->list, &kmmio_probes); |
| 426 | while (size < size_lim) { | 426 | while (size < size_lim) { |
| 427 | if (add_kmmio_fault_page(p->addr + size)) | 427 | if (add_kmmio_fault_page(p->addr + size)) |
| 428 | pr_err("kmmio: Unable to set page fault.\n"); | 428 | pr_err("Unable to set page fault.\n"); |
| 429 | size += PAGE_SIZE; | 429 | size += PAGE_SIZE; |
| 430 | } | 430 | } |
| 431 | out: | 431 | out: |
| @@ -490,7 +490,7 @@ static void remove_kmmio_fault_pages(struct rcu_head *head) | |||
| 490 | * 2. remove_kmmio_fault_pages() | 490 | * 2. remove_kmmio_fault_pages() |
| 491 | * Remove the pages from kmmio_page_table. | 491 | * Remove the pages from kmmio_page_table. |
| 492 | * 3. rcu_free_kmmio_fault_pages() | 492 | * 3. rcu_free_kmmio_fault_pages() |
| 493 | * Actally free the kmmio_fault_page structs as with RCU. | 493 | * Actually free the kmmio_fault_page structs as with RCU. |
| 494 | */ | 494 | */ |
| 495 | void unregister_kmmio_probe(struct kmmio_probe *p) | 495 | void unregister_kmmio_probe(struct kmmio_probe *p) |
| 496 | { | 496 | { |
| @@ -511,7 +511,7 @@ void unregister_kmmio_probe(struct kmmio_probe *p) | |||
| 511 | 511 | ||
| 512 | drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); | 512 | drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); |
| 513 | if (!drelease) { | 513 | if (!drelease) { |
| 514 | pr_crit("kmmio: leaking kmmio_fault_page objects.\n"); | 514 | pr_crit("leaking kmmio_fault_page objects.\n"); |
| 515 | return; | 515 | return; |
| 516 | } | 516 | } |
| 517 | drelease->release_list = release_list; | 517 | drelease->release_list = release_list; |
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 132772a8ec57..4c765e9c4664 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c | |||
| @@ -19,6 +19,9 @@ | |||
| 19 | * | 19 | * |
| 20 | * Derived from the read-mod example from relay-examples by Tom Zanussi. | 20 | * Derived from the read-mod example from relay-examples by Tom Zanussi. |
| 21 | */ | 21 | */ |
| 22 | |||
| 23 | #define pr_fmt(fmt) "mmiotrace: " | ||
| 24 | |||
| 22 | #define DEBUG 1 | 25 | #define DEBUG 1 |
| 23 | 26 | ||
| 24 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| @@ -36,8 +39,6 @@ | |||
| 36 | 39 | ||
| 37 | #include "pf_in.h" | 40 | #include "pf_in.h" |
| 38 | 41 | ||
| 39 | #define NAME "mmiotrace: " | ||
| 40 | |||
| 41 | struct trap_reason { | 42 | struct trap_reason { |
| 42 | unsigned long addr; | 43 | unsigned long addr; |
| 43 | unsigned long ip; | 44 | unsigned long ip; |
| @@ -96,17 +97,18 @@ static void print_pte(unsigned long address) | |||
| 96 | pte_t *pte = lookup_address(address, &level); | 97 | pte_t *pte = lookup_address(address, &level); |
| 97 | 98 | ||
| 98 | if (!pte) { | 99 | if (!pte) { |
| 99 | pr_err(NAME "Error in %s: no pte for page 0x%08lx\n", | 100 | pr_err("Error in %s: no pte for page 0x%08lx\n", |
| 100 | __func__, address); | 101 | __func__, address); |
| 101 | return; | 102 | return; |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | if (level == PG_LEVEL_2M) { | 105 | if (level == PG_LEVEL_2M) { |
| 105 | pr_emerg(NAME "4MB pages are not currently supported: " | 106 | pr_emerg("4MB pages are not currently supported: 0x%08lx\n", |
| 106 | "0x%08lx\n", address); | 107 | address); |
| 107 | BUG(); | 108 | BUG(); |
| 108 | } | 109 | } |
| 109 | pr_info(NAME "pte for 0x%lx: 0x%llx 0x%llx\n", address, | 110 | pr_info("pte for 0x%lx: 0x%llx 0x%llx\n", |
| 111 | address, | ||
| 110 | (unsigned long long)pte_val(*pte), | 112 | (unsigned long long)pte_val(*pte), |
| 111 | (unsigned long long)pte_val(*pte) & _PAGE_PRESENT); | 113 | (unsigned long long)pte_val(*pte) & _PAGE_PRESENT); |
| 112 | } | 114 | } |
| @@ -118,22 +120,21 @@ static void print_pte(unsigned long address) | |||
| 118 | static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) | 120 | static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) |
| 119 | { | 121 | { |
| 120 | const struct trap_reason *my_reason = &get_cpu_var(pf_reason); | 122 | const struct trap_reason *my_reason = &get_cpu_var(pf_reason); |
| 121 | pr_emerg(NAME "unexpected fault for address: 0x%08lx, " | 123 | pr_emerg("unexpected fault for address: 0x%08lx, last fault for address: 0x%08lx\n", |
| 122 | "last fault for address: 0x%08lx\n", | 124 | addr, my_reason->addr); |
| 123 | addr, my_reason->addr); | ||
| 124 | print_pte(addr); | 125 | print_pte(addr); |
| 125 | print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); | 126 | print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); |
| 126 | print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); | 127 | print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); |
| 127 | #ifdef __i386__ | 128 | #ifdef __i386__ |
| 128 | pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", | 129 | pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", |
| 129 | regs->ax, regs->bx, regs->cx, regs->dx); | 130 | regs->ax, regs->bx, regs->cx, regs->dx); |
| 130 | pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", | 131 | pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", |
| 131 | regs->si, regs->di, regs->bp, regs->sp); | 132 | regs->si, regs->di, regs->bp, regs->sp); |
| 132 | #else | 133 | #else |
| 133 | pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", | 134 | pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", |
| 134 | regs->ax, regs->cx, regs->dx); | 135 | regs->ax, regs->cx, regs->dx); |
| 135 | pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", | 136 | pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", |
| 136 | regs->si, regs->di, regs->bp, regs->sp); | 137 | regs->si, regs->di, regs->bp, regs->sp); |
| 137 | #endif | 138 | #endif |
| 138 | put_cpu_var(pf_reason); | 139 | put_cpu_var(pf_reason); |
| 139 | BUG(); | 140 | BUG(); |
| @@ -213,7 +214,7 @@ static void post(struct kmmio_probe *p, unsigned long condition, | |||
| 213 | /* this should always return the active_trace count to 0 */ | 214 | /* this should always return the active_trace count to 0 */ |
| 214 | my_reason->active_traces--; | 215 | my_reason->active_traces--; |
| 215 | if (my_reason->active_traces) { | 216 | if (my_reason->active_traces) { |
| 216 | pr_emerg(NAME "unexpected post handler"); | 217 | pr_emerg("unexpected post handler"); |
| 217 | BUG(); | 218 | BUG(); |
| 218 | } | 219 | } |
| 219 | 220 | ||
| @@ -244,7 +245,7 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size, | |||
| 244 | }; | 245 | }; |
| 245 | 246 | ||
| 246 | if (!trace) { | 247 | if (!trace) { |
| 247 | pr_err(NAME "kmalloc failed in ioremap\n"); | 248 | pr_err("kmalloc failed in ioremap\n"); |
| 248 | return; | 249 | return; |
| 249 | } | 250 | } |
| 250 | 251 | ||
| @@ -282,8 +283,8 @@ void mmiotrace_ioremap(resource_size_t offset, unsigned long size, | |||
| 282 | if (!is_enabled()) /* recheck and proper locking in *_core() */ | 283 | if (!is_enabled()) /* recheck and proper locking in *_core() */ |
| 283 | return; | 284 | return; |
| 284 | 285 | ||
| 285 | pr_debug(NAME "ioremap_*(0x%llx, 0x%lx) = %p\n", | 286 | pr_debug("ioremap_*(0x%llx, 0x%lx) = %p\n", |
| 286 | (unsigned long long)offset, size, addr); | 287 | (unsigned long long)offset, size, addr); |
| 287 | if ((filter_offset) && (offset != filter_offset)) | 288 | if ((filter_offset) && (offset != filter_offset)) |
| 288 | return; | 289 | return; |
| 289 | ioremap_trace_core(offset, size, addr); | 290 | ioremap_trace_core(offset, size, addr); |
| @@ -301,7 +302,7 @@ static void iounmap_trace_core(volatile void __iomem *addr) | |||
| 301 | struct remap_trace *tmp; | 302 | struct remap_trace *tmp; |
| 302 | struct remap_trace *found_trace = NULL; | 303 | struct remap_trace *found_trace = NULL; |
| 303 | 304 | ||
| 304 | pr_debug(NAME "Unmapping %p.\n", addr); | 305 | pr_debug("Unmapping %p.\n", addr); |
| 305 | 306 | ||
| 306 | spin_lock_irq(&trace_lock); | 307 | spin_lock_irq(&trace_lock); |
| 307 | if (!is_enabled()) | 308 | if (!is_enabled()) |
| @@ -363,9 +364,8 @@ static void clear_trace_list(void) | |||
| 363 | * Caller also ensures is_enabled() cannot change. | 364 | * Caller also ensures is_enabled() cannot change. |
| 364 | */ | 365 | */ |
| 365 | list_for_each_entry(trace, &trace_list, list) { | 366 | list_for_each_entry(trace, &trace_list, list) { |
| 366 | pr_notice(NAME "purging non-iounmapped " | 367 | pr_notice("purging non-iounmapped trace @0x%08lx, size 0x%lx.\n", |
| 367 | "trace @0x%08lx, size 0x%lx.\n", | 368 | trace->probe.addr, trace->probe.len); |
| 368 | trace->probe.addr, trace->probe.len); | ||
| 369 | if (!nommiotrace) | 369 | if (!nommiotrace) |
| 370 | unregister_kmmio_probe(&trace->probe); | 370 | unregister_kmmio_probe(&trace->probe); |
| 371 | } | 371 | } |
| @@ -387,7 +387,7 @@ static void enter_uniprocessor(void) | |||
| 387 | 387 | ||
| 388 | if (downed_cpus == NULL && | 388 | if (downed_cpus == NULL && |
| 389 | !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { | 389 | !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { |
| 390 | pr_notice(NAME "Failed to allocate mask\n"); | 390 | pr_notice("Failed to allocate mask\n"); |
| 391 | goto out; | 391 | goto out; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| @@ -395,20 +395,19 @@ static void enter_uniprocessor(void) | |||
| 395 | cpumask_copy(downed_cpus, cpu_online_mask); | 395 | cpumask_copy(downed_cpus, cpu_online_mask); |
| 396 | cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus); | 396 | cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus); |
| 397 | if (num_online_cpus() > 1) | 397 | if (num_online_cpus() > 1) |
| 398 | pr_notice(NAME "Disabling non-boot CPUs...\n"); | 398 | pr_notice("Disabling non-boot CPUs...\n"); |
| 399 | put_online_cpus(); | 399 | put_online_cpus(); |
| 400 | 400 | ||
| 401 | for_each_cpu(cpu, downed_cpus) { | 401 | for_each_cpu(cpu, downed_cpus) { |
| 402 | err = cpu_down(cpu); | 402 | err = cpu_down(cpu); |
| 403 | if (!err) | 403 | if (!err) |
| 404 | pr_info(NAME "CPU%d is down.\n", cpu); | 404 | pr_info("CPU%d is down.\n", cpu); |
| 405 | else | 405 | else |
| 406 | pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err); | 406 | pr_err("Error taking CPU%d down: %d\n", cpu, err); |
| 407 | } | 407 | } |
| 408 | out: | 408 | out: |
| 409 | if (num_online_cpus() > 1) | 409 | if (num_online_cpus() > 1) |
| 410 | pr_warning(NAME "multiple CPUs still online, " | 410 | pr_warning("multiple CPUs still online, may miss events.\n"); |
| 411 | "may miss events.\n"); | ||
| 412 | } | 411 | } |
| 413 | 412 | ||
| 414 | /* __ref because leave_uniprocessor calls cpu_up which is __cpuinit, | 413 | /* __ref because leave_uniprocessor calls cpu_up which is __cpuinit, |
| @@ -420,13 +419,13 @@ static void __ref leave_uniprocessor(void) | |||
| 420 | 419 | ||
| 421 | if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) | 420 | if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) |
| 422 | return; | 421 | return; |
| 423 | pr_notice(NAME "Re-enabling CPUs...\n"); | 422 | pr_notice("Re-enabling CPUs...\n"); |
| 424 | for_each_cpu(cpu, downed_cpus) { | 423 | for_each_cpu(cpu, downed_cpus) { |
| 425 | err = cpu_up(cpu); | 424 | err = cpu_up(cpu); |
| 426 | if (!err) | 425 | if (!err) |
| 427 | pr_info(NAME "enabled CPU%d.\n", cpu); | 426 | pr_info("enabled CPU%d.\n", cpu); |
| 428 | else | 427 | else |
| 429 | pr_err(NAME "cannot re-enable CPU%d: %d\n", cpu, err); | 428 | pr_err("cannot re-enable CPU%d: %d\n", cpu, err); |
| 430 | } | 429 | } |
| 431 | } | 430 | } |
| 432 | 431 | ||
| @@ -434,8 +433,8 @@ static void __ref leave_uniprocessor(void) | |||
| 434 | static void enter_uniprocessor(void) | 433 | static void enter_uniprocessor(void) |
| 435 | { | 434 | { |
| 436 | if (num_online_cpus() > 1) | 435 | if (num_online_cpus() > 1) |
| 437 | pr_warning(NAME "multiple CPUs are online, may miss events. " | 436 | pr_warning("multiple CPUs are online, may miss events. " |
| 438 | "Suggest booting with maxcpus=1 kernel argument.\n"); | 437 | "Suggest booting with maxcpus=1 kernel argument.\n"); |
| 439 | } | 438 | } |
| 440 | 439 | ||
| 441 | static void leave_uniprocessor(void) | 440 | static void leave_uniprocessor(void) |
| @@ -450,13 +449,13 @@ void enable_mmiotrace(void) | |||
| 450 | goto out; | 449 | goto out; |
| 451 | 450 | ||
| 452 | if (nommiotrace) | 451 | if (nommiotrace) |
| 453 | pr_info(NAME "MMIO tracing disabled.\n"); | 452 | pr_info("MMIO tracing disabled.\n"); |
| 454 | kmmio_init(); | 453 | kmmio_init(); |
| 455 | enter_uniprocessor(); | 454 | enter_uniprocessor(); |
| 456 | spin_lock_irq(&trace_lock); | 455 | spin_lock_irq(&trace_lock); |
| 457 | atomic_inc(&mmiotrace_enabled); | 456 | atomic_inc(&mmiotrace_enabled); |
| 458 | spin_unlock_irq(&trace_lock); | 457 | spin_unlock_irq(&trace_lock); |
| 459 | pr_info(NAME "enabled.\n"); | 458 | pr_info("enabled.\n"); |
| 460 | out: | 459 | out: |
| 461 | mutex_unlock(&mmiotrace_mutex); | 460 | mutex_unlock(&mmiotrace_mutex); |
| 462 | } | 461 | } |
| @@ -475,7 +474,7 @@ void disable_mmiotrace(void) | |||
| 475 | clear_trace_list(); /* guarantees: no more kmmio callbacks */ | 474 | clear_trace_list(); /* guarantees: no more kmmio callbacks */ |
| 476 | leave_uniprocessor(); | 475 | leave_uniprocessor(); |
| 477 | kmmio_cleanup(); | 476 | kmmio_cleanup(); |
| 478 | pr_info(NAME "disabled.\n"); | 477 | pr_info("disabled.\n"); |
| 479 | out: | 478 | out: |
| 480 | mutex_unlock(&mmiotrace_mutex); | 479 | mutex_unlock(&mmiotrace_mutex); |
| 481 | } | 480 | } |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 66b55d6e69ed..ae9648eb1c7f 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
| @@ -704,9 +704,8 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | |||
| 704 | if (!range_is_allowed(pfn, size)) | 704 | if (!range_is_allowed(pfn, size)) |
| 705 | return 0; | 705 | return 0; |
| 706 | 706 | ||
| 707 | if (file->f_flags & O_SYNC) { | 707 | if (file->f_flags & O_DSYNC) |
| 708 | flags = _PAGE_CACHE_UC_MINUS; | 708 | flags = _PAGE_CACHE_UC_MINUS; |
| 709 | } | ||
| 710 | 709 | ||
| 711 | #ifdef CONFIG_X86_32 | 710 | #ifdef CONFIG_X86_32 |
| 712 | /* | 711 | /* |
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index d49202e740ea..564b008a51c7 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile | |||
| @@ -15,3 +15,8 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o | |||
| 15 | 15 | ||
| 16 | obj-y += common.o early.o | 16 | obj-y += common.o early.o |
| 17 | obj-y += amd_bus.o | 17 | obj-y += amd_bus.o |
| 18 | obj-$(CONFIG_X86_64) += bus_numa.o intel_bus.o | ||
| 19 | |||
| 20 | ifeq ($(CONFIG_PCI_DEBUG),y) | ||
| 21 | EXTRA_CFLAGS += -DDEBUG | ||
| 22 | endif | ||
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 1014eb4bfc37..959e548a7039 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <asm/pci_x86.h> | 7 | #include <asm/pci_x86.h> |
| 8 | 8 | ||
| 9 | struct pci_root_info { | 9 | struct pci_root_info { |
| 10 | struct acpi_device *bridge; | ||
| 10 | char *name; | 11 | char *name; |
| 11 | unsigned int res_num; | 12 | unsigned int res_num; |
| 12 | struct resource *res; | 13 | struct resource *res; |
| @@ -58,6 +59,30 @@ bus_has_transparent_bridge(struct pci_bus *bus) | |||
| 58 | return false; | 59 | return false; |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 62 | static void | ||
| 63 | align_resource(struct acpi_device *bridge, struct resource *res) | ||
| 64 | { | ||
| 65 | int align = (res->flags & IORESOURCE_MEM) ? 16 : 4; | ||
| 66 | |||
| 67 | /* | ||
| 68 | * Host bridge windows are not BARs, but the decoders on the PCI side | ||
| 69 | * that claim this address space have starting alignment and length | ||
| 70 | * constraints, so fix any obvious BIOS goofs. | ||
| 71 | */ | ||
| 72 | if (!IS_ALIGNED(res->start, align)) { | ||
| 73 | dev_printk(KERN_DEBUG, &bridge->dev, | ||
| 74 | "host bridge window %pR invalid; " | ||
| 75 | "aligning start to %d-byte boundary\n", res, align); | ||
| 76 | res->start &= ~(align - 1); | ||
| 77 | } | ||
| 78 | if (!IS_ALIGNED(res->end + 1, align)) { | ||
| 79 | dev_printk(KERN_DEBUG, &bridge->dev, | ||
| 80 | "host bridge window %pR invalid; " | ||
| 81 | "aligning end to %d-byte boundary\n", res, align); | ||
| 82 | res->end = ALIGN(res->end, align) - 1; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 61 | static acpi_status | 86 | static acpi_status |
| 62 | setup_resource(struct acpi_resource *acpi_res, void *data) | 87 | setup_resource(struct acpi_resource *acpi_res, void *data) |
| 63 | { | 88 | { |
| @@ -91,11 +116,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
| 91 | start = addr.minimum + addr.translation_offset; | 116 | start = addr.minimum + addr.translation_offset; |
| 92 | end = start + addr.address_length - 1; | 117 | end = start + addr.address_length - 1; |
| 93 | if (info->res_num >= max_root_bus_resources) { | 118 | if (info->res_num >= max_root_bus_resources) { |
| 94 | printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx " | 119 | if (pci_probe & PCI_USE__CRS) |
| 95 | "from %s for %s due to _CRS returning more than " | 120 | printk(KERN_WARNING "PCI: Failed to allocate " |
| 96 | "%d resource descriptors\n", (unsigned long) start, | 121 | "0x%lx-0x%lx from %s for %s due to _CRS " |
| 97 | (unsigned long) end, root->name, info->name, | 122 | "returning more than %d resource descriptors\n", |
| 98 | max_root_bus_resources); | 123 | (unsigned long) start, (unsigned long) end, |
| 124 | root->name, info->name, max_root_bus_resources); | ||
| 99 | return AE_OK; | 125 | return AE_OK; |
| 100 | } | 126 | } |
| 101 | 127 | ||
| @@ -105,14 +131,28 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
| 105 | res->start = start; | 131 | res->start = start; |
| 106 | res->end = end; | 132 | res->end = end; |
| 107 | res->child = NULL; | 133 | res->child = NULL; |
| 134 | align_resource(info->bridge, res); | ||
| 135 | |||
| 136 | if (!(pci_probe & PCI_USE__CRS)) { | ||
| 137 | dev_printk(KERN_DEBUG, &info->bridge->dev, | ||
| 138 | "host bridge window %pR (ignored)\n", res); | ||
| 139 | return AE_OK; | ||
| 140 | } | ||
| 108 | 141 | ||
| 109 | if (insert_resource(root, res)) { | 142 | if (insert_resource(root, res)) { |
| 110 | printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx " | 143 | dev_err(&info->bridge->dev, |
| 111 | "from %s for %s\n", (unsigned long) res->start, | 144 | "can't allocate host bridge window %pR\n", res); |
| 112 | (unsigned long) res->end, root->name, info->name); | ||
| 113 | } else { | 145 | } else { |
| 114 | info->bus->resource[info->res_num] = res; | 146 | info->bus->resource[info->res_num] = res; |
| 115 | info->res_num++; | 147 | info->res_num++; |
| 148 | if (addr.translation_offset) | ||
| 149 | dev_info(&info->bridge->dev, "host bridge window %pR " | ||
| 150 | "(PCI address [%#llx-%#llx])\n", | ||
| 151 | res, res->start - addr.translation_offset, | ||
| 152 | res->end - addr.translation_offset); | ||
| 153 | else | ||
| 154 | dev_info(&info->bridge->dev, | ||
| 155 | "host bridge window %pR\n", res); | ||
| 116 | } | 156 | } |
| 117 | return AE_OK; | 157 | return AE_OK; |
| 118 | } | 158 | } |
| @@ -124,6 +164,12 @@ get_current_resources(struct acpi_device *device, int busnum, | |||
| 124 | struct pci_root_info info; | 164 | struct pci_root_info info; |
| 125 | size_t size; | 165 | size_t size; |
| 126 | 166 | ||
| 167 | if (!(pci_probe & PCI_USE__CRS)) | ||
| 168 | dev_info(&device->dev, | ||
| 169 | "ignoring host bridge windows from ACPI; " | ||
| 170 | "boot with \"pci=use_crs\" to use them\n"); | ||
| 171 | |||
| 172 | info.bridge = device; | ||
| 127 | info.bus = bus; | 173 | info.bus = bus; |
| 128 | info.res_num = 0; | 174 | info.res_num = 0; |
| 129 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, | 175 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, |
| @@ -163,8 +209,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
| 163 | #endif | 209 | #endif |
| 164 | 210 | ||
| 165 | if (domain && !pci_domains_supported) { | 211 | if (domain && !pci_domains_supported) { |
| 166 | printk(KERN_WARNING "PCI: Multiple domains not supported " | 212 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
| 167 | "(dom %d, bus %d)\n", domain, busnum); | 213 | "ignored (multiple domains not supported)\n", |
| 214 | domain, busnum); | ||
| 168 | return NULL; | 215 | return NULL; |
| 169 | } | 216 | } |
| 170 | 217 | ||
| @@ -188,7 +235,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
| 188 | */ | 235 | */ |
| 189 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); | 236 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); |
| 190 | if (!sd) { | 237 | if (!sd) { |
| 191 | printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum); | 238 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
| 239 | "ignored (out of memory)\n", domain, busnum); | ||
| 192 | return NULL; | 240 | return NULL; |
| 193 | } | 241 | } |
| 194 | 242 | ||
| @@ -209,9 +257,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
| 209 | } else { | 257 | } else { |
| 210 | bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); | 258 | bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); |
| 211 | if (bus) { | 259 | if (bus) { |
| 212 | if (pci_probe & PCI_USE__CRS) | 260 | get_current_resources(device, busnum, domain, bus); |
| 213 | get_current_resources(device, busnum, domain, | ||
| 214 | bus); | ||
| 215 | bus->subordinate = pci_scan_child_bus(bus); | 261 | bus->subordinate = pci_scan_child_bus(bus); |
| 216 | } | 262 | } |
| 217 | } | 263 | } |
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 572ee9782f2a..95ecbd495955 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
| @@ -6,10 +6,10 @@ | |||
| 6 | 6 | ||
| 7 | #ifdef CONFIG_X86_64 | 7 | #ifdef CONFIG_X86_64 |
| 8 | #include <asm/pci-direct.h> | 8 | #include <asm/pci-direct.h> |
| 9 | #include <asm/mpspec.h> | ||
| 10 | #include <linux/cpumask.h> | ||
| 11 | #endif | 9 | #endif |
| 12 | 10 | ||
| 11 | #include "bus_numa.h" | ||
| 12 | |||
| 13 | /* | 13 | /* |
| 14 | * This discovers the pcibus <-> node mapping on AMD K8. | 14 | * This discovers the pcibus <-> node mapping on AMD K8. |
| 15 | * also get peer root bus resource for io,mmio | 15 | * also get peer root bus resource for io,mmio |
| @@ -17,67 +17,6 @@ | |||
| 17 | 17 | ||
| 18 | #ifdef CONFIG_X86_64 | 18 | #ifdef CONFIG_X86_64 |
| 19 | 19 | ||
| 20 | /* | ||
| 21 | * sub bus (transparent) will use entres from 3 to store extra from root, | ||
| 22 | * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES? | ||
| 23 | */ | ||
| 24 | #define RES_NUM 16 | ||
| 25 | struct pci_root_info { | ||
| 26 | char name[12]; | ||
| 27 | unsigned int res_num; | ||
| 28 | struct resource res[RES_NUM]; | ||
| 29 | int bus_min; | ||
| 30 | int bus_max; | ||
| 31 | int node; | ||
| 32 | int link; | ||
| 33 | }; | ||
| 34 | |||
| 35 | /* 4 at this time, it may become to 32 */ | ||
| 36 | #define PCI_ROOT_NR 4 | ||
| 37 | static int pci_root_num; | ||
| 38 | static struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
| 39 | |||
| 40 | void x86_pci_root_bus_res_quirks(struct pci_bus *b) | ||
| 41 | { | ||
| 42 | int i; | ||
| 43 | int j; | ||
| 44 | struct pci_root_info *info; | ||
| 45 | |||
| 46 | /* don't go for it if _CRS is used already */ | ||
| 47 | if (b->resource[0] != &ioport_resource || | ||
| 48 | b->resource[1] != &iomem_resource) | ||
| 49 | return; | ||
| 50 | |||
| 51 | /* if only one root bus, don't need to anything */ | ||
| 52 | if (pci_root_num < 2) | ||
| 53 | return; | ||
| 54 | |||
| 55 | for (i = 0; i < pci_root_num; i++) { | ||
| 56 | if (pci_root_info[i].bus_min == b->number) | ||
| 57 | break; | ||
| 58 | } | ||
| 59 | |||
| 60 | if (i == pci_root_num) | ||
| 61 | return; | ||
| 62 | |||
| 63 | printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n", | ||
| 64 | b->number); | ||
| 65 | |||
| 66 | info = &pci_root_info[i]; | ||
| 67 | for (j = 0; j < info->res_num; j++) { | ||
| 68 | struct resource *res; | ||
| 69 | struct resource *root; | ||
| 70 | |||
| 71 | res = &info->res[j]; | ||
| 72 | b->resource[j] = res; | ||
| 73 | if (res->flags & IORESOURCE_IO) | ||
| 74 | root = &ioport_resource; | ||
| 75 | else | ||
| 76 | root = &iomem_resource; | ||
| 77 | insert_resource(root, res); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | #define RANGE_NUM 16 | 20 | #define RANGE_NUM 16 |
| 82 | 21 | ||
| 83 | struct res_range { | 22 | struct res_range { |
| @@ -130,52 +69,6 @@ static void __init update_range(struct res_range *range, size_t start, | |||
| 130 | } | 69 | } |
| 131 | } | 70 | } |
| 132 | 71 | ||
| 133 | static void __init update_res(struct pci_root_info *info, size_t start, | ||
| 134 | size_t end, unsigned long flags, int merge) | ||
| 135 | { | ||
| 136 | int i; | ||
| 137 | struct resource *res; | ||
| 138 | |||
| 139 | if (!merge) | ||
| 140 | goto addit; | ||
| 141 | |||
| 142 | /* try to merge it with old one */ | ||
| 143 | for (i = 0; i < info->res_num; i++) { | ||
| 144 | size_t final_start, final_end; | ||
| 145 | size_t common_start, common_end; | ||
| 146 | |||
| 147 | res = &info->res[i]; | ||
| 148 | if (res->flags != flags) | ||
| 149 | continue; | ||
| 150 | |||
| 151 | common_start = max((size_t)res->start, start); | ||
| 152 | common_end = min((size_t)res->end, end); | ||
| 153 | if (common_start > common_end + 1) | ||
| 154 | continue; | ||
| 155 | |||
| 156 | final_start = min((size_t)res->start, start); | ||
| 157 | final_end = max((size_t)res->end, end); | ||
| 158 | |||
| 159 | res->start = final_start; | ||
| 160 | res->end = final_end; | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 164 | addit: | ||
| 165 | |||
| 166 | /* need to add that */ | ||
| 167 | if (info->res_num >= RES_NUM) | ||
| 168 | return; | ||
| 169 | |||
| 170 | res = &info->res[info->res_num]; | ||
| 171 | res->name = info->name; | ||
| 172 | res->flags = flags; | ||
| 173 | res->start = start; | ||
| 174 | res->end = end; | ||
| 175 | res->child = NULL; | ||
| 176 | info->res_num++; | ||
| 177 | } | ||
| 178 | |||
| 179 | struct pci_hostbridge_probe { | 72 | struct pci_hostbridge_probe { |
| 180 | u32 bus; | 73 | u32 bus; |
| 181 | u32 slot; | 74 | u32 slot; |
| @@ -230,7 +123,6 @@ static int __init early_fill_mp_bus_info(void) | |||
| 230 | int j; | 123 | int j; |
| 231 | unsigned bus; | 124 | unsigned bus; |
| 232 | unsigned slot; | 125 | unsigned slot; |
| 233 | int found; | ||
| 234 | int node; | 126 | int node; |
| 235 | int link; | 127 | int link; |
| 236 | int def_node; | 128 | int def_node; |
| @@ -247,7 +139,7 @@ static int __init early_fill_mp_bus_info(void) | |||
| 247 | if (!early_pci_allowed()) | 139 | if (!early_pci_allowed()) |
| 248 | return -1; | 140 | return -1; |
| 249 | 141 | ||
| 250 | found = 0; | 142 | found_all_numa_early = 0; |
| 251 | for (i = 0; i < ARRAY_SIZE(pci_probes); i++) { | 143 | for (i = 0; i < ARRAY_SIZE(pci_probes); i++) { |
| 252 | u32 id; | 144 | u32 id; |
| 253 | u16 device; | 145 | u16 device; |
| @@ -261,12 +153,12 @@ static int __init early_fill_mp_bus_info(void) | |||
| 261 | device = (id>>16) & 0xffff; | 153 | device = (id>>16) & 0xffff; |
| 262 | if (pci_probes[i].vendor == vendor && | 154 | if (pci_probes[i].vendor == vendor && |
| 263 | pci_probes[i].device == device) { | 155 | pci_probes[i].device == device) { |
| 264 | found = 1; | 156 | found_all_numa_early = 1; |
| 265 | break; | 157 | break; |
| 266 | } | 158 | } |
| 267 | } | 159 | } |
| 268 | 160 | ||
| 269 | if (!found) | 161 | if (!found_all_numa_early) |
| 270 | return 0; | 162 | return 0; |
| 271 | 163 | ||
| 272 | pci_root_num = 0; | 164 | pci_root_num = 0; |
| @@ -488,7 +380,7 @@ static int __init early_fill_mp_bus_info(void) | |||
| 488 | info = &pci_root_info[i]; | 380 | info = &pci_root_info[i]; |
| 489 | res_num = info->res_num; | 381 | res_num = info->res_num; |
| 490 | busnum = info->bus_min; | 382 | busnum = info->bus_min; |
| 491 | printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n", | 383 | printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", |
| 492 | info->bus_min, info->bus_max, info->node, info->link); | 384 | info->bus_min, info->bus_max, info->node, info->link); |
| 493 | for (j = 0; j < res_num; j++) { | 385 | for (j = 0; j < res_num; j++) { |
| 494 | res = &info->res[j]; | 386 | res = &info->res[j]; |
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c new file mode 100644 index 000000000000..145df00e0387 --- /dev/null +++ b/arch/x86/pci/bus_numa.c | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | #include <linux/init.h> | ||
| 2 | #include <linux/pci.h> | ||
| 3 | |||
| 4 | #include "bus_numa.h" | ||
| 5 | |||
| 6 | int pci_root_num; | ||
| 7 | struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
| 8 | int found_all_numa_early; | ||
| 9 | |||
| 10 | void x86_pci_root_bus_res_quirks(struct pci_bus *b) | ||
| 11 | { | ||
| 12 | int i; | ||
| 13 | int j; | ||
| 14 | struct pci_root_info *info; | ||
| 15 | |||
| 16 | /* don't go for it if _CRS is used already */ | ||
| 17 | if (b->resource[0] != &ioport_resource || | ||
| 18 | b->resource[1] != &iomem_resource) | ||
| 19 | return; | ||
| 20 | |||
| 21 | if (!pci_root_num) | ||
| 22 | return; | ||
| 23 | |||
| 24 | /* for amd, if only one root bus, don't need to do anything */ | ||
| 25 | if (pci_root_num < 2 && found_all_numa_early) | ||
| 26 | return; | ||
| 27 | |||
| 28 | for (i = 0; i < pci_root_num; i++) { | ||
| 29 | if (pci_root_info[i].bus_min == b->number) | ||
| 30 | break; | ||
| 31 | } | ||
| 32 | |||
| 33 | if (i == pci_root_num) | ||
| 34 | return; | ||
| 35 | |||
| 36 | printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n", | ||
| 37 | b->number); | ||
| 38 | |||
| 39 | info = &pci_root_info[i]; | ||
| 40 | for (j = 0; j < info->res_num; j++) { | ||
| 41 | struct resource *res; | ||
| 42 | struct resource *root; | ||
| 43 | |||
| 44 | res = &info->res[j]; | ||
| 45 | b->resource[j] = res; | ||
| 46 | if (res->flags & IORESOURCE_IO) | ||
| 47 | root = &ioport_resource; | ||
| 48 | else | ||
| 49 | root = &iomem_resource; | ||
| 50 | insert_resource(root, res); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | void __init update_res(struct pci_root_info *info, size_t start, | ||
| 55 | size_t end, unsigned long flags, int merge) | ||
| 56 | { | ||
| 57 | int i; | ||
| 58 | struct resource *res; | ||
| 59 | |||
| 60 | if (start > end) | ||
| 61 | return; | ||
| 62 | |||
| 63 | if (!merge) | ||
| 64 | goto addit; | ||
| 65 | |||
| 66 | /* try to merge it with old one */ | ||
| 67 | for (i = 0; i < info->res_num; i++) { | ||
| 68 | size_t final_start, final_end; | ||
| 69 | size_t common_start, common_end; | ||
| 70 | |||
| 71 | res = &info->res[i]; | ||
| 72 | if (res->flags != flags) | ||
| 73 | continue; | ||
| 74 | |||
| 75 | common_start = max((size_t)res->start, start); | ||
| 76 | common_end = min((size_t)res->end, end); | ||
| 77 | if (common_start > common_end + 1) | ||
| 78 | continue; | ||
| 79 | |||
| 80 | final_start = min((size_t)res->start, start); | ||
| 81 | final_end = max((size_t)res->end, end); | ||
| 82 | |||
| 83 | res->start = final_start; | ||
| 84 | res->end = final_end; | ||
| 85 | return; | ||
| 86 | } | ||
| 87 | |||
| 88 | addit: | ||
| 89 | |||
| 90 | /* need to add that */ | ||
| 91 | if (info->res_num >= RES_NUM) | ||
| 92 | return; | ||
| 93 | |||
| 94 | res = &info->res[info->res_num]; | ||
| 95 | res->name = info->name; | ||
| 96 | res->flags = flags; | ||
| 97 | res->start = start; | ||
| 98 | res->end = end; | ||
| 99 | res->child = NULL; | ||
| 100 | info->res_num++; | ||
| 101 | } | ||
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h new file mode 100644 index 000000000000..adbc23fe82ac --- /dev/null +++ b/arch/x86/pci/bus_numa.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | #ifdef CONFIG_X86_64 | ||
| 2 | |||
| 3 | /* | ||
| 4 | * sub bus (transparent) will use entres from 3 to store extra from | ||
| 5 | * root, so need to make sure we have enough slot there, Should we | ||
| 6 | * increase PCI_BUS_NUM_RESOURCES? | ||
| 7 | */ | ||
| 8 | #define RES_NUM 16 | ||
| 9 | struct pci_root_info { | ||
| 10 | char name[12]; | ||
| 11 | unsigned int res_num; | ||
| 12 | struct resource res[RES_NUM]; | ||
| 13 | int bus_min; | ||
| 14 | int bus_max; | ||
| 15 | int node; | ||
| 16 | int link; | ||
| 17 | }; | ||
| 18 | |||
| 19 | /* 4 at this time, it may become to 32 */ | ||
| 20 | #define PCI_ROOT_NR 4 | ||
| 21 | extern int pci_root_num; | ||
| 22 | extern struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
| 23 | extern int found_all_numa_early; | ||
| 24 | |||
| 25 | extern void update_res(struct pci_root_info *info, size_t start, | ||
| 26 | size_t end, unsigned long flags, int merge); | ||
| 27 | #endif | ||
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 1331fcf26143..d2552c68e94d 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
| @@ -410,8 +410,6 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) | |||
| 410 | return bus; | 410 | return bus; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | extern u8 pci_cache_line_size; | ||
| 414 | |||
| 415 | int __init pcibios_init(void) | 413 | int __init pcibios_init(void) |
| 416 | { | 414 | { |
| 417 | struct cpuinfo_x86 *c = &boot_cpu_data; | 415 | struct cpuinfo_x86 *c = &boot_cpu_data; |
| @@ -422,15 +420,19 @@ int __init pcibios_init(void) | |||
| 422 | } | 420 | } |
| 423 | 421 | ||
| 424 | /* | 422 | /* |
| 425 | * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8 | 423 | * Set PCI cacheline size to that of the CPU if the CPU has reported it. |
| 426 | * and P4. It's also good for 386/486s (which actually have 16) | 424 | * (For older CPUs that don't support cpuid, we se it to 32 bytes |
| 425 | * It's also good for 386/486s (which actually have 16) | ||
| 427 | * as quite a few PCI devices do not support smaller values. | 426 | * as quite a few PCI devices do not support smaller values. |
| 428 | */ | 427 | */ |
| 429 | pci_cache_line_size = 32 >> 2; | 428 | if (c->x86_clflush_size > 0) { |
| 430 | if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD) | 429 | pci_dfl_cache_line_size = c->x86_clflush_size >> 2; |
| 431 | pci_cache_line_size = 64 >> 2; /* K7 & K8 */ | 430 | printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n", |
| 432 | else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL) | 431 | pci_dfl_cache_line_size << 2); |
| 433 | pci_cache_line_size = 128 >> 2; /* P4 */ | 432 | } else { |
| 433 | pci_dfl_cache_line_size = 32 >> 2; | ||
| 434 | printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n"); | ||
| 435 | } | ||
| 434 | 436 | ||
| 435 | pcibios_resource_survey(); | 437 | pcibios_resource_survey(); |
| 436 | 438 | ||
diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c index aaf26ae58cd5..d1067d539bee 100644 --- a/arch/x86/pci/early.c +++ b/arch/x86/pci/early.c | |||
| @@ -12,8 +12,6 @@ u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) | |||
| 12 | u32 v; | 12 | u32 v; |
| 13 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 13 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
| 14 | v = inl(0xcfc); | 14 | v = inl(0xcfc); |
| 15 | if (v != 0xffffffff) | ||
| 16 | pr_debug("%x reading 4 from %x: %x\n", slot, offset, v); | ||
| 17 | return v; | 15 | return v; |
| 18 | } | 16 | } |
| 19 | 17 | ||
| @@ -22,7 +20,6 @@ u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset) | |||
| 22 | u8 v; | 20 | u8 v; |
| 23 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 21 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
| 24 | v = inb(0xcfc + (offset&3)); | 22 | v = inb(0xcfc + (offset&3)); |
| 25 | pr_debug("%x reading 1 from %x: %x\n", slot, offset, v); | ||
| 26 | return v; | 23 | return v; |
| 27 | } | 24 | } |
| 28 | 25 | ||
| @@ -31,28 +28,24 @@ u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset) | |||
| 31 | u16 v; | 28 | u16 v; |
| 32 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 29 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
| 33 | v = inw(0xcfc + (offset&2)); | 30 | v = inw(0xcfc + (offset&2)); |
| 34 | pr_debug("%x reading 2 from %x: %x\n", slot, offset, v); | ||
| 35 | return v; | 31 | return v; |
| 36 | } | 32 | } |
| 37 | 33 | ||
| 38 | void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, | 34 | void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, |
| 39 | u32 val) | 35 | u32 val) |
| 40 | { | 36 | { |
| 41 | pr_debug("%x writing to %x: %x\n", slot, offset, val); | ||
| 42 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 37 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
| 43 | outl(val, 0xcfc); | 38 | outl(val, 0xcfc); |
| 44 | } | 39 | } |
| 45 | 40 | ||
| 46 | void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) | 41 | void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) |
| 47 | { | 42 | { |
| 48 | pr_debug("%x writing to %x: %x\n", slot, offset, val); | ||
| 49 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 43 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
| 50 | outb(val, 0xcfc + (offset&3)); | 44 | outb(val, 0xcfc + (offset&3)); |
| 51 | } | 45 | } |
| 52 | 46 | ||
| 53 | void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val) | 47 | void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val) |
| 54 | { | 48 | { |
| 55 | pr_debug("%x writing to %x: %x\n", slot, offset, val); | ||
| 56 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 49 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
| 57 | outw(val, 0xcfc + (offset&2)); | 50 | outw(val, 0xcfc + (offset&2)); |
| 58 | } | 51 | } |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index b22d13b0c71d..5dc9e8c63fcd 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
| @@ -129,7 +129,9 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
| 129 | continue; | 129 | continue; |
| 130 | if (!r->start || | 130 | if (!r->start || |
| 131 | pci_claim_resource(dev, idx) < 0) { | 131 | pci_claim_resource(dev, idx) < 0) { |
| 132 | dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx); | 132 | dev_info(&dev->dev, |
| 133 | "can't reserve window %pR\n", | ||
| 134 | r); | ||
| 133 | /* | 135 | /* |
| 134 | * Something is wrong with the region. | 136 | * Something is wrong with the region. |
| 135 | * Invalidate the resource to prevent | 137 | * Invalidate the resource to prevent |
| @@ -144,16 +146,29 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
| 144 | } | 146 | } |
| 145 | } | 147 | } |
| 146 | 148 | ||
| 149 | struct pci_check_idx_range { | ||
| 150 | int start; | ||
| 151 | int end; | ||
| 152 | }; | ||
| 153 | |||
| 147 | static void __init pcibios_allocate_resources(int pass) | 154 | static void __init pcibios_allocate_resources(int pass) |
| 148 | { | 155 | { |
| 149 | struct pci_dev *dev = NULL; | 156 | struct pci_dev *dev = NULL; |
| 150 | int idx, disabled; | 157 | int idx, disabled, i; |
| 151 | u16 command; | 158 | u16 command; |
| 152 | struct resource *r; | 159 | struct resource *r; |
| 153 | 160 | ||
| 161 | struct pci_check_idx_range idx_range[] = { | ||
| 162 | { PCI_STD_RESOURCES, PCI_STD_RESOURCE_END }, | ||
| 163 | #ifdef CONFIG_PCI_IOV | ||
| 164 | { PCI_IOV_RESOURCES, PCI_IOV_RESOURCE_END }, | ||
| 165 | #endif | ||
| 166 | }; | ||
| 167 | |||
| 154 | for_each_pci_dev(dev) { | 168 | for_each_pci_dev(dev) { |
| 155 | pci_read_config_word(dev, PCI_COMMAND, &command); | 169 | pci_read_config_word(dev, PCI_COMMAND, &command); |
| 156 | for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { | 170 | for (i = 0; i < ARRAY_SIZE(idx_range); i++) |
| 171 | for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) { | ||
| 157 | r = &dev->resource[idx]; | 172 | r = &dev->resource[idx]; |
| 158 | if (r->parent) /* Already allocated */ | 173 | if (r->parent) /* Already allocated */ |
| 159 | continue; | 174 | continue; |
| @@ -164,12 +179,12 @@ static void __init pcibios_allocate_resources(int pass) | |||
| 164 | else | 179 | else |
| 165 | disabled = !(command & PCI_COMMAND_MEMORY); | 180 | disabled = !(command & PCI_COMMAND_MEMORY); |
| 166 | if (pass == disabled) { | 181 | if (pass == disabled) { |
| 167 | dev_dbg(&dev->dev, "resource %#08llx-%#08llx (f=%lx, d=%d, p=%d)\n", | 182 | dev_dbg(&dev->dev, |
| 168 | (unsigned long long) r->start, | 183 | "BAR %d: reserving %pr (d=%d, p=%d)\n", |
| 169 | (unsigned long long) r->end, | 184 | idx, r, disabled, pass); |
| 170 | r->flags, disabled, pass); | ||
| 171 | if (pci_claim_resource(dev, idx) < 0) { | 185 | if (pci_claim_resource(dev, idx) < 0) { |
| 172 | dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx); | 186 | dev_info(&dev->dev, |
| 187 | "can't reserve %pR\n", r); | ||
| 173 | /* We'll assign a new address later */ | 188 | /* We'll assign a new address later */ |
| 174 | r->end -= r->start; | 189 | r->end -= r->start; |
| 175 | r->start = 0; | 190 | r->start = 0; |
| @@ -182,7 +197,7 @@ static void __init pcibios_allocate_resources(int pass) | |||
| 182 | /* Turn the ROM off, leave the resource region, | 197 | /* Turn the ROM off, leave the resource region, |
| 183 | * but keep it unregistered. */ | 198 | * but keep it unregistered. */ |
| 184 | u32 reg; | 199 | u32 reg; |
| 185 | dev_dbg(&dev->dev, "disabling ROM\n"); | 200 | dev_dbg(&dev->dev, "disabling ROM %pR\n", r); |
| 186 | r->flags &= ~IORESOURCE_ROM_ENABLE; | 201 | r->flags &= ~IORESOURCE_ROM_ENABLE; |
| 187 | pci_read_config_dword(dev, | 202 | pci_read_config_dword(dev, |
| 188 | dev->rom_base_reg, ®); | 203 | dev->rom_base_reg, ®); |
| @@ -282,6 +297,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
| 282 | return -EINVAL; | 297 | return -EINVAL; |
| 283 | 298 | ||
| 284 | prot = pgprot_val(vma->vm_page_prot); | 299 | prot = pgprot_val(vma->vm_page_prot); |
| 300 | |||
| 301 | /* | ||
| 302 | * Return error if pat is not enabled and write_combine is requested. | ||
| 303 | * Caller can followup with UC MINUS request and add a WC mtrr if there | ||
| 304 | * is a free mtrr slot. | ||
| 305 | */ | ||
| 306 | if (!pat_enabled && write_combine) | ||
| 307 | return -EINVAL; | ||
| 308 | |||
| 285 | if (pat_enabled && write_combine) | 309 | if (pat_enabled && write_combine) |
| 286 | prot |= _PAGE_CACHE_WC; | 310 | prot |= _PAGE_CACHE_WC; |
| 287 | else if (pat_enabled || boot_cpu_data.x86 > 3) | 311 | else if (pat_enabled || boot_cpu_data.x86 > 3) |
diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c new file mode 100644 index 000000000000..b7a55dc55d13 --- /dev/null +++ b/arch/x86/pci/intel_bus.c | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | /* | ||
| 2 | * to read io range from IOH pci conf, need to do it after mmconfig is there | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <linux/delay.h> | ||
| 6 | #include <linux/dmi.h> | ||
| 7 | #include <linux/pci.h> | ||
| 8 | #include <linux/init.h> | ||
| 9 | #include <asm/pci_x86.h> | ||
| 10 | |||
| 11 | #include "bus_numa.h" | ||
| 12 | |||
| 13 | static inline void print_ioh_resources(struct pci_root_info *info) | ||
| 14 | { | ||
| 15 | int res_num; | ||
| 16 | int busnum; | ||
| 17 | int i; | ||
| 18 | |||
| 19 | printk(KERN_DEBUG "IOH bus: [%02x, %02x]\n", | ||
| 20 | info->bus_min, info->bus_max); | ||
| 21 | res_num = info->res_num; | ||
| 22 | busnum = info->bus_min; | ||
| 23 | for (i = 0; i < res_num; i++) { | ||
| 24 | struct resource *res; | ||
| 25 | |||
| 26 | res = &info->res[i]; | ||
| 27 | printk(KERN_DEBUG "IOH bus: %02x index %x %s: [%llx, %llx]\n", | ||
| 28 | busnum, i, | ||
| 29 | (res->flags & IORESOURCE_IO) ? "io port" : | ||
| 30 | "mmio", | ||
| 31 | res->start, res->end); | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | #define IOH_LIO 0x108 | ||
| 36 | #define IOH_LMMIOL 0x10c | ||
| 37 | #define IOH_LMMIOH 0x110 | ||
| 38 | #define IOH_LMMIOH_BASEU 0x114 | ||
| 39 | #define IOH_LMMIOH_LIMITU 0x118 | ||
| 40 | #define IOH_LCFGBUS 0x11c | ||
| 41 | |||
| 42 | static void __devinit pci_root_bus_res(struct pci_dev *dev) | ||
| 43 | { | ||
| 44 | u16 word; | ||
| 45 | u32 dword; | ||
| 46 | struct pci_root_info *info; | ||
| 47 | u16 io_base, io_end; | ||
| 48 | u32 mmiol_base, mmiol_end; | ||
| 49 | u64 mmioh_base, mmioh_end; | ||
| 50 | int bus_base, bus_end; | ||
| 51 | |||
| 52 | if (pci_root_num >= PCI_ROOT_NR) { | ||
| 53 | printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n"); | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | |||
| 57 | info = &pci_root_info[pci_root_num]; | ||
| 58 | pci_root_num++; | ||
| 59 | |||
| 60 | pci_read_config_word(dev, IOH_LCFGBUS, &word); | ||
| 61 | bus_base = (word & 0xff); | ||
| 62 | bus_end = (word & 0xff00) >> 8; | ||
| 63 | sprintf(info->name, "PCI Bus #%02x", bus_base); | ||
| 64 | info->bus_min = bus_base; | ||
| 65 | info->bus_max = bus_end; | ||
| 66 | |||
| 67 | pci_read_config_word(dev, IOH_LIO, &word); | ||
| 68 | io_base = (word & 0xf0) << (12 - 4); | ||
| 69 | io_end = (word & 0xf000) | 0xfff; | ||
| 70 | update_res(info, io_base, io_end, IORESOURCE_IO, 0); | ||
| 71 | |||
| 72 | pci_read_config_dword(dev, IOH_LMMIOL, &dword); | ||
| 73 | mmiol_base = (dword & 0xff00) << (24 - 8); | ||
| 74 | mmiol_end = (dword & 0xff000000) | 0xffffff; | ||
| 75 | update_res(info, mmiol_base, mmiol_end, IORESOURCE_MEM, 0); | ||
| 76 | |||
| 77 | pci_read_config_dword(dev, IOH_LMMIOH, &dword); | ||
| 78 | mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10); | ||
| 79 | mmioh_end = ((u64)(dword & 0xfc000000) | 0x3ffffff); | ||
| 80 | pci_read_config_dword(dev, IOH_LMMIOH_BASEU, &dword); | ||
| 81 | mmioh_base |= ((u64)(dword & 0x7ffff)) << 32; | ||
| 82 | pci_read_config_dword(dev, IOH_LMMIOH_LIMITU, &dword); | ||
| 83 | mmioh_end |= ((u64)(dword & 0x7ffff)) << 32; | ||
| 84 | update_res(info, mmioh_base, mmioh_end, IORESOURCE_MEM, 0); | ||
| 85 | |||
| 86 | print_ioh_resources(info); | ||
| 87 | } | ||
| 88 | |||
| 89 | /* intel IOH */ | ||
| 90 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, pci_root_bus_res); | ||
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 602c172d3bd5..b19d1e54201e 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
| @@ -15,48 +15,98 @@ | |||
| 15 | #include <linux/acpi.h> | 15 | #include <linux/acpi.h> |
| 16 | #include <linux/sfi_acpi.h> | 16 | #include <linux/sfi_acpi.h> |
| 17 | #include <linux/bitmap.h> | 17 | #include <linux/bitmap.h> |
| 18 | #include <linux/sort.h> | 18 | #include <linux/dmi.h> |
| 19 | #include <asm/e820.h> | 19 | #include <asm/e820.h> |
| 20 | #include <asm/pci_x86.h> | 20 | #include <asm/pci_x86.h> |
| 21 | #include <asm/acpi.h> | 21 | #include <asm/acpi.h> |
| 22 | 22 | ||
| 23 | #define PREFIX "PCI: " | 23 | #define PREFIX "PCI: " |
| 24 | 24 | ||
| 25 | /* aperture is up to 256MB but BIOS may reserve less */ | ||
| 26 | #define MMCONFIG_APER_MIN (2 * 1024*1024) | ||
| 27 | #define MMCONFIG_APER_MAX (256 * 1024*1024) | ||
| 28 | |||
| 29 | /* Indicate if the mmcfg resources have been placed into the resource table. */ | 25 | /* Indicate if the mmcfg resources have been placed into the resource table. */ |
| 30 | static int __initdata pci_mmcfg_resources_inserted; | 26 | static int __initdata pci_mmcfg_resources_inserted; |
| 31 | 27 | ||
| 32 | static __init int extend_mmcfg(int num) | 28 | LIST_HEAD(pci_mmcfg_list); |
| 29 | |||
| 30 | static __init void pci_mmconfig_remove(struct pci_mmcfg_region *cfg) | ||
| 33 | { | 31 | { |
| 34 | struct acpi_mcfg_allocation *new; | 32 | if (cfg->res.parent) |
| 35 | int new_num = pci_mmcfg_config_num + num; | 33 | release_resource(&cfg->res); |
| 34 | list_del(&cfg->list); | ||
| 35 | kfree(cfg); | ||
| 36 | } | ||
| 36 | 37 | ||
| 37 | new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL); | 38 | static __init void free_all_mmcfg(void) |
| 38 | if (!new) | 39 | { |
| 39 | return -1; | 40 | struct pci_mmcfg_region *cfg, *tmp; |
| 40 | 41 | ||
| 41 | if (pci_mmcfg_config) { | 42 | pci_mmcfg_arch_free(); |
| 42 | memcpy(new, pci_mmcfg_config, | 43 | list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list) |
| 43 | sizeof(pci_mmcfg_config[0]) * new_num); | 44 | pci_mmconfig_remove(cfg); |
| 44 | kfree(pci_mmcfg_config); | 45 | } |
| 46 | |||
| 47 | static __init void list_add_sorted(struct pci_mmcfg_region *new) | ||
| 48 | { | ||
| 49 | struct pci_mmcfg_region *cfg; | ||
| 50 | |||
| 51 | /* keep list sorted by segment and starting bus number */ | ||
| 52 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | ||
| 53 | if (cfg->segment > new->segment || | ||
| 54 | (cfg->segment == new->segment && | ||
| 55 | cfg->start_bus >= new->start_bus)) { | ||
| 56 | list_add_tail(&new->list, &cfg->list); | ||
| 57 | return; | ||
| 58 | } | ||
| 45 | } | 59 | } |
| 46 | pci_mmcfg_config = new; | 60 | list_add_tail(&new->list, &pci_mmcfg_list); |
| 61 | } | ||
| 47 | 62 | ||
| 48 | return 0; | 63 | static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, |
| 64 | int end, u64 addr) | ||
| 65 | { | ||
| 66 | struct pci_mmcfg_region *new; | ||
| 67 | int num_buses; | ||
| 68 | struct resource *res; | ||
| 69 | |||
| 70 | if (addr == 0) | ||
| 71 | return NULL; | ||
| 72 | |||
| 73 | new = kzalloc(sizeof(*new), GFP_KERNEL); | ||
| 74 | if (!new) | ||
| 75 | return NULL; | ||
| 76 | |||
| 77 | new->address = addr; | ||
| 78 | new->segment = segment; | ||
| 79 | new->start_bus = start; | ||
| 80 | new->end_bus = end; | ||
| 81 | |||
| 82 | list_add_sorted(new); | ||
| 83 | |||
| 84 | num_buses = end - start + 1; | ||
| 85 | res = &new->res; | ||
| 86 | res->start = addr + PCI_MMCFG_BUS_OFFSET(start); | ||
| 87 | res->end = addr + PCI_MMCFG_BUS_OFFSET(num_buses) - 1; | ||
| 88 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
| 89 | snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN, | ||
| 90 | "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end); | ||
| 91 | res->name = new->name; | ||
| 92 | |||
| 93 | printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at " | ||
| 94 | "%pR (base %#lx)\n", segment, start, end, &new->res, | ||
| 95 | (unsigned long) addr); | ||
| 96 | |||
| 97 | return new; | ||
| 49 | } | 98 | } |
| 50 | 99 | ||
| 51 | static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end) | 100 | struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus) |
| 52 | { | 101 | { |
| 53 | int i = pci_mmcfg_config_num; | 102 | struct pci_mmcfg_region *cfg; |
| 54 | 103 | ||
| 55 | pci_mmcfg_config_num++; | 104 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
| 56 | pci_mmcfg_config[i].address = addr; | 105 | if (cfg->segment == segment && |
| 57 | pci_mmcfg_config[i].pci_segment = segment; | 106 | cfg->start_bus <= bus && bus <= cfg->end_bus) |
| 58 | pci_mmcfg_config[i].start_bus_number = start; | 107 | return cfg; |
| 59 | pci_mmcfg_config[i].end_bus_number = end; | 108 | |
| 109 | return NULL; | ||
| 60 | } | 110 | } |
| 61 | 111 | ||
| 62 | static const char __init *pci_mmcfg_e7520(void) | 112 | static const char __init *pci_mmcfg_e7520(void) |
| @@ -68,11 +118,9 @@ static const char __init *pci_mmcfg_e7520(void) | |||
| 68 | if (win == 0x0000 || win == 0xf000) | 118 | if (win == 0x0000 || win == 0xf000) |
| 69 | return NULL; | 119 | return NULL; |
| 70 | 120 | ||
| 71 | if (extend_mmcfg(1) == -1) | 121 | if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL) |
| 72 | return NULL; | 122 | return NULL; |
| 73 | 123 | ||
| 74 | fill_one_mmcfg(win << 16, 0, 0, 255); | ||
| 75 | |||
| 76 | return "Intel Corporation E7520 Memory Controller Hub"; | 124 | return "Intel Corporation E7520 Memory Controller Hub"; |
| 77 | } | 125 | } |
| 78 | 126 | ||
| @@ -114,11 +162,9 @@ static const char __init *pci_mmcfg_intel_945(void) | |||
| 114 | if ((pciexbar & mask) >= 0xf0000000U) | 162 | if ((pciexbar & mask) >= 0xf0000000U) |
| 115 | return NULL; | 163 | return NULL; |
| 116 | 164 | ||
| 117 | if (extend_mmcfg(1) == -1) | 165 | if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL) |
| 118 | return NULL; | 166 | return NULL; |
| 119 | 167 | ||
| 120 | fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1); | ||
| 121 | |||
| 122 | return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; | 168 | return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; |
| 123 | } | 169 | } |
| 124 | 170 | ||
| @@ -127,7 +173,7 @@ static const char __init *pci_mmcfg_amd_fam10h(void) | |||
| 127 | u32 low, high, address; | 173 | u32 low, high, address; |
| 128 | u64 base, msr; | 174 | u64 base, msr; |
| 129 | int i; | 175 | int i; |
| 130 | unsigned segnbits = 0, busnbits; | 176 | unsigned segnbits = 0, busnbits, end_bus; |
| 131 | 177 | ||
| 132 | if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF)) | 178 | if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF)) |
| 133 | return NULL; | 179 | return NULL; |
| @@ -161,11 +207,13 @@ static const char __init *pci_mmcfg_amd_fam10h(void) | |||
| 161 | busnbits = 8; | 207 | busnbits = 8; |
| 162 | } | 208 | } |
| 163 | 209 | ||
| 164 | if (extend_mmcfg(1 << segnbits) == -1) | 210 | end_bus = (1 << busnbits) - 1; |
| 165 | return NULL; | ||
| 166 | |||
| 167 | for (i = 0; i < (1 << segnbits); i++) | 211 | for (i = 0; i < (1 << segnbits); i++) |
| 168 | fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1); | 212 | if (pci_mmconfig_add(i, 0, end_bus, |
| 213 | base + (1<<28) * i) == NULL) { | ||
| 214 | free_all_mmcfg(); | ||
| 215 | return NULL; | ||
| 216 | } | ||
| 169 | 217 | ||
| 170 | return "AMD Family 10h NB"; | 218 | return "AMD Family 10h NB"; |
| 171 | } | 219 | } |
| @@ -190,7 +238,7 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void) | |||
| 190 | /* | 238 | /* |
| 191 | * do check if amd fam10h already took over | 239 | * do check if amd fam10h already took over |
| 192 | */ | 240 | */ |
| 193 | if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked) | 241 | if (!acpi_disabled || !list_empty(&pci_mmcfg_list) || mcp55_checked) |
| 194 | return NULL; | 242 | return NULL; |
| 195 | 243 | ||
| 196 | mcp55_checked = true; | 244 | mcp55_checked = true; |
| @@ -213,16 +261,14 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void) | |||
| 213 | if (!(extcfg & extcfg_enable_mask)) | 261 | if (!(extcfg & extcfg_enable_mask)) |
| 214 | continue; | 262 | continue; |
| 215 | 263 | ||
| 216 | if (extend_mmcfg(1) == -1) | ||
| 217 | continue; | ||
| 218 | |||
| 219 | size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift; | 264 | size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift; |
| 220 | base = extcfg & extcfg_base_mask[size_index]; | 265 | base = extcfg & extcfg_base_mask[size_index]; |
| 221 | /* base could > 4G */ | 266 | /* base could > 4G */ |
| 222 | base <<= extcfg_base_lshift; | 267 | base <<= extcfg_base_lshift; |
| 223 | start = (extcfg & extcfg_start_mask) >> extcfg_start_shift; | 268 | start = (extcfg & extcfg_start_mask) >> extcfg_start_shift; |
| 224 | end = start + extcfg_sizebus[size_index] - 1; | 269 | end = start + extcfg_sizebus[size_index] - 1; |
| 225 | fill_one_mmcfg(base, 0, start, end); | 270 | if (pci_mmconfig_add(0, start, end, base) == NULL) |
| 271 | continue; | ||
| 226 | mcp55_mmconf_found++; | 272 | mcp55_mmconf_found++; |
| 227 | } | 273 | } |
| 228 | 274 | ||
| @@ -253,45 +299,27 @@ static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = { | |||
| 253 | 0x0369, pci_mmcfg_nvidia_mcp55 }, | 299 | 0x0369, pci_mmcfg_nvidia_mcp55 }, |
| 254 | }; | 300 | }; |
| 255 | 301 | ||
| 256 | static int __init cmp_mmcfg(const void *x1, const void *x2) | ||
| 257 | { | ||
| 258 | const typeof(pci_mmcfg_config[0]) *m1 = x1; | ||
| 259 | const typeof(pci_mmcfg_config[0]) *m2 = x2; | ||
| 260 | int start1, start2; | ||
| 261 | |||
| 262 | start1 = m1->start_bus_number; | ||
| 263 | start2 = m2->start_bus_number; | ||
| 264 | |||
| 265 | return start1 - start2; | ||
| 266 | } | ||
| 267 | |||
| 268 | static void __init pci_mmcfg_check_end_bus_number(void) | 302 | static void __init pci_mmcfg_check_end_bus_number(void) |
| 269 | { | 303 | { |
| 270 | int i; | 304 | struct pci_mmcfg_region *cfg, *cfgx; |
| 271 | typeof(pci_mmcfg_config[0]) *cfg, *cfgx; | ||
| 272 | |||
| 273 | /* sort them at first */ | ||
| 274 | sort(pci_mmcfg_config, pci_mmcfg_config_num, | ||
| 275 | sizeof(pci_mmcfg_config[0]), cmp_mmcfg, NULL); | ||
| 276 | 305 | ||
| 277 | /* last one*/ | 306 | /* last one*/ |
| 278 | if (pci_mmcfg_config_num > 0) { | 307 | cfg = list_entry(pci_mmcfg_list.prev, typeof(*cfg), list); |
| 279 | i = pci_mmcfg_config_num - 1; | 308 | if (cfg) |
| 280 | cfg = &pci_mmcfg_config[i]; | 309 | if (cfg->end_bus < cfg->start_bus) |
| 281 | if (cfg->end_bus_number < cfg->start_bus_number) | 310 | cfg->end_bus = 255; |
| 282 | cfg->end_bus_number = 255; | ||
| 283 | } | ||
| 284 | 311 | ||
| 285 | /* don't overlap please */ | 312 | if (list_is_singular(&pci_mmcfg_list)) |
| 286 | for (i = 0; i < pci_mmcfg_config_num - 1; i++) { | 313 | return; |
| 287 | cfg = &pci_mmcfg_config[i]; | ||
| 288 | cfgx = &pci_mmcfg_config[i+1]; | ||
| 289 | 314 | ||
| 290 | if (cfg->end_bus_number < cfg->start_bus_number) | 315 | /* don't overlap please */ |
| 291 | cfg->end_bus_number = 255; | 316 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
| 317 | if (cfg->end_bus < cfg->start_bus) | ||
| 318 | cfg->end_bus = 255; | ||
| 292 | 319 | ||
| 293 | if (cfg->end_bus_number >= cfgx->start_bus_number) | 320 | cfgx = list_entry(cfg->list.next, typeof(*cfg), list); |
| 294 | cfg->end_bus_number = cfgx->start_bus_number - 1; | 321 | if (cfg != cfgx && cfg->end_bus >= cfgx->start_bus) |
| 322 | cfg->end_bus = cfgx->start_bus - 1; | ||
| 295 | } | 323 | } |
| 296 | } | 324 | } |
| 297 | 325 | ||
| @@ -306,8 +334,7 @@ static int __init pci_mmcfg_check_hostbridge(void) | |||
| 306 | if (!raw_pci_ops) | 334 | if (!raw_pci_ops) |
| 307 | return 0; | 335 | return 0; |
| 308 | 336 | ||
| 309 | pci_mmcfg_config_num = 0; | 337 | free_all_mmcfg(); |
| 310 | pci_mmcfg_config = NULL; | ||
| 311 | 338 | ||
| 312 | for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) { | 339 | for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) { |
| 313 | bus = pci_mmcfg_probes[i].bus; | 340 | bus = pci_mmcfg_probes[i].bus; |
| @@ -322,45 +349,22 @@ static int __init pci_mmcfg_check_hostbridge(void) | |||
| 322 | name = pci_mmcfg_probes[i].probe(); | 349 | name = pci_mmcfg_probes[i].probe(); |
| 323 | 350 | ||
| 324 | if (name) | 351 | if (name) |
| 325 | printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n", | 352 | printk(KERN_INFO PREFIX "%s with MMCONFIG support\n", |
| 326 | name); | 353 | name); |
| 327 | } | 354 | } |
| 328 | 355 | ||
| 329 | /* some end_bus_number is crazy, fix it */ | 356 | /* some end_bus_number is crazy, fix it */ |
| 330 | pci_mmcfg_check_end_bus_number(); | 357 | pci_mmcfg_check_end_bus_number(); |
| 331 | 358 | ||
| 332 | return pci_mmcfg_config_num != 0; | 359 | return !list_empty(&pci_mmcfg_list); |
| 333 | } | 360 | } |
| 334 | 361 | ||
| 335 | static void __init pci_mmcfg_insert_resources(void) | 362 | static void __init pci_mmcfg_insert_resources(void) |
| 336 | { | 363 | { |
| 337 | #define PCI_MMCFG_RESOURCE_NAME_LEN 24 | 364 | struct pci_mmcfg_region *cfg; |
| 338 | int i; | ||
| 339 | struct resource *res; | ||
| 340 | char *names; | ||
| 341 | unsigned num_buses; | ||
| 342 | |||
| 343 | res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), | ||
| 344 | pci_mmcfg_config_num, GFP_KERNEL); | ||
| 345 | if (!res) { | ||
| 346 | printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); | ||
| 347 | return; | ||
| 348 | } | ||
| 349 | 365 | ||
| 350 | names = (void *)&res[pci_mmcfg_config_num]; | 366 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
| 351 | for (i = 0; i < pci_mmcfg_config_num; i++, res++) { | 367 | insert_resource(&iomem_resource, &cfg->res); |
| 352 | struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i]; | ||
| 353 | num_buses = cfg->end_bus_number - cfg->start_bus_number + 1; | ||
| 354 | res->name = names; | ||
| 355 | snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, | ||
| 356 | "PCI MMCONFIG %u [%02x-%02x]", cfg->pci_segment, | ||
| 357 | cfg->start_bus_number, cfg->end_bus_number); | ||
| 358 | res->start = cfg->address + (cfg->start_bus_number << 20); | ||
| 359 | res->end = res->start + (num_buses << 20) - 1; | ||
| 360 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
| 361 | insert_resource(&iomem_resource, res); | ||
| 362 | names += PCI_MMCFG_RESOURCE_NAME_LEN; | ||
| 363 | } | ||
| 364 | 368 | ||
| 365 | /* Mark that the resources have been inserted. */ | 369 | /* Mark that the resources have been inserted. */ |
| 366 | pci_mmcfg_resources_inserted = 1; | 370 | pci_mmcfg_resources_inserted = 1; |
| @@ -437,11 +441,12 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) | |||
| 437 | typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); | 441 | typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); |
| 438 | 442 | ||
| 439 | static int __init is_mmconf_reserved(check_reserved_t is_reserved, | 443 | static int __init is_mmconf_reserved(check_reserved_t is_reserved, |
| 440 | u64 addr, u64 size, int i, | 444 | struct pci_mmcfg_region *cfg, int with_e820) |
| 441 | typeof(pci_mmcfg_config[0]) *cfg, int with_e820) | ||
| 442 | { | 445 | { |
| 446 | u64 addr = cfg->res.start; | ||
| 447 | u64 size = resource_size(&cfg->res); | ||
| 443 | u64 old_size = size; | 448 | u64 old_size = size; |
| 444 | int valid = 0; | 449 | int valid = 0, num_buses; |
| 445 | 450 | ||
| 446 | while (!is_reserved(addr, addr + size, E820_RESERVED)) { | 451 | while (!is_reserved(addr, addr + size, E820_RESERVED)) { |
| 447 | size >>= 1; | 452 | size >>= 1; |
| @@ -450,19 +455,25 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved, | |||
| 450 | } | 455 | } |
| 451 | 456 | ||
| 452 | if (size >= (16UL<<20) || size == old_size) { | 457 | if (size >= (16UL<<20) || size == old_size) { |
| 453 | printk(KERN_NOTICE | 458 | printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n", |
| 454 | "PCI: MCFG area at %Lx reserved in %s\n", | 459 | &cfg->res, |
| 455 | addr, with_e820?"E820":"ACPI motherboard resources"); | 460 | with_e820 ? "E820" : "ACPI motherboard resources"); |
| 456 | valid = 1; | 461 | valid = 1; |
| 457 | 462 | ||
| 458 | if (old_size != size) { | 463 | if (old_size != size) { |
| 459 | /* update end_bus_number */ | 464 | /* update end_bus */ |
| 460 | cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1); | 465 | cfg->end_bus = cfg->start_bus + ((size>>20) - 1); |
| 461 | printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx " | 466 | num_buses = cfg->end_bus - cfg->start_bus + 1; |
| 462 | "segment %hu buses %u - %u\n", | 467 | cfg->res.end = cfg->res.start + |
| 463 | i, (unsigned long)cfg->address, cfg->pci_segment, | 468 | PCI_MMCFG_BUS_OFFSET(num_buses) - 1; |
| 464 | (unsigned int)cfg->start_bus_number, | 469 | snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN, |
| 465 | (unsigned int)cfg->end_bus_number); | 470 | "PCI MMCONFIG %04x [bus %02x-%02x]", |
| 471 | cfg->segment, cfg->start_bus, cfg->end_bus); | ||
| 472 | printk(KERN_INFO PREFIX | ||
| 473 | "MMCONFIG for %04x [bus%02x-%02x] " | ||
| 474 | "at %pR (base %#lx) (size reduced!)\n", | ||
| 475 | cfg->segment, cfg->start_bus, cfg->end_bus, | ||
| 476 | &cfg->res, (unsigned long) cfg->address); | ||
| 466 | } | 477 | } |
| 467 | } | 478 | } |
| 468 | 479 | ||
| @@ -471,45 +482,26 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved, | |||
| 471 | 482 | ||
| 472 | static void __init pci_mmcfg_reject_broken(int early) | 483 | static void __init pci_mmcfg_reject_broken(int early) |
| 473 | { | 484 | { |
| 474 | typeof(pci_mmcfg_config[0]) *cfg; | 485 | struct pci_mmcfg_region *cfg; |
| 475 | int i; | ||
| 476 | 486 | ||
| 477 | if ((pci_mmcfg_config_num == 0) || | 487 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
| 478 | (pci_mmcfg_config == NULL) || | ||
| 479 | (pci_mmcfg_config[0].address == 0)) | ||
| 480 | return; | ||
| 481 | |||
| 482 | for (i = 0; i < pci_mmcfg_config_num; i++) { | ||
| 483 | int valid = 0; | 488 | int valid = 0; |
| 484 | u64 addr, size; | ||
| 485 | |||
| 486 | cfg = &pci_mmcfg_config[i]; | ||
| 487 | addr = cfg->start_bus_number; | ||
| 488 | addr <<= 20; | ||
| 489 | addr += cfg->address; | ||
| 490 | size = cfg->end_bus_number + 1 - cfg->start_bus_number; | ||
| 491 | size <<= 20; | ||
| 492 | printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " | ||
| 493 | "segment %hu buses %u - %u\n", | ||
| 494 | i, (unsigned long)cfg->address, cfg->pci_segment, | ||
| 495 | (unsigned int)cfg->start_bus_number, | ||
| 496 | (unsigned int)cfg->end_bus_number); | ||
| 497 | 489 | ||
| 498 | if (!early && !acpi_disabled) | 490 | if (!early && !acpi_disabled) |
| 499 | valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0); | 491 | valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0); |
| 500 | 492 | ||
| 501 | if (valid) | 493 | if (valid) |
| 502 | continue; | 494 | continue; |
| 503 | 495 | ||
| 504 | if (!early) | 496 | if (!early) |
| 505 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" | 497 | printk(KERN_ERR FW_BUG PREFIX |
| 506 | " reserved in ACPI motherboard resources\n", | 498 | "MMCONFIG at %pR not reserved in " |
| 507 | cfg->address); | 499 | "ACPI motherboard resources\n", &cfg->res); |
| 508 | 500 | ||
| 509 | /* Don't try to do this check unless configuration | 501 | /* Don't try to do this check unless configuration |
| 510 | type 1 is available. how about type 2 ?*/ | 502 | type 1 is available. how about type 2 ?*/ |
| 511 | if (raw_pci_ops) | 503 | if (raw_pci_ops) |
| 512 | valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1); | 504 | valid = is_mmconf_reserved(e820_all_mapped, cfg, 1); |
| 513 | 505 | ||
| 514 | if (!valid) | 506 | if (!valid) |
| 515 | goto reject; | 507 | goto reject; |
| @@ -518,34 +510,41 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
| 518 | return; | 510 | return; |
| 519 | 511 | ||
| 520 | reject: | 512 | reject: |
| 521 | printk(KERN_INFO "PCI: Not using MMCONFIG.\n"); | 513 | printk(KERN_INFO PREFIX "not using MMCONFIG\n"); |
| 522 | pci_mmcfg_arch_free(); | 514 | free_all_mmcfg(); |
| 523 | kfree(pci_mmcfg_config); | ||
| 524 | pci_mmcfg_config = NULL; | ||
| 525 | pci_mmcfg_config_num = 0; | ||
| 526 | } | 515 | } |
| 527 | 516 | ||
| 528 | static int __initdata known_bridge; | 517 | static int __initdata known_bridge; |
| 529 | 518 | ||
| 530 | static int acpi_mcfg_64bit_base_addr __initdata = FALSE; | 519 | static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, |
| 520 | struct acpi_mcfg_allocation *cfg) | ||
| 521 | { | ||
| 522 | int year; | ||
| 531 | 523 | ||
| 532 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ | 524 | if (cfg->address < 0xFFFFFFFF) |
| 533 | struct acpi_mcfg_allocation *pci_mmcfg_config; | 525 | return 0; |
| 534 | int pci_mmcfg_config_num; | ||
| 535 | 526 | ||
| 536 | static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg) | ||
| 537 | { | ||
| 538 | if (!strcmp(mcfg->header.oem_id, "SGI")) | 527 | if (!strcmp(mcfg->header.oem_id, "SGI")) |
| 539 | acpi_mcfg_64bit_base_addr = TRUE; | 528 | return 0; |
| 540 | 529 | ||
| 541 | return 0; | 530 | if (mcfg->header.revision >= 1) { |
| 531 | if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && | ||
| 532 | year >= 2010) | ||
| 533 | return 0; | ||
| 534 | } | ||
| 535 | |||
| 536 | printk(KERN_ERR PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " | ||
| 537 | "is above 4GB, ignored\n", cfg->pci_segment, | ||
| 538 | cfg->start_bus_number, cfg->end_bus_number, cfg->address); | ||
| 539 | return -EINVAL; | ||
| 542 | } | 540 | } |
| 543 | 541 | ||
| 544 | static int __init pci_parse_mcfg(struct acpi_table_header *header) | 542 | static int __init pci_parse_mcfg(struct acpi_table_header *header) |
| 545 | { | 543 | { |
| 546 | struct acpi_table_mcfg *mcfg; | 544 | struct acpi_table_mcfg *mcfg; |
| 545 | struct acpi_mcfg_allocation *cfg_table, *cfg; | ||
| 547 | unsigned long i; | 546 | unsigned long i; |
| 548 | int config_size; | 547 | int entries; |
| 549 | 548 | ||
| 550 | if (!header) | 549 | if (!header) |
| 551 | return -EINVAL; | 550 | return -EINVAL; |
| @@ -553,38 +552,33 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) | |||
| 553 | mcfg = (struct acpi_table_mcfg *)header; | 552 | mcfg = (struct acpi_table_mcfg *)header; |
| 554 | 553 | ||
| 555 | /* how many config structures do we have */ | 554 | /* how many config structures do we have */ |
| 556 | pci_mmcfg_config_num = 0; | 555 | free_all_mmcfg(); |
| 556 | entries = 0; | ||
| 557 | i = header->length - sizeof(struct acpi_table_mcfg); | 557 | i = header->length - sizeof(struct acpi_table_mcfg); |
| 558 | while (i >= sizeof(struct acpi_mcfg_allocation)) { | 558 | while (i >= sizeof(struct acpi_mcfg_allocation)) { |
| 559 | ++pci_mmcfg_config_num; | 559 | entries++; |
| 560 | i -= sizeof(struct acpi_mcfg_allocation); | 560 | i -= sizeof(struct acpi_mcfg_allocation); |
| 561 | }; | 561 | }; |
| 562 | if (pci_mmcfg_config_num == 0) { | 562 | if (entries == 0) { |
| 563 | printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); | 563 | printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); |
| 564 | return -ENODEV; | 564 | return -ENODEV; |
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); | 567 | cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1]; |
| 568 | pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); | 568 | for (i = 0; i < entries; i++) { |
| 569 | if (!pci_mmcfg_config) { | 569 | cfg = &cfg_table[i]; |
| 570 | printk(KERN_WARNING PREFIX | 570 | if (acpi_mcfg_check_entry(mcfg, cfg)) { |
| 571 | "No memory for MCFG config tables\n"); | 571 | free_all_mmcfg(); |
| 572 | return -ENOMEM; | ||
| 573 | } | ||
| 574 | |||
| 575 | memcpy(pci_mmcfg_config, &mcfg[1], config_size); | ||
| 576 | |||
| 577 | acpi_mcfg_oem_check(mcfg); | ||
| 578 | |||
| 579 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | ||
| 580 | if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) && | ||
| 581 | !acpi_mcfg_64bit_base_addr) { | ||
| 582 | printk(KERN_ERR PREFIX | ||
| 583 | "MMCONFIG not in low 4GB of memory\n"); | ||
| 584 | kfree(pci_mmcfg_config); | ||
| 585 | pci_mmcfg_config_num = 0; | ||
| 586 | return -ENODEV; | 572 | return -ENODEV; |
| 587 | } | 573 | } |
| 574 | |||
| 575 | if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number, | ||
| 576 | cfg->end_bus_number, cfg->address) == NULL) { | ||
| 577 | printk(KERN_WARNING PREFIX | ||
| 578 | "no memory for MCFG entries\n"); | ||
| 579 | free_all_mmcfg(); | ||
| 580 | return -ENOMEM; | ||
| 581 | } | ||
| 588 | } | 582 | } |
| 589 | 583 | ||
| 590 | return 0; | 584 | return 0; |
| @@ -614,9 +608,7 @@ static void __init __pci_mmcfg_init(int early) | |||
| 614 | 608 | ||
| 615 | pci_mmcfg_reject_broken(early); | 609 | pci_mmcfg_reject_broken(early); |
| 616 | 610 | ||
| 617 | if ((pci_mmcfg_config_num == 0) || | 611 | if (list_empty(&pci_mmcfg_list)) |
| 618 | (pci_mmcfg_config == NULL) || | ||
| 619 | (pci_mmcfg_config[0].address == 0)) | ||
| 620 | return; | 612 | return; |
| 621 | 613 | ||
| 622 | if (pci_mmcfg_arch_init()) | 614 | if (pci_mmcfg_arch_init()) |
| @@ -648,9 +640,7 @@ static int __init pci_mmcfg_late_insert_resources(void) | |||
| 648 | */ | 640 | */ |
| 649 | if ((pci_mmcfg_resources_inserted == 1) || | 641 | if ((pci_mmcfg_resources_inserted == 1) || |
| 650 | (pci_probe & PCI_PROBE_MMCONF) == 0 || | 642 | (pci_probe & PCI_PROBE_MMCONF) == 0 || |
| 651 | (pci_mmcfg_config_num == 0) || | 643 | list_empty(&pci_mmcfg_list)) |
| 652 | (pci_mmcfg_config == NULL) || | ||
| 653 | (pci_mmcfg_config[0].address == 0)) | ||
| 654 | return 1; | 644 | return 1; |
| 655 | 645 | ||
| 656 | /* | 646 | /* |
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index f10a7e94a84c..90d5fd476ed4 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c | |||
| @@ -27,18 +27,10 @@ static int mmcfg_last_accessed_cpu; | |||
| 27 | */ | 27 | */ |
| 28 | static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | 28 | static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) |
| 29 | { | 29 | { |
| 30 | struct acpi_mcfg_allocation *cfg; | 30 | struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus); |
| 31 | int cfg_num; | ||
| 32 | |||
| 33 | for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) { | ||
| 34 | cfg = &pci_mmcfg_config[cfg_num]; | ||
| 35 | if (cfg->pci_segment == seg && | ||
| 36 | (cfg->start_bus_number <= bus) && | ||
| 37 | (cfg->end_bus_number >= bus)) | ||
| 38 | return cfg->address; | ||
| 39 | } | ||
| 40 | 31 | ||
| 41 | /* Fall back to type 0 */ | 32 | if (cfg) |
| 33 | return cfg->address; | ||
| 42 | return 0; | 34 | return 0; |
| 43 | } | 35 | } |
| 44 | 36 | ||
| @@ -47,7 +39,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
| 47 | */ | 39 | */ |
| 48 | static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) | 40 | static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) |
| 49 | { | 41 | { |
| 50 | u32 dev_base = base | (bus << 20) | (devfn << 12); | 42 | u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12); |
| 51 | int cpu = smp_processor_id(); | 43 | int cpu = smp_processor_id(); |
| 52 | if (dev_base != mmcfg_last_accessed_device || | 44 | if (dev_base != mmcfg_last_accessed_device || |
| 53 | cpu != mmcfg_last_accessed_cpu) { | 45 | cpu != mmcfg_last_accessed_cpu) { |
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index 94349f8b2f96..e783841bd1d7 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c | |||
| @@ -12,38 +12,15 @@ | |||
| 12 | #include <asm/e820.h> | 12 | #include <asm/e820.h> |
| 13 | #include <asm/pci_x86.h> | 13 | #include <asm/pci_x86.h> |
| 14 | 14 | ||
| 15 | /* Static virtual mapping of the MMCONFIG aperture */ | 15 | #define PREFIX "PCI: " |
| 16 | struct mmcfg_virt { | ||
| 17 | struct acpi_mcfg_allocation *cfg; | ||
| 18 | char __iomem *virt; | ||
| 19 | }; | ||
| 20 | static struct mmcfg_virt *pci_mmcfg_virt; | ||
| 21 | |||
| 22 | static char __iomem *get_virt(unsigned int seg, unsigned bus) | ||
| 23 | { | ||
| 24 | struct acpi_mcfg_allocation *cfg; | ||
| 25 | int cfg_num; | ||
| 26 | |||
| 27 | for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) { | ||
| 28 | cfg = pci_mmcfg_virt[cfg_num].cfg; | ||
| 29 | if (cfg->pci_segment == seg && | ||
| 30 | (cfg->start_bus_number <= bus) && | ||
| 31 | (cfg->end_bus_number >= bus)) | ||
| 32 | return pci_mmcfg_virt[cfg_num].virt; | ||
| 33 | } | ||
| 34 | |||
| 35 | /* Fall back to type 0 */ | ||
| 36 | return NULL; | ||
| 37 | } | ||
| 38 | 16 | ||
| 39 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | 17 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) |
| 40 | { | 18 | { |
| 41 | char __iomem *addr; | 19 | struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus); |
| 42 | 20 | ||
| 43 | addr = get_virt(seg, bus); | 21 | if (cfg && cfg->virt) |
| 44 | if (!addr) | 22 | return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12)); |
| 45 | return NULL; | 23 | return NULL; |
| 46 | return addr + ((bus << 20) | (devfn << 12)); | ||
| 47 | } | 24 | } |
| 48 | 25 | ||
| 49 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | 26 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, |
| @@ -109,42 +86,30 @@ static struct pci_raw_ops pci_mmcfg = { | |||
| 109 | .write = pci_mmcfg_write, | 86 | .write = pci_mmcfg_write, |
| 110 | }; | 87 | }; |
| 111 | 88 | ||
| 112 | static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg) | 89 | static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg) |
| 113 | { | 90 | { |
| 114 | void __iomem *addr; | 91 | void __iomem *addr; |
| 115 | u64 start, size; | 92 | u64 start, size; |
| 93 | int num_buses; | ||
| 116 | 94 | ||
| 117 | start = cfg->start_bus_number; | 95 | start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus); |
| 118 | start <<= 20; | 96 | num_buses = cfg->end_bus - cfg->start_bus + 1; |
| 119 | start += cfg->address; | 97 | size = PCI_MMCFG_BUS_OFFSET(num_buses); |
| 120 | size = cfg->end_bus_number + 1 - cfg->start_bus_number; | ||
| 121 | size <<= 20; | ||
| 122 | addr = ioremap_nocache(start, size); | 98 | addr = ioremap_nocache(start, size); |
| 123 | if (addr) { | 99 | if (addr) |
| 124 | printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n", | 100 | addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus); |
| 125 | start, start + size - 1); | ||
| 126 | addr -= cfg->start_bus_number << 20; | ||
| 127 | } | ||
| 128 | return addr; | 101 | return addr; |
| 129 | } | 102 | } |
| 130 | 103 | ||
| 131 | int __init pci_mmcfg_arch_init(void) | 104 | int __init pci_mmcfg_arch_init(void) |
| 132 | { | 105 | { |
| 133 | int i; | 106 | struct pci_mmcfg_region *cfg; |
| 134 | pci_mmcfg_virt = kzalloc(sizeof(*pci_mmcfg_virt) * | ||
| 135 | pci_mmcfg_config_num, GFP_KERNEL); | ||
| 136 | if (pci_mmcfg_virt == NULL) { | ||
| 137 | printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n"); | ||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | 107 | ||
| 141 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | 108 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
| 142 | pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; | 109 | cfg->virt = mcfg_ioremap(cfg); |
| 143 | pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]); | 110 | if (!cfg->virt) { |
| 144 | if (!pci_mmcfg_virt[i].virt) { | 111 | printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", |
| 145 | printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " | 112 | &cfg->res); |
| 146 | "segment %d\n", | ||
| 147 | pci_mmcfg_config[i].pci_segment); | ||
| 148 | pci_mmcfg_arch_free(); | 113 | pci_mmcfg_arch_free(); |
| 149 | return 0; | 114 | return 0; |
| 150 | } | 115 | } |
| @@ -155,19 +120,12 @@ int __init pci_mmcfg_arch_init(void) | |||
| 155 | 120 | ||
| 156 | void __init pci_mmcfg_arch_free(void) | 121 | void __init pci_mmcfg_arch_free(void) |
| 157 | { | 122 | { |
| 158 | int i; | 123 | struct pci_mmcfg_region *cfg; |
| 159 | |||
| 160 | if (pci_mmcfg_virt == NULL) | ||
| 161 | return; | ||
| 162 | 124 | ||
| 163 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | 125 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
| 164 | if (pci_mmcfg_virt[i].virt) { | 126 | if (cfg->virt) { |
| 165 | iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20)); | 127 | iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); |
| 166 | pci_mmcfg_virt[i].virt = NULL; | 128 | cfg->virt = NULL; |
| 167 | pci_mmcfg_virt[i].cfg = NULL; | ||
| 168 | } | 129 | } |
| 169 | } | 130 | } |
| 170 | |||
| 171 | kfree(pci_mmcfg_virt); | ||
| 172 | pci_mmcfg_virt = NULL; | ||
| 173 | } | 131 | } |
diff --git a/arch/x86/tools/test_get_len.c b/arch/x86/tools/test_get_len.c index d8214dc03fa7..bee8d6ac2691 100644 --- a/arch/x86/tools/test_get_len.c +++ b/arch/x86/tools/test_get_len.c | |||
| @@ -113,7 +113,7 @@ int main(int argc, char **argv) | |||
| 113 | char line[BUFSIZE], sym[BUFSIZE] = "<unknown>"; | 113 | char line[BUFSIZE], sym[BUFSIZE] = "<unknown>"; |
| 114 | unsigned char insn_buf[16]; | 114 | unsigned char insn_buf[16]; |
| 115 | struct insn insn; | 115 | struct insn insn; |
| 116 | int insns = 0, c; | 116 | int insns = 0; |
| 117 | int warnings = 0; | 117 | int warnings = 0; |
| 118 | 118 | ||
| 119 | parse_args(argc, argv); | 119 | parse_args(argc, argv); |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index b8e45f164e2a..2b26dd5930c6 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -27,7 +27,9 @@ | |||
| 27 | #include <linux/page-flags.h> | 27 | #include <linux/page-flags.h> |
| 28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
| 29 | #include <linux/console.h> | 29 | #include <linux/console.h> |
| 30 | #include <linux/pci.h> | ||
| 30 | 31 | ||
| 32 | #include <xen/xen.h> | ||
| 31 | #include <xen/interface/xen.h> | 33 | #include <xen/interface/xen.h> |
| 32 | #include <xen/interface/version.h> | 34 | #include <xen/interface/version.h> |
| 33 | #include <xen/interface/physdev.h> | 35 | #include <xen/interface/physdev.h> |
| @@ -1175,7 +1177,11 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1175 | add_preferred_console("xenboot", 0, NULL); | 1177 | add_preferred_console("xenboot", 0, NULL); |
| 1176 | add_preferred_console("tty", 0, NULL); | 1178 | add_preferred_console("tty", 0, NULL); |
| 1177 | add_preferred_console("hvc", 0, NULL); | 1179 | add_preferred_console("hvc", 0, NULL); |
| 1180 | } else { | ||
| 1181 | /* Make sure ACS will be enabled */ | ||
| 1182 | pci_request_acs(); | ||
| 1178 | } | 1183 | } |
| 1184 | |||
| 1179 | 1185 | ||
| 1180 | xen_raw_console_write("about to get started...\n"); | 1186 | xen_raw_console_write("about to get started...\n"); |
| 1181 | 1187 | ||
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h index 05cebf8f62b1..4352dbe1186a 100644 --- a/arch/xtensa/include/asm/syscall.h +++ b/arch/xtensa/include/asm/syscall.h | |||
| @@ -13,8 +13,6 @@ struct sigaction; | |||
| 13 | asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); | 13 | asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); |
| 14 | asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); | 14 | asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); |
| 15 | asmlinkage long xtensa_pipe(int __user *); | 15 | asmlinkage long xtensa_pipe(int __user *); |
| 16 | asmlinkage long xtensa_mmap2(unsigned long, unsigned long, unsigned long, | ||
| 17 | unsigned long, unsigned long, unsigned long); | ||
| 18 | asmlinkage long xtensa_ptrace(long, long, long, long); | 16 | asmlinkage long xtensa_ptrace(long, long, long, long); |
| 19 | asmlinkage long xtensa_sigreturn(struct pt_regs*); | 17 | asmlinkage long xtensa_sigreturn(struct pt_regs*); |
| 20 | asmlinkage long xtensa_rt_sigreturn(struct pt_regs*); | 18 | asmlinkage long xtensa_rt_sigreturn(struct pt_regs*); |
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h index 4e55dc763021..fbf318b3af3e 100644 --- a/arch/xtensa/include/asm/unistd.h +++ b/arch/xtensa/include/asm/unistd.h | |||
| @@ -189,7 +189,7 @@ __SYSCALL( 79, sys_fremovexattr, 2) | |||
| 189 | /* File Map / Shared Memory Operations */ | 189 | /* File Map / Shared Memory Operations */ |
| 190 | 190 | ||
| 191 | #define __NR_mmap2 80 | 191 | #define __NR_mmap2 80 |
| 192 | __SYSCALL( 80, xtensa_mmap2, 6) | 192 | __SYSCALL( 80, sys_mmap_pgoff, 6) |
| 193 | #define __NR_munmap 81 | 193 | #define __NR_munmap 81 |
| 194 | __SYSCALL( 81, sys_munmap, 2) | 194 | __SYSCALL( 81, sys_munmap, 2) |
| 195 | #define __NR_mprotect 82 | 195 | #define __NR_mprotect 82 |
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index ac15ecbdf919..1e67bab775c1 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c | |||
| @@ -57,31 +57,6 @@ asmlinkage long xtensa_pipe(int __user *userfds) | |||
| 57 | return error; | 57 | return error; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | |||
| 61 | asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len, | ||
| 62 | unsigned long prot, unsigned long flags, | ||
| 63 | unsigned long fd, unsigned long pgoff) | ||
| 64 | { | ||
| 65 | int error = -EBADF; | ||
| 66 | struct file * file = NULL; | ||
| 67 | |||
| 68 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
| 69 | if (!(flags & MAP_ANONYMOUS)) { | ||
| 70 | file = fget(fd); | ||
| 71 | if (!file) | ||
| 72 | goto out; | ||
| 73 | } | ||
| 74 | |||
| 75 | down_write(¤t->mm->mmap_sem); | ||
| 76 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
| 77 | up_write(¤t->mm->mmap_sem); | ||
| 78 | |||
| 79 | if (file) | ||
| 80 | fput(file); | ||
| 81 | out: | ||
| 82 | return error; | ||
| 83 | } | ||
| 84 | |||
| 85 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) | 60 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) |
| 86 | { | 61 | { |
| 87 | unsigned long ret; | 62 | unsigned long ret; |
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 4c559cf7da2d..e60a1f57022f 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c | |||
| @@ -196,7 +196,7 @@ static const struct file_operations rs_proc_fops = { | |||
| 196 | .release = single_release, | 196 | .release = single_release, |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | static struct tty_operations serial_ops = { | 199 | static const struct tty_operations serial_ops = { |
| 200 | .open = rs_open, | 200 | .open = rs_open, |
| 201 | .close = rs_close, | 201 | .close = rs_close, |
| 202 | .write = rs_write, | 202 | .write = rs_write, |
