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