1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2023 ARM Ltd. 4 */ 5 6 #include <linux/jump_label.h> 7 #include <linux/memblock.h> 8 #include <linux/psci.h> 9 #include <linux/swiotlb.h> 10 #include <linux/cc_platform.h> 11 12 #include <asm/io.h> 13 #include <asm/mem_encrypt.h> 14 #include <asm/rsi.h> 15 16 static struct realm_config config; 17 18 unsigned long prot_ns_shared; 19 EXPORT_SYMBOL(prot_ns_shared); 20 21 DEFINE_STATIC_KEY_FALSE_RO(rsi_present); 22 EXPORT_SYMBOL(rsi_present); 23 24 bool cc_platform_has(enum cc_attr attr) 25 { 26 switch (attr) { 27 case CC_ATTR_MEM_ENCRYPT: 28 return is_realm_world(); 29 default: 30 return false; 31 } 32 } 33 EXPORT_SYMBOL_GPL(cc_platform_has); 34 35 static bool rsi_version_matches(void) 36 { 37 unsigned long ver_lower, ver_higher; 38 unsigned long ret = rsi_request_version(RSI_ABI_VERSION, 39 &ver_lower, 40 &ver_higher); 41 42 if (ret == SMCCC_RET_NOT_SUPPORTED) 43 return false; 44 45 if (ret != RSI_SUCCESS) { 46 pr_err("RME: RMM doesn't support RSI version %lu.%lu. Supported range: %lu.%lu-%lu.%lu\n", 47 RSI_ABI_VERSION_MAJOR, RSI_ABI_VERSION_MINOR, 48 RSI_ABI_VERSION_GET_MAJOR(ver_lower), 49 RSI_ABI_VERSION_GET_MINOR(ver_lower), 50 RSI_ABI_VERSION_GET_MAJOR(ver_higher), 51 RSI_ABI_VERSION_GET_MINOR(ver_higher)); 52 return false; 53 } 54 55 pr_info("RME: Using RSI version %lu.%lu\n", 56 RSI_ABI_VERSION_GET_MAJOR(ver_lower), 57 RSI_ABI_VERSION_GET_MINOR(ver_lower)); 58 59 return true; 60 } 61 62 static void __init arm64_rsi_setup_memory(void) 63 { 64 u64 i; 65 phys_addr_t start, end; 66 67 /* 68 * Iterate over the available memory ranges and convert the state to 69 * protected memory. We should take extra care to ensure that we DO NOT 70 * permit any "DESTROYED" pages to be converted to "RAM". 71 * 72 * panic() is used because if the attempt to switch the memory to 73 * protected has failed here, then future accesses to the memory are 74 * simply going to be reflected as a SEA (Synchronous External Abort) 75 * which we can't handle. Bailing out early prevents the guest limping 76 * on and dying later. 77 */ 78 for_each_mem_range(i, &start, &end) { 79 if (rsi_set_memory_range_protected_safe(start, end)) { 80 panic("Failed to set memory range to protected: %pa-%pa", 81 &start, &end); 82 } 83 } 84 } 85 86 bool __arm64_is_protected_mmio(phys_addr_t base, size_t size) 87 { 88 enum ripas ripas; 89 phys_addr_t end, top; 90 91 /* Overflow ? */ 92 if (WARN_ON(base + size <= base)) 93 return false; 94 95 end = ALIGN(base + size, RSI_GRANULE_SIZE); 96 base = ALIGN_DOWN(base, RSI_GRANULE_SIZE); 97 98 while (base < end) { 99 if (WARN_ON(rsi_ipa_state_get(base, end, &ripas, &top))) 100 break; 101 if (WARN_ON(top <= base)) 102 break; 103 if (ripas != RSI_RIPAS_DEV) 104 break; 105 base = top; 106 } 107 108 return base >= end; 109 } 110 EXPORT_SYMBOL(__arm64_is_protected_mmio); 111 112 static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot) 113 { 114 if (__arm64_is_protected_mmio(phys, size)) 115 *prot = pgprot_encrypted(*prot); 116 else 117 *prot = pgprot_decrypted(*prot); 118 119 return 0; 120 } 121 122 void __init arm64_rsi_init(void) 123 { 124 if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC) 125 return; 126 if (!rsi_version_matches()) 127 return; 128 if (WARN_ON(rsi_get_realm_config(&config))) 129 return; 130 prot_ns_shared = BIT(config.ipa_bits - 1); 131 132 if (arm64_ioremap_prot_hook_register(realm_ioremap_hook)) 133 return; 134 135 if (realm_register_memory_enc_ops()) 136 return; 137 138 arm64_rsi_setup_memory(); 139 140 static_branch_enable(&rsi_present); 141 } 142 143