diff options
| -rw-r--r-- | arch/x86/Kconfig.debug | 8 | ||||
| -rw-r--r-- | arch/x86/include/asm/io.h | 46 | ||||
| -rw-r--r-- | arch/x86/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/test_nx.c | 173 | ||||
| -rw-r--r-- | arch/x86/mm/dump_pagetables.c | 25 | ||||
| -rw-r--r-- | arch/x86/mm/pageattr.c | 13 | ||||
| -rw-r--r-- | arch/x86/mm/pat_rbtree.c | 12 | ||||
| -rw-r--r-- | tools/testing/selftests/x86/Makefile | 2 |
8 files changed, 79 insertions, 201 deletions
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 67eec55093a5..783099f2ac72 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
| @@ -120,14 +120,6 @@ config DEBUG_SET_MODULE_RONX | |||
| 120 | against certain classes of kernel exploits. | 120 | against certain classes of kernel exploits. |
| 121 | If in doubt, say "N". | 121 | If in doubt, say "N". |
| 122 | 122 | ||
| 123 | config DEBUG_NX_TEST | ||
| 124 | tristate "Testcase for the NX non-executable stack feature" | ||
| 125 | depends on DEBUG_KERNEL && m | ||
| 126 | ---help--- | ||
| 127 | This option enables a testcase for the CPU NX capability | ||
| 128 | and the software setup of this feature. | ||
| 129 | If in doubt, say "N" | ||
| 130 | |||
| 131 | config DOUBLEFAULT | 123 | config DOUBLEFAULT |
| 132 | default y | 124 | default y |
| 133 | bool "Enable doublefault exception handler" if EXPERT | 125 | bool "Enable doublefault exception handler" if EXPERT |
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index d34bd370074b..7afb0e2f07f4 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h | |||
| @@ -164,6 +164,17 @@ static inline unsigned int isa_virt_to_bus(volatile void *address) | |||
| 164 | #define virt_to_bus virt_to_phys | 164 | #define virt_to_bus virt_to_phys |
| 165 | #define bus_to_virt phys_to_virt | 165 | #define bus_to_virt phys_to_virt |
| 166 | 166 | ||
| 167 | /* | ||
| 168 | * The default ioremap() behavior is non-cached; if you need something | ||
| 169 | * else, you probably want one of the following. | ||
| 170 | */ | ||
| 171 | extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size); | ||
| 172 | extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size); | ||
| 173 | #define ioremap_uc ioremap_uc | ||
| 174 | |||
| 175 | extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size); | ||
| 176 | extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val); | ||
| 177 | |||
| 167 | /** | 178 | /** |
| 168 | * ioremap - map bus memory into CPU space | 179 | * ioremap - map bus memory into CPU space |
| 169 | * @offset: bus address of the memory | 180 | * @offset: bus address of the memory |
| @@ -178,17 +189,6 @@ static inline unsigned int isa_virt_to_bus(volatile void *address) | |||
| 178 | * If the area you are trying to map is a PCI BAR you should have a | 189 | * If the area you are trying to map is a PCI BAR you should have a |
| 179 | * look at pci_iomap(). | 190 | * look at pci_iomap(). |
| 180 | */ | 191 | */ |
| 181 | extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size); | ||
| 182 | extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size); | ||
| 183 | #define ioremap_uc ioremap_uc | ||
| 184 | |||
| 185 | extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size); | ||
| 186 | extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, | ||
| 187 | unsigned long prot_val); | ||
| 188 | |||
| 189 | /* | ||
| 190 | * The default ioremap() behavior is non-cached: | ||
| 191 | */ | ||
| 192 | static inline void __iomem *ioremap(resource_size_t offset, unsigned long size) | 192 | static inline void __iomem *ioremap(resource_size_t offset, unsigned long size) |
| 193 | { | 193 | { |
| 194 | return ioremap_nocache(offset, size); | 194 | return ioremap_nocache(offset, size); |
| @@ -207,18 +207,42 @@ extern void set_iounmap_nonlazy(void); | |||
| 207 | */ | 207 | */ |
| 208 | #define xlate_dev_kmem_ptr(p) p | 208 | #define xlate_dev_kmem_ptr(p) p |
| 209 | 209 | ||
| 210 | /** | ||
| 211 | * memset_io Set a range of I/O memory to a constant value | ||
| 212 | * @addr: The beginning of the I/O-memory range to set | ||
| 213 | * @val: The value to set the memory to | ||
| 214 | * @count: The number of bytes to set | ||
| 215 | * | ||
| 216 | * Set a range of I/O memory to a given value. | ||
| 217 | */ | ||
| 210 | static inline void | 218 | static inline void |
| 211 | memset_io(volatile void __iomem *addr, unsigned char val, size_t count) | 219 | memset_io(volatile void __iomem *addr, unsigned char val, size_t count) |
| 212 | { | 220 | { |
| 213 | memset((void __force *)addr, val, count); | 221 | memset((void __force *)addr, val, count); |
| 214 | } | 222 | } |
| 215 | 223 | ||
| 224 | /** | ||
| 225 | * memcpy_fromio Copy a block of data from I/O memory | ||
| 226 | * @dst: The (RAM) destination for the copy | ||
| 227 | * @src: The (I/O memory) source for the data | ||
| 228 | * @count: The number of bytes to copy | ||
| 229 | * | ||
| 230 | * Copy a block of data from I/O memory. | ||
| 231 | */ | ||
| 216 | static inline void | 232 | static inline void |
| 217 | memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count) | 233 | memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count) |
| 218 | { | 234 | { |
| 219 | memcpy(dst, (const void __force *)src, count); | 235 | memcpy(dst, (const void __force *)src, count); |
| 220 | } | 236 | } |
| 221 | 237 | ||
| 238 | /** | ||
| 239 | * memcpy_toio Copy a block of data into I/O memory | ||
| 240 | * @dst: The (I/O memory) destination for the copy | ||
| 241 | * @src: The (RAM) source for the data | ||
| 242 | * @count: The number of bytes to copy | ||
| 243 | * | ||
| 244 | * Copy a block of data to I/O memory. | ||
| 245 | */ | ||
| 222 | static inline void | 246 | static inline void |
| 223 | memcpy_toio(volatile void __iomem *dst, const void *src, size_t count) | 247 | memcpy_toio(volatile void __iomem *dst, const void *src, size_t count) |
| 224 | { | 248 | { |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 581386c7e429..bdcdb3b3a219 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
| @@ -101,7 +101,6 @@ obj-$(CONFIG_APB_TIMER) += apb_timer.o | |||
| 101 | 101 | ||
| 102 | obj-$(CONFIG_AMD_NB) += amd_nb.o | 102 | obj-$(CONFIG_AMD_NB) += amd_nb.o |
| 103 | obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o | 103 | obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o |
| 104 | obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o | ||
| 105 | obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o | 104 | obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o |
| 106 | 105 | ||
| 107 | obj-$(CONFIG_KVM_GUEST) += kvm.o kvmclock.o | 106 | obj-$(CONFIG_KVM_GUEST) += kvm.o kvmclock.o |
diff --git a/arch/x86/kernel/test_nx.c b/arch/x86/kernel/test_nx.c deleted file mode 100644 index a3b875c9e6af..000000000000 --- a/arch/x86/kernel/test_nx.c +++ /dev/null | |||
| @@ -1,173 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * test_nx.c: functional test for NX functionality | ||
| 3 | * | ||
| 4 | * (C) Copyright 2008 Intel Corporation | ||
| 5 | * Author: Arjan van de Ven <arjan@linux.intel.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; version 2 | ||
| 10 | * of the License. | ||
| 11 | */ | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/sort.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | |||
| 16 | #include <linux/uaccess.h> | ||
| 17 | #include <asm/asm.h> | ||
| 18 | |||
| 19 | extern int rodata_test_data; | ||
| 20 | |||
| 21 | /* | ||
| 22 | * This file checks 4 things: | ||
| 23 | * 1) Check if the stack is not executable | ||
| 24 | * 2) Check if kmalloc memory is not executable | ||
| 25 | * 3) Check if the .rodata section is not executable | ||
| 26 | * 4) Check if the .data section of a module is not executable | ||
| 27 | * | ||
| 28 | * To do this, the test code tries to execute memory in stack/kmalloc/etc, | ||
| 29 | * and then checks if the expected trap happens. | ||
| 30 | * | ||
| 31 | * Sadly, this implies having a dynamic exception handling table entry. | ||
| 32 | * ... which can be done (and will make Rusty cry)... but it can only | ||
| 33 | * be done in a stand-alone module with only 1 entry total. | ||
| 34 | * (otherwise we'd have to sort and that's just too messy) | ||
| 35 | */ | ||
| 36 | |||
| 37 | |||
| 38 | |||
| 39 | /* | ||
| 40 | * We want to set up an exception handling point on our stack, | ||
| 41 | * which means a variable value. This function is rather dirty | ||
| 42 | * and walks the exception table of the module, looking for a magic | ||
| 43 | * marker and replaces it with a specific function. | ||
| 44 | */ | ||
| 45 | static void fudze_exception_table(void *marker, void *new) | ||
| 46 | { | ||
| 47 | struct module *mod = THIS_MODULE; | ||
| 48 | struct exception_table_entry *extable; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Note: This module has only 1 exception table entry, | ||
| 52 | * so searching and sorting is not needed. If that changes, | ||
| 53 | * this would be the place to search and re-sort the exception | ||
| 54 | * table. | ||
| 55 | */ | ||
| 56 | if (mod->num_exentries > 1) { | ||
| 57 | printk(KERN_ERR "test_nx: too many exception table entries!\n"); | ||
| 58 | printk(KERN_ERR "test_nx: test results are not reliable.\n"); | ||
| 59 | return; | ||
| 60 | } | ||
| 61 | extable = (struct exception_table_entry *)mod->extable; | ||
| 62 | extable[0].insn = (unsigned long)new; | ||
| 63 | } | ||
| 64 | |||
| 65 | |||
| 66 | /* | ||
| 67 | * exception tables get their symbols translated so we need | ||
| 68 | * to use a fake function to put in there, which we can then | ||
| 69 | * replace at runtime. | ||
| 70 | */ | ||
| 71 | void foo_label(void); | ||
| 72 | |||
| 73 | /* | ||
| 74 | * returns 0 for not-executable, negative for executable | ||
| 75 | * | ||
| 76 | * Note: we cannot allow this function to be inlined, because | ||
| 77 | * that would give us more than 1 exception table entry. | ||
| 78 | * This in turn would break the assumptions above. | ||
| 79 | */ | ||
| 80 | static noinline int test_address(void *address) | ||
| 81 | { | ||
| 82 | unsigned long result; | ||
| 83 | |||
| 84 | /* Set up an exception table entry for our address */ | ||
| 85 | fudze_exception_table(&foo_label, address); | ||
| 86 | result = 1; | ||
| 87 | asm volatile( | ||
| 88 | "foo_label:\n" | ||
| 89 | "0: call *%[fake_code]\n" | ||
| 90 | "1:\n" | ||
| 91 | ".section .fixup,\"ax\"\n" | ||
| 92 | "2: mov %[zero], %[rslt]\n" | ||
| 93 | " ret\n" | ||
| 94 | ".previous\n" | ||
| 95 | _ASM_EXTABLE(0b,2b) | ||
| 96 | : [rslt] "=r" (result) | ||
| 97 | : [fake_code] "r" (address), [zero] "r" (0UL), "0" (result) | ||
| 98 | ); | ||
| 99 | /* change the exception table back for the next round */ | ||
| 100 | fudze_exception_table(address, &foo_label); | ||
| 101 | |||
| 102 | if (result) | ||
| 103 | return -ENODEV; | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static unsigned char test_data = 0xC3; /* 0xC3 is the opcode for "ret" */ | ||
| 108 | |||
| 109 | static int test_NX(void) | ||
| 110 | { | ||
| 111 | int ret = 0; | ||
| 112 | /* 0xC3 is the opcode for "ret" */ | ||
| 113 | char stackcode[] = {0xC3, 0x90, 0 }; | ||
| 114 | char *heap; | ||
| 115 | |||
| 116 | test_data = 0xC3; | ||
| 117 | |||
| 118 | printk(KERN_INFO "Testing NX protection\n"); | ||
| 119 | |||
| 120 | /* Test 1: check if the stack is not executable */ | ||
| 121 | if (test_address(&stackcode)) { | ||
| 122 | printk(KERN_ERR "test_nx: stack was executable\n"); | ||
| 123 | ret = -ENODEV; | ||
| 124 | } | ||
| 125 | |||
| 126 | |||
| 127 | /* Test 2: Check if the heap is executable */ | ||
| 128 | heap = kmalloc(64, GFP_KERNEL); | ||
| 129 | if (!heap) | ||
| 130 | return -ENOMEM; | ||
| 131 | heap[0] = 0xC3; /* opcode for "ret" */ | ||
| 132 | |||
| 133 | if (test_address(heap)) { | ||
| 134 | printk(KERN_ERR "test_nx: heap was executable\n"); | ||
| 135 | ret = -ENODEV; | ||
| 136 | } | ||
| 137 | kfree(heap); | ||
| 138 | |||
| 139 | /* | ||
| 140 | * The following 2 tests currently fail, this needs to get fixed | ||
| 141 | * Until then, don't run them to avoid too many people getting scared | ||
| 142 | * by the error message | ||
| 143 | */ | ||
| 144 | |||
| 145 | /* Test 3: Check if the .rodata section is executable */ | ||
| 146 | if (rodata_test_data != 0xC3) { | ||
| 147 | printk(KERN_ERR "test_nx: .rodata marker has invalid value\n"); | ||
| 148 | ret = -ENODEV; | ||
| 149 | } else if (test_address(&rodata_test_data)) { | ||
| 150 | printk(KERN_ERR "test_nx: .rodata section is executable\n"); | ||
| 151 | ret = -ENODEV; | ||
| 152 | } | ||
| 153 | |||
| 154 | #if 0 | ||
| 155 | /* Test 4: Check if the .data section of a module is executable */ | ||
| 156 | if (test_address(&test_data)) { | ||
| 157 | printk(KERN_ERR "test_nx: .data section is executable\n"); | ||
| 158 | ret = -ENODEV; | ||
| 159 | } | ||
| 160 | |||
| 161 | #endif | ||
| 162 | return ret; | ||
| 163 | } | ||
| 164 | |||
| 165 | static void test_exit(void) | ||
| 166 | { | ||
| 167 | } | ||
| 168 | |||
| 169 | module_init(test_NX); | ||
| 170 | module_exit(test_exit); | ||
| 171 | MODULE_LICENSE("GPL"); | ||
| 172 | MODULE_DESCRIPTION("Testcase for the NX infrastructure"); | ||
| 173 | MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>"); | ||
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c index 8aa6bea1cd6c..58b5bee7ea27 100644 --- a/arch/x86/mm/dump_pagetables.c +++ b/arch/x86/mm/dump_pagetables.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
| 19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
| 20 | 20 | ||
| 21 | #include <asm/kasan.h> | ||
| 21 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
| 22 | 23 | ||
| 23 | /* | 24 | /* |
| @@ -51,6 +52,10 @@ enum address_markers_idx { | |||
| 51 | LOW_KERNEL_NR, | 52 | LOW_KERNEL_NR, |
| 52 | VMALLOC_START_NR, | 53 | VMALLOC_START_NR, |
| 53 | VMEMMAP_START_NR, | 54 | VMEMMAP_START_NR, |
| 55 | #ifdef CONFIG_KASAN | ||
| 56 | KASAN_SHADOW_START_NR, | ||
| 57 | KASAN_SHADOW_END_NR, | ||
| 58 | #endif | ||
| 54 | # ifdef CONFIG_X86_ESPFIX64 | 59 | # ifdef CONFIG_X86_ESPFIX64 |
| 55 | ESPFIX_START_NR, | 60 | ESPFIX_START_NR, |
| 56 | # endif | 61 | # endif |
| @@ -76,6 +81,10 @@ static struct addr_marker address_markers[] = { | |||
| 76 | { 0/* PAGE_OFFSET */, "Low Kernel Mapping" }, | 81 | { 0/* PAGE_OFFSET */, "Low Kernel Mapping" }, |
| 77 | { 0/* VMALLOC_START */, "vmalloc() Area" }, | 82 | { 0/* VMALLOC_START */, "vmalloc() Area" }, |
| 78 | { 0/* VMEMMAP_START */, "Vmemmap" }, | 83 | { 0/* VMEMMAP_START */, "Vmemmap" }, |
| 84 | #ifdef CONFIG_KASAN | ||
| 85 | { KASAN_SHADOW_START, "KASAN shadow" }, | ||
| 86 | { KASAN_SHADOW_END, "KASAN shadow end" }, | ||
| 87 | #endif | ||
| 79 | # ifdef CONFIG_X86_ESPFIX64 | 88 | # ifdef CONFIG_X86_ESPFIX64 |
| 80 | { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, | 89 | { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, |
| 81 | # endif | 90 | # endif |
| @@ -327,18 +336,31 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr, | |||
| 327 | 336 | ||
| 328 | #if PTRS_PER_PUD > 1 | 337 | #if PTRS_PER_PUD > 1 |
| 329 | 338 | ||
| 339 | /* | ||
| 340 | * This is an optimization for CONFIG_DEBUG_WX=y + CONFIG_KASAN=y | ||
| 341 | * KASAN fills page tables with the same values. Since there is no | ||
| 342 | * point in checking page table more than once we just skip repeated | ||
| 343 | * entries. This saves us dozens of seconds during boot. | ||
| 344 | */ | ||
| 345 | static bool pud_already_checked(pud_t *prev_pud, pud_t *pud, bool checkwx) | ||
| 346 | { | ||
| 347 | return checkwx && prev_pud && (pud_val(*prev_pud) == pud_val(*pud)); | ||
| 348 | } | ||
| 349 | |||
| 330 | static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr, | 350 | static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr, |
| 331 | unsigned long P) | 351 | unsigned long P) |
| 332 | { | 352 | { |
| 333 | int i; | 353 | int i; |
| 334 | pud_t *start; | 354 | pud_t *start; |
| 335 | pgprotval_t prot; | 355 | pgprotval_t prot; |
| 356 | pud_t *prev_pud = NULL; | ||
| 336 | 357 | ||
| 337 | start = (pud_t *) pgd_page_vaddr(addr); | 358 | start = (pud_t *) pgd_page_vaddr(addr); |
| 338 | 359 | ||
| 339 | for (i = 0; i < PTRS_PER_PUD; i++) { | 360 | for (i = 0; i < PTRS_PER_PUD; i++) { |
| 340 | st->current_address = normalize_addr(P + i * PUD_LEVEL_MULT); | 361 | st->current_address = normalize_addr(P + i * PUD_LEVEL_MULT); |
| 341 | if (!pud_none(*start)) { | 362 | if (!pud_none(*start) && |
| 363 | !pud_already_checked(prev_pud, start, st->check_wx)) { | ||
| 342 | if (pud_large(*start) || !pud_present(*start)) { | 364 | if (pud_large(*start) || !pud_present(*start)) { |
| 343 | prot = pud_flags(*start); | 365 | prot = pud_flags(*start); |
| 344 | note_page(m, st, __pgprot(prot), 2); | 366 | note_page(m, st, __pgprot(prot), 2); |
| @@ -349,6 +371,7 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr, | |||
| 349 | } else | 371 | } else |
| 350 | note_page(m, st, __pgprot(0), 2); | 372 | note_page(m, st, __pgprot(0), 2); |
| 351 | 373 | ||
| 374 | prev_pud = start; | ||
| 352 | start++; | 375 | start++; |
| 353 | } | 376 | } |
| 354 | } | 377 | } |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 5a287e523eab..28d42130243c 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -214,7 +214,20 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache, | |||
| 214 | int in_flags, struct page **pages) | 214 | int in_flags, struct page **pages) |
| 215 | { | 215 | { |
| 216 | unsigned int i, level; | 216 | unsigned int i, level; |
| 217 | #ifdef CONFIG_PREEMPT | ||
| 218 | /* | ||
| 219 | * Avoid wbinvd() because it causes latencies on all CPUs, | ||
| 220 | * regardless of any CPU isolation that may be in effect. | ||
| 221 | * | ||
| 222 | * This should be extended for CAT enabled systems independent of | ||
| 223 | * PREEMPT because wbinvd() does not respect the CAT partitions and | ||
| 224 | * this is exposed to unpriviledged users through the graphics | ||
| 225 | * subsystem. | ||
| 226 | */ | ||
| 227 | unsigned long do_wbinvd = 0; | ||
| 228 | #else | ||
| 217 | unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */ | 229 | unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */ |
| 230 | #endif | ||
| 218 | 231 | ||
| 219 | BUG_ON(irqs_disabled()); | 232 | BUG_ON(irqs_disabled()); |
| 220 | 233 | ||
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c index 159b52ccd600..d76485b22824 100644 --- a/arch/x86/mm/pat_rbtree.c +++ b/arch/x86/mm/pat_rbtree.c | |||
| @@ -47,7 +47,7 @@ static u64 get_subtree_max_end(struct rb_node *node) | |||
| 47 | { | 47 | { |
| 48 | u64 ret = 0; | 48 | u64 ret = 0; |
| 49 | if (node) { | 49 | if (node) { |
| 50 | struct memtype *data = container_of(node, struct memtype, rb); | 50 | struct memtype *data = rb_entry(node, struct memtype, rb); |
| 51 | ret = data->subtree_max_end; | 51 | ret = data->subtree_max_end; |
| 52 | } | 52 | } |
| 53 | return ret; | 53 | return ret; |
| @@ -79,7 +79,7 @@ static struct memtype *memtype_rb_lowest_match(struct rb_root *root, | |||
| 79 | struct memtype *last_lower = NULL; | 79 | struct memtype *last_lower = NULL; |
| 80 | 80 | ||
| 81 | while (node) { | 81 | while (node) { |
| 82 | struct memtype *data = container_of(node, struct memtype, rb); | 82 | struct memtype *data = rb_entry(node, struct memtype, rb); |
| 83 | 83 | ||
| 84 | if (get_subtree_max_end(node->rb_left) > start) { | 84 | if (get_subtree_max_end(node->rb_left) > start) { |
| 85 | /* Lowest overlap if any must be on left side */ | 85 | /* Lowest overlap if any must be on left side */ |
| @@ -121,7 +121,7 @@ static struct memtype *memtype_rb_match(struct rb_root *root, | |||
| 121 | 121 | ||
| 122 | node = rb_next(&match->rb); | 122 | node = rb_next(&match->rb); |
| 123 | if (node) | 123 | if (node) |
| 124 | match = container_of(node, struct memtype, rb); | 124 | match = rb_entry(node, struct memtype, rb); |
| 125 | else | 125 | else |
| 126 | match = NULL; | 126 | match = NULL; |
| 127 | } | 127 | } |
| @@ -150,7 +150,7 @@ static int memtype_rb_check_conflict(struct rb_root *root, | |||
| 150 | 150 | ||
| 151 | node = rb_next(&match->rb); | 151 | node = rb_next(&match->rb); |
| 152 | while (node) { | 152 | while (node) { |
| 153 | match = container_of(node, struct memtype, rb); | 153 | match = rb_entry(node, struct memtype, rb); |
| 154 | 154 | ||
| 155 | if (match->start >= end) /* Checked all possible matches */ | 155 | if (match->start >= end) /* Checked all possible matches */ |
| 156 | goto success; | 156 | goto success; |
| @@ -181,7 +181,7 @@ static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata) | |||
| 181 | struct rb_node *parent = NULL; | 181 | struct rb_node *parent = NULL; |
| 182 | 182 | ||
| 183 | while (*node) { | 183 | while (*node) { |
| 184 | struct memtype *data = container_of(*node, struct memtype, rb); | 184 | struct memtype *data = rb_entry(*node, struct memtype, rb); |
| 185 | 185 | ||
| 186 | parent = *node; | 186 | parent = *node; |
| 187 | if (data->subtree_max_end < newdata->end) | 187 | if (data->subtree_max_end < newdata->end) |
| @@ -270,7 +270,7 @@ int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos) | |||
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | if (node) { /* pos == i */ | 272 | if (node) { /* pos == i */ |
| 273 | struct memtype *this = container_of(node, struct memtype, rb); | 273 | struct memtype *this = rb_entry(node, struct memtype, rb); |
| 274 | *out = *this; | 274 | *out = *this; |
| 275 | return 0; | 275 | return 0; |
| 276 | } else { | 276 | } else { |
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 25d4067c11e4..83d8b1c6cb0e 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile | |||
| @@ -5,7 +5,7 @@ include ../lib.mk | |||
| 5 | .PHONY: all all_32 all_64 warn_32bit_failure clean | 5 | .PHONY: all all_32 all_64 warn_32bit_failure clean |
| 6 | 6 | ||
| 7 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ | 7 | TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ |
| 8 | check_initial_reg_state sigreturn ldt_gdt iopl \ | 8 | check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test \ |
| 9 | protection_keys test_vdso | 9 | protection_keys test_vdso |
| 10 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ | 10 | TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ |
| 11 | test_FCMOV test_FCOMI test_FISTTP \ | 11 | test_FCMOV test_FCOMI test_FISTTP \ |
