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