1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2004, 2013 Intel Corporation 4 * Author: Naveen B S <naveen.b.s@intel.com> 5 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> 6 * 7 * All rights reserved. 8 * 9 * ACPI based HotPlug driver that supports Memory Hotplug 10 * This driver fields notifications from firmware for memory add 11 * and remove operations and alerts the VM of the affected memory 12 * ranges. 13 */ 14 15 #include <linux/acpi.h> 16 #include <linux/memory.h> 17 #include <linux/memory_hotplug.h> 18 19 #include "internal.h" 20 21 #define ACPI_MEMORY_DEVICE_HID "PNP0C80" 22 23 static const struct acpi_device_id memory_device_ids[] = { 24 {ACPI_MEMORY_DEVICE_HID, 0}, 25 {"", 0}, 26 }; 27 28 #ifdef CONFIG_ACPI_HOTPLUG_MEMORY 29 30 static int acpi_memory_device_add(struct acpi_device *device, 31 const struct acpi_device_id *not_used); 32 static void acpi_memory_device_remove(struct acpi_device *device); 33 34 static struct acpi_scan_handler memory_device_handler = { 35 .ids = memory_device_ids, 36 .attach = acpi_memory_device_add, 37 .detach = acpi_memory_device_remove, 38 .hotplug = { 39 .enabled = true, 40 }, 41 }; 42 43 struct acpi_memory_info { 44 struct list_head list; 45 u64 start_addr; /* Memory Range start physical addr */ 46 u64 length; /* Memory Range length */ 47 unsigned short caching; /* memory cache attribute */ 48 unsigned short write_protect; /* memory read/write attribute */ 49 unsigned int enabled:1; 50 }; 51 52 struct acpi_memory_device { 53 struct acpi_device *device; 54 struct list_head res_list; 55 int mgid; 56 }; 57 58 static acpi_status 59 acpi_memory_get_resource(struct acpi_resource *resource, void *context) 60 { 61 struct acpi_memory_device *mem_device = context; 62 struct acpi_resource_address64 address64; 63 struct acpi_memory_info *info, *new; 64 acpi_status status; 65 66 status = acpi_resource_to_address64(resource, &address64); 67 if (ACPI_FAILURE(status) || 68 (address64.resource_type != ACPI_MEMORY_RANGE)) 69 return AE_OK; 70 71 list_for_each_entry(info, &mem_device->res_list, list) { 72 /* Can we combine the resource range information? */ 73 if ((info->caching == address64.info.mem.caching) && 74 (info->write_protect == address64.info.mem.write_protect) && 75 (info->start_addr + info->length == address64.address.minimum)) { 76 info->length += address64.address.address_length; 77 return AE_OK; 78 } 79 } 80 81 new = kzalloc_obj(struct acpi_memory_info); 82 if (!new) 83 return AE_ERROR; 84 85 INIT_LIST_HEAD(&new->list); 86 new->caching = address64.info.mem.caching; 87 new->write_protect = address64.info.mem.write_protect; 88 new->start_addr = address64.address.minimum; 89 new->length = address64.address.address_length; 90 list_add_tail(&new->list, &mem_device->res_list); 91 92 return AE_OK; 93 } 94 95 static void 96 acpi_memory_free_device_resources(struct acpi_memory_device *mem_device) 97 { 98 struct acpi_memory_info *info, *n; 99 100 list_for_each_entry_safe(info, n, &mem_device->res_list, list) 101 kfree(info); 102 INIT_LIST_HEAD(&mem_device->res_list); 103 } 104 105 static int 106 acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) 107 { 108 acpi_status status; 109 110 if (!list_empty(&mem_device->res_list)) 111 return 0; 112 113 status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, 114 acpi_memory_get_resource, mem_device); 115 if (ACPI_FAILURE(status)) { 116 acpi_memory_free_device_resources(mem_device); 117 return -EINVAL; 118 } 119 120 return 0; 121 } 122 123 static int acpi_memory_check_device(struct acpi_memory_device *mem_device) 124 { 125 unsigned long long current_status; 126 127 /* Get device present/absent information from the _STA */ 128 if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, 129 METHOD_NAME__STA, NULL, 130 ¤t_status))) 131 return -ENODEV; 132 /* 133 * Check for device status. Device should be 134 * present/enabled/functioning. 135 */ 136 if (!((current_status & ACPI_STA_DEVICE_PRESENT) 137 && (current_status & ACPI_STA_DEVICE_ENABLED) 138 && (current_status & ACPI_STA_DEVICE_FUNCTIONING))) 139 return -ENODEV; 140 141 return 0; 142 } 143 144 static int acpi_bind_memblk(struct memory_block *mem, void *arg) 145 { 146 return acpi_bind_one(&mem->dev, arg); 147 } 148 149 static int acpi_bind_memory_blocks(struct acpi_memory_info *info, 150 struct acpi_device *adev) 151 { 152 return walk_memory_blocks(info->start_addr, info->length, adev, 153 acpi_bind_memblk); 154 } 155 156 static int acpi_unbind_memblk(struct memory_block *mem, void *arg) 157 { 158 acpi_unbind_one(&mem->dev); 159 return 0; 160 } 161 162 static void acpi_unbind_memory_blocks(struct acpi_memory_info *info) 163 { 164 walk_memory_blocks(info->start_addr, info->length, NULL, 165 acpi_unbind_memblk); 166 } 167 168 static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) 169 { 170 acpi_handle handle = mem_device->device->handle; 171 mhp_t mhp_flags = MHP_NID_IS_MGID; 172 int result, num_enabled = 0; 173 struct acpi_memory_info *info; 174 u64 total_length = 0; 175 int node, mgid; 176 177 node = acpi_get_node(handle); 178 179 list_for_each_entry(info, &mem_device->res_list, list) { 180 if (!info->length) 181 continue; 182 /* We want a single node for the whole memory group */ 183 if (node < 0) 184 node = memory_add_physaddr_to_nid(info->start_addr); 185 total_length += info->length; 186 } 187 188 if (!total_length) { 189 dev_err(&mem_device->device->dev, "device is empty\n"); 190 return -EINVAL; 191 } 192 193 mgid = memory_group_register_static(node, PFN_UP(total_length)); 194 if (mgid < 0) 195 return mgid; 196 mem_device->mgid = mgid; 197 198 /* 199 * Tell the VM there is more memory here... 200 * Note: Assume that this function returns zero on success 201 * We don't have memory-hot-add rollback function,now. 202 * (i.e. memory-hot-remove function) 203 */ 204 list_for_each_entry(info, &mem_device->res_list, list) { 205 /* 206 * If the memory block size is zero, please ignore it. 207 * Don't try to do the following memory hotplug flowchart. 208 */ 209 if (!info->length) 210 continue; 211 212 mhp_flags |= MHP_MEMMAP_ON_MEMORY; 213 result = __add_memory(mgid, info->start_addr, info->length, 214 mhp_flags); 215 216 /* 217 * If the memory block has been used by the kernel, add_memory() 218 * returns -EEXIST. If add_memory() returns the other error, it 219 * means that this memory block is not used by the kernel. 220 */ 221 if (result && result != -EEXIST) 222 continue; 223 224 result = acpi_bind_memory_blocks(info, mem_device->device); 225 if (result) { 226 acpi_unbind_memory_blocks(info); 227 return -ENODEV; 228 } 229 230 info->enabled = 1; 231 232 /* 233 * Add num_enable even if add_memory() returns -EEXIST, so the 234 * device is bound to this driver. 235 */ 236 num_enabled++; 237 } 238 if (!num_enabled) { 239 dev_err(&mem_device->device->dev, "add_memory failed\n"); 240 return -EINVAL; 241 } 242 /* 243 * Sometimes the memory device will contain several memory blocks. 244 * When one memory block is hot-added to the system memory, it will 245 * be regarded as a success. 246 * Otherwise if the last memory block can't be hot-added to the system 247 * memory, it will be failure and the memory device can't be bound with 248 * driver. 249 */ 250 return 0; 251 } 252 253 static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device) 254 { 255 struct acpi_memory_info *info, *n; 256 257 list_for_each_entry_safe(info, n, &mem_device->res_list, list) { 258 if (!info->enabled) 259 continue; 260 261 acpi_unbind_memory_blocks(info); 262 __remove_memory(info->start_addr, info->length); 263 list_del(&info->list); 264 kfree(info); 265 } 266 } 267 268 static void acpi_memory_device_free(struct acpi_memory_device *mem_device) 269 { 270 if (!mem_device) 271 return; 272 273 /* In case we succeeded adding *some* memory, unregistering fails. */ 274 if (mem_device->mgid >= 0) 275 memory_group_unregister(mem_device->mgid); 276 277 acpi_memory_free_device_resources(mem_device); 278 mem_device->device->driver_data = NULL; 279 kfree(mem_device); 280 } 281 282 static int acpi_memory_device_add(struct acpi_device *device, 283 const struct acpi_device_id *not_used) 284 { 285 struct acpi_memory_device *mem_device; 286 int result; 287 288 if (!device) 289 return -EINVAL; 290 291 mem_device = kzalloc_obj(struct acpi_memory_device); 292 if (!mem_device) 293 return -ENOMEM; 294 295 INIT_LIST_HEAD(&mem_device->res_list); 296 mem_device->device = device; 297 mem_device->mgid = -1; 298 device->driver_data = mem_device; 299 300 /* Get the range from the _CRS */ 301 result = acpi_memory_get_device_resources(mem_device); 302 if (result) { 303 device->driver_data = NULL; 304 kfree(mem_device); 305 return result; 306 } 307 308 result = acpi_memory_check_device(mem_device); 309 if (result) { 310 acpi_memory_device_free(mem_device); 311 return 0; 312 } 313 314 result = acpi_memory_enable_device(mem_device); 315 if (result) { 316 dev_err(&device->dev, "acpi_memory_enable_device() error\n"); 317 acpi_memory_device_free(mem_device); 318 return result; 319 } 320 321 dev_dbg(&device->dev, "Memory device configured by ACPI\n"); 322 return 1; 323 } 324 325 static void acpi_memory_device_remove(struct acpi_device *device) 326 { 327 struct acpi_memory_device *mem_device; 328 329 if (!device || !acpi_driver_data(device)) 330 return; 331 332 mem_device = acpi_driver_data(device); 333 acpi_memory_remove_memory(mem_device); 334 acpi_memory_device_free(mem_device); 335 } 336 337 static bool __initdata acpi_no_memhotplug; 338 339 void __init acpi_memory_hotplug_init(void) 340 { 341 if (acpi_no_memhotplug) { 342 memory_device_handler.attach = NULL; 343 acpi_scan_add_handler(&memory_device_handler); 344 return; 345 } 346 acpi_scan_add_handler_with_hotplug(&memory_device_handler, "memory"); 347 } 348 349 static int __init disable_acpi_memory_hotplug(char *str) 350 { 351 acpi_no_memhotplug = true; 352 return 1; 353 } 354 __setup("acpi_no_memhotplug", disable_acpi_memory_hotplug); 355 356 #else 357 358 static struct acpi_scan_handler memory_device_handler = { 359 .ids = memory_device_ids, 360 }; 361 362 void __init acpi_memory_hotplug_init(void) 363 { 364 acpi_scan_add_handler(&memory_device_handler); 365 } 366 367 #endif /* CONFIG_ACPI_HOTPLUG_MEMORY */ 368