Annotation of /trunk/kernel-alx/patches-4.4/0125-4.4.26-all-fixes.patch
Parent Directory | Revision Log
Revision 2861 -
(hide annotations)
(download)
Mon Mar 27 13:49:06 2017 UTC (7 years, 6 months ago) by niro
File size: 5332 byte(s)
Mon Mar 27 13:49:06 2017 UTC (7 years, 6 months ago) by niro
File size: 5332 byte(s)
linux-4.4.26
1 | niro | 2861 | diff --git a/Makefile b/Makefile |
2 | index 578a82554923..a127b9ef9ebc 100644 | ||
3 | --- a/Makefile | ||
4 | +++ b/Makefile | ||
5 | @@ -1,6 +1,6 @@ | ||
6 | VERSION = 4 | ||
7 | PATCHLEVEL = 4 | ||
8 | -SUBLEVEL = 25 | ||
9 | +SUBLEVEL = 26 | ||
10 | EXTRAVERSION = | ||
11 | NAME = Blurry Fish Butt | ||
12 | |||
13 | diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile | ||
14 | index 0a291cdfaf77..efa6073ffa7e 100644 | ||
15 | --- a/arch/x86/boot/compressed/Makefile | ||
16 | +++ b/arch/x86/boot/compressed/Makefile | ||
17 | @@ -22,7 +22,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ | ||
18 | vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 | ||
19 | |||
20 | KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 | ||
21 | -KBUILD_CFLAGS += -fno-strict-aliasing -fPIC | ||
22 | +KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC) | ||
23 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING | ||
24 | cflags-$(CONFIG_X86_32) := -march=i386 | ||
25 | cflags-$(CONFIG_X86_64) := -mcmodel=small | ||
26 | @@ -35,6 +35,18 @@ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ | ||
27 | GCOV_PROFILE := n | ||
28 | |||
29 | LDFLAGS := -m elf_$(UTS_MACHINE) | ||
30 | +ifeq ($(CONFIG_RELOCATABLE),y) | ||
31 | +# If kernel is relocatable, build compressed kernel as PIE. | ||
32 | +ifeq ($(CONFIG_X86_32),y) | ||
33 | +LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker) | ||
34 | +else | ||
35 | +# To build 64-bit compressed kernel as PIE, we disable relocation | ||
36 | +# overflow check to avoid relocation overflow error with a new linker | ||
37 | +# command-line option, -z noreloc-overflow. | ||
38 | +LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \ | ||
39 | + && echo "-z noreloc-overflow -pie --no-dynamic-linker") | ||
40 | +endif | ||
41 | +endif | ||
42 | LDFLAGS_vmlinux := -T | ||
43 | |||
44 | hostprogs-y := mkpiggy | ||
45 | diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S | ||
46 | index 8ef964ddc18e..0256064da8da 100644 | ||
47 | --- a/arch/x86/boot/compressed/head_32.S | ||
48 | +++ b/arch/x86/boot/compressed/head_32.S | ||
49 | @@ -31,6 +31,34 @@ | ||
50 | #include <asm/asm-offsets.h> | ||
51 | #include <asm/bootparam.h> | ||
52 | |||
53 | +/* | ||
54 | + * The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X | ||
55 | + * relocation to get the symbol address in PIC. When the compressed x86 | ||
56 | + * kernel isn't built as PIC, the linker optimizes R_386_GOT32X | ||
57 | + * relocations to their fixed symbol addresses. However, when the | ||
58 | + * compressed x86 kernel is loaded at a different address, it leads | ||
59 | + * to the following load failure: | ||
60 | + * | ||
61 | + * Failed to allocate space for phdrs | ||
62 | + * | ||
63 | + * during the decompression stage. | ||
64 | + * | ||
65 | + * If the compressed x86 kernel is relocatable at run-time, it should be | ||
66 | + * compiled with -fPIE, instead of -fPIC, if possible and should be built as | ||
67 | + * Position Independent Executable (PIE) so that linker won't optimize | ||
68 | + * R_386_GOT32X relocation to its fixed symbol address. Older | ||
69 | + * linkers generate R_386_32 relocations against locally defined symbols, | ||
70 | + * _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less | ||
71 | + * optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle | ||
72 | + * R_386_32 relocations when relocating the kernel. To generate | ||
73 | + * R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as | ||
74 | + * hidden: | ||
75 | + */ | ||
76 | + .hidden _bss | ||
77 | + .hidden _ebss | ||
78 | + .hidden _got | ||
79 | + .hidden _egot | ||
80 | + | ||
81 | __HEAD | ||
82 | ENTRY(startup_32) | ||
83 | #ifdef CONFIG_EFI_STUB | ||
84 | diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S | ||
85 | index b0c0d16ef58d..86558a199139 100644 | ||
86 | --- a/arch/x86/boot/compressed/head_64.S | ||
87 | +++ b/arch/x86/boot/compressed/head_64.S | ||
88 | @@ -33,6 +33,14 @@ | ||
89 | #include <asm/asm-offsets.h> | ||
90 | #include <asm/bootparam.h> | ||
91 | |||
92 | +/* | ||
93 | + * Locally defined symbols should be marked hidden: | ||
94 | + */ | ||
95 | + .hidden _bss | ||
96 | + .hidden _ebss | ||
97 | + .hidden _got | ||
98 | + .hidden _egot | ||
99 | + | ||
100 | __HEAD | ||
101 | .code32 | ||
102 | ENTRY(startup_32) | ||
103 | diff --git a/include/linux/mm.h b/include/linux/mm.h | ||
104 | index cfebb742ee18..f0ffa01c90d9 100644 | ||
105 | --- a/include/linux/mm.h | ||
106 | +++ b/include/linux/mm.h | ||
107 | @@ -2112,6 +2112,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma, | ||
108 | #define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */ | ||
109 | #define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */ | ||
110 | #define FOLL_MLOCK 0x1000 /* lock present pages */ | ||
111 | +#define FOLL_COW 0x4000 /* internal GUP flag */ | ||
112 | |||
113 | typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, | ||
114 | void *data); | ||
115 | diff --git a/mm/gup.c b/mm/gup.c | ||
116 | index deafa2c91b36..4b0b7e7d1136 100644 | ||
117 | --- a/mm/gup.c | ||
118 | +++ b/mm/gup.c | ||
119 | @@ -58,6 +58,16 @@ static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address, | ||
120 | return -EEXIST; | ||
121 | } | ||
122 | |||
123 | +/* | ||
124 | + * FOLL_FORCE can write to even unwritable pte's, but only | ||
125 | + * after we've gone through a COW cycle and they are dirty. | ||
126 | + */ | ||
127 | +static inline bool can_follow_write_pte(pte_t pte, unsigned int flags) | ||
128 | +{ | ||
129 | + return pte_write(pte) || | ||
130 | + ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte)); | ||
131 | +} | ||
132 | + | ||
133 | static struct page *follow_page_pte(struct vm_area_struct *vma, | ||
134 | unsigned long address, pmd_t *pmd, unsigned int flags) | ||
135 | { | ||
136 | @@ -92,7 +102,7 @@ retry: | ||
137 | } | ||
138 | if ((flags & FOLL_NUMA) && pte_protnone(pte)) | ||
139 | goto no_page; | ||
140 | - if ((flags & FOLL_WRITE) && !pte_write(pte)) { | ||
141 | + if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) { | ||
142 | pte_unmap_unlock(ptep, ptl); | ||
143 | return NULL; | ||
144 | } | ||
145 | @@ -352,7 +362,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, | ||
146 | * reCOWed by userspace write). | ||
147 | */ | ||
148 | if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE)) | ||
149 | - *flags &= ~FOLL_WRITE; | ||
150 | + *flags |= FOLL_COW; | ||
151 | return 0; | ||
152 | } | ||
153 |