diff options
107 files changed, 1072 insertions, 500 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index f935a0cef404..14bc7071f9df 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1077,7 +1077,7 @@ F: drivers/media/video/s5p-fimc/ | |||
| 1077 | ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT | 1077 | ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT |
| 1078 | M: Kyungmin Park <kyungmin.park@samsung.com> | 1078 | M: Kyungmin Park <kyungmin.park@samsung.com> |
| 1079 | M: Kamil Debski <k.debski@samsung.com> | 1079 | M: Kamil Debski <k.debski@samsung.com> |
| 1080 | M: Jeongtae Park <jtp.park@samsung.com> | 1080 | M: Jeongtae Park <jtp.park@samsung.com> |
| 1081 | L: linux-arm-kernel@lists.infradead.org | 1081 | L: linux-arm-kernel@lists.infradead.org |
| 1082 | L: linux-media@vger.kernel.org | 1082 | L: linux-media@vger.kernel.org |
| 1083 | S: Maintained | 1083 | S: Maintained |
| @@ -1743,10 +1743,10 @@ F: include/linux/can/platform/ | |||
| 1743 | CAPABILITIES | 1743 | CAPABILITIES |
| 1744 | M: Serge Hallyn <serge.hallyn@canonical.com> | 1744 | M: Serge Hallyn <serge.hallyn@canonical.com> |
| 1745 | L: linux-security-module@vger.kernel.org | 1745 | L: linux-security-module@vger.kernel.org |
| 1746 | S: Supported | 1746 | S: Supported |
| 1747 | F: include/linux/capability.h | 1747 | F: include/linux/capability.h |
| 1748 | F: security/capability.c | 1748 | F: security/capability.c |
| 1749 | F: security/commoncap.c | 1749 | F: security/commoncap.c |
| 1750 | F: kernel/capability.c | 1750 | F: kernel/capability.c |
| 1751 | 1751 | ||
| 1752 | CELL BROADBAND ENGINE ARCHITECTURE | 1752 | CELL BROADBAND ENGINE ARCHITECTURE |
| @@ -2146,11 +2146,11 @@ S: Orphan | |||
| 2146 | F: drivers/net/wan/pc300* | 2146 | F: drivers/net/wan/pc300* |
| 2147 | 2147 | ||
| 2148 | CYTTSP TOUCHSCREEN DRIVER | 2148 | CYTTSP TOUCHSCREEN DRIVER |
| 2149 | M: Javier Martinez Canillas <javier@dowhile0.org> | 2149 | M: Javier Martinez Canillas <javier@dowhile0.org> |
| 2150 | L: linux-input@vger.kernel.org | 2150 | L: linux-input@vger.kernel.org |
| 2151 | S: Maintained | 2151 | S: Maintained |
| 2152 | F: drivers/input/touchscreen/cyttsp* | 2152 | F: drivers/input/touchscreen/cyttsp* |
| 2153 | F: include/linux/input/cyttsp.h | 2153 | F: include/linux/input/cyttsp.h |
| 2154 | 2154 | ||
| 2155 | DAMA SLAVE for AX.25 | 2155 | DAMA SLAVE for AX.25 |
| 2156 | M: Joerg Reuter <jreuter@yaina.de> | 2156 | M: Joerg Reuter <jreuter@yaina.de> |
| @@ -2270,7 +2270,7 @@ F: include/linux/device-mapper.h | |||
| 2270 | F: include/linux/dm-*.h | 2270 | F: include/linux/dm-*.h |
| 2271 | 2271 | ||
| 2272 | DIOLAN U2C-12 I2C DRIVER | 2272 | DIOLAN U2C-12 I2C DRIVER |
| 2273 | M: Guenter Roeck <guenter.roeck@ericsson.com> | 2273 | M: Guenter Roeck <linux@roeck-us.net> |
| 2274 | L: linux-i2c@vger.kernel.org | 2274 | L: linux-i2c@vger.kernel.org |
| 2275 | S: Maintained | 2275 | S: Maintained |
| 2276 | F: drivers/i2c/busses/i2c-diolan-u2c.c | 2276 | F: drivers/i2c/busses/i2c-diolan-u2c.c |
| @@ -3145,7 +3145,7 @@ F: drivers/tty/hvc/ | |||
| 3145 | 3145 | ||
| 3146 | HARDWARE MONITORING | 3146 | HARDWARE MONITORING |
| 3147 | M: Jean Delvare <khali@linux-fr.org> | 3147 | M: Jean Delvare <khali@linux-fr.org> |
| 3148 | M: Guenter Roeck <guenter.roeck@ericsson.com> | 3148 | M: Guenter Roeck <linux@roeck-us.net> |
| 3149 | L: lm-sensors@lm-sensors.org | 3149 | L: lm-sensors@lm-sensors.org |
| 3150 | W: http://www.lm-sensors.org/ | 3150 | W: http://www.lm-sensors.org/ |
| 3151 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ | 3151 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ |
| @@ -4420,6 +4420,13 @@ S: Orphan | |||
| 4420 | F: drivers/video/matrox/matroxfb_* | 4420 | F: drivers/video/matrox/matroxfb_* |
| 4421 | F: include/linux/matroxfb.h | 4421 | F: include/linux/matroxfb.h |
| 4422 | 4422 | ||
| 4423 | MAX16065 HARDWARE MONITOR DRIVER | ||
| 4424 | M: Guenter Roeck <linux@roeck-us.net> | ||
| 4425 | L: lm-sensors@lm-sensors.org | ||
| 4426 | S: Maintained | ||
| 4427 | F: Documentation/hwmon/max16065 | ||
| 4428 | F: drivers/hwmon/max16065.c | ||
| 4429 | |||
| 4423 | MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER | 4430 | MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER |
| 4424 | M: "Hans J. Koch" <hjk@hansjkoch.de> | 4431 | M: "Hans J. Koch" <hjk@hansjkoch.de> |
| 4425 | L: lm-sensors@lm-sensors.org | 4432 | L: lm-sensors@lm-sensors.org |
| @@ -5158,7 +5165,7 @@ F: drivers/leds/leds-pca9532.c | |||
| 5158 | F: include/linux/leds-pca9532.h | 5165 | F: include/linux/leds-pca9532.h |
| 5159 | 5166 | ||
| 5160 | PCA9541 I2C BUS MASTER SELECTOR DRIVER | 5167 | PCA9541 I2C BUS MASTER SELECTOR DRIVER |
| 5161 | M: Guenter Roeck <guenter.roeck@ericsson.com> | 5168 | M: Guenter Roeck <linux@roeck-us.net> |
| 5162 | L: linux-i2c@vger.kernel.org | 5169 | L: linux-i2c@vger.kernel.org |
| 5163 | S: Maintained | 5170 | S: Maintained |
| 5164 | F: drivers/i2c/muxes/i2c-mux-pca9541.c | 5171 | F: drivers/i2c/muxes/i2c-mux-pca9541.c |
| @@ -5178,7 +5185,7 @@ S: Maintained | |||
| 5178 | F: drivers/firmware/pcdp.* | 5185 | F: drivers/firmware/pcdp.* |
| 5179 | 5186 | ||
| 5180 | PCI ERROR RECOVERY | 5187 | PCI ERROR RECOVERY |
| 5181 | M: Linas Vepstas <linasvepstas@gmail.com> | 5188 | M: Linas Vepstas <linasvepstas@gmail.com> |
| 5182 | L: linux-pci@vger.kernel.org | 5189 | L: linux-pci@vger.kernel.org |
| 5183 | S: Supported | 5190 | S: Supported |
| 5184 | F: Documentation/PCI/pci-error-recovery.txt | 5191 | F: Documentation/PCI/pci-error-recovery.txt |
| @@ -5308,7 +5315,7 @@ F: drivers/video/fb-puv3.c | |||
| 5308 | F: drivers/rtc/rtc-puv3.c | 5315 | F: drivers/rtc/rtc-puv3.c |
| 5309 | 5316 | ||
| 5310 | PMBUS HARDWARE MONITORING DRIVERS | 5317 | PMBUS HARDWARE MONITORING DRIVERS |
| 5311 | M: Guenter Roeck <guenter.roeck@ericsson.com> | 5318 | M: Guenter Roeck <linux@roeck-us.net> |
| 5312 | L: lm-sensors@lm-sensors.org | 5319 | L: lm-sensors@lm-sensors.org |
| 5313 | W: http://www.lm-sensors.org/ | 5320 | W: http://www.lm-sensors.org/ |
| 5314 | W: http://www.roeck-us.net/linux/drivers/ | 5321 | W: http://www.roeck-us.net/linux/drivers/ |
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index dbc3850b1d0d..5707f1a62341 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile | |||
| @@ -21,6 +21,7 @@ KBUILD_DEFCONFIG := default_defconfig | |||
| 21 | 21 | ||
| 22 | NM = sh $(srctree)/arch/parisc/nm | 22 | NM = sh $(srctree)/arch/parisc/nm |
| 23 | CHECKFLAGS += -D__hppa__=1 | 23 | CHECKFLAGS += -D__hppa__=1 |
| 24 | LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) | ||
| 24 | 25 | ||
| 25 | MACHINE := $(shell uname -m) | 26 | MACHINE := $(shell uname -m) |
| 26 | ifeq ($(MACHINE),parisc*) | 27 | ifeq ($(MACHINE),parisc*) |
| @@ -79,7 +80,7 @@ kernel-y := mm/ kernel/ math-emu/ | |||
| 79 | kernel-$(CONFIG_HPUX) += hpux/ | 80 | kernel-$(CONFIG_HPUX) += hpux/ |
| 80 | 81 | ||
| 81 | core-y += $(addprefix arch/parisc/, $(kernel-y)) | 82 | core-y += $(addprefix arch/parisc/, $(kernel-y)) |
| 82 | libs-y += arch/parisc/lib/ `$(CC) -print-libgcc-file-name` | 83 | libs-y += arch/parisc/lib/ $(LIBGCC) |
| 83 | 84 | ||
| 84 | drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ | 85 | drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ |
| 85 | 86 | ||
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index 19a434f55059..4383707d9801 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | include include/asm-generic/Kbuild.asm | 1 | include include/asm-generic/Kbuild.asm |
| 2 | 2 | ||
| 3 | header-y += pdc.h | 3 | header-y += pdc.h |
| 4 | generic-y += word-at-a-time.h | ||
diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h index 72cfdb0cfdd1..62a33338549c 100644 --- a/arch/parisc/include/asm/bug.h +++ b/arch/parisc/include/asm/bug.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #ifndef _PARISC_BUG_H | 1 | #ifndef _PARISC_BUG_H |
| 2 | #define _PARISC_BUG_H | 2 | #define _PARISC_BUG_H |
| 3 | 3 | ||
| 4 | #include <linux/kernel.h> /* for BUGFLAG_TAINT */ | ||
| 5 | |||
| 4 | /* | 6 | /* |
| 5 | * Tell the user there is some problem. | 7 | * Tell the user there is some problem. |
| 6 | * The offending file and line are encoded in the __bug_table section. | 8 | * The offending file and line are encoded in the __bug_table section. |
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 0b6d79617d7b..2e3200ca485f 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c | |||
| @@ -176,8 +176,8 @@ int module_frob_arch_sections(Elf32_Ehdr *hdr, | |||
| 176 | 176 | ||
| 177 | static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) | 177 | static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) |
| 178 | { | 178 | { |
| 179 | if (entry->jump[0] == 0x3d600000 + ((val + 0x8000) >> 16) | 179 | if (entry->jump[0] == 0x3d800000 + ((val + 0x8000) >> 16) |
| 180 | && entry->jump[1] == 0x396b0000 + (val & 0xffff)) | 180 | && entry->jump[1] == 0x398c0000 + (val & 0xffff)) |
| 181 | return 1; | 181 | return 1; |
| 182 | return 0; | 182 | return 0; |
| 183 | } | 183 | } |
| @@ -204,10 +204,9 @@ static uint32_t do_plt_call(void *location, | |||
| 204 | entry++; | 204 | entry++; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | /* Stolen from Paul Mackerras as well... */ | 207 | entry->jump[0] = 0x3d800000+((val+0x8000)>>16); /* lis r12,sym@ha */ |
| 208 | entry->jump[0] = 0x3d600000+((val+0x8000)>>16); /* lis r11,sym@ha */ | 208 | entry->jump[1] = 0x398c0000 + (val&0xffff); /* addi r12,r12,sym@l*/ |
| 209 | entry->jump[1] = 0x396b0000 + (val&0xffff); /* addi r11,r11,sym@l*/ | 209 | entry->jump[2] = 0x7d8903a6; /* mtctr r12 */ |
| 210 | entry->jump[2] = 0x7d6903a6; /* mtctr r11 */ | ||
| 211 | entry->jump[3] = 0x4e800420; /* bctr */ | 210 | entry->jump[3] = 0x4e800420; /* bctr */ |
| 212 | 211 | ||
| 213 | DEBUGP("Initialized plt for 0x%x at %p\n", val, entry); | 212 | DEBUGP("Initialized plt for 0x%x at %p\n", val, entry); |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 99a995c2a3f2..be171ee73bf8 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -475,6 +475,7 @@ void timer_interrupt(struct pt_regs * regs) | |||
| 475 | struct pt_regs *old_regs; | 475 | struct pt_regs *old_regs; |
| 476 | u64 *next_tb = &__get_cpu_var(decrementers_next_tb); | 476 | u64 *next_tb = &__get_cpu_var(decrementers_next_tb); |
| 477 | struct clock_event_device *evt = &__get_cpu_var(decrementers); | 477 | struct clock_event_device *evt = &__get_cpu_var(decrementers); |
| 478 | u64 now; | ||
| 478 | 479 | ||
| 479 | /* Ensure a positive value is written to the decrementer, or else | 480 | /* Ensure a positive value is written to the decrementer, or else |
| 480 | * some CPUs will continue to take decrementer exceptions. | 481 | * some CPUs will continue to take decrementer exceptions. |
| @@ -509,9 +510,16 @@ void timer_interrupt(struct pt_regs * regs) | |||
| 509 | irq_work_run(); | 510 | irq_work_run(); |
| 510 | } | 511 | } |
| 511 | 512 | ||
| 512 | *next_tb = ~(u64)0; | 513 | now = get_tb_or_rtc(); |
| 513 | if (evt->event_handler) | 514 | if (now >= *next_tb) { |
| 514 | evt->event_handler(evt); | 515 | *next_tb = ~(u64)0; |
| 516 | if (evt->event_handler) | ||
| 517 | evt->event_handler(evt); | ||
| 518 | } else { | ||
| 519 | now = *next_tb - now; | ||
| 520 | if (now <= DECREMENTER_MAX) | ||
| 521 | set_dec((int)now); | ||
| 522 | } | ||
| 515 | 523 | ||
| 516 | #ifdef CONFIG_PPC64 | 524 | #ifdef CONFIG_PPC64 |
| 517 | /* collect purr register values often, for accurate calculations */ | 525 | /* collect purr register values often, for accurate calculations */ |
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index 7e1fef36bde6..e9c670d7a7fe 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h | |||
| @@ -91,11 +91,6 @@ extern void smp_nap(void); | |||
| 91 | /* Enable interrupts racelessly and nap forever: helper for cpu_idle(). */ | 91 | /* Enable interrupts racelessly and nap forever: helper for cpu_idle(). */ |
| 92 | extern void _cpu_idle(void); | 92 | extern void _cpu_idle(void); |
| 93 | 93 | ||
| 94 | /* Switch boot idle thread to a freshly-allocated stack and free old stack. */ | ||
| 95 | extern void cpu_idle_on_new_stack(struct thread_info *old_ti, | ||
| 96 | unsigned long new_sp, | ||
| 97 | unsigned long new_ss10); | ||
| 98 | |||
| 99 | #else /* __ASSEMBLY__ */ | 94 | #else /* __ASSEMBLY__ */ |
| 100 | 95 | ||
| 101 | /* | 96 | /* |
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S index 133c4b56a99e..c31637baff28 100644 --- a/arch/tile/kernel/entry.S +++ b/arch/tile/kernel/entry.S | |||
| @@ -68,20 +68,6 @@ STD_ENTRY(KBacktraceIterator_init_current) | |||
| 68 | jrp lr /* keep backtracer happy */ | 68 | jrp lr /* keep backtracer happy */ |
| 69 | STD_ENDPROC(KBacktraceIterator_init_current) | 69 | STD_ENDPROC(KBacktraceIterator_init_current) |
| 70 | 70 | ||
| 71 | /* | ||
| 72 | * Reset our stack to r1/r2 (sp and ksp0+cpu respectively), then | ||
| 73 | * free the old stack (passed in r0) and re-invoke cpu_idle(). | ||
| 74 | * We update sp and ksp0 simultaneously to avoid backtracer warnings. | ||
| 75 | */ | ||
| 76 | STD_ENTRY(cpu_idle_on_new_stack) | ||
| 77 | { | ||
| 78 | move sp, r1 | ||
| 79 | mtspr SPR_SYSTEM_SAVE_K_0, r2 | ||
| 80 | } | ||
| 81 | jal free_thread_info | ||
| 82 | j cpu_idle | ||
| 83 | STD_ENDPROC(cpu_idle_on_new_stack) | ||
| 84 | |||
| 85 | /* Loop forever on a nap during SMP boot. */ | 71 | /* Loop forever on a nap during SMP boot. */ |
| 86 | STD_ENTRY(smp_nap) | 72 | STD_ENTRY(smp_nap) |
| 87 | nap | 73 | nap |
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index 6098ccc59be2..dd87f3420390 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/smp.h> | 29 | #include <linux/smp.h> |
| 30 | #include <linux/timex.h> | 30 | #include <linux/timex.h> |
| 31 | #include <linux/hugetlb.h> | 31 | #include <linux/hugetlb.h> |
| 32 | #include <linux/start_kernel.h> | ||
| 32 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
| 33 | #include <asm/sections.h> | 34 | #include <asm/sections.h> |
| 34 | #include <asm/cacheflush.h> | 35 | #include <asm/cacheflush.h> |
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 8bbea6aa40d9..efe5acfc79c3 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S | |||
| @@ -94,10 +94,10 @@ bs_die: | |||
| 94 | 94 | ||
| 95 | .section ".bsdata", "a" | 95 | .section ".bsdata", "a" |
| 96 | bugger_off_msg: | 96 | bugger_off_msg: |
| 97 | .ascii "Direct booting from floppy is no longer supported.\r\n" | 97 | .ascii "Direct floppy boot is not supported. " |
| 98 | .ascii "Please use a boot loader program instead.\r\n" | 98 | .ascii "Use a boot loader program instead.\r\n" |
| 99 | .ascii "\n" | 99 | .ascii "\n" |
| 100 | .ascii "Remove disk and press any key to reboot . . .\r\n" | 100 | .ascii "Remove disk and press any key to reboot ...\r\n" |
| 101 | .byte 0 | 101 | .byte 0 |
| 102 | 102 | ||
| 103 | #ifdef CONFIG_EFI_STUB | 103 | #ifdef CONFIG_EFI_STUB |
| @@ -111,7 +111,7 @@ coff_header: | |||
| 111 | #else | 111 | #else |
| 112 | .word 0x8664 # x86-64 | 112 | .word 0x8664 # x86-64 |
| 113 | #endif | 113 | #endif |
| 114 | .word 2 # nr_sections | 114 | .word 3 # nr_sections |
| 115 | .long 0 # TimeDateStamp | 115 | .long 0 # TimeDateStamp |
| 116 | .long 0 # PointerToSymbolTable | 116 | .long 0 # PointerToSymbolTable |
| 117 | .long 1 # NumberOfSymbols | 117 | .long 1 # NumberOfSymbols |
| @@ -158,8 +158,8 @@ extra_header_fields: | |||
| 158 | #else | 158 | #else |
| 159 | .quad 0 # ImageBase | 159 | .quad 0 # ImageBase |
| 160 | #endif | 160 | #endif |
| 161 | .long 0x1000 # SectionAlignment | 161 | .long 0x20 # SectionAlignment |
| 162 | .long 0x200 # FileAlignment | 162 | .long 0x20 # FileAlignment |
| 163 | .word 0 # MajorOperatingSystemVersion | 163 | .word 0 # MajorOperatingSystemVersion |
| 164 | .word 0 # MinorOperatingSystemVersion | 164 | .word 0 # MinorOperatingSystemVersion |
| 165 | .word 0 # MajorImageVersion | 165 | .word 0 # MajorImageVersion |
| @@ -200,8 +200,10 @@ extra_header_fields: | |||
| 200 | 200 | ||
| 201 | # Section table | 201 | # Section table |
| 202 | section_table: | 202 | section_table: |
| 203 | .ascii ".text" | 203 | # |
| 204 | .byte 0 | 204 | # The offset & size fields are filled in by build.c. |
| 205 | # | ||
| 206 | .ascii ".setup" | ||
| 205 | .byte 0 | 207 | .byte 0 |
| 206 | .byte 0 | 208 | .byte 0 |
| 207 | .long 0 | 209 | .long 0 |
| @@ -217,9 +219,8 @@ section_table: | |||
| 217 | 219 | ||
| 218 | # | 220 | # |
| 219 | # The EFI application loader requires a relocation section | 221 | # The EFI application loader requires a relocation section |
| 220 | # because EFI applications must be relocatable. But since | 222 | # because EFI applications must be relocatable. The .reloc |
| 221 | # we don't need the loader to fixup any relocs for us, we | 223 | # offset & size fields are filled in by build.c. |
| 222 | # just create an empty (zero-length) .reloc section header. | ||
| 223 | # | 224 | # |
| 224 | .ascii ".reloc" | 225 | .ascii ".reloc" |
| 225 | .byte 0 | 226 | .byte 0 |
| @@ -233,6 +234,25 @@ section_table: | |||
| 233 | .word 0 # NumberOfRelocations | 234 | .word 0 # NumberOfRelocations |
| 234 | .word 0 # NumberOfLineNumbers | 235 | .word 0 # NumberOfLineNumbers |
| 235 | .long 0x42100040 # Characteristics (section flags) | 236 | .long 0x42100040 # Characteristics (section flags) |
| 237 | |||
| 238 | # | ||
| 239 | # The offset & size fields are filled in by build.c. | ||
| 240 | # | ||
| 241 | .ascii ".text" | ||
| 242 | .byte 0 | ||
| 243 | .byte 0 | ||
| 244 | .byte 0 | ||
| 245 | .long 0 | ||
| 246 | .long 0x0 # startup_{32,64} | ||
| 247 | .long 0 # Size of initialized data | ||
| 248 | # on disk | ||
| 249 | .long 0x0 # startup_{32,64} | ||
| 250 | .long 0 # PointerToRelocations | ||
| 251 | .long 0 # PointerToLineNumbers | ||
| 252 | .word 0 # NumberOfRelocations | ||
| 253 | .word 0 # NumberOfLineNumbers | ||
| 254 | .long 0x60500020 # Characteristics (section flags) | ||
| 255 | |||
| 236 | #endif /* CONFIG_EFI_STUB */ | 256 | #endif /* CONFIG_EFI_STUB */ |
| 237 | 257 | ||
| 238 | # Kernel attributes; used by setup. This is part 1 of the | 258 | # Kernel attributes; used by setup. This is part 1 of the |
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index 3f61f6e2b46f..4b8e165ee572 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c | |||
| @@ -50,6 +50,8 @@ typedef unsigned int u32; | |||
| 50 | u8 buf[SETUP_SECT_MAX*512]; | 50 | u8 buf[SETUP_SECT_MAX*512]; |
| 51 | int is_big_kernel; | 51 | int is_big_kernel; |
| 52 | 52 | ||
| 53 | #define PECOFF_RELOC_RESERVE 0x20 | ||
| 54 | |||
| 53 | /*----------------------------------------------------------------------*/ | 55 | /*----------------------------------------------------------------------*/ |
| 54 | 56 | ||
| 55 | static const u32 crctab32[] = { | 57 | static const u32 crctab32[] = { |
| @@ -133,11 +135,103 @@ static void usage(void) | |||
| 133 | die("Usage: build setup system [> image]"); | 135 | die("Usage: build setup system [> image]"); |
| 134 | } | 136 | } |
| 135 | 137 | ||
| 136 | int main(int argc, char ** argv) | ||
| 137 | { | ||
| 138 | #ifdef CONFIG_EFI_STUB | 138 | #ifdef CONFIG_EFI_STUB |
| 139 | unsigned int file_sz, pe_header; | 139 | |
| 140 | static void update_pecoff_section_header(char *section_name, u32 offset, u32 size) | ||
| 141 | { | ||
| 142 | unsigned int pe_header; | ||
| 143 | unsigned short num_sections; | ||
| 144 | u8 *section; | ||
| 145 | |||
| 146 | pe_header = get_unaligned_le32(&buf[0x3c]); | ||
| 147 | num_sections = get_unaligned_le16(&buf[pe_header + 6]); | ||
| 148 | |||
| 149 | #ifdef CONFIG_X86_32 | ||
| 150 | section = &buf[pe_header + 0xa8]; | ||
| 151 | #else | ||
| 152 | section = &buf[pe_header + 0xb8]; | ||
| 140 | #endif | 153 | #endif |
| 154 | |||
| 155 | while (num_sections > 0) { | ||
| 156 | if (strncmp((char*)section, section_name, 8) == 0) { | ||
| 157 | /* section header size field */ | ||
| 158 | put_unaligned_le32(size, section + 0x8); | ||
| 159 | |||
| 160 | /* section header vma field */ | ||
| 161 | put_unaligned_le32(offset, section + 0xc); | ||
| 162 | |||
| 163 | /* section header 'size of initialised data' field */ | ||
| 164 | put_unaligned_le32(size, section + 0x10); | ||
| 165 | |||
| 166 | /* section header 'file offset' field */ | ||
| 167 | put_unaligned_le32(offset, section + 0x14); | ||
| 168 | |||
| 169 | break; | ||
| 170 | } | ||
| 171 | section += 0x28; | ||
| 172 | num_sections--; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | static void update_pecoff_setup_and_reloc(unsigned int size) | ||
| 177 | { | ||
| 178 | u32 setup_offset = 0x200; | ||
| 179 | u32 reloc_offset = size - PECOFF_RELOC_RESERVE; | ||
| 180 | u32 setup_size = reloc_offset - setup_offset; | ||
| 181 | |||
| 182 | update_pecoff_section_header(".setup", setup_offset, setup_size); | ||
| 183 | update_pecoff_section_header(".reloc", reloc_offset, PECOFF_RELOC_RESERVE); | ||
| 184 | |||
| 185 | /* | ||
| 186 | * Modify .reloc section contents with a single entry. The | ||
| 187 | * relocation is applied to offset 10 of the relocation section. | ||
| 188 | */ | ||
| 189 | put_unaligned_le32(reloc_offset + 10, &buf[reloc_offset]); | ||
| 190 | put_unaligned_le32(10, &buf[reloc_offset + 4]); | ||
| 191 | } | ||
| 192 | |||
| 193 | static void update_pecoff_text(unsigned int text_start, unsigned int file_sz) | ||
| 194 | { | ||
| 195 | unsigned int pe_header; | ||
| 196 | unsigned int text_sz = file_sz - text_start; | ||
| 197 | |||
| 198 | pe_header = get_unaligned_le32(&buf[0x3c]); | ||
| 199 | |||
| 200 | /* Size of image */ | ||
| 201 | put_unaligned_le32(file_sz, &buf[pe_header + 0x50]); | ||
| 202 | |||
| 203 | /* | ||
| 204 | * Size of code: Subtract the size of the first sector (512 bytes) | ||
| 205 | * which includes the header. | ||
| 206 | */ | ||
| 207 | put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]); | ||
| 208 | |||
| 209 | #ifdef CONFIG_X86_32 | ||
| 210 | /* | ||
| 211 | * Address of entry point. | ||
| 212 | * | ||
| 213 | * The EFI stub entry point is +16 bytes from the start of | ||
| 214 | * the .text section. | ||
| 215 | */ | ||
| 216 | put_unaligned_le32(text_start + 16, &buf[pe_header + 0x28]); | ||
| 217 | #else | ||
| 218 | /* | ||
| 219 | * Address of entry point. startup_32 is at the beginning and | ||
| 220 | * the 64-bit entry point (startup_64) is always 512 bytes | ||
| 221 | * after. The EFI stub entry point is 16 bytes after that, as | ||
| 222 | * the first instruction allows legacy loaders to jump over | ||
| 223 | * the EFI stub initialisation | ||
| 224 | */ | ||
| 225 | put_unaligned_le32(text_start + 528, &buf[pe_header + 0x28]); | ||
| 226 | #endif /* CONFIG_X86_32 */ | ||
| 227 | |||
| 228 | update_pecoff_section_header(".text", text_start, text_sz); | ||
| 229 | } | ||
| 230 | |||
| 231 | #endif /* CONFIG_EFI_STUB */ | ||
| 232 | |||
| 233 | int main(int argc, char ** argv) | ||
| 234 | { | ||
| 141 | unsigned int i, sz, setup_sectors; | 235 | unsigned int i, sz, setup_sectors; |
| 142 | int c; | 236 | int c; |
| 143 | u32 sys_size; | 237 | u32 sys_size; |
| @@ -163,6 +257,12 @@ int main(int argc, char ** argv) | |||
| 163 | die("Boot block hasn't got boot flag (0xAA55)"); | 257 | die("Boot block hasn't got boot flag (0xAA55)"); |
| 164 | fclose(file); | 258 | fclose(file); |
| 165 | 259 | ||
| 260 | #ifdef CONFIG_EFI_STUB | ||
| 261 | /* Reserve 0x20 bytes for .reloc section */ | ||
| 262 | memset(buf+c, 0, PECOFF_RELOC_RESERVE); | ||
| 263 | c += PECOFF_RELOC_RESERVE; | ||
| 264 | #endif | ||
| 265 | |||
| 166 | /* Pad unused space with zeros */ | 266 | /* Pad unused space with zeros */ |
| 167 | setup_sectors = (c + 511) / 512; | 267 | setup_sectors = (c + 511) / 512; |
| 168 | if (setup_sectors < SETUP_SECT_MIN) | 268 | if (setup_sectors < SETUP_SECT_MIN) |
| @@ -170,6 +270,10 @@ int main(int argc, char ** argv) | |||
| 170 | i = setup_sectors*512; | 270 | i = setup_sectors*512; |
| 171 | memset(buf+c, 0, i-c); | 271 | memset(buf+c, 0, i-c); |
| 172 | 272 | ||
| 273 | #ifdef CONFIG_EFI_STUB | ||
| 274 | update_pecoff_setup_and_reloc(i); | ||
| 275 | #endif | ||
| 276 | |||
| 173 | /* Set the default root device */ | 277 | /* Set the default root device */ |
| 174 | put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); | 278 | put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); |
| 175 | 279 | ||
| @@ -194,66 +298,8 @@ int main(int argc, char ** argv) | |||
| 194 | put_unaligned_le32(sys_size, &buf[0x1f4]); | 298 | put_unaligned_le32(sys_size, &buf[0x1f4]); |
| 195 | 299 | ||
| 196 | #ifdef CONFIG_EFI_STUB | 300 | #ifdef CONFIG_EFI_STUB |
| 197 | file_sz = sz + i + ((sys_size * 16) - sz); | 301 | update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz)); |
| 198 | 302 | #endif | |
| 199 | pe_header = get_unaligned_le32(&buf[0x3c]); | ||
| 200 | |||
| 201 | /* Size of image */ | ||
| 202 | put_unaligned_le32(file_sz, &buf[pe_header + 0x50]); | ||
| 203 | |||
| 204 | /* | ||
| 205 | * Subtract the size of the first section (512 bytes) which | ||
| 206 | * includes the header and .reloc section. The remaining size | ||
| 207 | * is that of the .text section. | ||
| 208 | */ | ||
| 209 | file_sz -= 512; | ||
| 210 | |||
| 211 | /* Size of code */ | ||
| 212 | put_unaligned_le32(file_sz, &buf[pe_header + 0x1c]); | ||
| 213 | |||
| 214 | #ifdef CONFIG_X86_32 | ||
| 215 | /* | ||
| 216 | * Address of entry point. | ||
| 217 | * | ||
| 218 | * The EFI stub entry point is +16 bytes from the start of | ||
| 219 | * the .text section. | ||
| 220 | */ | ||
| 221 | put_unaligned_le32(i + 16, &buf[pe_header + 0x28]); | ||
| 222 | |||
| 223 | /* .text size */ | ||
| 224 | put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]); | ||
| 225 | |||
| 226 | /* .text vma */ | ||
| 227 | put_unaligned_le32(0x200, &buf[pe_header + 0xb4]); | ||
| 228 | |||
| 229 | /* .text size of initialised data */ | ||
| 230 | put_unaligned_le32(file_sz, &buf[pe_header + 0xb8]); | ||
| 231 | |||
| 232 | /* .text file offset */ | ||
| 233 | put_unaligned_le32(0x200, &buf[pe_header + 0xbc]); | ||
| 234 | #else | ||
| 235 | /* | ||
| 236 | * Address of entry point. startup_32 is at the beginning and | ||
| 237 | * the 64-bit entry point (startup_64) is always 512 bytes | ||
| 238 | * after. The EFI stub entry point is 16 bytes after that, as | ||
| 239 | * the first instruction allows legacy loaders to jump over | ||
| 240 | * the EFI stub initialisation | ||
| 241 | */ | ||
| 242 | put_unaligned_le32(i + 528, &buf[pe_header + 0x28]); | ||
| 243 | |||
| 244 | /* .text size */ | ||
| 245 | put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]); | ||
| 246 | |||
| 247 | /* .text vma */ | ||
| 248 | put_unaligned_le32(0x200, &buf[pe_header + 0xc4]); | ||
| 249 | |||
| 250 | /* .text size of initialised data */ | ||
| 251 | put_unaligned_le32(file_sz, &buf[pe_header + 0xc8]); | ||
| 252 | |||
| 253 | /* .text file offset */ | ||
| 254 | put_unaligned_le32(0x200, &buf[pe_header + 0xcc]); | ||
| 255 | #endif /* CONFIG_X86_32 */ | ||
| 256 | #endif /* CONFIG_EFI_STUB */ | ||
| 257 | 303 | ||
| 258 | crc = partial_crc32(buf, i, crc); | 304 | crc = partial_crc32(buf, i, crc); |
| 259 | if (fwrite(buf, 1, i, stdout) != i) | 305 | if (fwrite(buf, 1, i, stdout) != i) |
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index 0e3793b821ef..dc580c42851c 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h | |||
| @@ -54,6 +54,20 @@ struct nmiaction { | |||
| 54 | __register_nmi_handler((t), &fn##_na); \ | 54 | __register_nmi_handler((t), &fn##_na); \ |
| 55 | }) | 55 | }) |
| 56 | 56 | ||
| 57 | /* | ||
| 58 | * For special handlers that register/unregister in the | ||
| 59 | * init section only. This should be considered rare. | ||
| 60 | */ | ||
| 61 | #define register_nmi_handler_initonly(t, fn, fg, n) \ | ||
| 62 | ({ \ | ||
| 63 | static struct nmiaction fn##_na __initdata = { \ | ||
| 64 | .handler = (fn), \ | ||
| 65 | .name = (n), \ | ||
| 66 | .flags = (fg), \ | ||
| 67 | }; \ | ||
| 68 | __register_nmi_handler((t), &fn##_na); \ | ||
| 69 | }) | ||
| 70 | |||
| 57 | int __register_nmi_handler(unsigned int, struct nmiaction *); | 71 | int __register_nmi_handler(unsigned int, struct nmiaction *); |
| 58 | 72 | ||
| 59 | void unregister_nmi_handler(unsigned int, const char *); | 73 | void unregister_nmi_handler(unsigned int, const char *); |
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 04cd6882308e..e1f3a17034fc 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h | |||
| @@ -33,9 +33,8 @@ | |||
| 33 | #define segment_eq(a, b) ((a).seg == (b).seg) | 33 | #define segment_eq(a, b) ((a).seg == (b).seg) |
| 34 | 34 | ||
| 35 | #define user_addr_max() (current_thread_info()->addr_limit.seg) | 35 | #define user_addr_max() (current_thread_info()->addr_limit.seg) |
| 36 | #define __addr_ok(addr) \ | 36 | #define __addr_ok(addr) \ |
| 37 | ((unsigned long __force)(addr) < \ | 37 | ((unsigned long __force)(addr) < user_addr_max()) |
| 38 | (current_thread_info()->addr_limit.seg)) | ||
| 39 | 38 | ||
| 40 | /* | 39 | /* |
| 41 | * Test whether a block of memory is a valid user space address. | 40 | * Test whether a block of memory is a valid user space address. |
| @@ -47,14 +46,14 @@ | |||
| 47 | * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry... | 46 | * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry... |
| 48 | */ | 47 | */ |
| 49 | 48 | ||
| 50 | #define __range_not_ok(addr, size) \ | 49 | #define __range_not_ok(addr, size, limit) \ |
| 51 | ({ \ | 50 | ({ \ |
| 52 | unsigned long flag, roksum; \ | 51 | unsigned long flag, roksum; \ |
| 53 | __chk_user_ptr(addr); \ | 52 | __chk_user_ptr(addr); \ |
| 54 | asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \ | 53 | asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \ |
| 55 | : "=&r" (flag), "=r" (roksum) \ | 54 | : "=&r" (flag), "=r" (roksum) \ |
| 56 | : "1" (addr), "g" ((long)(size)), \ | 55 | : "1" (addr), "g" ((long)(size)), \ |
| 57 | "rm" (current_thread_info()->addr_limit.seg)); \ | 56 | "rm" (limit)); \ |
| 58 | flag; \ | 57 | flag; \ |
| 59 | }) | 58 | }) |
| 60 | 59 | ||
| @@ -77,7 +76,8 @@ | |||
| 77 | * checks that the pointer is in the user space range - after calling | 76 | * checks that the pointer is in the user space range - after calling |
| 78 | * this function, memory access functions may still return -EFAULT. | 77 | * this function, memory access functions may still return -EFAULT. |
| 79 | */ | 78 | */ |
| 80 | #define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) | 79 | #define access_ok(type, addr, size) \ |
| 80 | (likely(__range_not_ok(addr, size, user_addr_max()) == 0)) | ||
| 81 | 81 | ||
| 82 | /* | 82 | /* |
| 83 | * The exception table consists of pairs of addresses relative to the | 83 | * The exception table consists of pairs of addresses relative to the |
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index becf47b81735..6149b476d9df 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
| @@ -149,7 +149,6 @@ | |||
| 149 | /* 4 bits of software ack period */ | 149 | /* 4 bits of software ack period */ |
| 150 | #define UV2_ACK_MASK 0x7UL | 150 | #define UV2_ACK_MASK 0x7UL |
| 151 | #define UV2_ACK_UNITS_SHFT 3 | 151 | #define UV2_ACK_UNITS_SHFT 3 |
| 152 | #define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT | ||
| 153 | #define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT | 152 | #define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT |
| 154 | 153 | ||
| 155 | /* | 154 | /* |
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 6e76c191a835..d5fd66f0d4cd 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
| 21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
| 22 | #include <linux/suspend.h> | 22 | #include <linux/suspend.h> |
| 23 | #include <linux/kmemleak.h> | ||
| 24 | #include <asm/e820.h> | 23 | #include <asm/e820.h> |
| 25 | #include <asm/io.h> | 24 | #include <asm/io.h> |
| 26 | #include <asm/iommu.h> | 25 | #include <asm/iommu.h> |
| @@ -95,11 +94,6 @@ static u32 __init allocate_aperture(void) | |||
| 95 | return 0; | 94 | return 0; |
| 96 | } | 95 | } |
| 97 | memblock_reserve(addr, aper_size); | 96 | memblock_reserve(addr, aper_size); |
| 98 | /* | ||
| 99 | * Kmemleak should not scan this block as it may not be mapped via the | ||
| 100 | * kernel direct mapping. | ||
| 101 | */ | ||
| 102 | kmemleak_ignore(phys_to_virt(addr)); | ||
| 103 | printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n", | 97 | printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n", |
| 104 | aper_size >> 10, addr); | 98 | aper_size >> 10, addr); |
| 105 | insert_aperture_resource((u32)addr, aper_size); | 99 | insert_aperture_resource((u32)addr, aper_size); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index ac96561d1a99..5f0ff597437c 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -1195,7 +1195,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) | |||
| 1195 | BUG_ON(!cfg->vector); | 1195 | BUG_ON(!cfg->vector); |
| 1196 | 1196 | ||
| 1197 | vector = cfg->vector; | 1197 | vector = cfg->vector; |
| 1198 | for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) | 1198 | for_each_cpu(cpu, cfg->domain) |
| 1199 | per_cpu(vector_irq, cpu)[vector] = -1; | 1199 | per_cpu(vector_irq, cpu)[vector] = -1; |
| 1200 | 1200 | ||
| 1201 | cfg->vector = 0; | 1201 | cfg->vector = 0; |
| @@ -1203,7 +1203,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) | |||
| 1203 | 1203 | ||
| 1204 | if (likely(!cfg->move_in_progress)) | 1204 | if (likely(!cfg->move_in_progress)) |
| 1205 | return; | 1205 | return; |
| 1206 | for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { | 1206 | for_each_cpu(cpu, cfg->old_domain) { |
| 1207 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; | 1207 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; |
| 1208 | vector++) { | 1208 | vector++) { |
| 1209 | if (per_cpu(vector_irq, cpu)[vector] != irq) | 1209 | if (per_cpu(vector_irq, cpu)[vector] != irq) |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index a97f3c4a3946..da27c5d2168a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -1557,7 +1557,7 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c) | |||
| 1557 | static void __mcheck_cpu_init_timer(void) | 1557 | static void __mcheck_cpu_init_timer(void) |
| 1558 | { | 1558 | { |
| 1559 | struct timer_list *t = &__get_cpu_var(mce_timer); | 1559 | struct timer_list *t = &__get_cpu_var(mce_timer); |
| 1560 | unsigned long iv = __this_cpu_read(mce_next_interval); | 1560 | unsigned long iv = check_interval * HZ; |
| 1561 | 1561 | ||
| 1562 | setup_timer(t, mce_timer_fn, smp_processor_id()); | 1562 | setup_timer(t, mce_timer_fn, smp_processor_id()); |
| 1563 | 1563 | ||
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index e049d6da0183..c4706cf9c011 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -1496,6 +1496,7 @@ static struct cpu_hw_events *allocate_fake_cpuc(void) | |||
| 1496 | if (!cpuc->shared_regs) | 1496 | if (!cpuc->shared_regs) |
| 1497 | goto error; | 1497 | goto error; |
| 1498 | } | 1498 | } |
| 1499 | cpuc->is_fake = 1; | ||
| 1499 | return cpuc; | 1500 | return cpuc; |
| 1500 | error: | 1501 | error: |
| 1501 | free_fake_cpuc(cpuc); | 1502 | free_fake_cpuc(cpuc); |
| @@ -1756,6 +1757,12 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
| 1756 | dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry); | 1757 | dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry); |
| 1757 | } | 1758 | } |
| 1758 | 1759 | ||
| 1760 | static inline int | ||
| 1761 | valid_user_frame(const void __user *fp, unsigned long size) | ||
| 1762 | { | ||
| 1763 | return (__range_not_ok(fp, size, TASK_SIZE) == 0); | ||
| 1764 | } | ||
| 1765 | |||
| 1759 | #ifdef CONFIG_COMPAT | 1766 | #ifdef CONFIG_COMPAT |
| 1760 | 1767 | ||
| 1761 | #include <asm/compat.h> | 1768 | #include <asm/compat.h> |
| @@ -1780,7 +1787,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
| 1780 | if (bytes != sizeof(frame)) | 1787 | if (bytes != sizeof(frame)) |
| 1781 | break; | 1788 | break; |
| 1782 | 1789 | ||
| 1783 | if (fp < compat_ptr(regs->sp)) | 1790 | if (!valid_user_frame(fp, sizeof(frame))) |
| 1784 | break; | 1791 | break; |
| 1785 | 1792 | ||
| 1786 | perf_callchain_store(entry, frame.return_address); | 1793 | perf_callchain_store(entry, frame.return_address); |
| @@ -1826,7 +1833,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
| 1826 | if (bytes != sizeof(frame)) | 1833 | if (bytes != sizeof(frame)) |
| 1827 | break; | 1834 | break; |
| 1828 | 1835 | ||
| 1829 | if ((unsigned long)fp < regs->sp) | 1836 | if (!valid_user_frame(fp, sizeof(frame))) |
| 1830 | break; | 1837 | break; |
| 1831 | 1838 | ||
| 1832 | perf_callchain_store(entry, frame.return_address); | 1839 | perf_callchain_store(entry, frame.return_address); |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 6638aaf54493..7241e2fc3c17 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
| @@ -117,6 +117,7 @@ struct cpu_hw_events { | |||
| 117 | struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ | 117 | struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ |
| 118 | 118 | ||
| 119 | unsigned int group_flag; | 119 | unsigned int group_flag; |
| 120 | int is_fake; | ||
| 120 | 121 | ||
| 121 | /* | 122 | /* |
| 122 | * Intel DebugStore bits | 123 | * Intel DebugStore bits |
| @@ -364,6 +365,7 @@ struct x86_pmu { | |||
| 364 | int pebs_record_size; | 365 | int pebs_record_size; |
| 365 | void (*drain_pebs)(struct pt_regs *regs); | 366 | void (*drain_pebs)(struct pt_regs *regs); |
| 366 | struct event_constraint *pebs_constraints; | 367 | struct event_constraint *pebs_constraints; |
| 368 | void (*pebs_aliases)(struct perf_event *event); | ||
| 367 | 369 | ||
| 368 | /* | 370 | /* |
| 369 | * Intel LBR | 371 | * Intel LBR |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 166546ec6aef..187c294bc658 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
| @@ -1119,27 +1119,33 @@ intel_bts_constraints(struct perf_event *event) | |||
| 1119 | return NULL; | 1119 | return NULL; |
| 1120 | } | 1120 | } |
| 1121 | 1121 | ||
| 1122 | static bool intel_try_alt_er(struct perf_event *event, int orig_idx) | 1122 | static int intel_alt_er(int idx) |
| 1123 | { | 1123 | { |
| 1124 | if (!(x86_pmu.er_flags & ERF_HAS_RSP_1)) | 1124 | if (!(x86_pmu.er_flags & ERF_HAS_RSP_1)) |
| 1125 | return false; | 1125 | return idx; |
| 1126 | 1126 | ||
| 1127 | if (event->hw.extra_reg.idx == EXTRA_REG_RSP_0) { | 1127 | if (idx == EXTRA_REG_RSP_0) |
| 1128 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; | 1128 | return EXTRA_REG_RSP_1; |
| 1129 | event->hw.config |= 0x01bb; | 1129 | |
| 1130 | event->hw.extra_reg.idx = EXTRA_REG_RSP_1; | 1130 | if (idx == EXTRA_REG_RSP_1) |
| 1131 | event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; | 1131 | return EXTRA_REG_RSP_0; |
| 1132 | } else if (event->hw.extra_reg.idx == EXTRA_REG_RSP_1) { | 1132 | |
| 1133 | return idx; | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | static void intel_fixup_er(struct perf_event *event, int idx) | ||
| 1137 | { | ||
| 1138 | event->hw.extra_reg.idx = idx; | ||
| 1139 | |||
| 1140 | if (idx == EXTRA_REG_RSP_0) { | ||
| 1133 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; | 1141 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; |
| 1134 | event->hw.config |= 0x01b7; | 1142 | event->hw.config |= 0x01b7; |
| 1135 | event->hw.extra_reg.idx = EXTRA_REG_RSP_0; | ||
| 1136 | event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; | 1143 | event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; |
| 1144 | } else if (idx == EXTRA_REG_RSP_1) { | ||
| 1145 | event->hw.config &= ~INTEL_ARCH_EVENT_MASK; | ||
| 1146 | event->hw.config |= 0x01bb; | ||
| 1147 | event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; | ||
| 1137 | } | 1148 | } |
| 1138 | |||
| 1139 | if (event->hw.extra_reg.idx == orig_idx) | ||
| 1140 | return false; | ||
| 1141 | |||
| 1142 | return true; | ||
| 1143 | } | 1149 | } |
| 1144 | 1150 | ||
| 1145 | /* | 1151 | /* |
| @@ -1157,14 +1163,18 @@ __intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc, | |||
| 1157 | struct event_constraint *c = &emptyconstraint; | 1163 | struct event_constraint *c = &emptyconstraint; |
| 1158 | struct er_account *era; | 1164 | struct er_account *era; |
| 1159 | unsigned long flags; | 1165 | unsigned long flags; |
| 1160 | int orig_idx = reg->idx; | 1166 | int idx = reg->idx; |
| 1161 | 1167 | ||
| 1162 | /* already allocated shared msr */ | 1168 | /* |
| 1163 | if (reg->alloc) | 1169 | * reg->alloc can be set due to existing state, so for fake cpuc we |
| 1170 | * need to ignore this, otherwise we might fail to allocate proper fake | ||
| 1171 | * state for this extra reg constraint. Also see the comment below. | ||
| 1172 | */ | ||
| 1173 | if (reg->alloc && !cpuc->is_fake) | ||
| 1164 | return NULL; /* call x86_get_event_constraint() */ | 1174 | return NULL; /* call x86_get_event_constraint() */ |
| 1165 | 1175 | ||
| 1166 | again: | 1176 | again: |
| 1167 | era = &cpuc->shared_regs->regs[reg->idx]; | 1177 | era = &cpuc->shared_regs->regs[idx]; |
| 1168 | /* | 1178 | /* |
| 1169 | * we use spin_lock_irqsave() to avoid lockdep issues when | 1179 | * we use spin_lock_irqsave() to avoid lockdep issues when |
| 1170 | * passing a fake cpuc | 1180 | * passing a fake cpuc |
| @@ -1173,6 +1183,29 @@ again: | |||
| 1173 | 1183 | ||
| 1174 | if (!atomic_read(&era->ref) || era->config == reg->config) { | 1184 | if (!atomic_read(&era->ref) || era->config == reg->config) { |
| 1175 | 1185 | ||
| 1186 | /* | ||
| 1187 | * If its a fake cpuc -- as per validate_{group,event}() we | ||
| 1188 | * shouldn't touch event state and we can avoid doing so | ||
| 1189 | * since both will only call get_event_constraints() once | ||
| 1190 | * on each event, this avoids the need for reg->alloc. | ||
| 1191 | * | ||
| 1192 | * Not doing the ER fixup will only result in era->reg being | ||
| 1193 | * wrong, but since we won't actually try and program hardware | ||
| 1194 | * this isn't a problem either. | ||
| 1195 | */ | ||
| 1196 | if (!cpuc->is_fake) { | ||
| 1197 | if (idx != reg->idx) | ||
| 1198 | intel_fixup_er(event, idx); | ||
| 1199 | |||
| 1200 | /* | ||
| 1201 | * x86_schedule_events() can call get_event_constraints() | ||
| 1202 | * multiple times on events in the case of incremental | ||
| 1203 | * scheduling(). reg->alloc ensures we only do the ER | ||
| 1204 | * allocation once. | ||
| 1205 | */ | ||
| 1206 | reg->alloc = 1; | ||
| 1207 | } | ||
| 1208 | |||
| 1176 | /* lock in msr value */ | 1209 | /* lock in msr value */ |
| 1177 | era->config = reg->config; | 1210 | era->config = reg->config; |
| 1178 | era->reg = reg->reg; | 1211 | era->reg = reg->reg; |
| @@ -1180,17 +1213,17 @@ again: | |||
| 1180 | /* one more user */ | 1213 | /* one more user */ |
| 1181 | atomic_inc(&era->ref); | 1214 | atomic_inc(&era->ref); |
| 1182 | 1215 | ||
| 1183 | /* no need to reallocate during incremental event scheduling */ | ||
| 1184 | reg->alloc = 1; | ||
| 1185 | |||
| 1186 | /* | 1216 | /* |
| 1187 | * need to call x86_get_event_constraint() | 1217 | * need to call x86_get_event_constraint() |
| 1188 | * to check if associated event has constraints | 1218 | * to check if associated event has constraints |
| 1189 | */ | 1219 | */ |
| 1190 | c = NULL; | 1220 | c = NULL; |
| 1191 | } else if (intel_try_alt_er(event, orig_idx)) { | 1221 | } else { |
| 1192 | raw_spin_unlock_irqrestore(&era->lock, flags); | 1222 | idx = intel_alt_er(idx); |
| 1193 | goto again; | 1223 | if (idx != reg->idx) { |
| 1224 | raw_spin_unlock_irqrestore(&era->lock, flags); | ||
| 1225 | goto again; | ||
| 1226 | } | ||
| 1194 | } | 1227 | } |
| 1195 | raw_spin_unlock_irqrestore(&era->lock, flags); | 1228 | raw_spin_unlock_irqrestore(&era->lock, flags); |
| 1196 | 1229 | ||
| @@ -1204,11 +1237,14 @@ __intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc, | |||
| 1204 | struct er_account *era; | 1237 | struct er_account *era; |
| 1205 | 1238 | ||
| 1206 | /* | 1239 | /* |
| 1207 | * only put constraint if extra reg was actually | 1240 | * Only put constraint if extra reg was actually allocated. Also takes |
| 1208 | * allocated. Also takes care of event which do | 1241 | * care of event which do not use an extra shared reg. |
| 1209 | * not use an extra shared reg | 1242 | * |
| 1243 | * Also, if this is a fake cpuc we shouldn't touch any event state | ||
| 1244 | * (reg->alloc) and we don't care about leaving inconsistent cpuc state | ||
| 1245 | * either since it'll be thrown out. | ||
| 1210 | */ | 1246 | */ |
| 1211 | if (!reg->alloc) | 1247 | if (!reg->alloc || cpuc->is_fake) |
| 1212 | return; | 1248 | return; |
| 1213 | 1249 | ||
| 1214 | era = &cpuc->shared_regs->regs[reg->idx]; | 1250 | era = &cpuc->shared_regs->regs[reg->idx]; |
| @@ -1300,15 +1336,9 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc, | |||
| 1300 | intel_put_shared_regs_event_constraints(cpuc, event); | 1336 | intel_put_shared_regs_event_constraints(cpuc, event); |
| 1301 | } | 1337 | } |
| 1302 | 1338 | ||
| 1303 | static int intel_pmu_hw_config(struct perf_event *event) | 1339 | static void intel_pebs_aliases_core2(struct perf_event *event) |
| 1304 | { | 1340 | { |
| 1305 | int ret = x86_pmu_hw_config(event); | 1341 | if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { |
| 1306 | |||
| 1307 | if (ret) | ||
| 1308 | return ret; | ||
| 1309 | |||
| 1310 | if (event->attr.precise_ip && | ||
| 1311 | (event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { | ||
| 1312 | /* | 1342 | /* |
| 1313 | * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P | 1343 | * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P |
| 1314 | * (0x003c) so that we can use it with PEBS. | 1344 | * (0x003c) so that we can use it with PEBS. |
| @@ -1329,10 +1359,48 @@ static int intel_pmu_hw_config(struct perf_event *event) | |||
| 1329 | */ | 1359 | */ |
| 1330 | u64 alt_config = X86_CONFIG(.event=0xc0, .inv=1, .cmask=16); | 1360 | u64 alt_config = X86_CONFIG(.event=0xc0, .inv=1, .cmask=16); |
| 1331 | 1361 | ||
| 1362 | alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); | ||
| 1363 | event->hw.config = alt_config; | ||
| 1364 | } | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | static void intel_pebs_aliases_snb(struct perf_event *event) | ||
| 1368 | { | ||
| 1369 | if ((event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { | ||
| 1370 | /* | ||
| 1371 | * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P | ||
| 1372 | * (0x003c) so that we can use it with PEBS. | ||
| 1373 | * | ||
| 1374 | * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't | ||
| 1375 | * PEBS capable. However we can use UOPS_RETIRED.ALL | ||
| 1376 | * (0x01c2), which is a PEBS capable event, to get the same | ||
| 1377 | * count. | ||
| 1378 | * | ||
| 1379 | * UOPS_RETIRED.ALL counts the number of cycles that retires | ||
| 1380 | * CNTMASK micro-ops. By setting CNTMASK to a value (16) | ||
| 1381 | * larger than the maximum number of micro-ops that can be | ||
| 1382 | * retired per cycle (4) and then inverting the condition, we | ||
| 1383 | * count all cycles that retire 16 or less micro-ops, which | ||
| 1384 | * is every cycle. | ||
| 1385 | * | ||
| 1386 | * Thereby we gain a PEBS capable cycle counter. | ||
| 1387 | */ | ||
| 1388 | u64 alt_config = X86_CONFIG(.event=0xc2, .umask=0x01, .inv=1, .cmask=16); | ||
| 1332 | 1389 | ||
| 1333 | alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); | 1390 | alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); |
| 1334 | event->hw.config = alt_config; | 1391 | event->hw.config = alt_config; |
| 1335 | } | 1392 | } |
| 1393 | } | ||
| 1394 | |||
| 1395 | static int intel_pmu_hw_config(struct perf_event *event) | ||
| 1396 | { | ||
| 1397 | int ret = x86_pmu_hw_config(event); | ||
| 1398 | |||
| 1399 | if (ret) | ||
| 1400 | return ret; | ||
| 1401 | |||
| 1402 | if (event->attr.precise_ip && x86_pmu.pebs_aliases) | ||
| 1403 | x86_pmu.pebs_aliases(event); | ||
| 1336 | 1404 | ||
| 1337 | if (intel_pmu_needs_lbr_smpl(event)) { | 1405 | if (intel_pmu_needs_lbr_smpl(event)) { |
| 1338 | ret = intel_pmu_setup_lbr_filter(event); | 1406 | ret = intel_pmu_setup_lbr_filter(event); |
| @@ -1607,6 +1675,7 @@ static __initconst const struct x86_pmu intel_pmu = { | |||
| 1607 | .max_period = (1ULL << 31) - 1, | 1675 | .max_period = (1ULL << 31) - 1, |
| 1608 | .get_event_constraints = intel_get_event_constraints, | 1676 | .get_event_constraints = intel_get_event_constraints, |
| 1609 | .put_event_constraints = intel_put_event_constraints, | 1677 | .put_event_constraints = intel_put_event_constraints, |
| 1678 | .pebs_aliases = intel_pebs_aliases_core2, | ||
| 1610 | 1679 | ||
| 1611 | .format_attrs = intel_arch3_formats_attr, | 1680 | .format_attrs = intel_arch3_formats_attr, |
| 1612 | 1681 | ||
| @@ -1840,8 +1909,9 @@ __init int intel_pmu_init(void) | |||
| 1840 | break; | 1909 | break; |
| 1841 | 1910 | ||
| 1842 | case 42: /* SandyBridge */ | 1911 | case 42: /* SandyBridge */ |
| 1843 | x86_add_quirk(intel_sandybridge_quirk); | ||
| 1844 | case 45: /* SandyBridge, "Romely-EP" */ | 1912 | case 45: /* SandyBridge, "Romely-EP" */ |
| 1913 | x86_add_quirk(intel_sandybridge_quirk); | ||
| 1914 | case 58: /* IvyBridge */ | ||
| 1845 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, | 1915 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, |
| 1846 | sizeof(hw_cache_event_ids)); | 1916 | sizeof(hw_cache_event_ids)); |
| 1847 | 1917 | ||
| @@ -1849,6 +1919,7 @@ __init int intel_pmu_init(void) | |||
| 1849 | 1919 | ||
| 1850 | x86_pmu.event_constraints = intel_snb_event_constraints; | 1920 | x86_pmu.event_constraints = intel_snb_event_constraints; |
| 1851 | x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; | 1921 | x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; |
| 1922 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; | ||
| 1852 | x86_pmu.extra_regs = intel_snb_extra_regs; | 1923 | x86_pmu.extra_regs = intel_snb_extra_regs; |
| 1853 | /* all extra regs are per-cpu when HT is on */ | 1924 | /* all extra regs are per-cpu when HT is on */ |
| 1854 | x86_pmu.er_flags |= ERF_HAS_RSP_1; | 1925 | x86_pmu.er_flags |= ERF_HAS_RSP_1; |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 5a3edc27f6e5..35e2192df9f4 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
| @@ -400,14 +400,7 @@ struct event_constraint intel_snb_pebs_event_constraints[] = { | |||
| 400 | INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ | 400 | INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ |
| 401 | INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ | 401 | INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ |
| 402 | INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.* */ | 402 | INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.* */ |
| 403 | INTEL_UEVENT_CONSTRAINT(0x11d0, 0xf), /* MEM_UOP_RETIRED.STLB_MISS_LOADS */ | 403 | INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ |
| 404 | INTEL_UEVENT_CONSTRAINT(0x12d0, 0xf), /* MEM_UOP_RETIRED.STLB_MISS_STORES */ | ||
| 405 | INTEL_UEVENT_CONSTRAINT(0x21d0, 0xf), /* MEM_UOP_RETIRED.LOCK_LOADS */ | ||
| 406 | INTEL_UEVENT_CONSTRAINT(0x22d0, 0xf), /* MEM_UOP_RETIRED.LOCK_STORES */ | ||
| 407 | INTEL_UEVENT_CONSTRAINT(0x41d0, 0xf), /* MEM_UOP_RETIRED.SPLIT_LOADS */ | ||
| 408 | INTEL_UEVENT_CONSTRAINT(0x42d0, 0xf), /* MEM_UOP_RETIRED.SPLIT_STORES */ | ||
| 409 | INTEL_UEVENT_CONSTRAINT(0x81d0, 0xf), /* MEM_UOP_RETIRED.ANY_LOADS */ | ||
| 410 | INTEL_UEVENT_CONSTRAINT(0x82d0, 0xf), /* MEM_UOP_RETIRED.ANY_STORES */ | ||
| 411 | INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ | 404 | INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ |
| 412 | INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ | 405 | INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ |
| 413 | INTEL_UEVENT_CONSTRAINT(0x02d4, 0xf), /* MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS */ | 406 | INTEL_UEVENT_CONSTRAINT(0x02d4, 0xf), /* MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS */ |
diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c index e31bf8d5c4d2..149b8d9c6ad4 100644 --- a/arch/x86/kernel/nmi_selftest.c +++ b/arch/x86/kernel/nmi_selftest.c | |||
| @@ -42,7 +42,7 @@ static int __init nmi_unk_cb(unsigned int val, struct pt_regs *regs) | |||
| 42 | static void __init init_nmi_testsuite(void) | 42 | static void __init init_nmi_testsuite(void) |
| 43 | { | 43 | { |
| 44 | /* trap all the unknown NMIs we may generate */ | 44 | /* trap all the unknown NMIs we may generate */ |
| 45 | register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk"); | 45 | register_nmi_handler_initonly(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk"); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | static void __init cleanup_nmi_testsuite(void) | 48 | static void __init cleanup_nmi_testsuite(void) |
| @@ -64,7 +64,7 @@ static void __init test_nmi_ipi(struct cpumask *mask) | |||
| 64 | { | 64 | { |
| 65 | unsigned long timeout; | 65 | unsigned long timeout; |
| 66 | 66 | ||
| 67 | if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback, | 67 | if (register_nmi_handler_initonly(NMI_LOCAL, test_nmi_ipi_callback, |
| 68 | NMI_FLAG_FIRST, "nmi_selftest")) { | 68 | NMI_FLAG_FIRST, "nmi_selftest")) { |
| 69 | nmi_fail = FAILURE; | 69 | nmi_fail = FAILURE; |
| 70 | return; | 70 | return; |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 79c45af81604..25b48edb847c 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
| @@ -639,9 +639,11 @@ void native_machine_shutdown(void) | |||
| 639 | set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id)); | 639 | set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id)); |
| 640 | 640 | ||
| 641 | /* | 641 | /* |
| 642 | * O.K Now that I'm on the appropriate processor, | 642 | * O.K Now that I'm on the appropriate processor, stop all of the |
| 643 | * stop all of the others. | 643 | * others. Also disable the local irq to not receive the per-cpu |
| 644 | * timer interrupt which may trigger scheduler's load balance. | ||
| 644 | */ | 645 | */ |
| 646 | local_irq_disable(); | ||
| 645 | stop_other_cpus(); | 647 | stop_other_cpus(); |
| 646 | #endif | 648 | #endif |
| 647 | 649 | ||
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c index f61ee67ec00f..677b1ed184c9 100644 --- a/arch/x86/lib/usercopy.c +++ b/arch/x86/lib/usercopy.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | 9 | ||
| 10 | #include <asm/word-at-a-time.h> | 10 | #include <asm/word-at-a-time.h> |
| 11 | #include <linux/sched.h> | ||
| 11 | 12 | ||
| 12 | /* | 13 | /* |
| 13 | * best effort, GUP based copy_from_user() that is NMI-safe | 14 | * best effort, GUP based copy_from_user() that is NMI-safe |
| @@ -21,6 +22,9 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) | |||
| 21 | void *map; | 22 | void *map; |
| 22 | int ret; | 23 | int ret; |
| 23 | 24 | ||
| 25 | if (__range_not_ok(from, n, TASK_SIZE) == 0) | ||
| 26 | return len; | ||
| 27 | |||
| 24 | do { | 28 | do { |
| 25 | ret = __get_user_pages_fast(addr, 1, 0, &page); | 29 | ret = __get_user_pages_fast(addr, 1, 0, &page); |
| 26 | if (!ret) | 30 | if (!ret) |
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt index 819137904428..5d7e51f3fd28 100644 --- a/arch/x86/lib/x86-opcode-map.txt +++ b/arch/x86/lib/x86-opcode-map.txt | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | # - (66): the last prefix is 0x66 | 28 | # - (66): the last prefix is 0x66 |
| 29 | # - (F3): the last prefix is 0xF3 | 29 | # - (F3): the last prefix is 0xF3 |
| 30 | # - (F2): the last prefix is 0xF2 | 30 | # - (F2): the last prefix is 0xF2 |
| 31 | # | 31 | # - (!F3) : the last prefix is not 0xF3 (including non-last prefix case) |
| 32 | 32 | ||
| 33 | Table: one byte opcode | 33 | Table: one byte opcode |
| 34 | Referrer: | 34 | Referrer: |
| @@ -515,12 +515,12 @@ b4: LFS Gv,Mp | |||
| 515 | b5: LGS Gv,Mp | 515 | b5: LGS Gv,Mp |
| 516 | b6: MOVZX Gv,Eb | 516 | b6: MOVZX Gv,Eb |
| 517 | b7: MOVZX Gv,Ew | 517 | b7: MOVZX Gv,Ew |
| 518 | b8: JMPE | POPCNT Gv,Ev (F3) | 518 | b8: JMPE (!F3) | POPCNT Gv,Ev (F3) |
| 519 | b9: Grp10 (1A) | 519 | b9: Grp10 (1A) |
| 520 | ba: Grp8 Ev,Ib (1A) | 520 | ba: Grp8 Ev,Ib (1A) |
| 521 | bb: BTC Ev,Gv | 521 | bb: BTC Ev,Gv |
| 522 | bc: BSF Gv,Ev | TZCNT Gv,Ev (F3) | 522 | bc: BSF Gv,Ev (!F3) | TZCNT Gv,Ev (F3) |
| 523 | bd: BSR Gv,Ev | LZCNT Gv,Ev (F3) | 523 | bd: BSR Gv,Ev (!F3) | LZCNT Gv,Ev (F3) |
| 524 | be: MOVSX Gv,Eb | 524 | be: MOVSX Gv,Eb |
| 525 | bf: MOVSX Gv,Ew | 525 | bf: MOVSX Gv,Ew |
| 526 | # 0x0f 0xc0-0xcf | 526 | # 0x0f 0xc0-0xcf |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 97141c26a13a..bc4e9d84157f 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
| @@ -62,7 +62,8 @@ static void __init find_early_table_space(struct map_range *mr, unsigned long en | |||
| 62 | extra += PMD_SIZE; | 62 | extra += PMD_SIZE; |
| 63 | #endif | 63 | #endif |
| 64 | /* The first 2/4M doesn't use large pages. */ | 64 | /* The first 2/4M doesn't use large pages. */ |
| 65 | extra += mr->end - mr->start; | 65 | if (mr->start < PMD_SIZE) |
| 66 | extra += mr->end - mr->start; | ||
| 66 | 67 | ||
| 67 | ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; | 68 | ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; |
| 68 | } else | 69 | } else |
diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c index 732af3a96183..4599c3e8bcb6 100644 --- a/arch/x86/mm/srat.c +++ b/arch/x86/mm/srat.c | |||
| @@ -176,6 +176,8 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
| 176 | return; | 176 | return; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | node_set(node, numa_nodes_parsed); | ||
| 180 | |||
| 179 | printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n", | 181 | printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n", |
| 180 | node, pxm, | 182 | node, pxm, |
| 181 | (unsigned long long) start, (unsigned long long) end - 1); | 183 | (unsigned long long) start, (unsigned long long) end - 1); |
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index e31bcd8f2eee..fd41a9262d65 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c | |||
| @@ -782,7 +782,7 @@ BLOCKING_NOTIFIER_HEAD(intel_scu_notifier); | |||
| 782 | EXPORT_SYMBOL_GPL(intel_scu_notifier); | 782 | EXPORT_SYMBOL_GPL(intel_scu_notifier); |
| 783 | 783 | ||
| 784 | /* Called by IPC driver */ | 784 | /* Called by IPC driver */ |
| 785 | void intel_scu_devices_create(void) | 785 | void __devinit intel_scu_devices_create(void) |
| 786 | { | 786 | { |
| 787 | int i; | 787 | int i; |
| 788 | 788 | ||
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 3ae0e61abd23..59880afa851f 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
| @@ -1295,7 +1295,6 @@ static void __init enable_timeouts(void) | |||
| 1295 | */ | 1295 | */ |
| 1296 | mmr_image |= (1L << SOFTACK_MSHIFT); | 1296 | mmr_image |= (1L << SOFTACK_MSHIFT); |
| 1297 | if (is_uv2_hub()) { | 1297 | if (is_uv2_hub()) { |
| 1298 | mmr_image &= ~(1L << UV2_LEG_SHFT); | ||
| 1299 | mmr_image |= (1L << UV2_EXT_SHFT); | 1298 | mmr_image |= (1L << UV2_EXT_SHFT); |
| 1300 | } | 1299 | } |
| 1301 | write_mmr_misc_control(pnode, mmr_image); | 1300 | write_mmr_misc_control(pnode, mmr_image); |
diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk index 5f6a5b6c3a15..ddcf39b1a18d 100644 --- a/arch/x86/tools/gen-insn-attr-x86.awk +++ b/arch/x86/tools/gen-insn-attr-x86.awk | |||
| @@ -66,9 +66,10 @@ BEGIN { | |||
| 66 | rex_expr = "^REX(\\.[XRWB]+)*" | 66 | rex_expr = "^REX(\\.[XRWB]+)*" |
| 67 | fpu_expr = "^ESC" # TODO | 67 | fpu_expr = "^ESC" # TODO |
| 68 | 68 | ||
| 69 | lprefix1_expr = "\\(66\\)" | 69 | lprefix1_expr = "\\((66|!F3)\\)" |
| 70 | lprefix2_expr = "\\(F3\\)" | 70 | lprefix2_expr = "\\(F3\\)" |
| 71 | lprefix3_expr = "\\(F2\\)" | 71 | lprefix3_expr = "\\((F2|!F3)\\)" |
| 72 | lprefix_expr = "\\((66|F2|F3)\\)" | ||
| 72 | max_lprefix = 4 | 73 | max_lprefix = 4 |
| 73 | 74 | ||
| 74 | # All opcodes starting with lower-case 'v' or with (v1) superscript | 75 | # All opcodes starting with lower-case 'v' or with (v1) superscript |
| @@ -333,13 +334,16 @@ function convert_operands(count,opnd, i,j,imm,mod) | |||
| 333 | if (match(ext, lprefix1_expr)) { | 334 | if (match(ext, lprefix1_expr)) { |
| 334 | lptable1[idx] = add_flags(lptable1[idx],flags) | 335 | lptable1[idx] = add_flags(lptable1[idx],flags) |
| 335 | variant = "INAT_VARIANT" | 336 | variant = "INAT_VARIANT" |
| 336 | } else if (match(ext, lprefix2_expr)) { | 337 | } |
| 338 | if (match(ext, lprefix2_expr)) { | ||
| 337 | lptable2[idx] = add_flags(lptable2[idx],flags) | 339 | lptable2[idx] = add_flags(lptable2[idx],flags) |
| 338 | variant = "INAT_VARIANT" | 340 | variant = "INAT_VARIANT" |
| 339 | } else if (match(ext, lprefix3_expr)) { | 341 | } |
| 342 | if (match(ext, lprefix3_expr)) { | ||
| 340 | lptable3[idx] = add_flags(lptable3[idx],flags) | 343 | lptable3[idx] = add_flags(lptable3[idx],flags) |
| 341 | variant = "INAT_VARIANT" | 344 | variant = "INAT_VARIANT" |
| 342 | } else { | 345 | } |
| 346 | if (!match(ext, lprefix_expr)){ | ||
| 343 | table[idx] = add_flags(table[idx],flags) | 347 | table[idx] = add_flags(table[idx],flags) |
| 344 | } | 348 | } |
| 345 | } | 349 | } |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 47768ff87343..80998958cf45 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
| @@ -208,7 +208,7 @@ config ACPI_IPMI | |||
| 208 | 208 | ||
| 209 | config ACPI_HOTPLUG_CPU | 209 | config ACPI_HOTPLUG_CPU |
| 210 | bool | 210 | bool |
| 211 | depends on ACPI_PROCESSOR && HOTPLUG_CPU | 211 | depends on EXPERIMENTAL && ACPI_PROCESSOR && HOTPLUG_CPU |
| 212 | select ACPI_CONTAINER | 212 | select ACPI_CONTAINER |
| 213 | default y | 213 | default y |
| 214 | 214 | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 86933ca8b472..7dd3f9fb9f3f 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -643,11 +643,19 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
| 643 | 643 | ||
| 644 | static void acpi_battery_refresh(struct acpi_battery *battery) | 644 | static void acpi_battery_refresh(struct acpi_battery *battery) |
| 645 | { | 645 | { |
| 646 | int power_unit; | ||
| 647 | |||
| 646 | if (!battery->bat.dev) | 648 | if (!battery->bat.dev) |
| 647 | return; | 649 | return; |
| 648 | 650 | ||
| 651 | power_unit = battery->power_unit; | ||
| 652 | |||
| 649 | acpi_battery_get_info(battery); | 653 | acpi_battery_get_info(battery); |
| 650 | /* The battery may have changed its reporting units. */ | 654 | |
| 655 | if (power_unit == battery->power_unit) | ||
| 656 | return; | ||
| 657 | |||
| 658 | /* The battery has changed its reporting units. */ | ||
| 651 | sysfs_remove_battery(battery); | 659 | sysfs_remove_battery(battery); |
| 652 | sysfs_add_battery(battery); | 660 | sysfs_add_battery(battery); |
| 653 | } | 661 | } |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 0af48a8554cd..a093dc163a42 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
| @@ -333,6 +333,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) | |||
| 333 | struct acpi_buffer state = { 0, NULL }; | 333 | struct acpi_buffer state = { 0, NULL }; |
| 334 | union acpi_object *pss = NULL; | 334 | union acpi_object *pss = NULL; |
| 335 | int i; | 335 | int i; |
| 336 | int last_invalid = -1; | ||
| 336 | 337 | ||
| 337 | 338 | ||
| 338 | status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); | 339 | status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); |
| @@ -394,14 +395,33 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) | |||
| 394 | ((u32)(px->core_frequency * 1000) != | 395 | ((u32)(px->core_frequency * 1000) != |
| 395 | (px->core_frequency * 1000))) { | 396 | (px->core_frequency * 1000))) { |
| 396 | printk(KERN_ERR FW_BUG PREFIX | 397 | printk(KERN_ERR FW_BUG PREFIX |
| 397 | "Invalid BIOS _PSS frequency: 0x%llx MHz\n", | 398 | "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n", |
| 398 | px->core_frequency); | 399 | pr->id, px->core_frequency); |
| 399 | result = -EFAULT; | 400 | if (last_invalid == -1) |
| 400 | kfree(pr->performance->states); | 401 | last_invalid = i; |
| 401 | goto end; | 402 | } else { |
| 403 | if (last_invalid != -1) { | ||
| 404 | /* | ||
| 405 | * Copy this valid entry over last_invalid entry | ||
| 406 | */ | ||
| 407 | memcpy(&(pr->performance->states[last_invalid]), | ||
| 408 | px, sizeof(struct acpi_processor_px)); | ||
| 409 | ++last_invalid; | ||
| 410 | } | ||
| 402 | } | 411 | } |
| 403 | } | 412 | } |
| 404 | 413 | ||
| 414 | if (last_invalid == 0) { | ||
| 415 | printk(KERN_ERR FW_BUG PREFIX | ||
| 416 | "No valid BIOS _PSS frequency found for processor %d\n", pr->id); | ||
| 417 | result = -EFAULT; | ||
| 418 | kfree(pr->performance->states); | ||
| 419 | pr->performance->states = NULL; | ||
| 420 | } | ||
| 421 | |||
| 422 | if (last_invalid > 0) | ||
| 423 | pr->performance->state_count = last_invalid; | ||
| 424 | |||
| 405 | end: | 425 | end: |
| 406 | kfree(buffer.pointer); | 426 | kfree(buffer.pointer); |
| 407 | 427 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9577b6fa2650..a576575617d7 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -1687,10 +1687,6 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
| 1687 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); | 1687 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); |
| 1688 | set_bit(KEY_DISPLAY_OFF, input->keybit); | 1688 | set_bit(KEY_DISPLAY_OFF, input->keybit); |
| 1689 | 1689 | ||
| 1690 | error = input_register_device(input); | ||
| 1691 | if (error) | ||
| 1692 | goto err_stop_video; | ||
| 1693 | |||
| 1694 | printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", | 1690 | printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", |
| 1695 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), | 1691 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), |
| 1696 | video->flags.multihead ? "yes" : "no", | 1692 | video->flags.multihead ? "yes" : "no", |
| @@ -1701,12 +1697,16 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
| 1701 | video->pm_nb.priority = 0; | 1697 | video->pm_nb.priority = 0; |
| 1702 | error = register_pm_notifier(&video->pm_nb); | 1698 | error = register_pm_notifier(&video->pm_nb); |
| 1703 | if (error) | 1699 | if (error) |
| 1704 | goto err_unregister_input_dev; | 1700 | goto err_stop_video; |
| 1701 | |||
| 1702 | error = input_register_device(input); | ||
| 1703 | if (error) | ||
| 1704 | goto err_unregister_pm_notifier; | ||
| 1705 | 1705 | ||
| 1706 | return 0; | 1706 | return 0; |
| 1707 | 1707 | ||
| 1708 | err_unregister_input_dev: | 1708 | err_unregister_pm_notifier: |
| 1709 | input_unregister_device(input); | 1709 | unregister_pm_notifier(&video->pm_nb); |
| 1710 | err_stop_video: | 1710 | err_stop_video: |
| 1711 | acpi_video_bus_stop_devices(video); | 1711 | acpi_video_bus_stop_devices(video); |
| 1712 | err_free_input_dev: | 1712 | err_free_input_dev: |
| @@ -1743,9 +1743,18 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) | |||
| 1743 | return 0; | 1743 | return 0; |
| 1744 | } | 1744 | } |
| 1745 | 1745 | ||
| 1746 | static int __init is_i740(struct pci_dev *dev) | ||
| 1747 | { | ||
| 1748 | if (dev->device == 0x00D1) | ||
| 1749 | return 1; | ||
| 1750 | if (dev->device == 0x7000) | ||
| 1751 | return 1; | ||
| 1752 | return 0; | ||
| 1753 | } | ||
| 1754 | |||
| 1746 | static int __init intel_opregion_present(void) | 1755 | static int __init intel_opregion_present(void) |
| 1747 | { | 1756 | { |
| 1748 | #if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE) | 1757 | int opregion = 0; |
| 1749 | struct pci_dev *dev = NULL; | 1758 | struct pci_dev *dev = NULL; |
| 1750 | u32 address; | 1759 | u32 address; |
| 1751 | 1760 | ||
| @@ -1754,13 +1763,15 @@ static int __init intel_opregion_present(void) | |||
| 1754 | continue; | 1763 | continue; |
| 1755 | if (dev->vendor != PCI_VENDOR_ID_INTEL) | 1764 | if (dev->vendor != PCI_VENDOR_ID_INTEL) |
| 1756 | continue; | 1765 | continue; |
| 1766 | /* We don't want to poke around undefined i740 registers */ | ||
| 1767 | if (is_i740(dev)) | ||
| 1768 | continue; | ||
| 1757 | pci_read_config_dword(dev, 0xfc, &address); | 1769 | pci_read_config_dword(dev, 0xfc, &address); |
| 1758 | if (!address) | 1770 | if (!address) |
| 1759 | continue; | 1771 | continue; |
| 1760 | return 1; | 1772 | opregion = 1; |
| 1761 | } | 1773 | } |
| 1762 | #endif | 1774 | return opregion; |
| 1763 | return 0; | ||
| 1764 | } | 1775 | } |
| 1765 | 1776 | ||
| 1766 | int acpi_video_register(void) | 1777 | int acpi_video_register(void) |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 764f70c5e690..0a4185279417 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
| @@ -898,6 +898,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
| 898 | ID(PCI_DEVICE_ID_INTEL_B43_HB), | 898 | ID(PCI_DEVICE_ID_INTEL_B43_HB), |
| 899 | ID(PCI_DEVICE_ID_INTEL_B43_1_HB), | 899 | ID(PCI_DEVICE_ID_INTEL_B43_1_HB), |
| 900 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), | 900 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), |
| 901 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB), | ||
| 901 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), | 902 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), |
| 902 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), | 903 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), |
| 903 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), | 904 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), |
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index c0091753a0d1..8e2d9140f300 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
| @@ -212,6 +212,7 @@ | |||
| 212 | #define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 | 212 | #define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 |
| 213 | #define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 | 213 | #define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 |
| 214 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB 0x0040 | 214 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB 0x0040 |
| 215 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB 0x0069 | ||
| 215 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG 0x0042 | 216 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG 0x0042 |
| 216 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB 0x0044 | 217 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB 0x0044 |
| 217 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 | 218 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 420953197d0a..d6de2e07fa03 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
| @@ -244,8 +244,8 @@ static const struct file_operations exynos_drm_driver_fops = { | |||
| 244 | }; | 244 | }; |
| 245 | 245 | ||
| 246 | static struct drm_driver exynos_drm_driver = { | 246 | static struct drm_driver exynos_drm_driver = { |
| 247 | .driver_features = DRIVER_HAVE_IRQ | DRIVER_BUS_PLATFORM | | 247 | .driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET | |
| 248 | DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, | 248 | DRIVER_GEM | DRIVER_PRIME, |
| 249 | .load = exynos_drm_load, | 249 | .load = exynos_drm_load, |
| 250 | .unload = exynos_drm_unload, | 250 | .unload = exynos_drm_unload, |
| 251 | .open = exynos_drm_open, | 251 | .open = exynos_drm_open, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 6e9ac7bd1dcf..23d5ad379f86 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
| @@ -172,19 +172,12 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) | |||
| 172 | manager_ops->commit(manager->dev); | 172 | manager_ops->commit(manager->dev); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | static struct drm_crtc * | ||
| 176 | exynos_drm_encoder_get_crtc(struct drm_encoder *encoder) | ||
| 177 | { | ||
| 178 | return encoder->crtc; | ||
| 179 | } | ||
| 180 | |||
| 181 | static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = { | 175 | static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = { |
| 182 | .dpms = exynos_drm_encoder_dpms, | 176 | .dpms = exynos_drm_encoder_dpms, |
| 183 | .mode_fixup = exynos_drm_encoder_mode_fixup, | 177 | .mode_fixup = exynos_drm_encoder_mode_fixup, |
| 184 | .mode_set = exynos_drm_encoder_mode_set, | 178 | .mode_set = exynos_drm_encoder_mode_set, |
| 185 | .prepare = exynos_drm_encoder_prepare, | 179 | .prepare = exynos_drm_encoder_prepare, |
| 186 | .commit = exynos_drm_encoder_commit, | 180 | .commit = exynos_drm_encoder_commit, |
| 187 | .get_crtc = exynos_drm_encoder_get_crtc, | ||
| 188 | }; | 181 | }; |
| 189 | 182 | ||
| 190 | static void exynos_drm_encoder_destroy(struct drm_encoder *encoder) | 183 | static void exynos_drm_encoder_destroy(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index f82a299553fb..4ccfe4328fab 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
| @@ -51,11 +51,22 @@ struct exynos_drm_fb { | |||
| 51 | static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) | 51 | static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) |
| 52 | { | 52 | { |
| 53 | struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); | 53 | struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); |
| 54 | unsigned int i; | ||
| 54 | 55 | ||
| 55 | DRM_DEBUG_KMS("%s\n", __FILE__); | 56 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 56 | 57 | ||
| 57 | drm_framebuffer_cleanup(fb); | 58 | drm_framebuffer_cleanup(fb); |
| 58 | 59 | ||
| 60 | for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem_obj); i++) { | ||
| 61 | struct drm_gem_object *obj; | ||
| 62 | |||
| 63 | if (exynos_fb->exynos_gem_obj[i] == NULL) | ||
| 64 | continue; | ||
| 65 | |||
| 66 | obj = &exynos_fb->exynos_gem_obj[i]->base; | ||
| 67 | drm_gem_object_unreference_unlocked(obj); | ||
| 68 | } | ||
| 69 | |||
| 59 | kfree(exynos_fb); | 70 | kfree(exynos_fb); |
| 60 | exynos_fb = NULL; | 71 | exynos_fb = NULL; |
| 61 | } | 72 | } |
| @@ -134,11 +145,11 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | |||
| 134 | return ERR_PTR(-ENOENT); | 145 | return ERR_PTR(-ENOENT); |
| 135 | } | 146 | } |
| 136 | 147 | ||
| 137 | drm_gem_object_unreference_unlocked(obj); | ||
| 138 | |||
| 139 | fb = exynos_drm_framebuffer_init(dev, mode_cmd, obj); | 148 | fb = exynos_drm_framebuffer_init(dev, mode_cmd, obj); |
| 140 | if (IS_ERR(fb)) | 149 | if (IS_ERR(fb)) { |
| 150 | drm_gem_object_unreference_unlocked(obj); | ||
| 141 | return fb; | 151 | return fb; |
| 152 | } | ||
| 142 | 153 | ||
| 143 | exynos_fb = to_exynos_fb(fb); | 154 | exynos_fb = to_exynos_fb(fb); |
| 144 | nr = exynos_drm_format_num_buffers(fb->pixel_format); | 155 | nr = exynos_drm_format_num_buffers(fb->pixel_format); |
| @@ -152,8 +163,6 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | |||
| 152 | return ERR_PTR(-ENOENT); | 163 | return ERR_PTR(-ENOENT); |
| 153 | } | 164 | } |
| 154 | 165 | ||
| 155 | drm_gem_object_unreference_unlocked(obj); | ||
| 156 | |||
| 157 | exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj); | 166 | exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj); |
| 158 | } | 167 | } |
| 159 | 168 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h b/drivers/gpu/drm/exynos/exynos_drm_fb.h index 3ecb30d93552..50823756cdea 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.h +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h | |||
| @@ -31,10 +31,10 @@ | |||
| 31 | static inline int exynos_drm_format_num_buffers(uint32_t format) | 31 | static inline int exynos_drm_format_num_buffers(uint32_t format) |
| 32 | { | 32 | { |
| 33 | switch (format) { | 33 | switch (format) { |
| 34 | case DRM_FORMAT_NV12M: | 34 | case DRM_FORMAT_NV12: |
| 35 | case DRM_FORMAT_NV12MT: | 35 | case DRM_FORMAT_NV12MT: |
| 36 | return 2; | 36 | return 2; |
| 37 | case DRM_FORMAT_YUV420M: | 37 | case DRM_FORMAT_YUV420: |
| 38 | return 3; | 38 | return 3; |
| 39 | default: | 39 | default: |
| 40 | return 1; | 40 | return 1; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index fc91293c4560..5c8b683029ea 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
| @@ -689,7 +689,6 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, | |||
| 689 | struct drm_device *dev, uint32_t handle, | 689 | struct drm_device *dev, uint32_t handle, |
| 690 | uint64_t *offset) | 690 | uint64_t *offset) |
| 691 | { | 691 | { |
| 692 | struct exynos_drm_gem_obj *exynos_gem_obj; | ||
| 693 | struct drm_gem_object *obj; | 692 | struct drm_gem_object *obj; |
| 694 | int ret = 0; | 693 | int ret = 0; |
| 695 | 694 | ||
| @@ -710,15 +709,13 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, | |||
| 710 | goto unlock; | 709 | goto unlock; |
| 711 | } | 710 | } |
| 712 | 711 | ||
| 713 | exynos_gem_obj = to_exynos_gem_obj(obj); | 712 | if (!obj->map_list.map) { |
| 714 | 713 | ret = drm_gem_create_mmap_offset(obj); | |
| 715 | if (!exynos_gem_obj->base.map_list.map) { | ||
| 716 | ret = drm_gem_create_mmap_offset(&exynos_gem_obj->base); | ||
| 717 | if (ret) | 714 | if (ret) |
| 718 | goto out; | 715 | goto out; |
| 719 | } | 716 | } |
| 720 | 717 | ||
| 721 | *offset = (u64)exynos_gem_obj->base.map_list.hash.key << PAGE_SHIFT; | 718 | *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; |
| 722 | DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset); | 719 | DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset); |
| 723 | 720 | ||
| 724 | out: | 721 | out: |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 68ef01028375..e2147a2ddcec 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
| @@ -365,7 +365,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) | |||
| 365 | switch (win_data->pixel_format) { | 365 | switch (win_data->pixel_format) { |
| 366 | case DRM_FORMAT_NV12MT: | 366 | case DRM_FORMAT_NV12MT: |
| 367 | tiled_mode = true; | 367 | tiled_mode = true; |
| 368 | case DRM_FORMAT_NV12M: | 368 | case DRM_FORMAT_NV12: |
| 369 | crcb_mode = false; | 369 | crcb_mode = false; |
| 370 | buf_num = 2; | 370 | buf_num = 2; |
| 371 | break; | 371 | break; |
| @@ -601,18 +601,20 @@ static void mixer_win_reset(struct mixer_context *ctx) | |||
| 601 | mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); | 601 | mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); |
| 602 | 602 | ||
| 603 | /* setting graphical layers */ | 603 | /* setting graphical layers */ |
| 604 | |||
| 605 | val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ | 604 | val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ |
| 606 | val |= MXR_GRP_CFG_WIN_BLEND_EN; | 605 | val |= MXR_GRP_CFG_WIN_BLEND_EN; |
| 606 | val |= MXR_GRP_CFG_BLEND_PRE_MUL; | ||
| 607 | val |= MXR_GRP_CFG_PIXEL_BLEND_EN; | ||
| 607 | val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */ | 608 | val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */ |
| 608 | 609 | ||
| 609 | /* the same configuration for both layers */ | 610 | /* the same configuration for both layers */ |
| 610 | mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val); | 611 | mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val); |
| 611 | |||
| 612 | val |= MXR_GRP_CFG_BLEND_PRE_MUL; | ||
| 613 | val |= MXR_GRP_CFG_PIXEL_BLEND_EN; | ||
| 614 | mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); | 612 | mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); |
| 615 | 613 | ||
| 614 | /* setting video layers */ | ||
| 615 | val = MXR_GRP_CFG_ALPHA_VAL(0); | ||
| 616 | mixer_reg_write(res, MXR_VIDEO_CFG, val); | ||
| 617 | |||
| 616 | /* configuration of Video Processor Registers */ | 618 | /* configuration of Video Processor Registers */ |
| 617 | vp_win_reset(ctx); | 619 | vp_win_reset(ctx); |
| 618 | vp_default_filter(res); | 620 | vp_default_filter(res); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 238a52165833..9fe9ebe52a7a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -233,6 +233,7 @@ static const struct intel_device_info intel_sandybridge_d_info = { | |||
| 233 | .has_blt_ring = 1, | 233 | .has_blt_ring = 1, |
| 234 | .has_llc = 1, | 234 | .has_llc = 1, |
| 235 | .has_pch_split = 1, | 235 | .has_pch_split = 1, |
| 236 | .has_force_wake = 1, | ||
| 236 | }; | 237 | }; |
| 237 | 238 | ||
| 238 | static const struct intel_device_info intel_sandybridge_m_info = { | 239 | static const struct intel_device_info intel_sandybridge_m_info = { |
| @@ -243,6 +244,7 @@ static const struct intel_device_info intel_sandybridge_m_info = { | |||
| 243 | .has_blt_ring = 1, | 244 | .has_blt_ring = 1, |
| 244 | .has_llc = 1, | 245 | .has_llc = 1, |
| 245 | .has_pch_split = 1, | 246 | .has_pch_split = 1, |
| 247 | .has_force_wake = 1, | ||
| 246 | }; | 248 | }; |
| 247 | 249 | ||
| 248 | static const struct intel_device_info intel_ivybridge_d_info = { | 250 | static const struct intel_device_info intel_ivybridge_d_info = { |
| @@ -252,6 +254,7 @@ static const struct intel_device_info intel_ivybridge_d_info = { | |||
| 252 | .has_blt_ring = 1, | 254 | .has_blt_ring = 1, |
| 253 | .has_llc = 1, | 255 | .has_llc = 1, |
| 254 | .has_pch_split = 1, | 256 | .has_pch_split = 1, |
| 257 | .has_force_wake = 1, | ||
| 255 | }; | 258 | }; |
| 256 | 259 | ||
| 257 | static const struct intel_device_info intel_ivybridge_m_info = { | 260 | static const struct intel_device_info intel_ivybridge_m_info = { |
| @@ -262,6 +265,7 @@ static const struct intel_device_info intel_ivybridge_m_info = { | |||
| 262 | .has_blt_ring = 1, | 265 | .has_blt_ring = 1, |
| 263 | .has_llc = 1, | 266 | .has_llc = 1, |
| 264 | .has_pch_split = 1, | 267 | .has_pch_split = 1, |
| 268 | .has_force_wake = 1, | ||
| 265 | }; | 269 | }; |
| 266 | 270 | ||
| 267 | static const struct intel_device_info intel_valleyview_m_info = { | 271 | static const struct intel_device_info intel_valleyview_m_info = { |
| @@ -289,6 +293,7 @@ static const struct intel_device_info intel_haswell_d_info = { | |||
| 289 | .has_blt_ring = 1, | 293 | .has_blt_ring = 1, |
| 290 | .has_llc = 1, | 294 | .has_llc = 1, |
| 291 | .has_pch_split = 1, | 295 | .has_pch_split = 1, |
| 296 | .has_force_wake = 1, | ||
| 292 | }; | 297 | }; |
| 293 | 298 | ||
| 294 | static const struct intel_device_info intel_haswell_m_info = { | 299 | static const struct intel_device_info intel_haswell_m_info = { |
| @@ -298,6 +303,7 @@ static const struct intel_device_info intel_haswell_m_info = { | |||
| 298 | .has_blt_ring = 1, | 303 | .has_blt_ring = 1, |
| 299 | .has_llc = 1, | 304 | .has_llc = 1, |
| 300 | .has_pch_split = 1, | 305 | .has_pch_split = 1, |
| 306 | .has_force_wake = 1, | ||
| 301 | }; | 307 | }; |
| 302 | 308 | ||
| 303 | static const struct pci_device_id pciidlist[] = { /* aka */ | 309 | static const struct pci_device_id pciidlist[] = { /* aka */ |
| @@ -1139,10 +1145,9 @@ MODULE_LICENSE("GPL and additional rights"); | |||
| 1139 | 1145 | ||
| 1140 | /* We give fast paths for the really cool registers */ | 1146 | /* We give fast paths for the really cool registers */ |
| 1141 | #define NEEDS_FORCE_WAKE(dev_priv, reg) \ | 1147 | #define NEEDS_FORCE_WAKE(dev_priv, reg) \ |
| 1142 | (((dev_priv)->info->gen >= 6) && \ | 1148 | ((HAS_FORCE_WAKE((dev_priv)->dev)) && \ |
| 1143 | ((reg) < 0x40000) && \ | 1149 | ((reg) < 0x40000) && \ |
| 1144 | ((reg) != FORCEWAKE)) && \ | 1150 | ((reg) != FORCEWAKE)) |
| 1145 | (!IS_VALLEYVIEW((dev_priv)->dev)) | ||
| 1146 | 1151 | ||
| 1147 | #define __i915_read(x, y) \ | 1152 | #define __i915_read(x, y) \ |
| 1148 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | 1153 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c9cfc67c2cf5..b0b676abde0d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -285,6 +285,7 @@ struct intel_device_info { | |||
| 285 | u8 is_ivybridge:1; | 285 | u8 is_ivybridge:1; |
| 286 | u8 is_valleyview:1; | 286 | u8 is_valleyview:1; |
| 287 | u8 has_pch_split:1; | 287 | u8 has_pch_split:1; |
| 288 | u8 has_force_wake:1; | ||
| 288 | u8 is_haswell:1; | 289 | u8 is_haswell:1; |
| 289 | u8 has_fbc:1; | 290 | u8 has_fbc:1; |
| 290 | u8 has_pipe_cxsr:1; | 291 | u8 has_pipe_cxsr:1; |
| @@ -1101,6 +1102,8 @@ struct drm_i915_file_private { | |||
| 1101 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) | 1102 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) |
| 1102 | #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) | 1103 | #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) |
| 1103 | 1104 | ||
| 1105 | #define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake) | ||
| 1106 | |||
| 1104 | #include "i915_trace.h" | 1107 | #include "i915_trace.h" |
| 1105 | 1108 | ||
| 1106 | /** | 1109 | /** |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1417660a93ec..b1fe0edda955 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -510,7 +510,7 @@ out: | |||
| 510 | return ret; | 510 | return ret; |
| 511 | } | 511 | } |
| 512 | 512 | ||
| 513 | static void pch_irq_handler(struct drm_device *dev, u32 pch_iir) | 513 | static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) |
| 514 | { | 514 | { |
| 515 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 515 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| 516 | int pipe; | 516 | int pipe; |
| @@ -550,6 +550,35 @@ static void pch_irq_handler(struct drm_device *dev, u32 pch_iir) | |||
| 550 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); | 550 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); |
| 551 | } | 551 | } |
| 552 | 552 | ||
| 553 | static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) | ||
| 554 | { | ||
| 555 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
| 556 | int pipe; | ||
| 557 | |||
| 558 | if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) | ||
| 559 | DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", | ||
| 560 | (pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> | ||
| 561 | SDE_AUDIO_POWER_SHIFT_CPT); | ||
| 562 | |||
| 563 | if (pch_iir & SDE_AUX_MASK_CPT) | ||
| 564 | DRM_DEBUG_DRIVER("AUX channel interrupt\n"); | ||
| 565 | |||
| 566 | if (pch_iir & SDE_GMBUS_CPT) | ||
| 567 | DRM_DEBUG_DRIVER("PCH GMBUS interrupt\n"); | ||
| 568 | |||
| 569 | if (pch_iir & SDE_AUDIO_CP_REQ_CPT) | ||
| 570 | DRM_DEBUG_DRIVER("Audio CP request interrupt\n"); | ||
| 571 | |||
| 572 | if (pch_iir & SDE_AUDIO_CP_CHG_CPT) | ||
| 573 | DRM_DEBUG_DRIVER("Audio CP change interrupt\n"); | ||
| 574 | |||
| 575 | if (pch_iir & SDE_FDI_MASK_CPT) | ||
| 576 | for_each_pipe(pipe) | ||
| 577 | DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n", | ||
| 578 | pipe_name(pipe), | ||
| 579 | I915_READ(FDI_RX_IIR(pipe))); | ||
| 580 | } | ||
| 581 | |||
| 553 | static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) | 582 | static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) |
| 554 | { | 583 | { |
| 555 | struct drm_device *dev = (struct drm_device *) arg; | 584 | struct drm_device *dev = (struct drm_device *) arg; |
| @@ -591,7 +620,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) | |||
| 591 | 620 | ||
| 592 | if (pch_iir & SDE_HOTPLUG_MASK_CPT) | 621 | if (pch_iir & SDE_HOTPLUG_MASK_CPT) |
| 593 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | 622 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); |
| 594 | pch_irq_handler(dev, pch_iir); | 623 | cpt_irq_handler(dev, pch_iir); |
| 595 | 624 | ||
| 596 | /* clear PCH hotplug event before clear CPU irq */ | 625 | /* clear PCH hotplug event before clear CPU irq */ |
| 597 | I915_WRITE(SDEIIR, pch_iir); | 626 | I915_WRITE(SDEIIR, pch_iir); |
| @@ -684,7 +713,10 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) | |||
| 684 | if (de_iir & DE_PCH_EVENT) { | 713 | if (de_iir & DE_PCH_EVENT) { |
| 685 | if (pch_iir & hotplug_mask) | 714 | if (pch_iir & hotplug_mask) |
| 686 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); | 715 | queue_work(dev_priv->wq, &dev_priv->hotplug_work); |
| 687 | pch_irq_handler(dev, pch_iir); | 716 | if (HAS_PCH_CPT(dev)) |
| 717 | cpt_irq_handler(dev, pch_iir); | ||
| 718 | else | ||
| 719 | ibx_irq_handler(dev, pch_iir); | ||
| 688 | } | 720 | } |
| 689 | 721 | ||
| 690 | if (de_iir & DE_PCU_EVENT) { | 722 | if (de_iir & DE_PCU_EVENT) { |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2d49b9507ed0..48d5e8e051cf 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -210,6 +210,14 @@ | |||
| 210 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) | 210 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) |
| 211 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) | 211 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) |
| 212 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) | 212 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) |
| 213 | /* IVB has funny definitions for which plane to flip. */ | ||
| 214 | #define MI_DISPLAY_FLIP_IVB_PLANE_A (0 << 19) | ||
| 215 | #define MI_DISPLAY_FLIP_IVB_PLANE_B (1 << 19) | ||
| 216 | #define MI_DISPLAY_FLIP_IVB_SPRITE_A (2 << 19) | ||
| 217 | #define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19) | ||
| 218 | #define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19) | ||
| 219 | #define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19) | ||
| 220 | |||
| 213 | #define MI_SET_CONTEXT MI_INSTR(0x18, 0) | 221 | #define MI_SET_CONTEXT MI_INSTR(0x18, 0) |
| 214 | #define MI_MM_SPACE_GTT (1<<8) | 222 | #define MI_MM_SPACE_GTT (1<<8) |
| 215 | #define MI_MM_SPACE_PHYSICAL (0<<8) | 223 | #define MI_MM_SPACE_PHYSICAL (0<<8) |
| @@ -3313,7 +3321,7 @@ | |||
| 3313 | 3321 | ||
| 3314 | /* PCH */ | 3322 | /* PCH */ |
| 3315 | 3323 | ||
| 3316 | /* south display engine interrupt */ | 3324 | /* south display engine interrupt: IBX */ |
| 3317 | #define SDE_AUDIO_POWER_D (1 << 27) | 3325 | #define SDE_AUDIO_POWER_D (1 << 27) |
| 3318 | #define SDE_AUDIO_POWER_C (1 << 26) | 3326 | #define SDE_AUDIO_POWER_C (1 << 26) |
| 3319 | #define SDE_AUDIO_POWER_B (1 << 25) | 3327 | #define SDE_AUDIO_POWER_B (1 << 25) |
| @@ -3349,15 +3357,44 @@ | |||
| 3349 | #define SDE_TRANSA_CRC_ERR (1 << 1) | 3357 | #define SDE_TRANSA_CRC_ERR (1 << 1) |
| 3350 | #define SDE_TRANSA_FIFO_UNDER (1 << 0) | 3358 | #define SDE_TRANSA_FIFO_UNDER (1 << 0) |
| 3351 | #define SDE_TRANS_MASK (0x3f) | 3359 | #define SDE_TRANS_MASK (0x3f) |
| 3352 | /* CPT */ | 3360 | |
| 3353 | #define SDE_CRT_HOTPLUG_CPT (1 << 19) | 3361 | /* south display engine interrupt: CPT/PPT */ |
| 3362 | #define SDE_AUDIO_POWER_D_CPT (1 << 31) | ||
| 3363 | #define SDE_AUDIO_POWER_C_CPT (1 << 30) | ||
| 3364 | #define SDE_AUDIO_POWER_B_CPT (1 << 29) | ||
| 3365 | #define SDE_AUDIO_POWER_SHIFT_CPT 29 | ||
| 3366 | #define SDE_AUDIO_POWER_MASK_CPT (7 << 29) | ||
| 3367 | #define SDE_AUXD_CPT (1 << 27) | ||
| 3368 | #define SDE_AUXC_CPT (1 << 26) | ||
| 3369 | #define SDE_AUXB_CPT (1 << 25) | ||
| 3370 | #define SDE_AUX_MASK_CPT (7 << 25) | ||
| 3354 | #define SDE_PORTD_HOTPLUG_CPT (1 << 23) | 3371 | #define SDE_PORTD_HOTPLUG_CPT (1 << 23) |
| 3355 | #define SDE_PORTC_HOTPLUG_CPT (1 << 22) | 3372 | #define SDE_PORTC_HOTPLUG_CPT (1 << 22) |
| 3356 | #define SDE_PORTB_HOTPLUG_CPT (1 << 21) | 3373 | #define SDE_PORTB_HOTPLUG_CPT (1 << 21) |
| 3374 | #define SDE_CRT_HOTPLUG_CPT (1 << 19) | ||
| 3357 | #define SDE_HOTPLUG_MASK_CPT (SDE_CRT_HOTPLUG_CPT | \ | 3375 | #define SDE_HOTPLUG_MASK_CPT (SDE_CRT_HOTPLUG_CPT | \ |
| 3358 | SDE_PORTD_HOTPLUG_CPT | \ | 3376 | SDE_PORTD_HOTPLUG_CPT | \ |
| 3359 | SDE_PORTC_HOTPLUG_CPT | \ | 3377 | SDE_PORTC_HOTPLUG_CPT | \ |
| 3360 | SDE_PORTB_HOTPLUG_CPT) | 3378 | SDE_PORTB_HOTPLUG_CPT) |
| 3379 | #define SDE_GMBUS_CPT (1 << 17) | ||
| 3380 | #define SDE_AUDIO_CP_REQ_C_CPT (1 << 10) | ||
| 3381 | #define SDE_AUDIO_CP_CHG_C_CPT (1 << 9) | ||
| 3382 | #define SDE_FDI_RXC_CPT (1 << 8) | ||
| 3383 | #define SDE_AUDIO_CP_REQ_B_CPT (1 << 6) | ||
| 3384 | #define SDE_AUDIO_CP_CHG_B_CPT (1 << 5) | ||
| 3385 | #define SDE_FDI_RXB_CPT (1 << 4) | ||
| 3386 | #define SDE_AUDIO_CP_REQ_A_CPT (1 << 2) | ||
| 3387 | #define SDE_AUDIO_CP_CHG_A_CPT (1 << 1) | ||
| 3388 | #define SDE_FDI_RXA_CPT (1 << 0) | ||
| 3389 | #define SDE_AUDIO_CP_REQ_CPT (SDE_AUDIO_CP_REQ_C_CPT | \ | ||
| 3390 | SDE_AUDIO_CP_REQ_B_CPT | \ | ||
| 3391 | SDE_AUDIO_CP_REQ_A_CPT) | ||
| 3392 | #define SDE_AUDIO_CP_CHG_CPT (SDE_AUDIO_CP_CHG_C_CPT | \ | ||
| 3393 | SDE_AUDIO_CP_CHG_B_CPT | \ | ||
| 3394 | SDE_AUDIO_CP_CHG_A_CPT) | ||
| 3395 | #define SDE_FDI_MASK_CPT (SDE_FDI_RXC_CPT | \ | ||
| 3396 | SDE_FDI_RXB_CPT | \ | ||
| 3397 | SDE_FDI_RXA_CPT) | ||
| 3361 | 3398 | ||
| 3362 | #define SDEISR 0xc4000 | 3399 | #define SDEISR 0xc4000 |
| 3363 | #define SDEIMR 0xc4004 | 3400 | #define SDEIMR 0xc4004 |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 914789420906..e0aa064def31 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -6158,17 +6158,34 @@ static int intel_gen7_queue_flip(struct drm_device *dev, | |||
| 6158 | struct drm_i915_private *dev_priv = dev->dev_private; | 6158 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 6159 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 6159 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 6160 | struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; | 6160 | struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; |
| 6161 | uint32_t plane_bit = 0; | ||
| 6161 | int ret; | 6162 | int ret; |
| 6162 | 6163 | ||
| 6163 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); | 6164 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); |
| 6164 | if (ret) | 6165 | if (ret) |
| 6165 | goto err; | 6166 | goto err; |
| 6166 | 6167 | ||
| 6168 | switch(intel_crtc->plane) { | ||
| 6169 | case PLANE_A: | ||
| 6170 | plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A; | ||
| 6171 | break; | ||
| 6172 | case PLANE_B: | ||
| 6173 | plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B; | ||
| 6174 | break; | ||
| 6175 | case PLANE_C: | ||
| 6176 | plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C; | ||
| 6177 | break; | ||
| 6178 | default: | ||
| 6179 | WARN_ONCE(1, "unknown plane in flip command\n"); | ||
| 6180 | ret = -ENODEV; | ||
| 6181 | goto err; | ||
| 6182 | } | ||
| 6183 | |||
| 6167 | ret = intel_ring_begin(ring, 4); | 6184 | ret = intel_ring_begin(ring, 4); |
| 6168 | if (ret) | 6185 | if (ret) |
| 6169 | goto err_unpin; | 6186 | goto err_unpin; |
| 6170 | 6187 | ||
| 6171 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19)); | 6188 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); |
| 6172 | intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); | 6189 | intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); |
| 6173 | intel_ring_emit(ring, (obj->gtt_offset)); | 6190 | intel_ring_emit(ring, (obj->gtt_offset)); |
| 6174 | intel_ring_emit(ring, (MI_NOOP)); | 6191 | intel_ring_emit(ring, (MI_NOOP)); |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b59b6d5b7583..e5b84ff89ca5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -266,10 +266,15 @@ u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) | |||
| 266 | 266 | ||
| 267 | static int init_ring_common(struct intel_ring_buffer *ring) | 267 | static int init_ring_common(struct intel_ring_buffer *ring) |
| 268 | { | 268 | { |
| 269 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 269 | struct drm_device *dev = ring->dev; |
| 270 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 270 | struct drm_i915_gem_object *obj = ring->obj; | 271 | struct drm_i915_gem_object *obj = ring->obj; |
| 272 | int ret = 0; | ||
| 271 | u32 head; | 273 | u32 head; |
| 272 | 274 | ||
| 275 | if (HAS_FORCE_WAKE(dev)) | ||
| 276 | gen6_gt_force_wake_get(dev_priv); | ||
| 277 | |||
| 273 | /* Stop the ring if it's running. */ | 278 | /* Stop the ring if it's running. */ |
| 274 | I915_WRITE_CTL(ring, 0); | 279 | I915_WRITE_CTL(ring, 0); |
| 275 | I915_WRITE_HEAD(ring, 0); | 280 | I915_WRITE_HEAD(ring, 0); |
| @@ -317,7 +322,8 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
| 317 | I915_READ_HEAD(ring), | 322 | I915_READ_HEAD(ring), |
| 318 | I915_READ_TAIL(ring), | 323 | I915_READ_TAIL(ring), |
| 319 | I915_READ_START(ring)); | 324 | I915_READ_START(ring)); |
| 320 | return -EIO; | 325 | ret = -EIO; |
| 326 | goto out; | ||
| 321 | } | 327 | } |
| 322 | 328 | ||
| 323 | if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) | 329 | if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) |
| @@ -326,9 +332,14 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
| 326 | ring->head = I915_READ_HEAD(ring); | 332 | ring->head = I915_READ_HEAD(ring); |
| 327 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; | 333 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; |
| 328 | ring->space = ring_space(ring); | 334 | ring->space = ring_space(ring); |
| 335 | ring->last_retired_head = -1; | ||
| 329 | } | 336 | } |
| 330 | 337 | ||
| 331 | return 0; | 338 | out: |
| 339 | if (HAS_FORCE_WAKE(dev)) | ||
| 340 | gen6_gt_force_wake_put(dev_priv); | ||
| 341 | |||
| 342 | return ret; | ||
| 332 | } | 343 | } |
| 333 | 344 | ||
| 334 | static int | 345 | static int |
| @@ -987,6 +998,10 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
| 987 | if (ret) | 998 | if (ret) |
| 988 | goto err_unref; | 999 | goto err_unref; |
| 989 | 1000 | ||
| 1001 | ret = i915_gem_object_set_to_gtt_domain(obj, true); | ||
| 1002 | if (ret) | ||
| 1003 | goto err_unpin; | ||
| 1004 | |||
| 990 | ring->virtual_start = ioremap_wc(dev->agp->base + obj->gtt_offset, | 1005 | ring->virtual_start = ioremap_wc(dev->agp->base + obj->gtt_offset, |
| 991 | ring->size); | 1006 | ring->size); |
| 992 | if (ring->virtual_start == NULL) { | 1007 | if (ring->virtual_start == NULL) { |
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 55ab284e22f2..b18870c455ad 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
| @@ -1593,6 +1593,10 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, | |||
| 1593 | struct net_device *pdev; | 1593 | struct net_device *pdev; |
| 1594 | 1594 | ||
| 1595 | pdev = ip_dev_find(&init_net, peer_ip); | 1595 | pdev = ip_dev_find(&init_net, peer_ip); |
| 1596 | if (!pdev) { | ||
| 1597 | err = -ENODEV; | ||
| 1598 | goto out; | ||
| 1599 | } | ||
| 1596 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, | 1600 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
| 1597 | n, pdev, 0); | 1601 | n, pdev, 0); |
| 1598 | if (!ep->l2t) | 1602 | if (!ep->l2t) |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index ee1c577238f7..3530c41fcd1f 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -140,7 +140,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
| 140 | props->max_mr_size = ~0ull; | 140 | props->max_mr_size = ~0ull; |
| 141 | props->page_size_cap = dev->dev->caps.page_size_cap; | 141 | props->page_size_cap = dev->dev->caps.page_size_cap; |
| 142 | props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps; | 142 | props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps; |
| 143 | props->max_qp_wr = dev->dev->caps.max_wqes; | 143 | props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; |
| 144 | props->max_sge = min(dev->dev->caps.max_sq_sg, | 144 | props->max_sge = min(dev->dev->caps.max_sq_sg, |
| 145 | dev->dev->caps.max_rq_sg); | 145 | dev->dev->caps.max_rq_sg); |
| 146 | props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs; | 146 | props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs; |
| @@ -1084,12 +1084,9 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | |||
| 1084 | int total_eqs = 0; | 1084 | int total_eqs = 0; |
| 1085 | int i, j, eq; | 1085 | int i, j, eq; |
| 1086 | 1086 | ||
| 1087 | /* Init eq table */ | 1087 | /* Legacy mode or comp_pool is not large enough */ |
| 1088 | ibdev->eq_table = NULL; | 1088 | if (dev->caps.comp_pool == 0 || |
| 1089 | ibdev->eq_added = 0; | 1089 | dev->caps.num_ports > dev->caps.comp_pool) |
| 1090 | |||
| 1091 | /* Legacy mode? */ | ||
| 1092 | if (dev->caps.comp_pool == 0) | ||
| 1093 | return; | 1090 | return; |
| 1094 | 1091 | ||
| 1095 | eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/ | 1092 | eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/ |
| @@ -1135,7 +1132,10 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | |||
| 1135 | static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | 1132 | static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) |
| 1136 | { | 1133 | { |
| 1137 | int i; | 1134 | int i; |
| 1138 | int total_eqs; | 1135 | |
| 1136 | /* no additional eqs were added */ | ||
| 1137 | if (!ibdev->eq_table) | ||
| 1138 | return; | ||
| 1139 | 1139 | ||
| 1140 | /* Reset the advertised EQ number */ | 1140 | /* Reset the advertised EQ number */ |
| 1141 | ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors; | 1141 | ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors; |
| @@ -1148,12 +1148,7 @@ static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | |||
| 1148 | mlx4_release_eq(dev, ibdev->eq_table[i]); | 1148 | mlx4_release_eq(dev, ibdev->eq_table[i]); |
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| 1151 | total_eqs = dev->caps.num_comp_vectors + ibdev->eq_added; | ||
| 1152 | memset(ibdev->eq_table, 0, total_eqs * sizeof(int)); | ||
| 1153 | kfree(ibdev->eq_table); | 1151 | kfree(ibdev->eq_table); |
| 1154 | |||
| 1155 | ibdev->eq_table = NULL; | ||
| 1156 | ibdev->eq_added = 0; | ||
| 1157 | } | 1152 | } |
| 1158 | 1153 | ||
| 1159 | static void *mlx4_ib_add(struct mlx4_dev *dev) | 1154 | static void *mlx4_ib_add(struct mlx4_dev *dev) |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index e62297cc77cc..ff36655d23d3 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
| @@ -44,6 +44,14 @@ | |||
| 44 | #include <linux/mlx4/device.h> | 44 | #include <linux/mlx4/device.h> |
| 45 | #include <linux/mlx4/doorbell.h> | 45 | #include <linux/mlx4/doorbell.h> |
| 46 | 46 | ||
| 47 | enum { | ||
| 48 | MLX4_IB_SQ_MIN_WQE_SHIFT = 6, | ||
| 49 | MLX4_IB_MAX_HEADROOM = 2048 | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define MLX4_IB_SQ_HEADROOM(shift) ((MLX4_IB_MAX_HEADROOM >> (shift)) + 1) | ||
| 53 | #define MLX4_IB_SQ_MAX_SPARE (MLX4_IB_SQ_HEADROOM(MLX4_IB_SQ_MIN_WQE_SHIFT)) | ||
| 54 | |||
| 47 | struct mlx4_ib_ucontext { | 55 | struct mlx4_ib_ucontext { |
| 48 | struct ib_ucontext ibucontext; | 56 | struct ib_ucontext ibucontext; |
| 49 | struct mlx4_uar uar; | 57 | struct mlx4_uar uar; |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index ceb33327091a..8d4ed24aef93 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -310,8 +310,8 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 310 | int is_user, int has_rq, struct mlx4_ib_qp *qp) | 310 | int is_user, int has_rq, struct mlx4_ib_qp *qp) |
| 311 | { | 311 | { |
| 312 | /* Sanity check RQ size before proceeding */ | 312 | /* Sanity check RQ size before proceeding */ |
| 313 | if (cap->max_recv_wr > dev->dev->caps.max_wqes || | 313 | if (cap->max_recv_wr > dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE || |
| 314 | cap->max_recv_sge > dev->dev->caps.max_rq_sg) | 314 | cap->max_recv_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg)) |
| 315 | return -EINVAL; | 315 | return -EINVAL; |
| 316 | 316 | ||
| 317 | if (!has_rq) { | 317 | if (!has_rq) { |
| @@ -329,8 +329,17 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 329 | qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg)); | 329 | qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg)); |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt; | 332 | /* leave userspace return values as they were, so as not to break ABI */ |
| 333 | cap->max_recv_sge = qp->rq.max_gs; | 333 | if (is_user) { |
| 334 | cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt; | ||
| 335 | cap->max_recv_sge = qp->rq.max_gs; | ||
| 336 | } else { | ||
| 337 | cap->max_recv_wr = qp->rq.max_post = | ||
| 338 | min(dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE, qp->rq.wqe_cnt); | ||
| 339 | cap->max_recv_sge = min(qp->rq.max_gs, | ||
| 340 | min(dev->dev->caps.max_sq_sg, | ||
| 341 | dev->dev->caps.max_rq_sg)); | ||
| 342 | } | ||
| 334 | 343 | ||
| 335 | return 0; | 344 | return 0; |
| 336 | } | 345 | } |
| @@ -341,8 +350,8 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 341 | int s; | 350 | int s; |
| 342 | 351 | ||
| 343 | /* Sanity check SQ size before proceeding */ | 352 | /* Sanity check SQ size before proceeding */ |
| 344 | if (cap->max_send_wr > dev->dev->caps.max_wqes || | 353 | if (cap->max_send_wr > (dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE) || |
| 345 | cap->max_send_sge > dev->dev->caps.max_sq_sg || | 354 | cap->max_send_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg) || |
| 346 | cap->max_inline_data + send_wqe_overhead(type, qp->flags) + | 355 | cap->max_inline_data + send_wqe_overhead(type, qp->flags) + |
| 347 | sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz) | 356 | sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz) |
| 348 | return -EINVAL; | 357 | return -EINVAL; |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index 85a69c958559..037f5cea85bd 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h | |||
| @@ -231,7 +231,6 @@ struct ocrdma_qp_hwq_info { | |||
| 231 | u32 entry_size; | 231 | u32 entry_size; |
| 232 | u32 max_cnt; | 232 | u32 max_cnt; |
| 233 | u32 max_wqe_idx; | 233 | u32 max_wqe_idx; |
| 234 | u32 free_delta; | ||
| 235 | u16 dbid; /* qid, where to ring the doorbell. */ | 234 | u16 dbid; /* qid, where to ring the doorbell. */ |
| 236 | u32 len; | 235 | u32 len; |
| 237 | dma_addr_t pa; | 236 | dma_addr_t pa; |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h index a411a4e3193d..517ab20b727c 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h | |||
| @@ -101,8 +101,6 @@ struct ocrdma_create_qp_uresp { | |||
| 101 | u32 rsvd1; | 101 | u32 rsvd1; |
| 102 | u32 num_wqe_allocated; | 102 | u32 num_wqe_allocated; |
| 103 | u32 num_rqe_allocated; | 103 | u32 num_rqe_allocated; |
| 104 | u32 free_wqe_delta; | ||
| 105 | u32 free_rqe_delta; | ||
| 106 | u32 db_sq_offset; | 104 | u32 db_sq_offset; |
| 107 | u32 db_rq_offset; | 105 | u32 db_rq_offset; |
| 108 | u32 db_shift; | 106 | u32 db_shift; |
| @@ -126,8 +124,7 @@ struct ocrdma_create_srq_uresp { | |||
| 126 | u32 db_rq_offset; | 124 | u32 db_rq_offset; |
| 127 | u32 db_shift; | 125 | u32 db_shift; |
| 128 | 126 | ||
| 129 | u32 free_rqe_delta; | 127 | u64 rsvd2; |
| 130 | u32 rsvd2; | ||
| 131 | u64 rsvd3; | 128 | u64 rsvd3; |
| 132 | } __packed; | 129 | } __packed; |
| 133 | 130 | ||
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 9b204b1ba336..9343a1522977 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c | |||
| @@ -732,7 +732,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev, | |||
| 732 | break; | 732 | break; |
| 733 | case OCRDMA_SRQ_LIMIT_EVENT: | 733 | case OCRDMA_SRQ_LIMIT_EVENT: |
| 734 | ib_evt.element.srq = &qp->srq->ibsrq; | 734 | ib_evt.element.srq = &qp->srq->ibsrq; |
| 735 | ib_evt.event = IB_EVENT_QP_LAST_WQE_REACHED; | 735 | ib_evt.event = IB_EVENT_SRQ_LIMIT_REACHED; |
| 736 | srq_event = 1; | 736 | srq_event = 1; |
| 737 | qp_event = 0; | 737 | qp_event = 0; |
| 738 | break; | 738 | break; |
| @@ -1990,19 +1990,12 @@ static void ocrdma_get_create_qp_rsp(struct ocrdma_create_qp_rsp *rsp, | |||
| 1990 | max_wqe_allocated = 1 << max_wqe_allocated; | 1990 | max_wqe_allocated = 1 << max_wqe_allocated; |
| 1991 | max_rqe_allocated = 1 << ((u16)rsp->max_wqe_rqe); | 1991 | max_rqe_allocated = 1 << ((u16)rsp->max_wqe_rqe); |
| 1992 | 1992 | ||
| 1993 | if (qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { | ||
| 1994 | qp->sq.free_delta = 0; | ||
| 1995 | qp->rq.free_delta = 1; | ||
| 1996 | } else | ||
| 1997 | qp->sq.free_delta = 1; | ||
| 1998 | |||
| 1999 | qp->sq.max_cnt = max_wqe_allocated; | 1993 | qp->sq.max_cnt = max_wqe_allocated; |
| 2000 | qp->sq.max_wqe_idx = max_wqe_allocated - 1; | 1994 | qp->sq.max_wqe_idx = max_wqe_allocated - 1; |
| 2001 | 1995 | ||
| 2002 | if (!attrs->srq) { | 1996 | if (!attrs->srq) { |
| 2003 | qp->rq.max_cnt = max_rqe_allocated; | 1997 | qp->rq.max_cnt = max_rqe_allocated; |
| 2004 | qp->rq.max_wqe_idx = max_rqe_allocated - 1; | 1998 | qp->rq.max_wqe_idx = max_rqe_allocated - 1; |
| 2005 | qp->rq.free_delta = 1; | ||
| 2006 | } | 1999 | } |
| 2007 | } | 2000 | } |
| 2008 | 2001 | ||
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index a20d16eaae71..04fef3de6d75 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | *******************************************************************/ | 26 | *******************************************************************/ |
| 27 | 27 | ||
| 28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 29 | #include <linux/version.h> | ||
| 30 | #include <linux/idr.h> | 29 | #include <linux/idr.h> |
| 31 | #include <rdma/ib_verbs.h> | 30 | #include <rdma/ib_verbs.h> |
| 32 | #include <rdma/ib_user_verbs.h> | 31 | #include <rdma/ib_user_verbs.h> |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index e9f74d1b48f6..d16d172b6b6b 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | |||
| @@ -940,8 +940,6 @@ static int ocrdma_copy_qp_uresp(struct ocrdma_qp *qp, | |||
| 940 | uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET; | 940 | uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET; |
| 941 | uresp.db_shift = 16; | 941 | uresp.db_shift = 16; |
| 942 | } | 942 | } |
| 943 | uresp.free_wqe_delta = qp->sq.free_delta; | ||
| 944 | uresp.free_rqe_delta = qp->rq.free_delta; | ||
| 945 | 943 | ||
| 946 | if (qp->dpp_enabled) { | 944 | if (qp->dpp_enabled) { |
| 947 | uresp.dpp_credit = dpp_credit_lmt; | 945 | uresp.dpp_credit = dpp_credit_lmt; |
| @@ -1307,8 +1305,6 @@ static int ocrdma_hwq_free_cnt(struct ocrdma_qp_hwq_info *q) | |||
| 1307 | free_cnt = (q->max_cnt - q->head) + q->tail; | 1305 | free_cnt = (q->max_cnt - q->head) + q->tail; |
| 1308 | else | 1306 | else |
| 1309 | free_cnt = q->tail - q->head; | 1307 | free_cnt = q->tail - q->head; |
| 1310 | if (q->free_delta) | ||
| 1311 | free_cnt -= q->free_delta; | ||
| 1312 | return free_cnt; | 1308 | return free_cnt; |
| 1313 | } | 1309 | } |
| 1314 | 1310 | ||
| @@ -1501,7 +1497,6 @@ static int ocrdma_copy_srq_uresp(struct ocrdma_srq *srq, struct ib_udata *udata) | |||
| 1501 | (srq->pd->id * srq->dev->nic_info.db_page_size); | 1497 | (srq->pd->id * srq->dev->nic_info.db_page_size); |
| 1502 | uresp.db_page_size = srq->dev->nic_info.db_page_size; | 1498 | uresp.db_page_size = srq->dev->nic_info.db_page_size; |
| 1503 | uresp.num_rqe_allocated = srq->rq.max_cnt; | 1499 | uresp.num_rqe_allocated = srq->rq.max_cnt; |
| 1504 | uresp.free_rqe_delta = 1; | ||
| 1505 | if (srq->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { | 1500 | if (srq->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { |
| 1506 | uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ1_OFFSET; | 1501 | uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ1_OFFSET; |
| 1507 | uresp.db_shift = 24; | 1502 | uresp.db_shift = 24; |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h index e6483439f25f..633f03d80274 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #ifndef __OCRDMA_VERBS_H__ | 28 | #ifndef __OCRDMA_VERBS_H__ |
| 29 | #define __OCRDMA_VERBS_H__ | 29 | #define __OCRDMA_VERBS_H__ |
| 30 | 30 | ||
| 31 | #include <linux/version.h> | ||
| 32 | int ocrdma_post_send(struct ib_qp *, struct ib_send_wr *, | 31 | int ocrdma_post_send(struct ib_qp *, struct ib_send_wr *, |
| 33 | struct ib_send_wr **bad_wr); | 32 | struct ib_send_wr **bad_wr); |
| 34 | int ocrdma_post_recv(struct ib_qp *, struct ib_recv_wr *, | 33 | int ocrdma_post_recv(struct ib_qp *, struct ib_recv_wr *, |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index d90a421e9cac..a2e418cba0ff 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
| @@ -547,26 +547,12 @@ static void iommu_poll_events(struct amd_iommu *iommu) | |||
| 547 | spin_unlock_irqrestore(&iommu->lock, flags); | 547 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u32 head) | 550 | static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw) |
| 551 | { | 551 | { |
| 552 | struct amd_iommu_fault fault; | 552 | struct amd_iommu_fault fault; |
| 553 | volatile u64 *raw; | ||
| 554 | int i; | ||
| 555 | 553 | ||
| 556 | INC_STATS_COUNTER(pri_requests); | 554 | INC_STATS_COUNTER(pri_requests); |
| 557 | 555 | ||
| 558 | raw = (u64 *)(iommu->ppr_log + head); | ||
| 559 | |||
| 560 | /* | ||
| 561 | * Hardware bug: Interrupt may arrive before the entry is written to | ||
| 562 | * memory. If this happens we need to wait for the entry to arrive. | ||
| 563 | */ | ||
| 564 | for (i = 0; i < LOOP_TIMEOUT; ++i) { | ||
| 565 | if (PPR_REQ_TYPE(raw[0]) != 0) | ||
| 566 | break; | ||
| 567 | udelay(1); | ||
| 568 | } | ||
| 569 | |||
| 570 | if (PPR_REQ_TYPE(raw[0]) != PPR_REQ_FAULT) { | 556 | if (PPR_REQ_TYPE(raw[0]) != PPR_REQ_FAULT) { |
| 571 | pr_err_ratelimited("AMD-Vi: Unknown PPR request received\n"); | 557 | pr_err_ratelimited("AMD-Vi: Unknown PPR request received\n"); |
| 572 | return; | 558 | return; |
| @@ -578,12 +564,6 @@ static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u32 head) | |||
| 578 | fault.tag = PPR_TAG(raw[0]); | 564 | fault.tag = PPR_TAG(raw[0]); |
| 579 | fault.flags = PPR_FLAGS(raw[0]); | 565 | fault.flags = PPR_FLAGS(raw[0]); |
| 580 | 566 | ||
| 581 | /* | ||
| 582 | * To detect the hardware bug we need to clear the entry | ||
| 583 | * to back to zero. | ||
| 584 | */ | ||
| 585 | raw[0] = raw[1] = 0; | ||
| 586 | |||
| 587 | atomic_notifier_call_chain(&ppr_notifier, 0, &fault); | 567 | atomic_notifier_call_chain(&ppr_notifier, 0, &fault); |
| 588 | } | 568 | } |
| 589 | 569 | ||
| @@ -595,25 +575,62 @@ static void iommu_poll_ppr_log(struct amd_iommu *iommu) | |||
| 595 | if (iommu->ppr_log == NULL) | 575 | if (iommu->ppr_log == NULL) |
| 596 | return; | 576 | return; |
| 597 | 577 | ||
| 578 | /* enable ppr interrupts again */ | ||
| 579 | writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
| 580 | |||
| 598 | spin_lock_irqsave(&iommu->lock, flags); | 581 | spin_lock_irqsave(&iommu->lock, flags); |
| 599 | 582 | ||
| 600 | head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); | 583 | head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); |
| 601 | tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); | 584 | tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); |
| 602 | 585 | ||
| 603 | while (head != tail) { | 586 | while (head != tail) { |
| 587 | volatile u64 *raw; | ||
| 588 | u64 entry[2]; | ||
| 589 | int i; | ||
| 604 | 590 | ||
| 605 | /* Handle PPR entry */ | 591 | raw = (u64 *)(iommu->ppr_log + head); |
| 606 | iommu_handle_ppr_entry(iommu, head); | 592 | |
| 593 | /* | ||
| 594 | * Hardware bug: Interrupt may arrive before the entry is | ||
| 595 | * written to memory. If this happens we need to wait for the | ||
| 596 | * entry to arrive. | ||
| 597 | */ | ||
| 598 | for (i = 0; i < LOOP_TIMEOUT; ++i) { | ||
| 599 | if (PPR_REQ_TYPE(raw[0]) != 0) | ||
| 600 | break; | ||
| 601 | udelay(1); | ||
| 602 | } | ||
| 603 | |||
| 604 | /* Avoid memcpy function-call overhead */ | ||
| 605 | entry[0] = raw[0]; | ||
| 606 | entry[1] = raw[1]; | ||
| 607 | 607 | ||
| 608 | /* Update and refresh ring-buffer state*/ | 608 | /* |
| 609 | * To detect the hardware bug we need to clear the entry | ||
| 610 | * back to zero. | ||
| 611 | */ | ||
| 612 | raw[0] = raw[1] = 0UL; | ||
| 613 | |||
| 614 | /* Update head pointer of hardware ring-buffer */ | ||
| 609 | head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE; | 615 | head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE; |
| 610 | writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); | 616 | writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); |
| 617 | |||
| 618 | /* | ||
| 619 | * Release iommu->lock because ppr-handling might need to | ||
| 620 | * re-aquire it | ||
| 621 | */ | ||
| 622 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 623 | |||
| 624 | /* Handle PPR entry */ | ||
| 625 | iommu_handle_ppr_entry(iommu, entry); | ||
| 626 | |||
| 627 | spin_lock_irqsave(&iommu->lock, flags); | ||
| 628 | |||
| 629 | /* Refresh ring-buffer information */ | ||
| 630 | head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); | ||
| 611 | tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); | 631 | tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); |
| 612 | } | 632 | } |
| 613 | 633 | ||
| 614 | /* enable ppr interrupts again */ | ||
| 615 | writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
| 616 | |||
| 617 | spin_unlock_irqrestore(&iommu->lock, flags); | 634 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 618 | } | 635 | } |
| 619 | 636 | ||
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index c56790375e0f..542024ba6dba 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
| @@ -1029,6 +1029,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) | |||
| 1029 | if (!iommu->dev) | 1029 | if (!iommu->dev) |
| 1030 | return 1; | 1030 | return 1; |
| 1031 | 1031 | ||
| 1032 | iommu->root_pdev = pci_get_bus_and_slot(iommu->dev->bus->number, | ||
| 1033 | PCI_DEVFN(0, 0)); | ||
| 1034 | |||
| 1032 | iommu->cap_ptr = h->cap_ptr; | 1035 | iommu->cap_ptr = h->cap_ptr; |
| 1033 | iommu->pci_seg = h->pci_seg; | 1036 | iommu->pci_seg = h->pci_seg; |
| 1034 | iommu->mmio_phys = h->mmio_phys; | 1037 | iommu->mmio_phys = h->mmio_phys; |
| @@ -1323,20 +1326,16 @@ static void iommu_apply_resume_quirks(struct amd_iommu *iommu) | |||
| 1323 | { | 1326 | { |
| 1324 | int i, j; | 1327 | int i, j; |
| 1325 | u32 ioc_feature_control; | 1328 | u32 ioc_feature_control; |
| 1326 | struct pci_dev *pdev = NULL; | 1329 | struct pci_dev *pdev = iommu->root_pdev; |
| 1327 | 1330 | ||
| 1328 | /* RD890 BIOSes may not have completely reconfigured the iommu */ | 1331 | /* RD890 BIOSes may not have completely reconfigured the iommu */ |
| 1329 | if (!is_rd890_iommu(iommu->dev)) | 1332 | if (!is_rd890_iommu(iommu->dev) || !pdev) |
| 1330 | return; | 1333 | return; |
| 1331 | 1334 | ||
| 1332 | /* | 1335 | /* |
| 1333 | * First, we need to ensure that the iommu is enabled. This is | 1336 | * First, we need to ensure that the iommu is enabled. This is |
| 1334 | * controlled by a register in the northbridge | 1337 | * controlled by a register in the northbridge |
| 1335 | */ | 1338 | */ |
| 1336 | pdev = pci_get_bus_and_slot(iommu->dev->bus->number, PCI_DEVFN(0, 0)); | ||
| 1337 | |||
| 1338 | if (!pdev) | ||
| 1339 | return; | ||
| 1340 | 1339 | ||
| 1341 | /* Select Northbridge indirect register 0x75 and enable writing */ | 1340 | /* Select Northbridge indirect register 0x75 and enable writing */ |
| 1342 | pci_write_config_dword(pdev, 0x60, 0x75 | (1 << 7)); | 1341 | pci_write_config_dword(pdev, 0x60, 0x75 | (1 << 7)); |
| @@ -1346,8 +1345,6 @@ static void iommu_apply_resume_quirks(struct amd_iommu *iommu) | |||
| 1346 | if (!(ioc_feature_control & 0x1)) | 1345 | if (!(ioc_feature_control & 0x1)) |
| 1347 | pci_write_config_dword(pdev, 0x64, ioc_feature_control | 1); | 1346 | pci_write_config_dword(pdev, 0x64, ioc_feature_control | 1); |
| 1348 | 1347 | ||
| 1349 | pci_dev_put(pdev); | ||
| 1350 | |||
| 1351 | /* Restore the iommu BAR */ | 1348 | /* Restore the iommu BAR */ |
| 1352 | pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4, | 1349 | pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4, |
| 1353 | iommu->stored_addr_lo); | 1350 | iommu->stored_addr_lo); |
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 2452f3b71736..24355559a2ad 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h | |||
| @@ -481,6 +481,9 @@ struct amd_iommu { | |||
| 481 | /* Pointer to PCI device of this IOMMU */ | 481 | /* Pointer to PCI device of this IOMMU */ |
| 482 | struct pci_dev *dev; | 482 | struct pci_dev *dev; |
| 483 | 483 | ||
| 484 | /* Cache pdev to root device for resume quirks */ | ||
| 485 | struct pci_dev *root_pdev; | ||
| 486 | |||
| 484 | /* physical address of MMIO space */ | 487 | /* physical address of MMIO space */ |
| 485 | u64 mmio_phys; | 488 | u64 mmio_phys; |
| 486 | /* virtual address of MMIO space */ | 489 | /* virtual address of MMIO space */ |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 835de7168cd3..a9c7981ddd24 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -2550,6 +2550,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) | |||
| 2550 | err = -EINVAL; | 2550 | err = -EINVAL; |
| 2551 | spin_lock_init(&conf->device_lock); | 2551 | spin_lock_init(&conf->device_lock); |
| 2552 | rdev_for_each(rdev, mddev) { | 2552 | rdev_for_each(rdev, mddev) { |
| 2553 | struct request_queue *q; | ||
| 2553 | int disk_idx = rdev->raid_disk; | 2554 | int disk_idx = rdev->raid_disk; |
| 2554 | if (disk_idx >= mddev->raid_disks | 2555 | if (disk_idx >= mddev->raid_disks |
| 2555 | || disk_idx < 0) | 2556 | || disk_idx < 0) |
| @@ -2562,6 +2563,9 @@ static struct r1conf *setup_conf(struct mddev *mddev) | |||
| 2562 | if (disk->rdev) | 2563 | if (disk->rdev) |
| 2563 | goto abort; | 2564 | goto abort; |
| 2564 | disk->rdev = rdev; | 2565 | disk->rdev = rdev; |
| 2566 | q = bdev_get_queue(rdev->bdev); | ||
| 2567 | if (q->merge_bvec_fn) | ||
| 2568 | mddev->merge_check_needed = 1; | ||
| 2565 | 2569 | ||
| 2566 | disk->head_position = 0; | 2570 | disk->head_position = 0; |
| 2567 | } | 2571 | } |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 987db37cb875..99ae6068e456 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -3475,6 +3475,7 @@ static int run(struct mddev *mddev) | |||
| 3475 | 3475 | ||
| 3476 | rdev_for_each(rdev, mddev) { | 3476 | rdev_for_each(rdev, mddev) { |
| 3477 | long long diff; | 3477 | long long diff; |
| 3478 | struct request_queue *q; | ||
| 3478 | 3479 | ||
| 3479 | disk_idx = rdev->raid_disk; | 3480 | disk_idx = rdev->raid_disk; |
| 3480 | if (disk_idx < 0) | 3481 | if (disk_idx < 0) |
| @@ -3493,6 +3494,9 @@ static int run(struct mddev *mddev) | |||
| 3493 | goto out_free_conf; | 3494 | goto out_free_conf; |
| 3494 | disk->rdev = rdev; | 3495 | disk->rdev = rdev; |
| 3495 | } | 3496 | } |
| 3497 | q = bdev_get_queue(rdev->bdev); | ||
| 3498 | if (q->merge_bvec_fn) | ||
| 3499 | mddev->merge_check_needed = 1; | ||
| 3496 | diff = (rdev->new_data_offset - rdev->data_offset); | 3500 | diff = (rdev->new_data_offset - rdev->data_offset); |
| 3497 | if (!mddev->reshape_backwards) | 3501 | if (!mddev->reshape_backwards) |
| 3498 | diff = -diff; | 3502 | diff = -diff; |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 9f957c2d48e9..09d4f8d9d592 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
| @@ -264,6 +264,9 @@ static struct dentry *dfs_rootdir; | |||
| 264 | */ | 264 | */ |
| 265 | int ubi_debugfs_init(void) | 265 | int ubi_debugfs_init(void) |
| 266 | { | 266 | { |
| 267 | if (!IS_ENABLED(DEBUG_FS)) | ||
| 268 | return 0; | ||
| 269 | |||
| 267 | dfs_rootdir = debugfs_create_dir("ubi", NULL); | 270 | dfs_rootdir = debugfs_create_dir("ubi", NULL); |
| 268 | if (IS_ERR_OR_NULL(dfs_rootdir)) { | 271 | if (IS_ERR_OR_NULL(dfs_rootdir)) { |
| 269 | int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir); | 272 | int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir); |
| @@ -281,7 +284,8 @@ int ubi_debugfs_init(void) | |||
| 281 | */ | 284 | */ |
| 282 | void ubi_debugfs_exit(void) | 285 | void ubi_debugfs_exit(void) |
| 283 | { | 286 | { |
| 284 | debugfs_remove(dfs_rootdir); | 287 | if (IS_ENABLED(DEBUG_FS)) |
| 288 | debugfs_remove(dfs_rootdir); | ||
| 285 | } | 289 | } |
| 286 | 290 | ||
| 287 | /* Read an UBI debugfs file */ | 291 | /* Read an UBI debugfs file */ |
| @@ -403,6 +407,9 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) | |||
| 403 | struct dentry *dent; | 407 | struct dentry *dent; |
| 404 | struct ubi_debug_info *d = ubi->dbg; | 408 | struct ubi_debug_info *d = ubi->dbg; |
| 405 | 409 | ||
| 410 | if (!IS_ENABLED(DEBUG_FS)) | ||
| 411 | return 0; | ||
| 412 | |||
| 406 | n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, | 413 | n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, |
| 407 | ubi->ubi_num); | 414 | ubi->ubi_num); |
| 408 | if (n == UBI_DFS_DIR_LEN) { | 415 | if (n == UBI_DFS_DIR_LEN) { |
| @@ -470,5 +477,6 @@ out: | |||
| 470 | */ | 477 | */ |
| 471 | void ubi_debugfs_exit_dev(struct ubi_device *ubi) | 478 | void ubi_debugfs_exit_dev(struct ubi_device *ubi) |
| 472 | { | 479 | { |
| 473 | debugfs_remove_recursive(ubi->dbg->dfs_dir); | 480 | if (IS_ENABLED(DEBUG_FS)) |
| 481 | debugfs_remove_recursive(ubi->dbg->dfs_dir); | ||
| 474 | } | 482 | } |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 9df100a4ec38..b6be644e7b85 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
| @@ -1262,11 +1262,11 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) | |||
| 1262 | dbg_wl("flush pending work for LEB %d:%d (%d pending works)", | 1262 | dbg_wl("flush pending work for LEB %d:%d (%d pending works)", |
| 1263 | vol_id, lnum, ubi->works_count); | 1263 | vol_id, lnum, ubi->works_count); |
| 1264 | 1264 | ||
| 1265 | down_write(&ubi->work_sem); | ||
| 1266 | while (found) { | 1265 | while (found) { |
| 1267 | struct ubi_work *wrk; | 1266 | struct ubi_work *wrk; |
| 1268 | found = 0; | 1267 | found = 0; |
| 1269 | 1268 | ||
| 1269 | down_read(&ubi->work_sem); | ||
| 1270 | spin_lock(&ubi->wl_lock); | 1270 | spin_lock(&ubi->wl_lock); |
| 1271 | list_for_each_entry(wrk, &ubi->works, list) { | 1271 | list_for_each_entry(wrk, &ubi->works, list) { |
| 1272 | if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) && | 1272 | if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) && |
| @@ -1277,18 +1277,27 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) | |||
| 1277 | spin_unlock(&ubi->wl_lock); | 1277 | spin_unlock(&ubi->wl_lock); |
| 1278 | 1278 | ||
| 1279 | err = wrk->func(ubi, wrk, 0); | 1279 | err = wrk->func(ubi, wrk, 0); |
| 1280 | if (err) | 1280 | if (err) { |
| 1281 | goto out; | 1281 | up_read(&ubi->work_sem); |
| 1282 | return err; | ||
| 1283 | } | ||
| 1284 | |||
| 1282 | spin_lock(&ubi->wl_lock); | 1285 | spin_lock(&ubi->wl_lock); |
| 1283 | found = 1; | 1286 | found = 1; |
| 1284 | break; | 1287 | break; |
| 1285 | } | 1288 | } |
| 1286 | } | 1289 | } |
| 1287 | spin_unlock(&ubi->wl_lock); | 1290 | spin_unlock(&ubi->wl_lock); |
| 1291 | up_read(&ubi->work_sem); | ||
| 1288 | } | 1292 | } |
| 1289 | 1293 | ||
| 1290 | out: | 1294 | /* |
| 1295 | * Make sure all the works which have been done in parallel are | ||
| 1296 | * finished. | ||
| 1297 | */ | ||
| 1298 | down_write(&ubi->work_sem); | ||
| 1291 | up_write(&ubi->work_sem); | 1299 | up_write(&ubi->work_sem); |
| 1300 | |||
| 1292 | return err; | 1301 | return err; |
| 1293 | } | 1302 | } |
| 1294 | 1303 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 1fe2c7a8b40c..a8fb52992c64 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
| @@ -697,10 +697,10 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
| 697 | if (slave != dev->caps.function) | 697 | if (slave != dev->caps.function) |
| 698 | memset(inbox->buf, 0, 256); | 698 | memset(inbox->buf, 0, 256); |
| 699 | if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { | 699 | if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { |
| 700 | *(u8 *) inbox->buf = !!reset_qkey_viols << 6; | 700 | *(u8 *) inbox->buf |= !!reset_qkey_viols << 6; |
| 701 | ((__be32 *) inbox->buf)[2] = agg_cap_mask; | 701 | ((__be32 *) inbox->buf)[2] = agg_cap_mask; |
| 702 | } else { | 702 | } else { |
| 703 | ((u8 *) inbox->buf)[3] = !!reset_qkey_viols; | 703 | ((u8 *) inbox->buf)[3] |= !!reset_qkey_viols; |
| 704 | ((__be32 *) inbox->buf)[1] = agg_cap_mask; | 704 | ((__be32 *) inbox->buf)[1] = agg_cap_mask; |
| 705 | } | 705 | } |
| 706 | 706 | ||
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 639db4d0aa76..2fd9d36acd15 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * (C) 2009 - Peter Feuerer peter (a) piie.net | 6 | * (C) 2009 - Peter Feuerer peter (a) piie.net |
| 7 | * http://piie.net | 7 | * http://piie.net |
| 8 | * 2009 Borislav Petkov <petkovbb@gmail.com> | 8 | * 2009 Borislav Petkov bp (a) alien8.de |
| 9 | * | 9 | * |
| 10 | * Inspired by and many thanks to: | 10 | * Inspired by and many thanks to: |
| 11 | * o acerfand - Rachel Greenham | 11 | * o acerfand - Rachel Greenham |
diff --git a/fs/dcache.c b/fs/dcache.c index 85c9e2bff8e6..40469044088d 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -683,6 +683,8 @@ EXPORT_SYMBOL(dget_parent); | |||
| 683 | /** | 683 | /** |
| 684 | * d_find_alias - grab a hashed alias of inode | 684 | * d_find_alias - grab a hashed alias of inode |
| 685 | * @inode: inode in question | 685 | * @inode: inode in question |
| 686 | * @want_discon: flag, used by d_splice_alias, to request | ||
| 687 | * that only a DISCONNECTED alias be returned. | ||
| 686 | * | 688 | * |
| 687 | * If inode has a hashed alias, or is a directory and has any alias, | 689 | * If inode has a hashed alias, or is a directory and has any alias, |
| 688 | * acquire the reference to alias and return it. Otherwise return NULL. | 690 | * acquire the reference to alias and return it. Otherwise return NULL. |
| @@ -691,9 +693,10 @@ EXPORT_SYMBOL(dget_parent); | |||
| 691 | * of a filesystem. | 693 | * of a filesystem. |
| 692 | * | 694 | * |
| 693 | * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer | 695 | * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer |
| 694 | * any other hashed alias over that. | 696 | * any other hashed alias over that one unless @want_discon is set, |
| 697 | * in which case only return an IS_ROOT, DCACHE_DISCONNECTED alias. | ||
| 695 | */ | 698 | */ |
| 696 | static struct dentry *__d_find_alias(struct inode *inode) | 699 | static struct dentry *__d_find_alias(struct inode *inode, int want_discon) |
| 697 | { | 700 | { |
| 698 | struct dentry *alias, *discon_alias; | 701 | struct dentry *alias, *discon_alias; |
| 699 | 702 | ||
| @@ -705,7 +708,7 @@ again: | |||
| 705 | if (IS_ROOT(alias) && | 708 | if (IS_ROOT(alias) && |
| 706 | (alias->d_flags & DCACHE_DISCONNECTED)) { | 709 | (alias->d_flags & DCACHE_DISCONNECTED)) { |
| 707 | discon_alias = alias; | 710 | discon_alias = alias; |
| 708 | } else { | 711 | } else if (!want_discon) { |
| 709 | __dget_dlock(alias); | 712 | __dget_dlock(alias); |
| 710 | spin_unlock(&alias->d_lock); | 713 | spin_unlock(&alias->d_lock); |
| 711 | return alias; | 714 | return alias; |
| @@ -736,7 +739,7 @@ struct dentry *d_find_alias(struct inode *inode) | |||
| 736 | 739 | ||
| 737 | if (!list_empty(&inode->i_dentry)) { | 740 | if (!list_empty(&inode->i_dentry)) { |
| 738 | spin_lock(&inode->i_lock); | 741 | spin_lock(&inode->i_lock); |
| 739 | de = __d_find_alias(inode); | 742 | de = __d_find_alias(inode, 0); |
| 740 | spin_unlock(&inode->i_lock); | 743 | spin_unlock(&inode->i_lock); |
| 741 | } | 744 | } |
| 742 | return de; | 745 | return de; |
| @@ -1647,8 +1650,9 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
| 1647 | 1650 | ||
| 1648 | if (inode && S_ISDIR(inode->i_mode)) { | 1651 | if (inode && S_ISDIR(inode->i_mode)) { |
| 1649 | spin_lock(&inode->i_lock); | 1652 | spin_lock(&inode->i_lock); |
| 1650 | new = __d_find_any_alias(inode); | 1653 | new = __d_find_alias(inode, 1); |
| 1651 | if (new) { | 1654 | if (new) { |
| 1655 | BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); | ||
| 1652 | spin_unlock(&inode->i_lock); | 1656 | spin_unlock(&inode->i_lock); |
| 1653 | security_d_instantiate(new, inode); | 1657 | security_d_instantiate(new, inode); |
| 1654 | d_move(new, dentry); | 1658 | d_move(new, dentry); |
| @@ -2478,7 +2482,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | |||
| 2478 | struct dentry *alias; | 2482 | struct dentry *alias; |
| 2479 | 2483 | ||
| 2480 | /* Does an aliased dentry already exist? */ | 2484 | /* Does an aliased dentry already exist? */ |
| 2481 | alias = __d_find_alias(inode); | 2485 | alias = __d_find_alias(inode, 0); |
| 2482 | if (alias) { | 2486 | if (alias) { |
| 2483 | actual = alias; | 2487 | actual = alias; |
| 2484 | write_seqlock(&rename_lock); | 2488 | write_seqlock(&rename_lock); |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 99b6324290db..cee7812cc3cf 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -90,8 +90,8 @@ unsigned ext4_num_overhead_clusters(struct super_block *sb, | |||
| 90 | * unusual file system layouts. | 90 | * unusual file system layouts. |
| 91 | */ | 91 | */ |
| 92 | if (ext4_block_in_group(sb, ext4_block_bitmap(sb, gdp), block_group)) { | 92 | if (ext4_block_in_group(sb, ext4_block_bitmap(sb, gdp), block_group)) { |
| 93 | block_cluster = EXT4_B2C(sbi, (start - | 93 | block_cluster = EXT4_B2C(sbi, |
| 94 | ext4_block_bitmap(sb, gdp))); | 94 | ext4_block_bitmap(sb, gdp) - start); |
| 95 | if (block_cluster < num_clusters) | 95 | if (block_cluster < num_clusters) |
| 96 | block_cluster = -1; | 96 | block_cluster = -1; |
| 97 | else if (block_cluster == num_clusters) { | 97 | else if (block_cluster == num_clusters) { |
| @@ -102,7 +102,7 @@ unsigned ext4_num_overhead_clusters(struct super_block *sb, | |||
| 102 | 102 | ||
| 103 | if (ext4_block_in_group(sb, ext4_inode_bitmap(sb, gdp), block_group)) { | 103 | if (ext4_block_in_group(sb, ext4_inode_bitmap(sb, gdp), block_group)) { |
| 104 | inode_cluster = EXT4_B2C(sbi, | 104 | inode_cluster = EXT4_B2C(sbi, |
| 105 | start - ext4_inode_bitmap(sb, gdp)); | 105 | ext4_inode_bitmap(sb, gdp) - start); |
| 106 | if (inode_cluster < num_clusters) | 106 | if (inode_cluster < num_clusters) |
| 107 | inode_cluster = -1; | 107 | inode_cluster = -1; |
| 108 | else if (inode_cluster == num_clusters) { | 108 | else if (inode_cluster == num_clusters) { |
| @@ -114,7 +114,7 @@ unsigned ext4_num_overhead_clusters(struct super_block *sb, | |||
| 114 | itbl_blk = ext4_inode_table(sb, gdp); | 114 | itbl_blk = ext4_inode_table(sb, gdp); |
| 115 | for (i = 0; i < sbi->s_itb_per_group; i++) { | 115 | for (i = 0; i < sbi->s_itb_per_group; i++) { |
| 116 | if (ext4_block_in_group(sb, itbl_blk + i, block_group)) { | 116 | if (ext4_block_in_group(sb, itbl_blk + i, block_group)) { |
| 117 | c = EXT4_B2C(sbi, start - itbl_blk + i); | 117 | c = EXT4_B2C(sbi, itbl_blk + i - start); |
| 118 | if ((c < num_clusters) || (c == inode_cluster) || | 118 | if ((c < num_clusters) || (c == inode_cluster) || |
| 119 | (c == block_cluster) || (c == itbl_cluster)) | 119 | (c == block_cluster) || (c == itbl_cluster)) |
| 120 | continue; | 120 | continue; |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 8ad112ae0ade..e34deac3f366 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
| @@ -123,7 +123,6 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 123 | else | 123 | else |
| 124 | ext4_clear_inode_flag(inode, i); | 124 | ext4_clear_inode_flag(inode, i); |
| 125 | } | 125 | } |
| 126 | ei->i_flags = flags; | ||
| 127 | 126 | ||
| 128 | ext4_set_inode_flags(inode); | 127 | ext4_set_inode_flags(inode); |
| 129 | inode->i_ctime = ext4_current_time(inode); | 128 | inode->i_ctime = ext4_current_time(inode); |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 685a83756b2b..84a7e6f3c046 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
| @@ -2918,6 +2918,9 @@ int dbg_debugfs_init_fs(struct ubifs_info *c) | |||
| 2918 | struct dentry *dent; | 2918 | struct dentry *dent; |
| 2919 | struct ubifs_debug_info *d = c->dbg; | 2919 | struct ubifs_debug_info *d = c->dbg; |
| 2920 | 2920 | ||
| 2921 | if (!IS_ENABLED(DEBUG_FS)) | ||
| 2922 | return 0; | ||
| 2923 | |||
| 2921 | n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, | 2924 | n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, |
| 2922 | c->vi.ubi_num, c->vi.vol_id); | 2925 | c->vi.ubi_num, c->vi.vol_id); |
| 2923 | if (n == UBIFS_DFS_DIR_LEN) { | 2926 | if (n == UBIFS_DFS_DIR_LEN) { |
| @@ -3010,7 +3013,8 @@ out: | |||
| 3010 | */ | 3013 | */ |
| 3011 | void dbg_debugfs_exit_fs(struct ubifs_info *c) | 3014 | void dbg_debugfs_exit_fs(struct ubifs_info *c) |
| 3012 | { | 3015 | { |
| 3013 | debugfs_remove_recursive(c->dbg->dfs_dir); | 3016 | if (IS_ENABLED(DEBUG_FS)) |
| 3017 | debugfs_remove_recursive(c->dbg->dfs_dir); | ||
| 3014 | } | 3018 | } |
| 3015 | 3019 | ||
| 3016 | struct ubifs_global_debug_info ubifs_dbg; | 3020 | struct ubifs_global_debug_info ubifs_dbg; |
| @@ -3095,6 +3099,9 @@ int dbg_debugfs_init(void) | |||
| 3095 | const char *fname; | 3099 | const char *fname; |
| 3096 | struct dentry *dent; | 3100 | struct dentry *dent; |
| 3097 | 3101 | ||
| 3102 | if (!IS_ENABLED(DEBUG_FS)) | ||
| 3103 | return 0; | ||
| 3104 | |||
| 3098 | fname = "ubifs"; | 3105 | fname = "ubifs"; |
| 3099 | dent = debugfs_create_dir(fname, NULL); | 3106 | dent = debugfs_create_dir(fname, NULL); |
| 3100 | if (IS_ERR_OR_NULL(dent)) | 3107 | if (IS_ERR_OR_NULL(dent)) |
| @@ -3159,7 +3166,8 @@ out: | |||
| 3159 | */ | 3166 | */ |
| 3160 | void dbg_debugfs_exit(void) | 3167 | void dbg_debugfs_exit(void) |
| 3161 | { | 3168 | { |
| 3162 | debugfs_remove_recursive(dfs_rootdir); | 3169 | if (IS_ENABLED(DEBUG_FS)) |
| 3170 | debugfs_remove_recursive(dfs_rootdir); | ||
| 3163 | } | 3171 | } |
| 3164 | 3172 | ||
| 3165 | /** | 3173 | /** |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index b0d62820ada1..9e6e1c6eb60a 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
| @@ -440,8 +440,8 @@ static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
| 440 | 440 | ||
| 441 | #else /* CONFIG_ACPI */ | 441 | #else /* CONFIG_ACPI */ |
| 442 | 442 | ||
| 443 | static int register_acpi_bus_type(struct acpi_bus_type *bus) { return 0; } | 443 | static inline int register_acpi_bus_type(void *bus) { return 0; } |
| 444 | static int unregister_acpi_bus_type(struct acpi_bus_type *bus) { return 0; } | 444 | static inline int unregister_acpi_bus_type(void *bus) { return 0; } |
| 445 | 445 | ||
| 446 | #endif /* CONFIG_ACPI */ | 446 | #endif /* CONFIG_ACPI */ |
| 447 | 447 | ||
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h index b6d7ce92eadd..68733587e700 100644 --- a/include/drm/exynos_drm.h +++ b/include/drm/exynos_drm.h | |||
| @@ -64,6 +64,7 @@ struct drm_exynos_gem_map_off { | |||
| 64 | * A structure for mapping buffer. | 64 | * A structure for mapping buffer. |
| 65 | * | 65 | * |
| 66 | * @handle: a handle to gem object created. | 66 | * @handle: a handle to gem object created. |
| 67 | * @pad: just padding to be 64-bit aligned. | ||
| 67 | * @size: memory size to be mapped. | 68 | * @size: memory size to be mapped. |
| 68 | * @mapped: having user virtual address mmaped. | 69 | * @mapped: having user virtual address mmaped. |
| 69 | * - this variable would be filled by exynos gem module | 70 | * - this variable would be filled by exynos gem module |
| @@ -72,7 +73,8 @@ struct drm_exynos_gem_map_off { | |||
| 72 | */ | 73 | */ |
| 73 | struct drm_exynos_gem_mmap { | 74 | struct drm_exynos_gem_mmap { |
| 74 | unsigned int handle; | 75 | unsigned int handle; |
| 75 | unsigned int size; | 76 | unsigned int pad; |
| 77 | uint64_t size; | ||
| 76 | uint64_t mapped; | 78 | uint64_t mapped; |
| 77 | }; | 79 | }; |
| 78 | 80 | ||
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 1b14d25162cb..d6a58065c09c 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h | |||
| @@ -128,7 +128,7 @@ struct kparam_array | |||
| 128 | * The ops can have NULL set or get functions. | 128 | * The ops can have NULL set or get functions. |
| 129 | */ | 129 | */ |
| 130 | #define module_param_cb(name, ops, arg, perm) \ | 130 | #define module_param_cb(name, ops, arg, perm) \ |
| 131 | __module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, 0) | 131 | __module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, -1) |
| 132 | 132 | ||
| 133 | /** | 133 | /** |
| 134 | * <level>_param_cb - general callback for a module/cmdline parameter | 134 | * <level>_param_cb - general callback for a module/cmdline parameter |
| @@ -192,7 +192,7 @@ struct kparam_array | |||
| 192 | { (void *)set, (void *)get }; \ | 192 | { (void *)set, (void *)get }; \ |
| 193 | __module_param_call(MODULE_PARAM_PREFIX, \ | 193 | __module_param_call(MODULE_PARAM_PREFIX, \ |
| 194 | name, &__param_ops_##name, arg, \ | 194 | name, &__param_ops_##name, arg, \ |
| 195 | (perm) + sizeof(__check_old_set_param(set))*0, 0) | 195 | (perm) + sizeof(__check_old_set_param(set))*0, -1) |
| 196 | 196 | ||
| 197 | /* We don't get oldget: it's often a new-style param_get_uint, etc. */ | 197 | /* We don't get oldget: it's often a new-style param_get_uint, etc. */ |
| 198 | static inline int | 198 | static inline int |
| @@ -272,7 +272,7 @@ static inline void __kernel_param_unlock(void) | |||
| 272 | */ | 272 | */ |
| 273 | #define core_param(name, var, type, perm) \ | 273 | #define core_param(name, var, type, perm) \ |
| 274 | param_check_##type(name, &(var)); \ | 274 | param_check_##type(name, &(var)); \ |
| 275 | __module_param_call("", name, ¶m_ops_##type, &var, perm, 0) | 275 | __module_param_call("", name, ¶m_ops_##type, &var, perm, -1) |
| 276 | #endif /* !MODULE */ | 276 | #endif /* !MODULE */ |
| 277 | 277 | ||
| 278 | /** | 278 | /** |
| @@ -290,7 +290,7 @@ static inline void __kernel_param_unlock(void) | |||
| 290 | = { len, string }; \ | 290 | = { len, string }; \ |
| 291 | __module_param_call(MODULE_PARAM_PREFIX, name, \ | 291 | __module_param_call(MODULE_PARAM_PREFIX, name, \ |
| 292 | ¶m_ops_string, \ | 292 | ¶m_ops_string, \ |
| 293 | .str = &__param_string_##name, perm, 0); \ | 293 | .str = &__param_string_##name, perm, -1); \ |
| 294 | __MODULE_PARM_TYPE(name, "string") | 294 | __MODULE_PARM_TYPE(name, "string") |
| 295 | 295 | ||
| 296 | /** | 296 | /** |
| @@ -432,7 +432,7 @@ extern int param_set_bint(const char *val, const struct kernel_param *kp); | |||
| 432 | __module_param_call(MODULE_PARAM_PREFIX, name, \ | 432 | __module_param_call(MODULE_PARAM_PREFIX, name, \ |
| 433 | ¶m_array_ops, \ | 433 | ¶m_array_ops, \ |
| 434 | .arr = &__param_arr_##name, \ | 434 | .arr = &__param_arr_##name, \ |
| 435 | perm, 0); \ | 435 | perm, -1); \ |
| 436 | __MODULE_PARM_TYPE(name, "array of " #type) | 436 | __MODULE_PARM_TYPE(name, "array of " #type) |
| 437 | 437 | ||
| 438 | extern struct kernel_param_ops param_array_ops; | 438 | extern struct kernel_param_ops param_array_ops; |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index f32578634d9d..45db49f64bb4 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -555,6 +555,8 @@ enum perf_event_type { | |||
| 555 | PERF_RECORD_MAX, /* non-ABI */ | 555 | PERF_RECORD_MAX, /* non-ABI */ |
| 556 | }; | 556 | }; |
| 557 | 557 | ||
| 558 | #define PERF_MAX_STACK_DEPTH 127 | ||
| 559 | |||
| 558 | enum perf_callchain_context { | 560 | enum perf_callchain_context { |
| 559 | PERF_CONTEXT_HV = (__u64)-32, | 561 | PERF_CONTEXT_HV = (__u64)-32, |
| 560 | PERF_CONTEXT_KERNEL = (__u64)-128, | 562 | PERF_CONTEXT_KERNEL = (__u64)-128, |
| @@ -609,8 +611,6 @@ struct perf_guest_info_callbacks { | |||
| 609 | #include <linux/sysfs.h> | 611 | #include <linux/sysfs.h> |
| 610 | #include <asm/local.h> | 612 | #include <asm/local.h> |
| 611 | 613 | ||
| 612 | #define PERF_MAX_STACK_DEPTH 255 | ||
| 613 | |||
| 614 | struct perf_callchain_entry { | 614 | struct perf_callchain_entry { |
| 615 | __u64 nr; | 615 | __u64 nr; |
| 616 | __u64 ip[PERF_MAX_STACK_DEPTH]; | 616 | __u64 ip[PERF_MAX_STACK_DEPTH]; |
diff --git a/include/linux/prctl.h b/include/linux/prctl.h index 711e0a30aacc..3988012255dc 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h | |||
| @@ -127,8 +127,8 @@ | |||
| 127 | #define PR_SET_PTRACER 0x59616d61 | 127 | #define PR_SET_PTRACER 0x59616d61 |
| 128 | # define PR_SET_PTRACER_ANY ((unsigned long)-1) | 128 | # define PR_SET_PTRACER_ANY ((unsigned long)-1) |
| 129 | 129 | ||
| 130 | #define PR_SET_CHILD_SUBREAPER 36 | 130 | #define PR_SET_CHILD_SUBREAPER 36 |
| 131 | #define PR_GET_CHILD_SUBREAPER 37 | 131 | #define PR_GET_CHILD_SUBREAPER 37 |
| 132 | 132 | ||
| 133 | /* | 133 | /* |
| 134 | * If no_new_privs is set, then operations that grant new privileges (i.e. | 134 | * If no_new_privs is set, then operations that grant new privileges (i.e. |
| @@ -142,7 +142,9 @@ | |||
| 142 | * asking selinux for a specific new context (e.g. with runcon) will result | 142 | * asking selinux for a specific new context (e.g. with runcon) will result |
| 143 | * in execve returning -EPERM. | 143 | * in execve returning -EPERM. |
| 144 | */ | 144 | */ |
| 145 | #define PR_SET_NO_NEW_PRIVS 38 | 145 | #define PR_SET_NO_NEW_PRIVS 38 |
| 146 | #define PR_GET_NO_NEW_PRIVS 39 | 146 | #define PR_GET_NO_NEW_PRIVS 39 |
| 147 | |||
| 148 | #define PR_GET_TID_ADDRESS 40 | ||
| 147 | 149 | ||
| 148 | #endif /* _LINUX_PRCTL_H */ | 150 | #endif /* _LINUX_PRCTL_H */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index ac321d753470..4059c0f33f07 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -439,6 +439,7 @@ extern int get_dumpable(struct mm_struct *mm); | |||
| 439 | /* leave room for more dump flags */ | 439 | /* leave room for more dump flags */ |
| 440 | #define MMF_VM_MERGEABLE 16 /* KSM may merge identical pages */ | 440 | #define MMF_VM_MERGEABLE 16 /* KSM may merge identical pages */ |
| 441 | #define MMF_VM_HUGEPAGE 17 /* set when VM_HUGEPAGE is set on vma */ | 441 | #define MMF_VM_HUGEPAGE 17 /* set when VM_HUGEPAGE is set on vma */ |
| 442 | #define MMF_EXE_FILE_CHANGED 18 /* see prctl_set_mm_exe_file() */ | ||
| 442 | 443 | ||
| 443 | #define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK) | 444 | #define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK) |
| 444 | 445 | ||
diff --git a/init/main.c b/init/main.c index 1ca6b32c4828..b5cc0a7c4708 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -508,7 +508,7 @@ asmlinkage void __init start_kernel(void) | |||
| 508 | parse_early_param(); | 508 | parse_early_param(); |
| 509 | parse_args("Booting kernel", static_command_line, __start___param, | 509 | parse_args("Booting kernel", static_command_line, __start___param, |
| 510 | __stop___param - __start___param, | 510 | __stop___param - __start___param, |
| 511 | 0, 0, &unknown_bootoption); | 511 | -1, -1, &unknown_bootoption); |
| 512 | 512 | ||
| 513 | jump_label_init(); | 513 | jump_label_init(); |
| 514 | 514 | ||
| @@ -755,13 +755,8 @@ static void __init do_initcalls(void) | |||
| 755 | { | 755 | { |
| 756 | int level; | 756 | int level; |
| 757 | 757 | ||
| 758 | for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) { | 758 | for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) |
| 759 | pr_info("initlevel:%d=%s, %d registered initcalls\n", | ||
| 760 | level, initcall_level_names[level], | ||
| 761 | (int) (initcall_levels[level+1] | ||
| 762 | - initcall_levels[level])); | ||
| 763 | do_initcall_level(level); | 759 | do_initcall_level(level); |
| 764 | } | ||
| 765 | } | 760 | } |
| 766 | 761 | ||
| 767 | /* | 762 | /* |
| @@ -393,6 +393,16 @@ static int shm_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 393 | return sfd->file->f_op->fsync(sfd->file, start, end, datasync); | 393 | return sfd->file->f_op->fsync(sfd->file, start, end, datasync); |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | static long shm_fallocate(struct file *file, int mode, loff_t offset, | ||
| 397 | loff_t len) | ||
| 398 | { | ||
| 399 | struct shm_file_data *sfd = shm_file_data(file); | ||
| 400 | |||
| 401 | if (!sfd->file->f_op->fallocate) | ||
| 402 | return -EOPNOTSUPP; | ||
| 403 | return sfd->file->f_op->fallocate(file, mode, offset, len); | ||
| 404 | } | ||
| 405 | |||
| 396 | static unsigned long shm_get_unmapped_area(struct file *file, | 406 | static unsigned long shm_get_unmapped_area(struct file *file, |
| 397 | unsigned long addr, unsigned long len, unsigned long pgoff, | 407 | unsigned long addr, unsigned long len, unsigned long pgoff, |
| 398 | unsigned long flags) | 408 | unsigned long flags) |
| @@ -410,6 +420,7 @@ static const struct file_operations shm_file_operations = { | |||
| 410 | .get_unmapped_area = shm_get_unmapped_area, | 420 | .get_unmapped_area = shm_get_unmapped_area, |
| 411 | #endif | 421 | #endif |
| 412 | .llseek = noop_llseek, | 422 | .llseek = noop_llseek, |
| 423 | .fallocate = shm_fallocate, | ||
| 413 | }; | 424 | }; |
| 414 | 425 | ||
| 415 | static const struct file_operations shm_file_operations_huge = { | 426 | static const struct file_operations shm_file_operations_huge = { |
| @@ -418,6 +429,7 @@ static const struct file_operations shm_file_operations_huge = { | |||
| 418 | .release = shm_release, | 429 | .release = shm_release, |
| 419 | .get_unmapped_area = shm_get_unmapped_area, | 430 | .get_unmapped_area = shm_get_unmapped_area, |
| 420 | .llseek = noop_llseek, | 431 | .llseek = noop_llseek, |
| 432 | .fallocate = shm_fallocate, | ||
| 421 | }; | 433 | }; |
| 422 | 434 | ||
| 423 | int is_file_shm_hugepages(struct file *file) | 435 | int is_file_shm_hugepages(struct file *file) |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 5b06cbbf6931..f85c0154b333 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -3181,7 +3181,6 @@ static void perf_event_for_each(struct perf_event *event, | |||
| 3181 | event = event->group_leader; | 3181 | event = event->group_leader; |
| 3182 | 3182 | ||
| 3183 | perf_event_for_each_child(event, func); | 3183 | perf_event_for_each_child(event, func); |
| 3184 | func(event); | ||
| 3185 | list_for_each_entry(sibling, &event->sibling_list, group_entry) | 3184 | list_for_each_entry(sibling, &event->sibling_list, group_entry) |
| 3186 | perf_event_for_each_child(sibling, func); | 3185 | perf_event_for_each_child(sibling, func); |
| 3187 | mutex_unlock(&ctx->mutex); | 3186 | mutex_unlock(&ctx->mutex); |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index c9fd6d673d05..c099cc6eebe3 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
| @@ -3632,7 +3632,7 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group) | |||
| 3632 | 3632 | ||
| 3633 | /** | 3633 | /** |
| 3634 | * update_sg_lb_stats - Update sched_group's statistics for load balancing. | 3634 | * update_sg_lb_stats - Update sched_group's statistics for load balancing. |
| 3635 | * @sd: The sched_domain whose statistics are to be updated. | 3635 | * @env: The load balancing environment. |
| 3636 | * @group: sched_group whose statistics are to be updated. | 3636 | * @group: sched_group whose statistics are to be updated. |
| 3637 | * @load_idx: Load index of sched_domain of this_cpu for load calc. | 3637 | * @load_idx: Load index of sched_domain of this_cpu for load calc. |
| 3638 | * @local_group: Does group contain this_cpu. | 3638 | * @local_group: Does group contain this_cpu. |
| @@ -3742,11 +3742,10 @@ static inline void update_sg_lb_stats(struct lb_env *env, | |||
| 3742 | 3742 | ||
| 3743 | /** | 3743 | /** |
| 3744 | * update_sd_pick_busiest - return 1 on busiest group | 3744 | * update_sd_pick_busiest - return 1 on busiest group |
| 3745 | * @sd: sched_domain whose statistics are to be checked | 3745 | * @env: The load balancing environment. |
| 3746 | * @sds: sched_domain statistics | 3746 | * @sds: sched_domain statistics |
| 3747 | * @sg: sched_group candidate to be checked for being the busiest | 3747 | * @sg: sched_group candidate to be checked for being the busiest |
| 3748 | * @sgs: sched_group statistics | 3748 | * @sgs: sched_group statistics |
| 3749 | * @this_cpu: the current cpu | ||
| 3750 | * | 3749 | * |
| 3751 | * Determine if @sg is a busier group than the previously selected | 3750 | * Determine if @sg is a busier group than the previously selected |
| 3752 | * busiest group. | 3751 | * busiest group. |
| @@ -3784,9 +3783,7 @@ static bool update_sd_pick_busiest(struct lb_env *env, | |||
| 3784 | 3783 | ||
| 3785 | /** | 3784 | /** |
| 3786 | * update_sd_lb_stats - Update sched_domain's statistics for load balancing. | 3785 | * update_sd_lb_stats - Update sched_domain's statistics for load balancing. |
| 3787 | * @sd: sched_domain whose statistics are to be updated. | 3786 | * @env: The load balancing environment. |
| 3788 | * @this_cpu: Cpu for which load balance is currently performed. | ||
| 3789 | * @idle: Idle status of this_cpu | ||
| 3790 | * @cpus: Set of cpus considered for load balancing. | 3787 | * @cpus: Set of cpus considered for load balancing. |
| 3791 | * @balance: Should we balance. | 3788 | * @balance: Should we balance. |
| 3792 | * @sds: variable to hold the statistics for this sched_domain. | 3789 | * @sds: variable to hold the statistics for this sched_domain. |
| @@ -3875,10 +3872,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, | |||
| 3875 | * Returns 1 when packing is required and a task should be moved to | 3872 | * Returns 1 when packing is required and a task should be moved to |
| 3876 | * this CPU. The amount of the imbalance is returned in *imbalance. | 3873 | * this CPU. The amount of the imbalance is returned in *imbalance. |
| 3877 | * | 3874 | * |
| 3878 | * @sd: The sched_domain whose packing is to be checked. | 3875 | * @env: The load balancing environment. |
| 3879 | * @sds: Statistics of the sched_domain which is to be packed | 3876 | * @sds: Statistics of the sched_domain which is to be packed |
| 3880 | * @this_cpu: The cpu at whose sched_domain we're performing load-balance. | ||
| 3881 | * @imbalance: returns amount of imbalanced due to packing. | ||
| 3882 | */ | 3877 | */ |
| 3883 | static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds) | 3878 | static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds) |
| 3884 | { | 3879 | { |
| @@ -3904,9 +3899,8 @@ static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds) | |||
| 3904 | * fix_small_imbalance - Calculate the minor imbalance that exists | 3899 | * fix_small_imbalance - Calculate the minor imbalance that exists |
| 3905 | * amongst the groups of a sched_domain, during | 3900 | * amongst the groups of a sched_domain, during |
| 3906 | * load balancing. | 3901 | * load balancing. |
| 3902 | * @env: The load balancing environment. | ||
| 3907 | * @sds: Statistics of the sched_domain whose imbalance is to be calculated. | 3903 | * @sds: Statistics of the sched_domain whose imbalance is to be calculated. |
| 3908 | * @this_cpu: The cpu at whose sched_domain we're performing load-balance. | ||
| 3909 | * @imbalance: Variable to store the imbalance. | ||
| 3910 | */ | 3904 | */ |
| 3911 | static inline | 3905 | static inline |
| 3912 | void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) | 3906 | void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) |
| @@ -4049,11 +4043,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
| 4049 | * Also calculates the amount of weighted load which should be moved | 4043 | * Also calculates the amount of weighted load which should be moved |
| 4050 | * to restore balance. | 4044 | * to restore balance. |
| 4051 | * | 4045 | * |
| 4052 | * @sd: The sched_domain whose busiest group is to be returned. | 4046 | * @env: The load balancing environment. |
| 4053 | * @this_cpu: The cpu for which load balancing is currently being performed. | ||
| 4054 | * @imbalance: Variable which stores amount of weighted load which should | ||
| 4055 | * be moved to restore balance/put a group to idle. | ||
| 4056 | * @idle: The idle status of this_cpu. | ||
| 4057 | * @cpus: The set of CPUs under consideration for load-balancing. | 4047 | * @cpus: The set of CPUs under consideration for load-balancing. |
| 4058 | * @balance: Pointer to a variable indicating if this_cpu | 4048 | * @balance: Pointer to a variable indicating if this_cpu |
| 4059 | * is the appropriate cpu to perform load balancing at this_level. | 4049 | * is the appropriate cpu to perform load balancing at this_level. |
diff --git a/kernel/sys.c b/kernel/sys.c index 9ff89cb9657a..f0ec44dcd415 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -1786,27 +1786,13 @@ SYSCALL_DEFINE1(umask, int, mask) | |||
| 1786 | } | 1786 | } |
| 1787 | 1787 | ||
| 1788 | #ifdef CONFIG_CHECKPOINT_RESTORE | 1788 | #ifdef CONFIG_CHECKPOINT_RESTORE |
| 1789 | static bool vma_flags_mismatch(struct vm_area_struct *vma, | ||
| 1790 | unsigned long required, | ||
| 1791 | unsigned long banned) | ||
| 1792 | { | ||
| 1793 | return (vma->vm_flags & required) != required || | ||
| 1794 | (vma->vm_flags & banned); | ||
| 1795 | } | ||
| 1796 | |||
| 1797 | static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | 1789 | static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) |
| 1798 | { | 1790 | { |
| 1791 | struct vm_area_struct *vma; | ||
| 1799 | struct file *exe_file; | 1792 | struct file *exe_file; |
| 1800 | struct dentry *dentry; | 1793 | struct dentry *dentry; |
| 1801 | int err; | 1794 | int err; |
| 1802 | 1795 | ||
| 1803 | /* | ||
| 1804 | * Setting new mm::exe_file is only allowed when no VM_EXECUTABLE vma's | ||
| 1805 | * remain. So perform a quick test first. | ||
| 1806 | */ | ||
| 1807 | if (mm->num_exe_file_vmas) | ||
| 1808 | return -EBUSY; | ||
| 1809 | |||
| 1810 | exe_file = fget(fd); | 1796 | exe_file = fget(fd); |
| 1811 | if (!exe_file) | 1797 | if (!exe_file) |
| 1812 | return -EBADF; | 1798 | return -EBADF; |
| @@ -1827,17 +1813,30 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | |||
| 1827 | if (err) | 1813 | if (err) |
| 1828 | goto exit; | 1814 | goto exit; |
| 1829 | 1815 | ||
| 1816 | down_write(&mm->mmap_sem); | ||
| 1817 | |||
| 1818 | /* | ||
| 1819 | * Forbid mm->exe_file change if there are mapped other files. | ||
| 1820 | */ | ||
| 1821 | err = -EBUSY; | ||
| 1822 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | ||
| 1823 | if (vma->vm_file && !path_equal(&vma->vm_file->f_path, | ||
| 1824 | &exe_file->f_path)) | ||
| 1825 | goto exit_unlock; | ||
| 1826 | } | ||
| 1827 | |||
| 1830 | /* | 1828 | /* |
| 1831 | * The symlink can be changed only once, just to disallow arbitrary | 1829 | * The symlink can be changed only once, just to disallow arbitrary |
| 1832 | * transitions malicious software might bring in. This means one | 1830 | * transitions malicious software might bring in. This means one |
| 1833 | * could make a snapshot over all processes running and monitor | 1831 | * could make a snapshot over all processes running and monitor |
| 1834 | * /proc/pid/exe changes to notice unusual activity if needed. | 1832 | * /proc/pid/exe changes to notice unusual activity if needed. |
| 1835 | */ | 1833 | */ |
| 1836 | down_write(&mm->mmap_sem); | 1834 | err = -EPERM; |
| 1837 | if (likely(!mm->exe_file)) | 1835 | if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags)) |
| 1838 | set_mm_exe_file(mm, exe_file); | 1836 | goto exit_unlock; |
| 1839 | else | 1837 | |
| 1840 | err = -EBUSY; | 1838 | set_mm_exe_file(mm, exe_file); |
| 1839 | exit_unlock: | ||
| 1841 | up_write(&mm->mmap_sem); | 1840 | up_write(&mm->mmap_sem); |
| 1842 | 1841 | ||
| 1843 | exit: | 1842 | exit: |
| @@ -1862,7 +1861,7 @@ static int prctl_set_mm(int opt, unsigned long addr, | |||
| 1862 | if (opt == PR_SET_MM_EXE_FILE) | 1861 | if (opt == PR_SET_MM_EXE_FILE) |
| 1863 | return prctl_set_mm_exe_file(mm, (unsigned int)addr); | 1862 | return prctl_set_mm_exe_file(mm, (unsigned int)addr); |
| 1864 | 1863 | ||
| 1865 | if (addr >= TASK_SIZE) | 1864 | if (addr >= TASK_SIZE || addr < mmap_min_addr) |
| 1866 | return -EINVAL; | 1865 | return -EINVAL; |
| 1867 | 1866 | ||
| 1868 | error = -EINVAL; | 1867 | error = -EINVAL; |
| @@ -1924,12 +1923,6 @@ static int prctl_set_mm(int opt, unsigned long addr, | |||
| 1924 | error = -EFAULT; | 1923 | error = -EFAULT; |
| 1925 | goto out; | 1924 | goto out; |
| 1926 | } | 1925 | } |
| 1927 | #ifdef CONFIG_STACK_GROWSUP | ||
| 1928 | if (vma_flags_mismatch(vma, VM_READ | VM_WRITE | VM_GROWSUP, 0)) | ||
| 1929 | #else | ||
| 1930 | if (vma_flags_mismatch(vma, VM_READ | VM_WRITE | VM_GROWSDOWN, 0)) | ||
| 1931 | #endif | ||
| 1932 | goto out; | ||
| 1933 | if (opt == PR_SET_MM_START_STACK) | 1926 | if (opt == PR_SET_MM_START_STACK) |
| 1934 | mm->start_stack = addr; | 1927 | mm->start_stack = addr; |
| 1935 | else if (opt == PR_SET_MM_ARG_START) | 1928 | else if (opt == PR_SET_MM_ARG_START) |
| @@ -1981,12 +1974,22 @@ out: | |||
| 1981 | up_read(&mm->mmap_sem); | 1974 | up_read(&mm->mmap_sem); |
| 1982 | return error; | 1975 | return error; |
| 1983 | } | 1976 | } |
| 1977 | |||
| 1978 | static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr) | ||
| 1979 | { | ||
| 1980 | return put_user(me->clear_child_tid, tid_addr); | ||
| 1981 | } | ||
| 1982 | |||
| 1984 | #else /* CONFIG_CHECKPOINT_RESTORE */ | 1983 | #else /* CONFIG_CHECKPOINT_RESTORE */ |
| 1985 | static int prctl_set_mm(int opt, unsigned long addr, | 1984 | static int prctl_set_mm(int opt, unsigned long addr, |
| 1986 | unsigned long arg4, unsigned long arg5) | 1985 | unsigned long arg4, unsigned long arg5) |
| 1987 | { | 1986 | { |
| 1988 | return -EINVAL; | 1987 | return -EINVAL; |
| 1989 | } | 1988 | } |
| 1989 | static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr) | ||
| 1990 | { | ||
| 1991 | return -EINVAL; | ||
| 1992 | } | ||
| 1990 | #endif | 1993 | #endif |
| 1991 | 1994 | ||
| 1992 | SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | 1995 | SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, |
| @@ -2124,6 +2127,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
| 2124 | else | 2127 | else |
| 2125 | return -EINVAL; | 2128 | return -EINVAL; |
| 2126 | break; | 2129 | break; |
| 2130 | case PR_GET_TID_ADDRESS: | ||
| 2131 | error = prctl_get_tid_address(me, (int __user **)arg2); | ||
| 2132 | break; | ||
| 2127 | default: | 2133 | default: |
| 2128 | return -EINVAL; | 2134 | return -EINVAL; |
| 2129 | } | 2135 | } |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 6e46cacf5969..6f46a00a1e8a 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -962,6 +962,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
| 962 | timekeeper.xtime.tv_sec++; | 962 | timekeeper.xtime.tv_sec++; |
| 963 | leap = second_overflow(timekeeper.xtime.tv_sec); | 963 | leap = second_overflow(timekeeper.xtime.tv_sec); |
| 964 | timekeeper.xtime.tv_sec += leap; | 964 | timekeeper.xtime.tv_sec += leap; |
| 965 | timekeeper.wall_to_monotonic.tv_sec -= leap; | ||
| 965 | } | 966 | } |
| 966 | 967 | ||
| 967 | /* Accumulate raw time */ | 968 | /* Accumulate raw time */ |
| @@ -1077,6 +1078,7 @@ static void update_wall_time(void) | |||
| 1077 | timekeeper.xtime.tv_sec++; | 1078 | timekeeper.xtime.tv_sec++; |
| 1078 | leap = second_overflow(timekeeper.xtime.tv_sec); | 1079 | leap = second_overflow(timekeeper.xtime.tv_sec); |
| 1079 | timekeeper.xtime.tv_sec += leap; | 1080 | timekeeper.xtime.tv_sec += leap; |
| 1081 | timekeeper.wall_to_monotonic.tv_sec -= leap; | ||
| 1080 | } | 1082 | } |
| 1081 | 1083 | ||
| 1082 | timekeeping_update(false); | 1084 | timekeeping_update(false); |
diff --git a/lib/btree.c b/lib/btree.c index e5ec1e9c1aa5..f9a484676cb6 100644 --- a/lib/btree.c +++ b/lib/btree.c | |||
| @@ -319,8 +319,8 @@ void *btree_get_prev(struct btree_head *head, struct btree_geo *geo, | |||
| 319 | 319 | ||
| 320 | if (head->height == 0) | 320 | if (head->height == 0) |
| 321 | return NULL; | 321 | return NULL; |
| 322 | retry: | ||
| 323 | longcpy(key, __key, geo->keylen); | 322 | longcpy(key, __key, geo->keylen); |
| 323 | retry: | ||
| 324 | dec_key(geo, key); | 324 | dec_key(geo, key); |
| 325 | 325 | ||
| 326 | node = head->node; | 326 | node = head->node; |
| @@ -351,7 +351,7 @@ retry: | |||
| 351 | } | 351 | } |
| 352 | miss: | 352 | miss: |
| 353 | if (retry_key) { | 353 | if (retry_key) { |
| 354 | __key = retry_key; | 354 | longcpy(key, retry_key, geo->keylen); |
| 355 | retry_key = NULL; | 355 | retry_key = NULL; |
| 356 | goto retry; | 356 | goto retry; |
| 357 | } | 357 | } |
| @@ -509,6 +509,7 @@ retry: | |||
| 509 | int btree_insert(struct btree_head *head, struct btree_geo *geo, | 509 | int btree_insert(struct btree_head *head, struct btree_geo *geo, |
| 510 | unsigned long *key, void *val, gfp_t gfp) | 510 | unsigned long *key, void *val, gfp_t gfp) |
| 511 | { | 511 | { |
| 512 | BUG_ON(!val); | ||
| 512 | return btree_insert_level(head, geo, key, val, 1, gfp); | 513 | return btree_insert_level(head, geo, key, val, 1, gfp); |
| 513 | } | 514 | } |
| 514 | EXPORT_SYMBOL_GPL(btree_insert); | 515 | EXPORT_SYMBOL_GPL(btree_insert); |
diff --git a/lib/raid6/recov.c b/lib/raid6/recov.c index 1805a5cc5daa..a95bccb8497d 100644 --- a/lib/raid6/recov.c +++ b/lib/raid6/recov.c | |||
| @@ -22,8 +22,8 @@ | |||
| 22 | #include <linux/raid/pq.h> | 22 | #include <linux/raid/pq.h> |
| 23 | 23 | ||
| 24 | /* Recover two failed data blocks. */ | 24 | /* Recover two failed data blocks. */ |
| 25 | void raid6_2data_recov_intx1(int disks, size_t bytes, int faila, int failb, | 25 | static void raid6_2data_recov_intx1(int disks, size_t bytes, int faila, |
| 26 | void **ptrs) | 26 | int failb, void **ptrs) |
| 27 | { | 27 | { |
| 28 | u8 *p, *q, *dp, *dq; | 28 | u8 *p, *q, *dp, *dq; |
| 29 | u8 px, qx, db; | 29 | u8 px, qx, db; |
| @@ -66,7 +66,8 @@ void raid6_2data_recov_intx1(int disks, size_t bytes, int faila, int failb, | |||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | /* Recover failure of one data block plus the P block */ | 68 | /* Recover failure of one data block plus the P block */ |
| 69 | void raid6_datap_recov_intx1(int disks, size_t bytes, int faila, void **ptrs) | 69 | static void raid6_datap_recov_intx1(int disks, size_t bytes, int faila, |
| 70 | void **ptrs) | ||
| 70 | { | 71 | { |
| 71 | u8 *p, *q, *dq; | 72 | u8 *p, *q, *dq; |
| 72 | const u8 *qmul; /* Q multiplier table */ | 73 | const u8 *qmul; /* Q multiplier table */ |
diff --git a/lib/raid6/recov_ssse3.c b/lib/raid6/recov_ssse3.c index 37ae61930559..ecb710c0b4d9 100644 --- a/lib/raid6/recov_ssse3.c +++ b/lib/raid6/recov_ssse3.c | |||
| @@ -19,8 +19,8 @@ static int raid6_has_ssse3(void) | |||
| 19 | boot_cpu_has(X86_FEATURE_SSSE3); | 19 | boot_cpu_has(X86_FEATURE_SSSE3); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | void raid6_2data_recov_ssse3(int disks, size_t bytes, int faila, int failb, | 22 | static void raid6_2data_recov_ssse3(int disks, size_t bytes, int faila, |
| 23 | void **ptrs) | 23 | int failb, void **ptrs) |
| 24 | { | 24 | { |
| 25 | u8 *p, *q, *dp, *dq; | 25 | u8 *p, *q, *dp, *dq; |
| 26 | const u8 *pbmul; /* P multiplier table for B data */ | 26 | const u8 *pbmul; /* P multiplier table for B data */ |
| @@ -194,7 +194,8 @@ void raid6_2data_recov_ssse3(int disks, size_t bytes, int faila, int failb, | |||
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | 196 | ||
| 197 | void raid6_datap_recov_ssse3(int disks, size_t bytes, int faila, void **ptrs) | 197 | static void raid6_datap_recov_ssse3(int disks, size_t bytes, int faila, |
| 198 | void **ptrs) | ||
| 198 | { | 199 | { |
| 199 | u8 *p, *q, *dq; | 200 | u8 *p, *q, *dq; |
| 200 | const u8 *qmul; /* Q multiplier table */ | 201 | const u8 *qmul; /* Q multiplier table */ |
diff --git a/mm/shmem.c b/mm/shmem.c index 585bd220a21e..a15a466d0d1d 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -683,10 +683,21 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, | |||
| 683 | mutex_lock(&shmem_swaplist_mutex); | 683 | mutex_lock(&shmem_swaplist_mutex); |
| 684 | /* | 684 | /* |
| 685 | * We needed to drop mutex to make that restrictive page | 685 | * We needed to drop mutex to make that restrictive page |
| 686 | * allocation; but the inode might already be freed by now, | 686 | * allocation, but the inode might have been freed while we |
| 687 | * and we cannot refer to inode or mapping or info to check. | 687 | * dropped it: although a racing shmem_evict_inode() cannot |
| 688 | * However, we do hold page lock on the PageSwapCache page, | 688 | * complete without emptying the radix_tree, our page lock |
| 689 | * so can check if that still has our reference remaining. | 689 | * on this swapcache page is not enough to prevent that - |
| 690 | * free_swap_and_cache() of our swap entry will only | ||
| 691 | * trylock_page(), removing swap from radix_tree whatever. | ||
| 692 | * | ||
| 693 | * We must not proceed to shmem_add_to_page_cache() if the | ||
| 694 | * inode has been freed, but of course we cannot rely on | ||
| 695 | * inode or mapping or info to check that. However, we can | ||
| 696 | * safely check if our swap entry is still in use (and here | ||
| 697 | * it can't have got reused for another page): if it's still | ||
| 698 | * in use, then the inode cannot have been freed yet, and we | ||
| 699 | * can safely proceed (if it's no longer in use, that tells | ||
| 700 | * nothing about the inode, but we don't need to unuse swap). | ||
| 690 | */ | 701 | */ |
| 691 | if (!page_swapcount(*pagep)) | 702 | if (!page_swapcount(*pagep)) |
| 692 | error = -ENOENT; | 703 | error = -ENOENT; |
| @@ -730,9 +741,9 @@ int shmem_unuse(swp_entry_t swap, struct page *page) | |||
| 730 | 741 | ||
| 731 | /* | 742 | /* |
| 732 | * There's a faint possibility that swap page was replaced before | 743 | * There's a faint possibility that swap page was replaced before |
| 733 | * caller locked it: it will come back later with the right page. | 744 | * caller locked it: caller will come back later with the right page. |
| 734 | */ | 745 | */ |
| 735 | if (unlikely(!PageSwapCache(page))) | 746 | if (unlikely(!PageSwapCache(page) || page_private(page) != swap.val)) |
| 736 | goto out; | 747 | goto out; |
| 737 | 748 | ||
| 738 | /* | 749 | /* |
| @@ -995,21 +1006,15 @@ static int shmem_replace_page(struct page **pagep, gfp_t gfp, | |||
| 995 | newpage = shmem_alloc_page(gfp, info, index); | 1006 | newpage = shmem_alloc_page(gfp, info, index); |
| 996 | if (!newpage) | 1007 | if (!newpage) |
| 997 | return -ENOMEM; | 1008 | return -ENOMEM; |
| 998 | VM_BUG_ON(shmem_should_replace_page(newpage, gfp)); | ||
| 999 | 1009 | ||
| 1000 | *pagep = newpage; | ||
| 1001 | page_cache_get(newpage); | 1010 | page_cache_get(newpage); |
| 1002 | copy_highpage(newpage, oldpage); | 1011 | copy_highpage(newpage, oldpage); |
| 1012 | flush_dcache_page(newpage); | ||
| 1003 | 1013 | ||
| 1004 | VM_BUG_ON(!PageLocked(oldpage)); | ||
| 1005 | __set_page_locked(newpage); | 1014 | __set_page_locked(newpage); |
| 1006 | VM_BUG_ON(!PageUptodate(oldpage)); | ||
| 1007 | SetPageUptodate(newpage); | 1015 | SetPageUptodate(newpage); |
| 1008 | VM_BUG_ON(!PageSwapBacked(oldpage)); | ||
| 1009 | SetPageSwapBacked(newpage); | 1016 | SetPageSwapBacked(newpage); |
| 1010 | VM_BUG_ON(!swap_index); | ||
| 1011 | set_page_private(newpage, swap_index); | 1017 | set_page_private(newpage, swap_index); |
| 1012 | VM_BUG_ON(!PageSwapCache(oldpage)); | ||
| 1013 | SetPageSwapCache(newpage); | 1018 | SetPageSwapCache(newpage); |
| 1014 | 1019 | ||
| 1015 | /* | 1020 | /* |
| @@ -1019,13 +1024,24 @@ static int shmem_replace_page(struct page **pagep, gfp_t gfp, | |||
| 1019 | spin_lock_irq(&swap_mapping->tree_lock); | 1024 | spin_lock_irq(&swap_mapping->tree_lock); |
| 1020 | error = shmem_radix_tree_replace(swap_mapping, swap_index, oldpage, | 1025 | error = shmem_radix_tree_replace(swap_mapping, swap_index, oldpage, |
| 1021 | newpage); | 1026 | newpage); |
| 1022 | __inc_zone_page_state(newpage, NR_FILE_PAGES); | 1027 | if (!error) { |
| 1023 | __dec_zone_page_state(oldpage, NR_FILE_PAGES); | 1028 | __inc_zone_page_state(newpage, NR_FILE_PAGES); |
| 1029 | __dec_zone_page_state(oldpage, NR_FILE_PAGES); | ||
| 1030 | } | ||
| 1024 | spin_unlock_irq(&swap_mapping->tree_lock); | 1031 | spin_unlock_irq(&swap_mapping->tree_lock); |
| 1025 | BUG_ON(error); | ||
| 1026 | 1032 | ||
| 1027 | mem_cgroup_replace_page_cache(oldpage, newpage); | 1033 | if (unlikely(error)) { |
| 1028 | lru_cache_add_anon(newpage); | 1034 | /* |
| 1035 | * Is this possible? I think not, now that our callers check | ||
| 1036 | * both PageSwapCache and page_private after getting page lock; | ||
| 1037 | * but be defensive. Reverse old to newpage for clear and free. | ||
| 1038 | */ | ||
| 1039 | oldpage = newpage; | ||
| 1040 | } else { | ||
| 1041 | mem_cgroup_replace_page_cache(oldpage, newpage); | ||
| 1042 | lru_cache_add_anon(newpage); | ||
| 1043 | *pagep = newpage; | ||
| 1044 | } | ||
| 1029 | 1045 | ||
| 1030 | ClearPageSwapCache(oldpage); | 1046 | ClearPageSwapCache(oldpage); |
| 1031 | set_page_private(oldpage, 0); | 1047 | set_page_private(oldpage, 0); |
| @@ -1033,7 +1049,7 @@ static int shmem_replace_page(struct page **pagep, gfp_t gfp, | |||
| 1033 | unlock_page(oldpage); | 1049 | unlock_page(oldpage); |
| 1034 | page_cache_release(oldpage); | 1050 | page_cache_release(oldpage); |
| 1035 | page_cache_release(oldpage); | 1051 | page_cache_release(oldpage); |
| 1036 | return 0; | 1052 | return error; |
| 1037 | } | 1053 | } |
| 1038 | 1054 | ||
| 1039 | /* | 1055 | /* |
| @@ -1107,7 +1123,8 @@ repeat: | |||
| 1107 | 1123 | ||
| 1108 | /* We have to do this with page locked to prevent races */ | 1124 | /* We have to do this with page locked to prevent races */ |
| 1109 | lock_page(page); | 1125 | lock_page(page); |
| 1110 | if (!PageSwapCache(page) || page->mapping) { | 1126 | if (!PageSwapCache(page) || page_private(page) != swap.val || |
| 1127 | page->mapping) { | ||
| 1111 | error = -EEXIST; /* try again */ | 1128 | error = -EEXIST; /* try again */ |
| 1112 | goto failed; | 1129 | goto failed; |
| 1113 | } | 1130 | } |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 5476bc0a1eac..b4b572e8c100 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | tools/perf | 1 | tools/perf |
| 2 | tools/scripts | ||
| 3 | tools/lib/traceevent | ||
| 2 | include/linux/const.h | 4 | include/linux/const.h |
| 3 | include/linux/perf_event.h | 5 | include/linux/perf_event.h |
| 4 | include/linux/rbtree.h | 6 | include/linux/rbtree.h |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 8c767c6bca91..25249f76329d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -152,7 +152,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel, | |||
| 152 | 152 | ||
| 153 | if (symbol_conf.use_callchain) { | 153 | if (symbol_conf.use_callchain) { |
| 154 | err = callchain_append(he->callchain, | 154 | err = callchain_append(he->callchain, |
| 155 | &evsel->hists.callchain_cursor, | 155 | &callchain_cursor, |
| 156 | sample->period); | 156 | sample->period); |
| 157 | if (err) | 157 | if (err) |
| 158 | return err; | 158 | return err; |
| @@ -162,7 +162,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel, | |||
| 162 | * so we don't allocated the extra space needed because the stdio | 162 | * so we don't allocated the extra space needed because the stdio |
| 163 | * code will not use it. | 163 | * code will not use it. |
| 164 | */ | 164 | */ |
| 165 | if (al->sym != NULL && use_browser > 0) { | 165 | if (he->ms.sym != NULL && use_browser > 0) { |
| 166 | struct annotation *notes = symbol__annotation(he->ms.sym); | 166 | struct annotation *notes = symbol__annotation(he->ms.sym); |
| 167 | 167 | ||
| 168 | assert(evsel != NULL); | 168 | assert(evsel != NULL); |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 62ae30d34fa6..262589991ea4 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -1129,7 +1129,7 @@ static int add_default_attributes(void) | |||
| 1129 | return 0; | 1129 | return 0; |
| 1130 | 1130 | ||
| 1131 | if (!evsel_list->nr_entries) { | 1131 | if (!evsel_list->nr_entries) { |
| 1132 | if (perf_evlist__add_attrs_array(evsel_list, default_attrs) < 0) | 1132 | if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0) |
| 1133 | return -1; | 1133 | return -1; |
| 1134 | } | 1134 | } |
| 1135 | 1135 | ||
| @@ -1139,21 +1139,21 @@ static int add_default_attributes(void) | |||
| 1139 | return 0; | 1139 | return 0; |
| 1140 | 1140 | ||
| 1141 | /* Append detailed run extra attributes: */ | 1141 | /* Append detailed run extra attributes: */ |
| 1142 | if (perf_evlist__add_attrs_array(evsel_list, detailed_attrs) < 0) | 1142 | if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) |
| 1143 | return -1; | 1143 | return -1; |
| 1144 | 1144 | ||
| 1145 | if (detailed_run < 2) | 1145 | if (detailed_run < 2) |
| 1146 | return 0; | 1146 | return 0; |
| 1147 | 1147 | ||
| 1148 | /* Append very detailed run extra attributes: */ | 1148 | /* Append very detailed run extra attributes: */ |
| 1149 | if (perf_evlist__add_attrs_array(evsel_list, very_detailed_attrs) < 0) | 1149 | if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) |
| 1150 | return -1; | 1150 | return -1; |
| 1151 | 1151 | ||
| 1152 | if (detailed_run < 3) | 1152 | if (detailed_run < 3) |
| 1153 | return 0; | 1153 | return 0; |
| 1154 | 1154 | ||
| 1155 | /* Append very, very detailed run extra attributes: */ | 1155 | /* Append very, very detailed run extra attributes: */ |
| 1156 | return perf_evlist__add_attrs_array(evsel_list, very_very_detailed_attrs); | 1156 | return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); |
| 1157 | } | 1157 | } |
| 1158 | 1158 | ||
| 1159 | int cmd_stat(int argc, const char **argv, const char *prefix __used) | 1159 | int cmd_stat(int argc, const char **argv, const char *prefix __used) |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 871b540293e1..6bb0277b7dfe 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -787,7 +787,7 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
| 787 | } | 787 | } |
| 788 | 788 | ||
| 789 | if (symbol_conf.use_callchain) { | 789 | if (symbol_conf.use_callchain) { |
| 790 | err = callchain_append(he->callchain, &evsel->hists.callchain_cursor, | 790 | err = callchain_append(he->callchain, &callchain_cursor, |
| 791 | sample->period); | 791 | sample->period); |
| 792 | if (err) | 792 | if (err) |
| 793 | return; | 793 | return; |
diff --git a/tools/perf/design.txt b/tools/perf/design.txt index bd0bb1b1279b..67e5d0cace85 100644 --- a/tools/perf/design.txt +++ b/tools/perf/design.txt | |||
| @@ -409,14 +409,15 @@ Counters can be enabled and disabled in two ways: via ioctl and via | |||
| 409 | prctl. When a counter is disabled, it doesn't count or generate | 409 | prctl. When a counter is disabled, it doesn't count or generate |
| 410 | events but does continue to exist and maintain its count value. | 410 | events but does continue to exist and maintain its count value. |
| 411 | 411 | ||
| 412 | An individual counter or counter group can be enabled with | 412 | An individual counter can be enabled with |
| 413 | 413 | ||
| 414 | ioctl(fd, PERF_EVENT_IOC_ENABLE); | 414 | ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); |
| 415 | 415 | ||
| 416 | or disabled with | 416 | or disabled with |
| 417 | 417 | ||
| 418 | ioctl(fd, PERF_EVENT_IOC_DISABLE); | 418 | ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); |
| 419 | 419 | ||
| 420 | For a counter group, pass PERF_IOC_FLAG_GROUP as the third argument. | ||
| 420 | Enabling or disabling the leader of a group enables or disables the | 421 | Enabling or disabling the leader of a group enables or disables the |
| 421 | whole group; that is, while the group leader is disabled, none of the | 422 | whole group; that is, while the group leader is disabled, none of the |
| 422 | counters in the group will count. Enabling or disabling a member of a | 423 | counters in the group will count. Enabling or disabling a member of a |
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 4deea6aaf927..34b1c46eaf42 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
| @@ -668,7 +668,7 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx, | |||
| 668 | "q/ESC/CTRL+C Exit\n\n" | 668 | "q/ESC/CTRL+C Exit\n\n" |
| 669 | "-> Go to target\n" | 669 | "-> Go to target\n" |
| 670 | "<- Exit\n" | 670 | "<- Exit\n" |
| 671 | "h Cycle thru hottest instructions\n" | 671 | "H Cycle thru hottest instructions\n" |
| 672 | "j Toggle showing jump to target arrows\n" | 672 | "j Toggle showing jump to target arrows\n" |
| 673 | "J Toggle showing number of jump sources on targets\n" | 673 | "J Toggle showing number of jump sources on targets\n" |
| 674 | "n Search next string\n" | 674 | "n Search next string\n" |
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index ad73300f7bac..95264f304179 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN | |||
| @@ -12,7 +12,7 @@ LF=' | |||
| 12 | # First check if there is a .git to get the version from git describe | 12 | # First check if there is a .git to get the version from git describe |
| 13 | # otherwise try to get the version from the kernel makefile | 13 | # otherwise try to get the version from the kernel makefile |
| 14 | if test -d ../../.git -o -f ../../.git && | 14 | if test -d ../../.git -o -f ../../.git && |
| 15 | VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && | 15 | VN=$(git describe --match 'v[0-9].[0-9]*' --abbrev=4 HEAD 2>/dev/null) && |
| 16 | case "$VN" in | 16 | case "$VN" in |
| 17 | *$LF*) (exit 1) ;; | 17 | *$LF*) (exit 1) ;; |
| 18 | v[0-9]*) | 18 | v[0-9]*) |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 9f7106a8d9a4..3a6bff47614f 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #include "util.h" | 18 | #include "util.h" |
| 19 | #include "callchain.h" | 19 | #include "callchain.h" |
| 20 | 20 | ||
| 21 | __thread struct callchain_cursor callchain_cursor; | ||
| 22 | |||
| 21 | bool ip_callchain__valid(struct ip_callchain *chain, | 23 | bool ip_callchain__valid(struct ip_callchain *chain, |
| 22 | const union perf_event *event) | 24 | const union perf_event *event) |
| 23 | { | 25 | { |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 7f9c0f1ae3a9..3bdb407f9cd9 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
| @@ -76,6 +76,8 @@ struct callchain_cursor { | |||
| 76 | struct callchain_cursor_node *curr; | 76 | struct callchain_cursor_node *curr; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | extern __thread struct callchain_cursor callchain_cursor; | ||
| 80 | |||
| 79 | static inline void callchain_init(struct callchain_root *root) | 81 | static inline void callchain_init(struct callchain_root *root) |
| 80 | { | 82 | { |
| 81 | INIT_LIST_HEAD(&root->node.siblings); | 83 | INIT_LIST_HEAD(&root->node.siblings); |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4ac5f5ae4ce9..7400fb3fc50c 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -159,6 +159,17 @@ out_delete_partial_list: | |||
| 159 | return -1; | 159 | return -1; |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, | ||
| 163 | struct perf_event_attr *attrs, size_t nr_attrs) | ||
| 164 | { | ||
| 165 | size_t i; | ||
| 166 | |||
| 167 | for (i = 0; i < nr_attrs; i++) | ||
| 168 | event_attr_init(attrs + i); | ||
| 169 | |||
| 170 | return perf_evlist__add_attrs(evlist, attrs, nr_attrs); | ||
| 171 | } | ||
| 172 | |||
| 162 | static int trace_event__id(const char *evname) | 173 | static int trace_event__id(const char *evname) |
| 163 | { | 174 | { |
| 164 | char *filename, *colon; | 175 | char *filename, *colon; |
| @@ -263,7 +274,8 @@ void perf_evlist__disable(struct perf_evlist *evlist) | |||
| 263 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { | 274 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { |
| 264 | list_for_each_entry(pos, &evlist->entries, node) { | 275 | list_for_each_entry(pos, &evlist->entries, node) { |
| 265 | for (thread = 0; thread < evlist->threads->nr; thread++) | 276 | for (thread = 0; thread < evlist->threads->nr; thread++) |
| 266 | ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_DISABLE); | 277 | ioctl(FD(pos, cpu, thread), |
| 278 | PERF_EVENT_IOC_DISABLE, 0); | ||
| 267 | } | 279 | } |
| 268 | } | 280 | } |
| 269 | } | 281 | } |
| @@ -276,7 +288,8 @@ void perf_evlist__enable(struct perf_evlist *evlist) | |||
| 276 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { | 288 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { |
| 277 | list_for_each_entry(pos, &evlist->entries, node) { | 289 | list_for_each_entry(pos, &evlist->entries, node) { |
| 278 | for (thread = 0; thread < evlist->threads->nr; thread++) | 290 | for (thread = 0; thread < evlist->threads->nr; thread++) |
| 279 | ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_ENABLE); | 291 | ioctl(FD(pos, cpu, thread), |
| 292 | PERF_EVENT_IOC_ENABLE, 0); | ||
| 280 | } | 293 | } |
| 281 | } | 294 | } |
| 282 | } | 295 | } |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 58abb63ac13a..989bee9624c2 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -54,6 +54,8 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); | |||
| 54 | int perf_evlist__add_default(struct perf_evlist *evlist); | 54 | int perf_evlist__add_default(struct perf_evlist *evlist); |
| 55 | int perf_evlist__add_attrs(struct perf_evlist *evlist, | 55 | int perf_evlist__add_attrs(struct perf_evlist *evlist, |
| 56 | struct perf_event_attr *attrs, size_t nr_attrs); | 56 | struct perf_event_attr *attrs, size_t nr_attrs); |
| 57 | int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, | ||
| 58 | struct perf_event_attr *attrs, size_t nr_attrs); | ||
| 57 | int perf_evlist__add_tracepoints(struct perf_evlist *evlist, | 59 | int perf_evlist__add_tracepoints(struct perf_evlist *evlist, |
| 58 | const char *tracepoints[], size_t nr_tracepoints); | 60 | const char *tracepoints[], size_t nr_tracepoints); |
| 59 | int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, | 61 | int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, |
| @@ -62,6 +64,8 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, | |||
| 62 | 64 | ||
| 63 | #define perf_evlist__add_attrs_array(evlist, array) \ | 65 | #define perf_evlist__add_attrs_array(evlist, array) \ |
| 64 | perf_evlist__add_attrs(evlist, array, ARRAY_SIZE(array)) | 66 | perf_evlist__add_attrs(evlist, array, ARRAY_SIZE(array)) |
| 67 | #define perf_evlist__add_default_attrs(evlist, array) \ | ||
| 68 | __perf_evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array)) | ||
| 65 | 69 | ||
| 66 | #define perf_evlist__add_tracepoints_array(evlist, array) \ | 70 | #define perf_evlist__add_tracepoints_array(evlist, array) \ |
| 67 | perf_evlist__add_tracepoints(evlist, array, ARRAY_SIZE(array)) | 71 | perf_evlist__add_tracepoints(evlist, array, ARRAY_SIZE(array)) |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 91d19138f3ec..9f6cebd798ee 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -494,16 +494,24 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel, | |||
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | static int perf_event__parse_id_sample(const union perf_event *event, u64 type, | 496 | static int perf_event__parse_id_sample(const union perf_event *event, u64 type, |
| 497 | struct perf_sample *sample) | 497 | struct perf_sample *sample, |
| 498 | bool swapped) | ||
| 498 | { | 499 | { |
| 499 | const u64 *array = event->sample.array; | 500 | const u64 *array = event->sample.array; |
| 501 | union u64_swap u; | ||
| 500 | 502 | ||
| 501 | array += ((event->header.size - | 503 | array += ((event->header.size - |
| 502 | sizeof(event->header)) / sizeof(u64)) - 1; | 504 | sizeof(event->header)) / sizeof(u64)) - 1; |
| 503 | 505 | ||
| 504 | if (type & PERF_SAMPLE_CPU) { | 506 | if (type & PERF_SAMPLE_CPU) { |
| 505 | u32 *p = (u32 *)array; | 507 | u.val64 = *array; |
| 506 | sample->cpu = *p; | 508 | if (swapped) { |
| 509 | /* undo swap of u64, then swap on individual u32s */ | ||
| 510 | u.val64 = bswap_64(u.val64); | ||
| 511 | u.val32[0] = bswap_32(u.val32[0]); | ||
| 512 | } | ||
| 513 | |||
| 514 | sample->cpu = u.val32[0]; | ||
| 507 | array--; | 515 | array--; |
| 508 | } | 516 | } |
| 509 | 517 | ||
| @@ -523,9 +531,16 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type, | |||
| 523 | } | 531 | } |
| 524 | 532 | ||
| 525 | if (type & PERF_SAMPLE_TID) { | 533 | if (type & PERF_SAMPLE_TID) { |
| 526 | u32 *p = (u32 *)array; | 534 | u.val64 = *array; |
| 527 | sample->pid = p[0]; | 535 | if (swapped) { |
| 528 | sample->tid = p[1]; | 536 | /* undo swap of u64, then swap on individual u32s */ |
| 537 | u.val64 = bswap_64(u.val64); | ||
| 538 | u.val32[0] = bswap_32(u.val32[0]); | ||
| 539 | u.val32[1] = bswap_32(u.val32[1]); | ||
| 540 | } | ||
| 541 | |||
| 542 | sample->pid = u.val32[0]; | ||
| 543 | sample->tid = u.val32[1]; | ||
| 529 | } | 544 | } |
| 530 | 545 | ||
| 531 | return 0; | 546 | return 0; |
| @@ -562,7 +577,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
| 562 | if (event->header.type != PERF_RECORD_SAMPLE) { | 577 | if (event->header.type != PERF_RECORD_SAMPLE) { |
| 563 | if (!sample_id_all) | 578 | if (!sample_id_all) |
| 564 | return 0; | 579 | return 0; |
| 565 | return perf_event__parse_id_sample(event, type, data); | 580 | return perf_event__parse_id_sample(event, type, data, swapped); |
| 566 | } | 581 | } |
| 567 | 582 | ||
| 568 | array = event->sample.array; | 583 | array = event->sample.array; |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 1293b5ebea4d..514e2a4b367d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -378,7 +378,7 @@ void hist_entry__free(struct hist_entry *he) | |||
| 378 | * collapse the histogram | 378 | * collapse the histogram |
| 379 | */ | 379 | */ |
| 380 | 380 | ||
| 381 | static bool hists__collapse_insert_entry(struct hists *hists, | 381 | static bool hists__collapse_insert_entry(struct hists *hists __used, |
| 382 | struct rb_root *root, | 382 | struct rb_root *root, |
| 383 | struct hist_entry *he) | 383 | struct hist_entry *he) |
| 384 | { | 384 | { |
| @@ -397,8 +397,9 @@ static bool hists__collapse_insert_entry(struct hists *hists, | |||
| 397 | iter->period += he->period; | 397 | iter->period += he->period; |
| 398 | iter->nr_events += he->nr_events; | 398 | iter->nr_events += he->nr_events; |
| 399 | if (symbol_conf.use_callchain) { | 399 | if (symbol_conf.use_callchain) { |
| 400 | callchain_cursor_reset(&hists->callchain_cursor); | 400 | callchain_cursor_reset(&callchain_cursor); |
| 401 | callchain_merge(&hists->callchain_cursor, iter->callchain, | 401 | callchain_merge(&callchain_cursor, |
| 402 | iter->callchain, | ||
| 402 | he->callchain); | 403 | he->callchain); |
| 403 | } | 404 | } |
| 404 | hist_entry__free(he); | 405 | hist_entry__free(he); |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index cfc64e293f90..34bb556d6219 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -67,8 +67,6 @@ struct hists { | |||
| 67 | struct events_stats stats; | 67 | struct events_stats stats; |
| 68 | u64 event_stream; | 68 | u64 event_stream; |
| 69 | u16 col_len[HISTC_NR_COLS]; | 69 | u16 col_len[HISTC_NR_COLS]; |
| 70 | /* Best would be to reuse the session callchain cursor */ | ||
| 71 | struct callchain_cursor callchain_cursor; | ||
| 72 | }; | 70 | }; |
| 73 | 71 | ||
| 74 | struct hist_entry *__hists__add_entry(struct hists *self, | 72 | struct hist_entry *__hists__add_entry(struct hists *self, |
diff --git a/tools/perf/util/pager.c b/tools/perf/util/pager.c index 1915de20dcac..3322b8446e89 100644 --- a/tools/perf/util/pager.c +++ b/tools/perf/util/pager.c | |||
| @@ -57,6 +57,10 @@ void setup_pager(void) | |||
| 57 | } | 57 | } |
| 58 | if (!pager) | 58 | if (!pager) |
| 59 | pager = getenv("PAGER"); | 59 | pager = getenv("PAGER"); |
| 60 | if (!pager) { | ||
| 61 | if (!access("/usr/bin/pager", X_OK)) | ||
| 62 | pager = "/usr/bin/pager"; | ||
| 63 | } | ||
| 60 | if (!pager) | 64 | if (!pager) |
| 61 | pager = "less"; | 65 | pager = "less"; |
| 62 | else if (!*pager || !strcmp(pager, "cat")) | 66 | else if (!*pager || !strcmp(pager, "cat")) |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 59dccc98b554..0dda25d82d06 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
| @@ -2164,16 +2164,12 @@ int del_perf_probe_events(struct strlist *dellist) | |||
| 2164 | 2164 | ||
| 2165 | error: | 2165 | error: |
| 2166 | if (kfd >= 0) { | 2166 | if (kfd >= 0) { |
| 2167 | if (namelist) | 2167 | strlist__delete(namelist); |
| 2168 | strlist__delete(namelist); | ||
| 2169 | |||
| 2170 | close(kfd); | 2168 | close(kfd); |
| 2171 | } | 2169 | } |
| 2172 | 2170 | ||
| 2173 | if (ufd >= 0) { | 2171 | if (ufd >= 0) { |
| 2174 | if (unamelist) | 2172 | strlist__delete(unamelist); |
| 2175 | strlist__delete(unamelist); | ||
| 2176 | |||
| 2177 | close(ufd); | 2173 | close(ufd); |
| 2178 | } | 2174 | } |
| 2179 | 2175 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 93d355d27109..2600916efa83 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -288,7 +288,8 @@ struct branch_info *machine__resolve_bstack(struct machine *self, | |||
| 288 | return bi; | 288 | return bi; |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, | 291 | int machine__resolve_callchain(struct machine *self, |
| 292 | struct perf_evsel *evsel __used, | ||
| 292 | struct thread *thread, | 293 | struct thread *thread, |
| 293 | struct ip_callchain *chain, | 294 | struct ip_callchain *chain, |
| 294 | struct symbol **parent) | 295 | struct symbol **parent) |
| @@ -297,7 +298,12 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, | |||
| 297 | unsigned int i; | 298 | unsigned int i; |
| 298 | int err; | 299 | int err; |
| 299 | 300 | ||
| 300 | callchain_cursor_reset(&evsel->hists.callchain_cursor); | 301 | callchain_cursor_reset(&callchain_cursor); |
| 302 | |||
| 303 | if (chain->nr > PERF_MAX_STACK_DEPTH) { | ||
| 304 | pr_warning("corrupted callchain. skipping...\n"); | ||
| 305 | return 0; | ||
| 306 | } | ||
| 301 | 307 | ||
| 302 | for (i = 0; i < chain->nr; i++) { | 308 | for (i = 0; i < chain->nr; i++) { |
| 303 | u64 ip; | 309 | u64 ip; |
| @@ -317,7 +323,14 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, | |||
| 317 | case PERF_CONTEXT_USER: | 323 | case PERF_CONTEXT_USER: |
| 318 | cpumode = PERF_RECORD_MISC_USER; break; | 324 | cpumode = PERF_RECORD_MISC_USER; break; |
| 319 | default: | 325 | default: |
| 320 | break; | 326 | pr_debug("invalid callchain context: " |
| 327 | "%"PRId64"\n", (s64) ip); | ||
| 328 | /* | ||
| 329 | * It seems the callchain is corrupted. | ||
| 330 | * Discard all. | ||
| 331 | */ | ||
| 332 | callchain_cursor_reset(&callchain_cursor); | ||
| 333 | return 0; | ||
| 321 | } | 334 | } |
| 322 | continue; | 335 | continue; |
| 323 | } | 336 | } |
| @@ -333,7 +346,7 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, | |||
| 333 | break; | 346 | break; |
| 334 | } | 347 | } |
| 335 | 348 | ||
| 336 | err = callchain_cursor_append(&evsel->hists.callchain_cursor, | 349 | err = callchain_cursor_append(&callchain_cursor, |
| 337 | ip, al.map, al.sym); | 350 | ip, al.map, al.sym); |
| 338 | if (err) | 351 | if (err) |
| 339 | return err; | 352 | return err; |
| @@ -441,37 +454,65 @@ void mem_bswap_64(void *src, int byte_size) | |||
| 441 | } | 454 | } |
| 442 | } | 455 | } |
| 443 | 456 | ||
| 444 | static void perf_event__all64_swap(union perf_event *event) | 457 | static void swap_sample_id_all(union perf_event *event, void *data) |
| 458 | { | ||
| 459 | void *end = (void *) event + event->header.size; | ||
| 460 | int size = end - data; | ||
| 461 | |||
| 462 | BUG_ON(size % sizeof(u64)); | ||
| 463 | mem_bswap_64(data, size); | ||
| 464 | } | ||
| 465 | |||
| 466 | static void perf_event__all64_swap(union perf_event *event, | ||
| 467 | bool sample_id_all __used) | ||
| 445 | { | 468 | { |
| 446 | struct perf_event_header *hdr = &event->header; | 469 | struct perf_event_header *hdr = &event->header; |
| 447 | mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr)); | 470 | mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr)); |
| 448 | } | 471 | } |
| 449 | 472 | ||
| 450 | static void perf_event__comm_swap(union perf_event *event) | 473 | static void perf_event__comm_swap(union perf_event *event, bool sample_id_all) |
| 451 | { | 474 | { |
| 452 | event->comm.pid = bswap_32(event->comm.pid); | 475 | event->comm.pid = bswap_32(event->comm.pid); |
| 453 | event->comm.tid = bswap_32(event->comm.tid); | 476 | event->comm.tid = bswap_32(event->comm.tid); |
| 477 | |||
| 478 | if (sample_id_all) { | ||
| 479 | void *data = &event->comm.comm; | ||
| 480 | |||
| 481 | data += ALIGN(strlen(data) + 1, sizeof(u64)); | ||
| 482 | swap_sample_id_all(event, data); | ||
| 483 | } | ||
| 454 | } | 484 | } |
| 455 | 485 | ||
| 456 | static void perf_event__mmap_swap(union perf_event *event) | 486 | static void perf_event__mmap_swap(union perf_event *event, |
| 487 | bool sample_id_all) | ||
| 457 | { | 488 | { |
| 458 | event->mmap.pid = bswap_32(event->mmap.pid); | 489 | event->mmap.pid = bswap_32(event->mmap.pid); |
| 459 | event->mmap.tid = bswap_32(event->mmap.tid); | 490 | event->mmap.tid = bswap_32(event->mmap.tid); |
| 460 | event->mmap.start = bswap_64(event->mmap.start); | 491 | event->mmap.start = bswap_64(event->mmap.start); |
| 461 | event->mmap.len = bswap_64(event->mmap.len); | 492 | event->mmap.len = bswap_64(event->mmap.len); |
| 462 | event->mmap.pgoff = bswap_64(event->mmap.pgoff); | 493 | event->mmap.pgoff = bswap_64(event->mmap.pgoff); |
| 494 | |||
| 495 | if (sample_id_all) { | ||
| 496 | void *data = &event->mmap.filename; | ||
| 497 | |||
| 498 | data += ALIGN(strlen(data) + 1, sizeof(u64)); | ||
| 499 | swap_sample_id_all(event, data); | ||
| 500 | } | ||
| 463 | } | 501 | } |
| 464 | 502 | ||
| 465 | static void perf_event__task_swap(union perf_event *event) | 503 | static void perf_event__task_swap(union perf_event *event, bool sample_id_all) |
| 466 | { | 504 | { |
| 467 | event->fork.pid = bswap_32(event->fork.pid); | 505 | event->fork.pid = bswap_32(event->fork.pid); |
| 468 | event->fork.tid = bswap_32(event->fork.tid); | 506 | event->fork.tid = bswap_32(event->fork.tid); |
| 469 | event->fork.ppid = bswap_32(event->fork.ppid); | 507 | event->fork.ppid = bswap_32(event->fork.ppid); |
| 470 | event->fork.ptid = bswap_32(event->fork.ptid); | 508 | event->fork.ptid = bswap_32(event->fork.ptid); |
| 471 | event->fork.time = bswap_64(event->fork.time); | 509 | event->fork.time = bswap_64(event->fork.time); |
| 510 | |||
| 511 | if (sample_id_all) | ||
| 512 | swap_sample_id_all(event, &event->fork + 1); | ||
| 472 | } | 513 | } |
| 473 | 514 | ||
| 474 | static void perf_event__read_swap(union perf_event *event) | 515 | static void perf_event__read_swap(union perf_event *event, bool sample_id_all) |
| 475 | { | 516 | { |
| 476 | event->read.pid = bswap_32(event->read.pid); | 517 | event->read.pid = bswap_32(event->read.pid); |
| 477 | event->read.tid = bswap_32(event->read.tid); | 518 | event->read.tid = bswap_32(event->read.tid); |
| @@ -479,6 +520,9 @@ static void perf_event__read_swap(union perf_event *event) | |||
| 479 | event->read.time_enabled = bswap_64(event->read.time_enabled); | 520 | event->read.time_enabled = bswap_64(event->read.time_enabled); |
| 480 | event->read.time_running = bswap_64(event->read.time_running); | 521 | event->read.time_running = bswap_64(event->read.time_running); |
| 481 | event->read.id = bswap_64(event->read.id); | 522 | event->read.id = bswap_64(event->read.id); |
| 523 | |||
| 524 | if (sample_id_all) | ||
| 525 | swap_sample_id_all(event, &event->read + 1); | ||
| 482 | } | 526 | } |
| 483 | 527 | ||
| 484 | static u8 revbyte(u8 b) | 528 | static u8 revbyte(u8 b) |
| @@ -530,7 +574,8 @@ void perf_event__attr_swap(struct perf_event_attr *attr) | |||
| 530 | swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64)); | 574 | swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64)); |
| 531 | } | 575 | } |
| 532 | 576 | ||
| 533 | static void perf_event__hdr_attr_swap(union perf_event *event) | 577 | static void perf_event__hdr_attr_swap(union perf_event *event, |
| 578 | bool sample_id_all __used) | ||
| 534 | { | 579 | { |
| 535 | size_t size; | 580 | size_t size; |
| 536 | 581 | ||
| @@ -541,18 +586,21 @@ static void perf_event__hdr_attr_swap(union perf_event *event) | |||
| 541 | mem_bswap_64(event->attr.id, size); | 586 | mem_bswap_64(event->attr.id, size); |
| 542 | } | 587 | } |
| 543 | 588 | ||
| 544 | static void perf_event__event_type_swap(union perf_event *event) | 589 | static void perf_event__event_type_swap(union perf_event *event, |
| 590 | bool sample_id_all __used) | ||
| 545 | { | 591 | { |
| 546 | event->event_type.event_type.event_id = | 592 | event->event_type.event_type.event_id = |
| 547 | bswap_64(event->event_type.event_type.event_id); | 593 | bswap_64(event->event_type.event_type.event_id); |
| 548 | } | 594 | } |
| 549 | 595 | ||
| 550 | static void perf_event__tracing_data_swap(union perf_event *event) | 596 | static void perf_event__tracing_data_swap(union perf_event *event, |
| 597 | bool sample_id_all __used) | ||
| 551 | { | 598 | { |
| 552 | event->tracing_data.size = bswap_32(event->tracing_data.size); | 599 | event->tracing_data.size = bswap_32(event->tracing_data.size); |
| 553 | } | 600 | } |
| 554 | 601 | ||
| 555 | typedef void (*perf_event__swap_op)(union perf_event *event); | 602 | typedef void (*perf_event__swap_op)(union perf_event *event, |
| 603 | bool sample_id_all); | ||
| 556 | 604 | ||
| 557 | static perf_event__swap_op perf_event__swap_ops[] = { | 605 | static perf_event__swap_op perf_event__swap_ops[] = { |
| 558 | [PERF_RECORD_MMAP] = perf_event__mmap_swap, | 606 | [PERF_RECORD_MMAP] = perf_event__mmap_swap, |
| @@ -986,6 +1034,15 @@ static int perf_session__process_user_event(struct perf_session *session, union | |||
| 986 | } | 1034 | } |
| 987 | } | 1035 | } |
| 988 | 1036 | ||
| 1037 | static void event_swap(union perf_event *event, bool sample_id_all) | ||
| 1038 | { | ||
| 1039 | perf_event__swap_op swap; | ||
| 1040 | |||
| 1041 | swap = perf_event__swap_ops[event->header.type]; | ||
| 1042 | if (swap) | ||
| 1043 | swap(event, sample_id_all); | ||
| 1044 | } | ||
| 1045 | |||
| 989 | static int perf_session__process_event(struct perf_session *session, | 1046 | static int perf_session__process_event(struct perf_session *session, |
| 990 | union perf_event *event, | 1047 | union perf_event *event, |
| 991 | struct perf_tool *tool, | 1048 | struct perf_tool *tool, |
| @@ -994,9 +1051,8 @@ static int perf_session__process_event(struct perf_session *session, | |||
| 994 | struct perf_sample sample; | 1051 | struct perf_sample sample; |
| 995 | int ret; | 1052 | int ret; |
| 996 | 1053 | ||
| 997 | if (session->header.needs_swap && | 1054 | if (session->header.needs_swap) |
| 998 | perf_event__swap_ops[event->header.type]) | 1055 | event_swap(event, session->sample_id_all); |
| 999 | perf_event__swap_ops[event->header.type](event); | ||
| 1000 | 1056 | ||
| 1001 | if (event->header.type >= PERF_RECORD_HEADER_MAX) | 1057 | if (event->header.type >= PERF_RECORD_HEADER_MAX) |
| 1002 | return -EINVAL; | 1058 | return -EINVAL; |
| @@ -1428,7 +1484,6 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | |||
| 1428 | int print_sym, int print_dso, int print_symoffset) | 1484 | int print_sym, int print_dso, int print_symoffset) |
| 1429 | { | 1485 | { |
| 1430 | struct addr_location al; | 1486 | struct addr_location al; |
| 1431 | struct callchain_cursor *cursor = &evsel->hists.callchain_cursor; | ||
| 1432 | struct callchain_cursor_node *node; | 1487 | struct callchain_cursor_node *node; |
| 1433 | 1488 | ||
| 1434 | if (perf_event__preprocess_sample(event, machine, &al, sample, | 1489 | if (perf_event__preprocess_sample(event, machine, &al, sample, |
| @@ -1446,10 +1501,10 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | |||
| 1446 | error("Failed to resolve callchain. Skipping\n"); | 1501 | error("Failed to resolve callchain. Skipping\n"); |
| 1447 | return; | 1502 | return; |
| 1448 | } | 1503 | } |
| 1449 | callchain_cursor_commit(cursor); | 1504 | callchain_cursor_commit(&callchain_cursor); |
| 1450 | 1505 | ||
| 1451 | while (1) { | 1506 | while (1) { |
| 1452 | node = callchain_cursor_current(cursor); | 1507 | node = callchain_cursor_current(&callchain_cursor); |
| 1453 | if (!node) | 1508 | if (!node) |
| 1454 | break; | 1509 | break; |
| 1455 | 1510 | ||
| @@ -1460,12 +1515,12 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | |||
| 1460 | } | 1515 | } |
| 1461 | if (print_dso) { | 1516 | if (print_dso) { |
| 1462 | printf(" ("); | 1517 | printf(" ("); |
| 1463 | map__fprintf_dsoname(al.map, stdout); | 1518 | map__fprintf_dsoname(node->map, stdout); |
| 1464 | printf(")"); | 1519 | printf(")"); |
| 1465 | } | 1520 | } |
| 1466 | printf("\n"); | 1521 | printf("\n"); |
| 1467 | 1522 | ||
| 1468 | callchain_cursor_advance(cursor); | 1523 | callchain_cursor_advance(&callchain_cursor); |
| 1469 | } | 1524 | } |
| 1470 | 1525 | ||
| 1471 | } else { | 1526 | } else { |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e2ba8858f3e1..3e2e5ea0f03f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -323,6 +323,7 @@ struct dso *dso__new(const char *name) | |||
| 323 | dso->sorted_by_name = 0; | 323 | dso->sorted_by_name = 0; |
| 324 | dso->has_build_id = 0; | 324 | dso->has_build_id = 0; |
| 325 | dso->kernel = DSO_TYPE_USER; | 325 | dso->kernel = DSO_TYPE_USER; |
| 326 | dso->needs_swap = DSO_SWAP__UNSET; | ||
| 326 | INIT_LIST_HEAD(&dso->node); | 327 | INIT_LIST_HEAD(&dso->node); |
| 327 | } | 328 | } |
| 328 | 329 | ||
| @@ -1156,6 +1157,33 @@ static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr) | |||
| 1156 | return -1; | 1157 | return -1; |
| 1157 | } | 1158 | } |
| 1158 | 1159 | ||
| 1160 | static int dso__swap_init(struct dso *dso, unsigned char eidata) | ||
| 1161 | { | ||
| 1162 | static unsigned int const endian = 1; | ||
| 1163 | |||
| 1164 | dso->needs_swap = DSO_SWAP__NO; | ||
| 1165 | |||
| 1166 | switch (eidata) { | ||
| 1167 | case ELFDATA2LSB: | ||
| 1168 | /* We are big endian, DSO is little endian. */ | ||
| 1169 | if (*(unsigned char const *)&endian != 1) | ||
| 1170 | dso->needs_swap = DSO_SWAP__YES; | ||
| 1171 | break; | ||
| 1172 | |||
| 1173 | case ELFDATA2MSB: | ||
| 1174 | /* We are little endian, DSO is big endian. */ | ||
| 1175 | if (*(unsigned char const *)&endian != 0) | ||
| 1176 | dso->needs_swap = DSO_SWAP__YES; | ||
| 1177 | break; | ||
| 1178 | |||
| 1179 | default: | ||
| 1180 | pr_err("unrecognized DSO data encoding %d\n", eidata); | ||
| 1181 | return -EINVAL; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | return 0; | ||
| 1185 | } | ||
| 1186 | |||
| 1159 | static int dso__load_sym(struct dso *dso, struct map *map, const char *name, | 1187 | static int dso__load_sym(struct dso *dso, struct map *map, const char *name, |
| 1160 | int fd, symbol_filter_t filter, int kmodule, | 1188 | int fd, symbol_filter_t filter, int kmodule, |
| 1161 | int want_symtab) | 1189 | int want_symtab) |
| @@ -1187,6 +1215,9 @@ static int dso__load_sym(struct dso *dso, struct map *map, const char *name, | |||
| 1187 | goto out_elf_end; | 1215 | goto out_elf_end; |
| 1188 | } | 1216 | } |
| 1189 | 1217 | ||
| 1218 | if (dso__swap_init(dso, ehdr.e_ident[EI_DATA])) | ||
| 1219 | goto out_elf_end; | ||
| 1220 | |||
| 1190 | /* Always reject images with a mismatched build-id: */ | 1221 | /* Always reject images with a mismatched build-id: */ |
| 1191 | if (dso->has_build_id) { | 1222 | if (dso->has_build_id) { |
| 1192 | u8 build_id[BUILD_ID_SIZE]; | 1223 | u8 build_id[BUILD_ID_SIZE]; |
| @@ -1272,7 +1303,7 @@ static int dso__load_sym(struct dso *dso, struct map *map, const char *name, | |||
| 1272 | if (opdsec && sym.st_shndx == opdidx) { | 1303 | if (opdsec && sym.st_shndx == opdidx) { |
| 1273 | u32 offset = sym.st_value - opdshdr.sh_addr; | 1304 | u32 offset = sym.st_value - opdshdr.sh_addr; |
| 1274 | u64 *opd = opddata->d_buf + offset; | 1305 | u64 *opd = opddata->d_buf + offset; |
| 1275 | sym.st_value = *opd; | 1306 | sym.st_value = DSO__SWAP(dso, u64, *opd); |
| 1276 | sym.st_shndx = elf_addr_to_index(elf, sym.st_value); | 1307 | sym.st_shndx = elf_addr_to_index(elf, sym.st_value); |
| 1277 | } | 1308 | } |
| 1278 | 1309 | ||
| @@ -2786,8 +2817,11 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type, | |||
| 2786 | 2817 | ||
| 2787 | struct map *dso__new_map(const char *name) | 2818 | struct map *dso__new_map(const char *name) |
| 2788 | { | 2819 | { |
| 2820 | struct map *map = NULL; | ||
| 2789 | struct dso *dso = dso__new(name); | 2821 | struct dso *dso = dso__new(name); |
| 2790 | struct map *map = map__new2(0, dso, MAP__FUNCTION); | 2822 | |
| 2823 | if (dso) | ||
| 2824 | map = map__new2(0, dso, MAP__FUNCTION); | ||
| 2791 | 2825 | ||
| 2792 | return map; | 2826 | return map; |
| 2793 | } | 2827 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 5649d63798cb..af0752b1aca1 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <linux/list.h> | 9 | #include <linux/list.h> |
| 10 | #include <linux/rbtree.h> | 10 | #include <linux/rbtree.h> |
| 11 | #include <stdio.h> | 11 | #include <stdio.h> |
| 12 | #include <byteswap.h> | ||
| 12 | 13 | ||
| 13 | #ifdef HAVE_CPLUS_DEMANGLE | 14 | #ifdef HAVE_CPLUS_DEMANGLE |
| 14 | extern char *cplus_demangle(const char *, int); | 15 | extern char *cplus_demangle(const char *, int); |
| @@ -160,11 +161,18 @@ enum dso_kernel_type { | |||
| 160 | DSO_TYPE_GUEST_KERNEL | 161 | DSO_TYPE_GUEST_KERNEL |
| 161 | }; | 162 | }; |
| 162 | 163 | ||
| 164 | enum dso_swap_type { | ||
| 165 | DSO_SWAP__UNSET, | ||
| 166 | DSO_SWAP__NO, | ||
| 167 | DSO_SWAP__YES, | ||
| 168 | }; | ||
| 169 | |||
| 163 | struct dso { | 170 | struct dso { |
| 164 | struct list_head node; | 171 | struct list_head node; |
| 165 | struct rb_root symbols[MAP__NR_TYPES]; | 172 | struct rb_root symbols[MAP__NR_TYPES]; |
| 166 | struct rb_root symbol_names[MAP__NR_TYPES]; | 173 | struct rb_root symbol_names[MAP__NR_TYPES]; |
| 167 | enum dso_kernel_type kernel; | 174 | enum dso_kernel_type kernel; |
| 175 | enum dso_swap_type needs_swap; | ||
| 168 | u8 adjust_symbols:1; | 176 | u8 adjust_symbols:1; |
| 169 | u8 has_build_id:1; | 177 | u8 has_build_id:1; |
| 170 | u8 hit:1; | 178 | u8 hit:1; |
| @@ -182,6 +190,28 @@ struct dso { | |||
| 182 | char name[0]; | 190 | char name[0]; |
| 183 | }; | 191 | }; |
| 184 | 192 | ||
| 193 | #define DSO__SWAP(dso, type, val) \ | ||
| 194 | ({ \ | ||
| 195 | type ____r = val; \ | ||
| 196 | BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \ | ||
| 197 | if (dso->needs_swap == DSO_SWAP__YES) { \ | ||
| 198 | switch (sizeof(____r)) { \ | ||
| 199 | case 2: \ | ||
| 200 | ____r = bswap_16(val); \ | ||
| 201 | break; \ | ||
| 202 | case 4: \ | ||
| 203 | ____r = bswap_32(val); \ | ||
| 204 | break; \ | ||
| 205 | case 8: \ | ||
| 206 | ____r = bswap_64(val); \ | ||
| 207 | break; \ | ||
| 208 | default: \ | ||
| 209 | BUG_ON(1); \ | ||
| 210 | } \ | ||
| 211 | } \ | ||
| 212 | ____r; \ | ||
| 213 | }) | ||
| 214 | |||
| 185 | struct dso *dso__new(const char *name); | 215 | struct dso *dso__new(const char *name); |
| 186 | void dso__delete(struct dso *dso); | 216 | void dso__delete(struct dso *dso); |
| 187 | 217 | ||
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index ab2f682fd44c..16de7ad4850f 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
| @@ -73,8 +73,8 @@ int backwards_count; | |||
| 73 | char *progname; | 73 | char *progname; |
| 74 | 74 | ||
| 75 | int num_cpus; | 75 | int num_cpus; |
| 76 | cpu_set_t *cpu_mask; | 76 | cpu_set_t *cpu_present_set, *cpu_mask; |
| 77 | size_t cpu_mask_size; | 77 | size_t cpu_present_setsize, cpu_mask_size; |
| 78 | 78 | ||
| 79 | struct counters { | 79 | struct counters { |
| 80 | unsigned long long tsc; /* per thread */ | 80 | unsigned long long tsc; /* per thread */ |
| @@ -103,6 +103,12 @@ struct timeval tv_even; | |||
| 103 | struct timeval tv_odd; | 103 | struct timeval tv_odd; |
| 104 | struct timeval tv_delta; | 104 | struct timeval tv_delta; |
| 105 | 105 | ||
| 106 | int mark_cpu_present(int pkg, int core, int cpu) | ||
| 107 | { | ||
| 108 | CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set); | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 106 | /* | 112 | /* |
| 107 | * cpu_mask_init(ncpus) | 113 | * cpu_mask_init(ncpus) |
| 108 | * | 114 | * |
| @@ -118,6 +124,18 @@ void cpu_mask_init(int ncpus) | |||
| 118 | } | 124 | } |
| 119 | cpu_mask_size = CPU_ALLOC_SIZE(ncpus); | 125 | cpu_mask_size = CPU_ALLOC_SIZE(ncpus); |
| 120 | CPU_ZERO_S(cpu_mask_size, cpu_mask); | 126 | CPU_ZERO_S(cpu_mask_size, cpu_mask); |
| 127 | |||
| 128 | /* | ||
| 129 | * Allocate and initialize cpu_present_set | ||
| 130 | */ | ||
| 131 | cpu_present_set = CPU_ALLOC(ncpus); | ||
| 132 | if (cpu_present_set == NULL) { | ||
| 133 | perror("CPU_ALLOC"); | ||
| 134 | exit(3); | ||
| 135 | } | ||
| 136 | cpu_present_setsize = CPU_ALLOC_SIZE(ncpus); | ||
| 137 | CPU_ZERO_S(cpu_present_setsize, cpu_present_set); | ||
| 138 | for_all_cpus(mark_cpu_present); | ||
| 121 | } | 139 | } |
| 122 | 140 | ||
| 123 | void cpu_mask_uninit() | 141 | void cpu_mask_uninit() |
| @@ -125,6 +143,9 @@ void cpu_mask_uninit() | |||
| 125 | CPU_FREE(cpu_mask); | 143 | CPU_FREE(cpu_mask); |
| 126 | cpu_mask = NULL; | 144 | cpu_mask = NULL; |
| 127 | cpu_mask_size = 0; | 145 | cpu_mask_size = 0; |
| 146 | CPU_FREE(cpu_present_set); | ||
| 147 | cpu_present_set = NULL; | ||
| 148 | cpu_present_setsize = 0; | ||
| 128 | } | 149 | } |
| 129 | 150 | ||
| 130 | int cpu_migrate(int cpu) | 151 | int cpu_migrate(int cpu) |
| @@ -912,6 +933,8 @@ int is_snb(unsigned int family, unsigned int model) | |||
| 912 | switch (model) { | 933 | switch (model) { |
| 913 | case 0x2A: | 934 | case 0x2A: |
| 914 | case 0x2D: | 935 | case 0x2D: |
| 936 | case 0x3A: /* IVB */ | ||
| 937 | case 0x3D: /* IVB Xeon */ | ||
| 915 | return 1; | 938 | return 1; |
| 916 | } | 939 | } |
| 917 | return 0; | 940 | return 0; |
| @@ -1047,6 +1070,9 @@ int fork_it(char **argv) | |||
| 1047 | int retval; | 1070 | int retval; |
| 1048 | pid_t child_pid; | 1071 | pid_t child_pid; |
| 1049 | get_counters(cnt_even); | 1072 | get_counters(cnt_even); |
| 1073 | |||
| 1074 | /* clear affinity side-effect of get_counters() */ | ||
| 1075 | sched_setaffinity(0, cpu_present_setsize, cpu_present_set); | ||
| 1050 | gettimeofday(&tv_even, (struct timezone *)NULL); | 1076 | gettimeofday(&tv_even, (struct timezone *)NULL); |
| 1051 | 1077 | ||
| 1052 | child_pid = fork(); | 1078 | child_pid = fork(); |
