Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'x86_urgent_for_v5.17_rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:

- Free shmem backing storage for SGX enclave pages when those are
swapped back into EPC memory

- Prevent do_int3() from being kprobed, to avoid recursion

- Remap setup_data and setup_indirect structures properly when
accessing their members

- Correct the alternatives patching order for modules too

* tag 'x86_urgent_for_v5.17_rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/sgx: Free backing memory after faulting the enclave page
x86/traps: Mark do_int3() NOKPROBE_SYMBOL
x86/boot: Add setup_indirect support in early_memremap_is_setup_data()
x86/boot: Fix memremap of setup_indirect structures
x86/module: Fix the paravirt vs alternative order

+253 -62
+48 -9
arch/x86/kernel/cpu/sgx/encl.c
··· 13 13 #include "sgx.h" 14 14 15 15 /* 16 + * Calculate byte offset of a PCMD struct associated with an enclave page. PCMD's 17 + * follow right after the EPC data in the backing storage. In addition to the 18 + * visible enclave pages, there's one extra page slot for SECS, before PCMD 19 + * structs. 20 + */ 21 + static inline pgoff_t sgx_encl_get_backing_page_pcmd_offset(struct sgx_encl *encl, 22 + unsigned long page_index) 23 + { 24 + pgoff_t epc_end_off = encl->size + sizeof(struct sgx_secs); 25 + 26 + return epc_end_off + page_index * sizeof(struct sgx_pcmd); 27 + } 28 + 29 + /* 30 + * Free a page from the backing storage in the given page index. 31 + */ 32 + static inline void sgx_encl_truncate_backing_page(struct sgx_encl *encl, unsigned long page_index) 33 + { 34 + struct inode *inode = file_inode(encl->backing); 35 + 36 + shmem_truncate_range(inode, PFN_PHYS(page_index), PFN_PHYS(page_index) + PAGE_SIZE - 1); 37 + } 38 + 39 + /* 16 40 * ELDU: Load an EPC page as unblocked. For more info, see "OS Management of EPC 17 41 * Pages" in the SDM. 18 42 */ ··· 46 22 { 47 23 unsigned long va_offset = encl_page->desc & SGX_ENCL_PAGE_VA_OFFSET_MASK; 48 24 struct sgx_encl *encl = encl_page->encl; 25 + pgoff_t page_index, page_pcmd_off; 49 26 struct sgx_pageinfo pginfo; 50 27 struct sgx_backing b; 51 - pgoff_t page_index; 28 + bool pcmd_page_empty; 29 + u8 *pcmd_page; 52 30 int ret; 53 31 54 32 if (secs_page) ··· 58 32 else 59 33 page_index = PFN_DOWN(encl->size); 60 34 35 + page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index); 36 + 61 37 ret = sgx_encl_get_backing(encl, page_index, &b); 62 38 if (ret) 63 39 return ret; 64 40 65 41 pginfo.addr = encl_page->desc & PAGE_MASK; 66 42 pginfo.contents = (unsigned long)kmap_atomic(b.contents); 67 - pginfo.metadata = (unsigned long)kmap_atomic(b.pcmd) + 68 - b.pcmd_offset; 43 + pcmd_page = kmap_atomic(b.pcmd); 44 + pginfo.metadata = (unsigned long)pcmd_page + b.pcmd_offset; 69 45 70 46 if (secs_page) 71 47 pginfo.secs = (u64)sgx_get_epc_virt_addr(secs_page); ··· 83 55 ret = -EFAULT; 84 56 } 85 57 86 - kunmap_atomic((void *)(unsigned long)(pginfo.metadata - b.pcmd_offset)); 58 + memset(pcmd_page + b.pcmd_offset, 0, sizeof(struct sgx_pcmd)); 59 + 60 + /* 61 + * The area for the PCMD in the page was zeroed above. Check if the 62 + * whole page is now empty meaning that all PCMD's have been zeroed: 63 + */ 64 + pcmd_page_empty = !memchr_inv(pcmd_page, 0, PAGE_SIZE); 65 + 66 + kunmap_atomic(pcmd_page); 87 67 kunmap_atomic((void *)(unsigned long)pginfo.contents); 88 68 89 69 sgx_encl_put_backing(&b, false); 70 + 71 + sgx_encl_truncate_backing_page(encl, page_index); 72 + 73 + if (pcmd_page_empty) 74 + sgx_encl_truncate_backing_page(encl, PFN_DOWN(page_pcmd_off)); 90 75 91 76 return ret; 92 77 } ··· 620 579 int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, 621 580 struct sgx_backing *backing) 622 581 { 623 - pgoff_t pcmd_index = PFN_DOWN(encl->size) + 1 + (page_index >> 5); 582 + pgoff_t page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index); 624 583 struct page *contents; 625 584 struct page *pcmd; 626 585 ··· 628 587 if (IS_ERR(contents)) 629 588 return PTR_ERR(contents); 630 589 631 - pcmd = sgx_encl_get_backing_page(encl, pcmd_index); 590 + pcmd = sgx_encl_get_backing_page(encl, PFN_DOWN(page_pcmd_off)); 632 591 if (IS_ERR(pcmd)) { 633 592 put_page(contents); 634 593 return PTR_ERR(pcmd); ··· 637 596 backing->page_index = page_index; 638 597 backing->contents = contents; 639 598 backing->pcmd = pcmd; 640 - backing->pcmd_offset = 641 - (page_index & (PAGE_SIZE / sizeof(struct sgx_pcmd) - 1)) * 642 - sizeof(struct sgx_pcmd); 599 + backing->pcmd_offset = page_pcmd_off & (PAGE_SIZE - 1); 643 600 644 601 return 0; 645 602 }
+30 -11
arch/x86/kernel/e820.c
··· 995 995 */ 996 996 void __init e820__reserve_setup_data(void) 997 997 { 998 + struct setup_indirect *indirect; 998 999 struct setup_data *data; 999 - u64 pa_data; 1000 + u64 pa_data, pa_next; 1001 + u32 len; 1000 1002 1001 1003 pa_data = boot_params.hdr.setup_data; 1002 1004 if (!pa_data) ··· 1006 1004 1007 1005 while (pa_data) { 1008 1006 data = early_memremap(pa_data, sizeof(*data)); 1007 + if (!data) { 1008 + pr_warn("e820: failed to memremap setup_data entry\n"); 1009 + return; 1010 + } 1011 + 1012 + len = sizeof(*data); 1013 + pa_next = data->next; 1014 + 1009 1015 e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); 1010 1016 1011 1017 /* ··· 1025 1015 sizeof(*data) + data->len, 1026 1016 E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); 1027 1017 1028 - if (data->type == SETUP_INDIRECT && 1029 - ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) { 1030 - e820__range_update(((struct setup_indirect *)data->data)->addr, 1031 - ((struct setup_indirect *)data->data)->len, 1032 - E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); 1033 - e820__range_update_kexec(((struct setup_indirect *)data->data)->addr, 1034 - ((struct setup_indirect *)data->data)->len, 1035 - E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); 1018 + if (data->type == SETUP_INDIRECT) { 1019 + len += data->len; 1020 + early_memunmap(data, sizeof(*data)); 1021 + data = early_memremap(pa_data, len); 1022 + if (!data) { 1023 + pr_warn("e820: failed to memremap indirect setup_data\n"); 1024 + return; 1025 + } 1026 + 1027 + indirect = (struct setup_indirect *)data->data; 1028 + 1029 + if (indirect->type != SETUP_INDIRECT) { 1030 + e820__range_update(indirect->addr, indirect->len, 1031 + E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); 1032 + e820__range_update_kexec(indirect->addr, indirect->len, 1033 + E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); 1034 + } 1036 1035 } 1037 1036 1038 - pa_data = data->next; 1039 - early_memunmap(data, sizeof(*data)); 1037 + pa_data = pa_next; 1038 + early_memunmap(data, len); 1040 1039 } 1041 1040 1042 1041 e820__update_table(e820_table);
+27 -8
arch/x86/kernel/kdebugfs.c
··· 88 88 89 89 static int __init create_setup_data_nodes(struct dentry *parent) 90 90 { 91 + struct setup_indirect *indirect; 91 92 struct setup_data_node *node; 92 93 struct setup_data *data; 93 - int error; 94 + u64 pa_data, pa_next; 94 95 struct dentry *d; 95 - u64 pa_data; 96 + int error; 97 + u32 len; 96 98 int no = 0; 97 99 98 100 d = debugfs_create_dir("setup_data", parent); ··· 114 112 error = -ENOMEM; 115 113 goto err_dir; 116 114 } 115 + pa_next = data->next; 117 116 118 - if (data->type == SETUP_INDIRECT && 119 - ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) { 120 - node->paddr = ((struct setup_indirect *)data->data)->addr; 121 - node->type = ((struct setup_indirect *)data->data)->type; 122 - node->len = ((struct setup_indirect *)data->data)->len; 117 + if (data->type == SETUP_INDIRECT) { 118 + len = sizeof(*data) + data->len; 119 + memunmap(data); 120 + data = memremap(pa_data, len, MEMREMAP_WB); 121 + if (!data) { 122 + kfree(node); 123 + error = -ENOMEM; 124 + goto err_dir; 125 + } 126 + 127 + indirect = (struct setup_indirect *)data->data; 128 + 129 + if (indirect->type != SETUP_INDIRECT) { 130 + node->paddr = indirect->addr; 131 + node->type = indirect->type; 132 + node->len = indirect->len; 133 + } else { 134 + node->paddr = pa_data; 135 + node->type = data->type; 136 + node->len = data->len; 137 + } 123 138 } else { 124 139 node->paddr = pa_data; 125 140 node->type = data->type; ··· 144 125 } 145 126 146 127 create_setup_data_node(d, no, node); 147 - pa_data = data->next; 128 + pa_data = pa_next; 148 129 149 130 memunmap(data); 150 131 no++;
+61 -16
arch/x86/kernel/ksysfs.c
··· 91 91 92 92 static int __init get_setup_data_size(int nr, size_t *size) 93 93 { 94 - int i = 0; 94 + u64 pa_data = boot_params.hdr.setup_data, pa_next; 95 + struct setup_indirect *indirect; 95 96 struct setup_data *data; 96 - u64 pa_data = boot_params.hdr.setup_data; 97 + int i = 0; 98 + u32 len; 97 99 98 100 while (pa_data) { 99 101 data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); 100 102 if (!data) 101 103 return -ENOMEM; 104 + pa_next = data->next; 105 + 102 106 if (nr == i) { 103 - if (data->type == SETUP_INDIRECT && 104 - ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) 105 - *size = ((struct setup_indirect *)data->data)->len; 106 - else 107 + if (data->type == SETUP_INDIRECT) { 108 + len = sizeof(*data) + data->len; 109 + memunmap(data); 110 + data = memremap(pa_data, len, MEMREMAP_WB); 111 + if (!data) 112 + return -ENOMEM; 113 + 114 + indirect = (struct setup_indirect *)data->data; 115 + 116 + if (indirect->type != SETUP_INDIRECT) 117 + *size = indirect->len; 118 + else 119 + *size = data->len; 120 + } else { 107 121 *size = data->len; 122 + } 108 123 109 124 memunmap(data); 110 125 return 0; 111 126 } 112 127 113 - pa_data = data->next; 128 + pa_data = pa_next; 114 129 memunmap(data); 115 130 i++; 116 131 } ··· 135 120 static ssize_t type_show(struct kobject *kobj, 136 121 struct kobj_attribute *attr, char *buf) 137 122 { 123 + struct setup_indirect *indirect; 124 + struct setup_data *data; 138 125 int nr, ret; 139 126 u64 paddr; 140 - struct setup_data *data; 127 + u32 len; 141 128 142 129 ret = kobj_to_setup_data_nr(kobj, &nr); 143 130 if (ret) ··· 152 135 if (!data) 153 136 return -ENOMEM; 154 137 155 - if (data->type == SETUP_INDIRECT) 156 - ret = sprintf(buf, "0x%x\n", ((struct setup_indirect *)data->data)->type); 157 - else 138 + if (data->type == SETUP_INDIRECT) { 139 + len = sizeof(*data) + data->len; 140 + memunmap(data); 141 + data = memremap(paddr, len, MEMREMAP_WB); 142 + if (!data) 143 + return -ENOMEM; 144 + 145 + indirect = (struct setup_indirect *)data->data; 146 + 147 + ret = sprintf(buf, "0x%x\n", indirect->type); 148 + } else { 158 149 ret = sprintf(buf, "0x%x\n", data->type); 150 + } 151 + 159 152 memunmap(data); 160 153 return ret; 161 154 } ··· 176 149 char *buf, 177 150 loff_t off, size_t count) 178 151 { 152 + struct setup_indirect *indirect; 153 + struct setup_data *data; 179 154 int nr, ret = 0; 180 155 u64 paddr, len; 181 - struct setup_data *data; 182 156 void *p; 183 157 184 158 ret = kobj_to_setup_data_nr(kobj, &nr); ··· 193 165 if (!data) 194 166 return -ENOMEM; 195 167 196 - if (data->type == SETUP_INDIRECT && 197 - ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) { 198 - paddr = ((struct setup_indirect *)data->data)->addr; 199 - len = ((struct setup_indirect *)data->data)->len; 168 + if (data->type == SETUP_INDIRECT) { 169 + len = sizeof(*data) + data->len; 170 + memunmap(data); 171 + data = memremap(paddr, len, MEMREMAP_WB); 172 + if (!data) 173 + return -ENOMEM; 174 + 175 + indirect = (struct setup_indirect *)data->data; 176 + 177 + if (indirect->type != SETUP_INDIRECT) { 178 + paddr = indirect->addr; 179 + len = indirect->len; 180 + } else { 181 + /* 182 + * Even though this is technically undefined, return 183 + * the data as though it is a normal setup_data struct. 184 + * This will at least allow it to be inspected. 185 + */ 186 + paddr += sizeof(*data); 187 + len = data->len; 188 + } 200 189 } else { 201 190 paddr += sizeof(*data); 202 191 len = data->len;
+8 -5
arch/x86/kernel/module.c
··· 273 273 retpolines = s; 274 274 } 275 275 276 + /* 277 + * See alternative_instructions() for the ordering rules between the 278 + * various patching types. 279 + */ 280 + if (para) { 281 + void *pseg = (void *)para->sh_addr; 282 + apply_paravirt(pseg, pseg + para->sh_size); 283 + } 276 284 if (retpolines) { 277 285 void *rseg = (void *)retpolines->sh_addr; 278 286 apply_retpolines(rseg, rseg + retpolines->sh_size); ··· 296 288 alternatives_smp_module_add(me, me->name, 297 289 lseg, lseg + locks->sh_size, 298 290 tseg, tseg + text->sh_size); 299 - } 300 - 301 - if (para) { 302 - void *pseg = (void *)para->sh_addr; 303 - apply_paravirt(pseg, pseg + para->sh_size); 304 291 } 305 292 306 293 /* make jump label nops */
+27 -7
arch/x86/kernel/setup.c
··· 369 369 370 370 static void __init memblock_x86_reserve_range_setup_data(void) 371 371 { 372 + struct setup_indirect *indirect; 372 373 struct setup_data *data; 373 - u64 pa_data; 374 + u64 pa_data, pa_next; 375 + u32 len; 374 376 375 377 pa_data = boot_params.hdr.setup_data; 376 378 while (pa_data) { 377 379 data = early_memremap(pa_data, sizeof(*data)); 380 + if (!data) { 381 + pr_warn("setup: failed to memremap setup_data entry\n"); 382 + return; 383 + } 384 + 385 + len = sizeof(*data); 386 + pa_next = data->next; 387 + 378 388 memblock_reserve(pa_data, sizeof(*data) + data->len); 379 389 380 - if (data->type == SETUP_INDIRECT && 381 - ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) 382 - memblock_reserve(((struct setup_indirect *)data->data)->addr, 383 - ((struct setup_indirect *)data->data)->len); 390 + if (data->type == SETUP_INDIRECT) { 391 + len += data->len; 392 + early_memunmap(data, sizeof(*data)); 393 + data = early_memremap(pa_data, len); 394 + if (!data) { 395 + pr_warn("setup: failed to memremap indirect setup_data\n"); 396 + return; 397 + } 384 398 385 - pa_data = data->next; 386 - early_memunmap(data, sizeof(*data)); 399 + indirect = (struct setup_indirect *)data->data; 400 + 401 + if (indirect->type != SETUP_INDIRECT) 402 + memblock_reserve(indirect->addr, indirect->len); 403 + } 404 + 405 + pa_data = pa_next; 406 + early_memunmap(data, len); 387 407 } 388 408 } 389 409
+1
arch/x86/kernel/traps.c
··· 659 659 660 660 return res == NOTIFY_STOP; 661 661 } 662 + NOKPROBE_SYMBOL(do_int3); 662 663 663 664 static void do_int3_user(struct pt_regs *regs) 664 665 {
+51 -6
arch/x86/mm/ioremap.c
··· 615 615 static bool memremap_is_setup_data(resource_size_t phys_addr, 616 616 unsigned long size) 617 617 { 618 + struct setup_indirect *indirect; 618 619 struct setup_data *data; 619 620 u64 paddr, paddr_next; 620 621 ··· 628 627 629 628 data = memremap(paddr, sizeof(*data), 630 629 MEMREMAP_WB | MEMREMAP_DEC); 630 + if (!data) { 631 + pr_warn("failed to memremap setup_data entry\n"); 632 + return false; 633 + } 631 634 632 635 paddr_next = data->next; 633 636 len = data->len; ··· 641 636 return true; 642 637 } 643 638 644 - if (data->type == SETUP_INDIRECT && 645 - ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) { 646 - paddr = ((struct setup_indirect *)data->data)->addr; 647 - len = ((struct setup_indirect *)data->data)->len; 639 + if (data->type == SETUP_INDIRECT) { 640 + memunmap(data); 641 + data = memremap(paddr, sizeof(*data) + len, 642 + MEMREMAP_WB | MEMREMAP_DEC); 643 + if (!data) { 644 + pr_warn("failed to memremap indirect setup_data\n"); 645 + return false; 646 + } 647 + 648 + indirect = (struct setup_indirect *)data->data; 649 + 650 + if (indirect->type != SETUP_INDIRECT) { 651 + paddr = indirect->addr; 652 + len = indirect->len; 653 + } 648 654 } 649 655 650 656 memunmap(data); ··· 676 660 static bool __init early_memremap_is_setup_data(resource_size_t phys_addr, 677 661 unsigned long size) 678 662 { 663 + struct setup_indirect *indirect; 679 664 struct setup_data *data; 680 665 u64 paddr, paddr_next; 681 666 682 667 paddr = boot_params.hdr.setup_data; 683 668 while (paddr) { 684 - unsigned int len; 669 + unsigned int len, size; 685 670 686 671 if (phys_addr == paddr) 687 672 return true; 688 673 689 674 data = early_memremap_decrypted(paddr, sizeof(*data)); 675 + if (!data) { 676 + pr_warn("failed to early memremap setup_data entry\n"); 677 + return false; 678 + } 679 + 680 + size = sizeof(*data); 690 681 691 682 paddr_next = data->next; 692 683 len = data->len; 693 684 694 - early_memunmap(data, sizeof(*data)); 685 + if ((phys_addr > paddr) && (phys_addr < (paddr + len))) { 686 + early_memunmap(data, sizeof(*data)); 687 + return true; 688 + } 689 + 690 + if (data->type == SETUP_INDIRECT) { 691 + size += len; 692 + early_memunmap(data, sizeof(*data)); 693 + data = early_memremap_decrypted(paddr, size); 694 + if (!data) { 695 + pr_warn("failed to early memremap indirect setup_data\n"); 696 + return false; 697 + } 698 + 699 + indirect = (struct setup_indirect *)data->data; 700 + 701 + if (indirect->type != SETUP_INDIRECT) { 702 + paddr = indirect->addr; 703 + len = indirect->len; 704 + } 705 + } 706 + 707 + early_memunmap(data, size); 695 708 696 709 if ((phys_addr > paddr) && (phys_addr < (paddr + len))) 697 710 return true;