Contents of /trunk/kernel-alx/patches-4.4/0125-4.4.26-all-fixes.patch
Parent Directory | Revision Log
Revision 2861 -
(show 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 | 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 |