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

Merge branch 'pvbase' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD

s390 base parts (non kvm) for protvirt

+659 -14
+5
Documentation/admin-guide/kernel-parameters.txt
··· 3795 3795 before loading. 3796 3796 See Documentation/admin-guide/blockdev/ramdisk.rst. 3797 3797 3798 + prot_virt= [S390] enable hosting protected virtual machines 3799 + isolated from the hypervisor (if hardware supports 3800 + that). 3801 + Format: <bool> 3802 + 3798 3803 psi= [KNL] Enable or disable pressure stall information 3799 3804 tracking. 3800 3805 Format: <bool>
+1 -1
arch/s390/boot/Makefile
··· 37 37 obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o 38 38 obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o 39 39 obj-y += version.o pgm_check_info.o ctype.o text_dma.o 40 - obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o 40 + obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o 41 41 obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o 42 42 obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o 43 43 targets := bzImage startup.a section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
+20
arch/s390/boot/uv.c
··· 3 3 #include <asm/facility.h> 4 4 #include <asm/sections.h> 5 5 6 + /* will be used in arch/s390/kernel/uv.c */ 7 + #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST 6 8 int __bootdata_preserved(prot_virt_guest); 9 + #endif 10 + #if IS_ENABLED(CONFIG_KVM) 11 + struct uv_info __bootdata_preserved(uv_info); 12 + #endif 7 13 8 14 void uv_query_info(void) 9 15 { ··· 25 19 if (uv_call(0, (uint64_t)&uvcb) && uvcb.header.rc != 0x100) 26 20 return; 27 21 22 + if (IS_ENABLED(CONFIG_KVM)) { 23 + memcpy(uv_info.inst_calls_list, uvcb.inst_calls_list, sizeof(uv_info.inst_calls_list)); 24 + uv_info.uv_base_stor_len = uvcb.uv_base_stor_len; 25 + uv_info.guest_base_stor_len = uvcb.conf_base_phys_stor_len; 26 + uv_info.guest_virt_base_stor_len = uvcb.conf_base_virt_stor_len; 27 + uv_info.guest_virt_var_stor_len = uvcb.conf_virt_var_stor_len; 28 + uv_info.guest_cpu_stor_len = uvcb.cpu_stor_len; 29 + uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE); 30 + uv_info.max_num_sec_conf = uvcb.max_num_sec_conf; 31 + uv_info.max_guest_cpus = uvcb.max_guest_cpus; 32 + } 33 + 34 + #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST 28 35 if (test_bit_inv(BIT_UVC_CMD_SET_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list) && 29 36 test_bit_inv(BIT_UVC_CMD_REMOVE_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list)) 30 37 prot_virt_guest = 1; 38 + #endif 31 39 }
+4
arch/s390/include/asm/gmap.h
··· 9 9 #ifndef _ASM_S390_GMAP_H 10 10 #define _ASM_S390_GMAP_H 11 11 12 + #include <linux/radix-tree.h> 12 13 #include <linux/refcount.h> 13 14 14 15 /* Generic bits for GMAP notification on DAT table entry changes. */ ··· 32 31 * @table: pointer to the page directory 33 32 * @asce: address space control element for gmap page table 34 33 * @pfault_enabled: defines if pfaults are applicable for the guest 34 + * @guest_handle: protected virtual machine handle for the ultravisor 35 35 * @host_to_rmap: radix tree with gmap_rmap lists 36 36 * @children: list of shadow gmap structures 37 37 * @pt_list: list of all page tables used in the shadow guest address space ··· 56 54 unsigned long asce_end; 57 55 void *private; 58 56 bool pfault_enabled; 57 + /* only set for protected virtual machines */ 58 + unsigned long guest_handle; 59 59 /* Additional data for shadow guest address spaces */ 60 60 struct radix_tree_root host_to_rmap; 61 61 struct list_head children;
+2
arch/s390/include/asm/mmu.h
··· 16 16 unsigned long asce; 17 17 unsigned long asce_limit; 18 18 unsigned long vdso_base; 19 + /* The mmu context belongs to a secure guest. */ 20 + atomic_t is_protected; 19 21 /* 20 22 * The following bitfields need a down_write on the mm 21 23 * semaphore when they are written to. As they are only
+1
arch/s390/include/asm/mmu_context.h
··· 23 23 INIT_LIST_HEAD(&mm->context.gmap_list); 24 24 cpumask_clear(&mm->context.cpu_attach_mask); 25 25 atomic_set(&mm->context.flush_count, 0); 26 + atomic_set(&mm->context.is_protected, 0); 26 27 mm->context.gmap_asce = 0; 27 28 mm->context.flush_mm = 0; 28 29 mm->context.compat_mm = test_thread_flag(TIF_31BIT);
+5
arch/s390/include/asm/page.h
··· 153 153 #define HAVE_ARCH_FREE_PAGE 154 154 #define HAVE_ARCH_ALLOC_PAGE 155 155 156 + #if IS_ENABLED(CONFIG_PGSTE) 157 + int arch_make_page_accessible(struct page *page); 158 + #define HAVE_ARCH_MAKE_PAGE_ACCESSIBLE 159 + #endif 160 + 156 161 #endif /* !__ASSEMBLY__ */ 157 162 158 163 #define __PAGE_OFFSET 0x0UL
+30 -5
arch/s390/include/asm/pgtable.h
··· 19 19 #include <linux/atomic.h> 20 20 #include <asm/bug.h> 21 21 #include <asm/page.h> 22 + #include <asm/uv.h> 22 23 23 24 extern pgd_t swapper_pg_dir[]; 24 25 extern void paging_init(void); ··· 516 515 { 517 516 #ifdef CONFIG_PGSTE 518 517 if (unlikely(mm->context.has_pgste)) 518 + return 1; 519 + #endif 520 + return 0; 521 + } 522 + 523 + static inline int mm_is_protected(struct mm_struct *mm) 524 + { 525 + #ifdef CONFIG_PGSTE 526 + if (unlikely(atomic_read(&mm->context.is_protected))) 519 527 return 1; 520 528 #endif 521 529 return 0; ··· 1071 1061 static inline pte_t ptep_get_and_clear(struct mm_struct *mm, 1072 1062 unsigned long addr, pte_t *ptep) 1073 1063 { 1074 - return ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); 1064 + pte_t res; 1065 + 1066 + res = ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); 1067 + if (mm_is_protected(mm) && pte_present(res)) 1068 + uv_convert_from_secure(pte_val(res) & PAGE_MASK); 1069 + return res; 1075 1070 } 1076 1071 1077 1072 #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION ··· 1088 1073 static inline pte_t ptep_clear_flush(struct vm_area_struct *vma, 1089 1074 unsigned long addr, pte_t *ptep) 1090 1075 { 1091 - return ptep_xchg_direct(vma->vm_mm, addr, ptep, __pte(_PAGE_INVALID)); 1076 + pte_t res; 1077 + 1078 + res = ptep_xchg_direct(vma->vm_mm, addr, ptep, __pte(_PAGE_INVALID)); 1079 + if (mm_is_protected(vma->vm_mm) && pte_present(res)) 1080 + uv_convert_from_secure(pte_val(res) & PAGE_MASK); 1081 + return res; 1092 1082 } 1093 1083 1094 1084 /* ··· 1108 1088 unsigned long addr, 1109 1089 pte_t *ptep, int full) 1110 1090 { 1091 + pte_t res; 1092 + 1111 1093 if (full) { 1112 - pte_t pte = *ptep; 1094 + res = *ptep; 1113 1095 *ptep = __pte(_PAGE_INVALID); 1114 - return pte; 1096 + } else { 1097 + res = ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); 1115 1098 } 1116 - return ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); 1099 + if (mm_is_protected(mm) && pte_present(res)) 1100 + uv_convert_from_secure(pte_val(res) & PAGE_MASK); 1101 + return res; 1117 1102 } 1118 1103 1119 1104 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
+89 -2
arch/s390/include/asm/uv.h
··· 15 15 #include <linux/errno.h> 16 16 #include <linux/bug.h> 17 17 #include <asm/page.h> 18 + #include <asm/gmap.h> 18 19 19 20 #define UVC_RC_EXECUTED 0x0001 20 21 #define UVC_RC_INV_CMD 0x0002 ··· 24 23 #define UVC_RC_NO_RESUME 0x0007 25 24 26 25 #define UVC_CMD_QUI 0x0001 26 + #define UVC_CMD_INIT_UV 0x000f 27 + #define UVC_CMD_CONV_TO_SEC_STOR 0x0200 28 + #define UVC_CMD_CONV_FROM_SEC_STOR 0x0201 29 + #define UVC_CMD_PIN_PAGE_SHARED 0x0341 30 + #define UVC_CMD_UNPIN_PAGE_SHARED 0x0342 27 31 #define UVC_CMD_SET_SHARED_ACCESS 0x1000 28 32 #define UVC_CMD_REMOVE_SHARED_ACCESS 0x1001 29 33 30 34 /* Bits in installed uv calls */ 31 35 enum uv_cmds_inst { 32 36 BIT_UVC_CMD_QUI = 0, 37 + BIT_UVC_CMD_INIT_UV = 1, 38 + BIT_UVC_CMD_CONV_TO_SEC_STOR = 6, 39 + BIT_UVC_CMD_CONV_FROM_SEC_STOR = 7, 33 40 BIT_UVC_CMD_SET_SHARED_ACCESS = 8, 34 41 BIT_UVC_CMD_REMOVE_SHARED_ACCESS = 9, 42 + BIT_UVC_CMD_PIN_PAGE_SHARED = 21, 43 + BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22, 35 44 }; 36 45 37 46 struct uv_cb_header { ··· 55 44 struct uv_cb_header header; 56 45 u64 reserved08; 57 46 u64 inst_calls_list[4]; 58 - u64 reserved30[15]; 47 + u64 reserved30[2]; 48 + u64 uv_base_stor_len; 49 + u64 reserved48; 50 + u64 conf_base_phys_stor_len; 51 + u64 conf_base_virt_stor_len; 52 + u64 conf_virt_var_stor_len; 53 + u64 cpu_stor_len; 54 + u32 reserved70[3]; 55 + u32 max_num_sec_conf; 56 + u64 max_guest_stor_addr; 57 + u8 reserved88[158 - 136]; 58 + u16 max_guest_cpus; 59 + u8 reserveda0[200 - 160]; 60 + } __packed __aligned(8); 61 + 62 + struct uv_cb_init { 63 + struct uv_cb_header header; 64 + u64 reserved08[2]; 65 + u64 stor_origin; 66 + u64 stor_len; 67 + u64 reserved28[4]; 68 + } __packed __aligned(8); 69 + 70 + struct uv_cb_cts { 71 + struct uv_cb_header header; 72 + u64 reserved08[2]; 73 + u64 guest_handle; 74 + u64 gaddr; 75 + } __packed __aligned(8); 76 + 77 + struct uv_cb_cfs { 78 + struct uv_cb_header header; 79 + u64 reserved08[2]; 80 + u64 paddr; 59 81 } __packed __aligned(8); 60 82 61 83 struct uv_cb_share { ··· 112 68 : "memory", "cc"); 113 69 return cc; 114 70 } 71 + 72 + struct uv_info { 73 + unsigned long inst_calls_list[4]; 74 + unsigned long uv_base_stor_len; 75 + unsigned long guest_base_stor_len; 76 + unsigned long guest_virt_base_stor_len; 77 + unsigned long guest_virt_var_stor_len; 78 + unsigned long guest_cpu_stor_len; 79 + unsigned long max_sec_stor_addr; 80 + unsigned int max_num_sec_conf; 81 + unsigned short max_guest_cpus; 82 + }; 83 + 84 + extern struct uv_info uv_info; 115 85 116 86 #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST 117 87 extern int prot_virt_guest; ··· 179 121 return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS); 180 122 } 181 123 182 - void uv_query_info(void); 183 124 #else 184 125 #define is_prot_virt_guest() 0 185 126 static inline int uv_set_shared(unsigned long addr) { return 0; } 186 127 static inline int uv_remove_shared(unsigned long addr) { return 0; } 128 + #endif 129 + 130 + #if IS_ENABLED(CONFIG_KVM) 131 + extern int prot_virt_host; 132 + 133 + static inline int is_prot_virt_host(void) 134 + { 135 + return prot_virt_host; 136 + } 137 + 138 + int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb); 139 + int uv_convert_from_secure(unsigned long paddr); 140 + int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr); 141 + 142 + void setup_uv(void); 143 + void adjust_to_uv_max(unsigned long *vmax); 144 + #else 145 + #define is_prot_virt_host() 0 146 + static inline void setup_uv(void) {} 147 + static inline void adjust_to_uv_max(unsigned long *vmax) {} 148 + 149 + static inline int uv_convert_from_secure(unsigned long paddr) 150 + { 151 + return 0; 152 + } 153 + #endif 154 + 155 + #if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM) 156 + void uv_query_info(void); 157 + #else 187 158 static inline void uv_query_info(void) {} 188 159 #endif 189 160
+1
arch/s390/kernel/Makefile
··· 78 78 obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_diag.o 79 79 80 80 obj-$(CONFIG_TRACEPOINTS) += trace.o 81 + obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o 81 82 82 83 # vdso 83 84 obj-y += vdso64/
+2
arch/s390/kernel/entry.h
··· 24 24 25 25 void do_protection_exception(struct pt_regs *regs); 26 26 void do_dat_exception(struct pt_regs *regs); 27 + void do_secure_storage_access(struct pt_regs *regs); 28 + void do_non_secure_storage_access(struct pt_regs *regs); 27 29 28 30 void addressing_exception(struct pt_regs *regs); 29 31 void data_exception(struct pt_regs *regs);
+2 -2
arch/s390/kernel/pgm_check.S
··· 78 78 PGM_CHECK(do_dat_exception) /* 3a */ 79 79 PGM_CHECK(do_dat_exception) /* 3b */ 80 80 PGM_CHECK_DEFAULT /* 3c */ 81 - PGM_CHECK_DEFAULT /* 3d */ 82 - PGM_CHECK_DEFAULT /* 3e */ 81 + PGM_CHECK(do_secure_storage_access) /* 3d */ 82 + PGM_CHECK(do_non_secure_storage_access) /* 3e */ 83 83 PGM_CHECK_DEFAULT /* 3f */ 84 84 PGM_CHECK(monitor_event_exception) /* 40 */ 85 85 PGM_CHECK_DEFAULT /* 41 */
+5 -4
arch/s390/kernel/setup.c
··· 92 92 93 93 unsigned long int_hwcap = 0; 94 94 95 - #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST 96 - int __bootdata_preserved(prot_virt_guest); 97 - #endif 98 - 99 95 int __bootdata(noexec_disabled); 100 96 int __bootdata(memory_end_set); 101 97 unsigned long __bootdata(memory_end); ··· 559 563 else 560 564 vmax = _REGION1_SIZE; /* 4-level kernel page table */ 561 565 } 566 + 567 + if (is_prot_virt_host()) 568 + adjust_to_uv_max(&vmax); 562 569 563 570 /* module area is at the end of the kernel address space. */ 564 571 MODULES_END = vmax; ··· 1137 1138 */ 1138 1139 memblock_trim_memory(1UL << (MAX_ORDER - 1 + PAGE_SHIFT)); 1139 1140 1141 + if (is_prot_virt_host()) 1142 + setup_uv(); 1140 1143 setup_memory_end(); 1141 1144 setup_memory(); 1142 1145 dma_contiguous_reserve(memory_end);
+414
arch/s390/kernel/uv.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Common Ultravisor functions and initialization 4 + * 5 + * Copyright IBM Corp. 2019, 2020 6 + */ 7 + #define KMSG_COMPONENT "prot_virt" 8 + #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 9 + 10 + #include <linux/kernel.h> 11 + #include <linux/types.h> 12 + #include <linux/sizes.h> 13 + #include <linux/bitmap.h> 14 + #include <linux/memblock.h> 15 + #include <linux/pagemap.h> 16 + #include <linux/swap.h> 17 + #include <asm/facility.h> 18 + #include <asm/sections.h> 19 + #include <asm/uv.h> 20 + 21 + /* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */ 22 + #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST 23 + int __bootdata_preserved(prot_virt_guest); 24 + #endif 25 + 26 + #if IS_ENABLED(CONFIG_KVM) 27 + int prot_virt_host; 28 + EXPORT_SYMBOL(prot_virt_host); 29 + struct uv_info __bootdata_preserved(uv_info); 30 + EXPORT_SYMBOL(uv_info); 31 + 32 + static int __init prot_virt_setup(char *val) 33 + { 34 + bool enabled; 35 + int rc; 36 + 37 + rc = kstrtobool(val, &enabled); 38 + if (!rc && enabled) 39 + prot_virt_host = 1; 40 + 41 + if (is_prot_virt_guest() && prot_virt_host) { 42 + prot_virt_host = 0; 43 + pr_warn("Protected virtualization not available in protected guests."); 44 + } 45 + 46 + if (prot_virt_host && !test_facility(158)) { 47 + prot_virt_host = 0; 48 + pr_warn("Protected virtualization not supported by the hardware."); 49 + } 50 + 51 + return rc; 52 + } 53 + early_param("prot_virt", prot_virt_setup); 54 + 55 + static int __init uv_init(unsigned long stor_base, unsigned long stor_len) 56 + { 57 + struct uv_cb_init uvcb = { 58 + .header.cmd = UVC_CMD_INIT_UV, 59 + .header.len = sizeof(uvcb), 60 + .stor_origin = stor_base, 61 + .stor_len = stor_len, 62 + }; 63 + 64 + if (uv_call(0, (uint64_t)&uvcb)) { 65 + pr_err("Ultravisor init failed with rc: 0x%x rrc: 0%x\n", 66 + uvcb.header.rc, uvcb.header.rrc); 67 + return -1; 68 + } 69 + return 0; 70 + } 71 + 72 + void __init setup_uv(void) 73 + { 74 + unsigned long uv_stor_base; 75 + 76 + uv_stor_base = (unsigned long)memblock_alloc_try_nid( 77 + uv_info.uv_base_stor_len, SZ_1M, SZ_2G, 78 + MEMBLOCK_ALLOC_ACCESSIBLE, NUMA_NO_NODE); 79 + if (!uv_stor_base) { 80 + pr_warn("Failed to reserve %lu bytes for ultravisor base storage\n", 81 + uv_info.uv_base_stor_len); 82 + goto fail; 83 + } 84 + 85 + if (uv_init(uv_stor_base, uv_info.uv_base_stor_len)) { 86 + memblock_free(uv_stor_base, uv_info.uv_base_stor_len); 87 + goto fail; 88 + } 89 + 90 + pr_info("Reserving %luMB as ultravisor base storage\n", 91 + uv_info.uv_base_stor_len >> 20); 92 + return; 93 + fail: 94 + pr_info("Disabling support for protected virtualization"); 95 + prot_virt_host = 0; 96 + } 97 + 98 + void adjust_to_uv_max(unsigned long *vmax) 99 + { 100 + *vmax = min_t(unsigned long, *vmax, uv_info.max_sec_stor_addr); 101 + } 102 + 103 + /* 104 + * Requests the Ultravisor to pin the page in the shared state. This will 105 + * cause an intercept when the guest attempts to unshare the pinned page. 106 + */ 107 + static int uv_pin_shared(unsigned long paddr) 108 + { 109 + struct uv_cb_cfs uvcb = { 110 + .header.cmd = UVC_CMD_PIN_PAGE_SHARED, 111 + .header.len = sizeof(uvcb), 112 + .paddr = paddr, 113 + }; 114 + 115 + if (uv_call(0, (u64)&uvcb)) 116 + return -EINVAL; 117 + return 0; 118 + } 119 + 120 + /* 121 + * Requests the Ultravisor to encrypt a guest page and make it 122 + * accessible to the host for paging (export). 123 + * 124 + * @paddr: Absolute host address of page to be exported 125 + */ 126 + int uv_convert_from_secure(unsigned long paddr) 127 + { 128 + struct uv_cb_cfs uvcb = { 129 + .header.cmd = UVC_CMD_CONV_FROM_SEC_STOR, 130 + .header.len = sizeof(uvcb), 131 + .paddr = paddr 132 + }; 133 + 134 + if (uv_call(0, (u64)&uvcb)) 135 + return -EINVAL; 136 + return 0; 137 + } 138 + 139 + /* 140 + * Calculate the expected ref_count for a page that would otherwise have no 141 + * further pins. This was cribbed from similar functions in other places in 142 + * the kernel, but with some slight modifications. We know that a secure 143 + * page can not be a huge page for example. 144 + */ 145 + static int expected_page_refs(struct page *page) 146 + { 147 + int res; 148 + 149 + res = page_mapcount(page); 150 + if (PageSwapCache(page)) { 151 + res++; 152 + } else if (page_mapping(page)) { 153 + res++; 154 + if (page_has_private(page)) 155 + res++; 156 + } 157 + return res; 158 + } 159 + 160 + static int make_secure_pte(pte_t *ptep, unsigned long addr, 161 + struct page *exp_page, struct uv_cb_header *uvcb) 162 + { 163 + pte_t entry = READ_ONCE(*ptep); 164 + struct page *page; 165 + int expected, rc = 0; 166 + 167 + if (!pte_present(entry)) 168 + return -ENXIO; 169 + if (pte_val(entry) & _PAGE_INVALID) 170 + return -ENXIO; 171 + 172 + page = pte_page(entry); 173 + if (page != exp_page) 174 + return -ENXIO; 175 + if (PageWriteback(page)) 176 + return -EAGAIN; 177 + expected = expected_page_refs(page); 178 + if (!page_ref_freeze(page, expected)) 179 + return -EBUSY; 180 + set_bit(PG_arch_1, &page->flags); 181 + rc = uv_call(0, (u64)uvcb); 182 + page_ref_unfreeze(page, expected); 183 + /* Return -ENXIO if the page was not mapped, -EINVAL otherwise */ 184 + if (rc) 185 + rc = uvcb->rc == 0x10a ? -ENXIO : -EINVAL; 186 + return rc; 187 + } 188 + 189 + /* 190 + * Requests the Ultravisor to make a page accessible to a guest. 191 + * If it's brought in the first time, it will be cleared. If 192 + * it has been exported before, it will be decrypted and integrity 193 + * checked. 194 + */ 195 + int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb) 196 + { 197 + struct vm_area_struct *vma; 198 + bool local_drain = false; 199 + spinlock_t *ptelock; 200 + unsigned long uaddr; 201 + struct page *page; 202 + pte_t *ptep; 203 + int rc; 204 + 205 + again: 206 + rc = -EFAULT; 207 + down_read(&gmap->mm->mmap_sem); 208 + 209 + uaddr = __gmap_translate(gmap, gaddr); 210 + if (IS_ERR_VALUE(uaddr)) 211 + goto out; 212 + vma = find_vma(gmap->mm, uaddr); 213 + if (!vma) 214 + goto out; 215 + /* 216 + * Secure pages cannot be huge and userspace should not combine both. 217 + * In case userspace does it anyway this will result in an -EFAULT for 218 + * the unpack. The guest is thus never reaching secure mode. If 219 + * userspace is playing dirty tricky with mapping huge pages later 220 + * on this will result in a segmentation fault. 221 + */ 222 + if (is_vm_hugetlb_page(vma)) 223 + goto out; 224 + 225 + rc = -ENXIO; 226 + page = follow_page(vma, uaddr, FOLL_WRITE); 227 + if (IS_ERR_OR_NULL(page)) 228 + goto out; 229 + 230 + lock_page(page); 231 + ptep = get_locked_pte(gmap->mm, uaddr, &ptelock); 232 + rc = make_secure_pte(ptep, uaddr, page, uvcb); 233 + pte_unmap_unlock(ptep, ptelock); 234 + unlock_page(page); 235 + out: 236 + up_read(&gmap->mm->mmap_sem); 237 + 238 + if (rc == -EAGAIN) { 239 + wait_on_page_writeback(page); 240 + } else if (rc == -EBUSY) { 241 + /* 242 + * If we have tried a local drain and the page refcount 243 + * still does not match our expected safe value, try with a 244 + * system wide drain. This is needed if the pagevecs holding 245 + * the page are on a different CPU. 246 + */ 247 + if (local_drain) { 248 + lru_add_drain_all(); 249 + /* We give up here, and let the caller try again */ 250 + return -EAGAIN; 251 + } 252 + /* 253 + * We are here if the page refcount does not match the 254 + * expected safe value. The main culprits are usually 255 + * pagevecs. With lru_add_drain() we drain the pagevecs 256 + * on the local CPU so that hopefully the refcount will 257 + * reach the expected safe value. 258 + */ 259 + lru_add_drain(); 260 + local_drain = true; 261 + /* And now we try again immediately after draining */ 262 + goto again; 263 + } else if (rc == -ENXIO) { 264 + if (gmap_fault(gmap, gaddr, FAULT_FLAG_WRITE)) 265 + return -EFAULT; 266 + return -EAGAIN; 267 + } 268 + return rc; 269 + } 270 + EXPORT_SYMBOL_GPL(gmap_make_secure); 271 + 272 + int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr) 273 + { 274 + struct uv_cb_cts uvcb = { 275 + .header.cmd = UVC_CMD_CONV_TO_SEC_STOR, 276 + .header.len = sizeof(uvcb), 277 + .guest_handle = gmap->guest_handle, 278 + .gaddr = gaddr, 279 + }; 280 + 281 + return gmap_make_secure(gmap, gaddr, &uvcb); 282 + } 283 + EXPORT_SYMBOL_GPL(gmap_convert_to_secure); 284 + 285 + /* 286 + * To be called with the page locked or with an extra reference! This will 287 + * prevent gmap_make_secure from touching the page concurrently. Having 2 288 + * parallel make_page_accessible is fine, as the UV calls will become a 289 + * no-op if the page is already exported. 290 + */ 291 + int arch_make_page_accessible(struct page *page) 292 + { 293 + int rc = 0; 294 + 295 + /* Hugepage cannot be protected, so nothing to do */ 296 + if (PageHuge(page)) 297 + return 0; 298 + 299 + /* 300 + * PG_arch_1 is used in 3 places: 301 + * 1. for kernel page tables during early boot 302 + * 2. for storage keys of huge pages and KVM 303 + * 3. As an indication that this page might be secure. This can 304 + * overindicate, e.g. we set the bit before calling 305 + * convert_to_secure. 306 + * As secure pages are never huge, all 3 variants can co-exists. 307 + */ 308 + if (!test_bit(PG_arch_1, &page->flags)) 309 + return 0; 310 + 311 + rc = uv_pin_shared(page_to_phys(page)); 312 + if (!rc) { 313 + clear_bit(PG_arch_1, &page->flags); 314 + return 0; 315 + } 316 + 317 + rc = uv_convert_from_secure(page_to_phys(page)); 318 + if (!rc) { 319 + clear_bit(PG_arch_1, &page->flags); 320 + return 0; 321 + } 322 + 323 + return rc; 324 + } 325 + EXPORT_SYMBOL_GPL(arch_make_page_accessible); 326 + 327 + #endif 328 + 329 + #if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM) 330 + static ssize_t uv_query_facilities(struct kobject *kobj, 331 + struct kobj_attribute *attr, char *page) 332 + { 333 + return snprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n", 334 + uv_info.inst_calls_list[0], 335 + uv_info.inst_calls_list[1], 336 + uv_info.inst_calls_list[2], 337 + uv_info.inst_calls_list[3]); 338 + } 339 + 340 + static struct kobj_attribute uv_query_facilities_attr = 341 + __ATTR(facilities, 0444, uv_query_facilities, NULL); 342 + 343 + static ssize_t uv_query_max_guest_cpus(struct kobject *kobj, 344 + struct kobj_attribute *attr, char *page) 345 + { 346 + return snprintf(page, PAGE_SIZE, "%d\n", 347 + uv_info.max_guest_cpus); 348 + } 349 + 350 + static struct kobj_attribute uv_query_max_guest_cpus_attr = 351 + __ATTR(max_cpus, 0444, uv_query_max_guest_cpus, NULL); 352 + 353 + static ssize_t uv_query_max_guest_vms(struct kobject *kobj, 354 + struct kobj_attribute *attr, char *page) 355 + { 356 + return snprintf(page, PAGE_SIZE, "%d\n", 357 + uv_info.max_num_sec_conf); 358 + } 359 + 360 + static struct kobj_attribute uv_query_max_guest_vms_attr = 361 + __ATTR(max_guests, 0444, uv_query_max_guest_vms, NULL); 362 + 363 + static ssize_t uv_query_max_guest_addr(struct kobject *kobj, 364 + struct kobj_attribute *attr, char *page) 365 + { 366 + return snprintf(page, PAGE_SIZE, "%lx\n", 367 + uv_info.max_sec_stor_addr); 368 + } 369 + 370 + static struct kobj_attribute uv_query_max_guest_addr_attr = 371 + __ATTR(max_address, 0444, uv_query_max_guest_addr, NULL); 372 + 373 + static struct attribute *uv_query_attrs[] = { 374 + &uv_query_facilities_attr.attr, 375 + &uv_query_max_guest_cpus_attr.attr, 376 + &uv_query_max_guest_vms_attr.attr, 377 + &uv_query_max_guest_addr_attr.attr, 378 + NULL, 379 + }; 380 + 381 + static struct attribute_group uv_query_attr_group = { 382 + .attrs = uv_query_attrs, 383 + }; 384 + 385 + static struct kset *uv_query_kset; 386 + static struct kobject *uv_kobj; 387 + 388 + static int __init uv_info_init(void) 389 + { 390 + int rc = -ENOMEM; 391 + 392 + if (!test_facility(158)) 393 + return 0; 394 + 395 + uv_kobj = kobject_create_and_add("uv", firmware_kobj); 396 + if (!uv_kobj) 397 + return -ENOMEM; 398 + 399 + uv_query_kset = kset_create_and_add("query", NULL, uv_kobj); 400 + if (!uv_query_kset) 401 + goto out_kobj; 402 + 403 + rc = sysfs_create_group(&uv_query_kset->kobj, &uv_query_attr_group); 404 + if (!rc) 405 + return 0; 406 + 407 + kset_unregister(uv_query_kset); 408 + out_kobj: 409 + kobject_del(uv_kobj); 410 + kobject_put(uv_kobj); 411 + return rc; 412 + } 413 + device_initcall(uv_info_init); 414 + #endif
+78
arch/s390/mm/fault.c
··· 38 38 #include <asm/irq.h> 39 39 #include <asm/mmu_context.h> 40 40 #include <asm/facility.h> 41 + #include <asm/uv.h> 41 42 #include "../kernel/entry.h" 42 43 43 44 #define __FAIL_ADDR_MASK -4096L ··· 817 816 early_initcall(pfault_irq_init); 818 817 819 818 #endif /* CONFIG_PFAULT */ 819 + 820 + #if IS_ENABLED(CONFIG_PGSTE) 821 + void do_secure_storage_access(struct pt_regs *regs) 822 + { 823 + unsigned long addr = regs->int_parm_long & __FAIL_ADDR_MASK; 824 + struct vm_area_struct *vma; 825 + struct mm_struct *mm; 826 + struct page *page; 827 + int rc; 828 + 829 + switch (get_fault_type(regs)) { 830 + case USER_FAULT: 831 + mm = current->mm; 832 + down_read(&mm->mmap_sem); 833 + vma = find_vma(mm, addr); 834 + if (!vma) { 835 + up_read(&mm->mmap_sem); 836 + do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP); 837 + break; 838 + } 839 + page = follow_page(vma, addr, FOLL_WRITE | FOLL_GET); 840 + if (IS_ERR_OR_NULL(page)) { 841 + up_read(&mm->mmap_sem); 842 + break; 843 + } 844 + if (arch_make_page_accessible(page)) 845 + send_sig(SIGSEGV, current, 0); 846 + put_page(page); 847 + up_read(&mm->mmap_sem); 848 + break; 849 + case KERNEL_FAULT: 850 + page = phys_to_page(addr); 851 + if (unlikely(!try_get_page(page))) 852 + break; 853 + rc = arch_make_page_accessible(page); 854 + put_page(page); 855 + if (rc) 856 + BUG(); 857 + break; 858 + case VDSO_FAULT: 859 + /* fallthrough */ 860 + case GMAP_FAULT: 861 + /* fallthrough */ 862 + default: 863 + do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP); 864 + WARN_ON_ONCE(1); 865 + } 866 + } 867 + NOKPROBE_SYMBOL(do_secure_storage_access); 868 + 869 + void do_non_secure_storage_access(struct pt_regs *regs) 870 + { 871 + unsigned long gaddr = regs->int_parm_long & __FAIL_ADDR_MASK; 872 + struct gmap *gmap = (struct gmap *)S390_lowcore.gmap; 873 + 874 + if (get_fault_type(regs) != GMAP_FAULT) { 875 + do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP); 876 + WARN_ON_ONCE(1); 877 + return; 878 + } 879 + 880 + if (gmap_convert_to_secure(gmap, gaddr) == -EINVAL) 881 + send_sig(SIGSEGV, current, 0); 882 + } 883 + NOKPROBE_SYMBOL(do_non_secure_storage_access); 884 + 885 + #else 886 + void do_secure_storage_access(struct pt_regs *regs) 887 + { 888 + default_trap_handler(regs); 889 + } 890 + 891 + void do_non_secure_storage_access(struct pt_regs *regs) 892 + { 893 + default_trap_handler(regs); 894 + } 895 + #endif