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

Merge tag 'cxl-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl

Pull cxl updates from Dan Williams:
"Compute Express Link (CXL) updates for this cycle.

The highlight is new driver-core infrastructure and CXL subsystem
changes for allowing lockdep to validate device_lock() usage. Thanks
to PeterZ for setting me straight on the current capabilities of the
lockdep API, and Greg acked it as well.

On the CXL ACPI side this update adds support for CXL _OSC so that
platform firmware knows that it is safe to still grant Linux native
control of PCIe hotplug and error handling in the presence of CXL
devices. A circular dependency problem was discovered between suspend
and CXL memory for cases where the suspend image might be stored in
CXL memory where that image also contains the PCI register state to
restore to re-enable the device. Disable suspend for now until an
architecture is defined to clarify that conflict.

Lastly a collection of reworks, fixes, and cleanups to the CXL
subsystem where support for snooping mailbox commands and properly
handling the "mem_enable" flow are the highlights.

Summary:

- Add driver-core infrastructure for lockdep validation of
device_lock(), and fixup a deadlock report that was previously
hidden behind the 'lockdep no validate' policy.

- Add CXL _OSC support for claiming native control of CXL hotplug and
error handling.

- Disable suspend in the presence of CXL memory unless and until a
protocol is identified for restoring PCI device context from memory
hosted on CXL PCI devices.

- Add support for snooping CXL mailbox commands to protect against
inopportune changes, like set-partition with the 'immediate' flag
set.

- Rework how the driver detects legacy CXL 1.1 configurations (CXL
DVSEC / 'mem_enable') before enabling new CXL 2.0 decode
configurations (CXL HDM Capability).

- Miscellaneous cleanups and fixes from -next exposure"

* tag 'cxl-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: (47 commits)
cxl/port: Enable HDM Capability after validating DVSEC Ranges
cxl/port: Reuse 'struct cxl_hdm' context for hdm init
cxl/port: Move endpoint HDM Decoder Capability init to port driver
cxl/pci: Drop @info argument to cxl_hdm_decode_init()
cxl/mem: Merge cxl_dvsec_ranges() and cxl_hdm_decode_init()
cxl/mem: Skip range enumeration if mem_enable clear
cxl/mem: Consolidate CXL DVSEC Range enumeration in the core
cxl/pci: Move cxl_await_media_ready() to the core
cxl/mem: Validate port connectivity before dvsec ranges
cxl/mem: Fix cxl_mem_probe() error exit
cxl/pci: Drop wait_for_valid() from cxl_await_media_ready()
cxl/pci: Consolidate wait_for_media() and wait_for_media_ready()
cxl/mem: Drop mem_enabled check from wait_for_media()
nvdimm: Fix firmware activation deadlock scenarios
device-core: Kill the lockdep_mutex
nvdimm: Drop nd_device_lock()
ACPI: NFIT: Drop nfit_device_lock()
nvdimm: Replace lockdep_mutex with local lock classes
cxl: Drop cxl_device_lock()
cxl/acpi: Add root device lockdep validation
...

+1282 -879
+1 -1
drivers/Makefile
··· 72 72 obj-y += base/ block/ misc/ mfd/ nfc/ 73 73 obj-$(CONFIG_LIBNVDIMM) += nvdimm/ 74 74 obj-$(CONFIG_DAX) += dax/ 75 - obj-$(CONFIG_CXL_BUS) += cxl/ 76 75 obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/ 77 76 obj-$(CONFIG_NUBUS) += nubus/ 77 + obj-y += cxl/ 78 78 obj-y += macintosh/ 79 79 obj-y += scsi/ 80 80 obj-y += nvme/
+1 -1
drivers/acpi/bus.c
··· 443 443 } 444 444 445 445 osc_sb_native_usb4_control = 446 - control & ((u32 *)context.ret.pointer)[OSC_CONTROL_DWORD]; 446 + control & acpi_osc_ctx_get_pci_control(&context); 447 447 448 448 acpi_bus_decode_usb_osc("USB4 _OSC: OS supports", control); 449 449 acpi_bus_decode_usb_osc("USB4 _OSC: OS controls",
+15 -15
drivers/acpi/nfit/core.c
··· 1230 1230 if (rc) 1231 1231 return rc; 1232 1232 1233 - nfit_device_lock(dev); 1233 + device_lock(dev); 1234 1234 nd_desc = dev_get_drvdata(dev); 1235 1235 if (nd_desc) { 1236 1236 struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); ··· 1247 1247 break; 1248 1248 } 1249 1249 } 1250 - nfit_device_unlock(dev); 1250 + device_unlock(dev); 1251 1251 if (rc) 1252 1252 return rc; 1253 1253 return size; ··· 1267 1267 ssize_t rc = -ENXIO; 1268 1268 bool busy; 1269 1269 1270 - nfit_device_lock(dev); 1270 + device_lock(dev); 1271 1271 nd_desc = dev_get_drvdata(dev); 1272 1272 if (!nd_desc) { 1273 - nfit_device_unlock(dev); 1273 + device_unlock(dev); 1274 1274 return rc; 1275 1275 } 1276 1276 acpi_desc = to_acpi_desc(nd_desc); ··· 1287 1287 } 1288 1288 1289 1289 mutex_unlock(&acpi_desc->init_mutex); 1290 - nfit_device_unlock(dev); 1290 + device_unlock(dev); 1291 1291 return rc; 1292 1292 } 1293 1293 ··· 1304 1304 if (val != 1) 1305 1305 return -EINVAL; 1306 1306 1307 - nfit_device_lock(dev); 1307 + device_lock(dev); 1308 1308 nd_desc = dev_get_drvdata(dev); 1309 1309 if (nd_desc) { 1310 1310 struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); 1311 1311 1312 1312 rc = acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_LONG); 1313 1313 } 1314 - nfit_device_unlock(dev); 1314 + device_unlock(dev); 1315 1315 if (rc) 1316 1316 return rc; 1317 1317 return size; ··· 1697 1697 struct acpi_device *adev = data; 1698 1698 struct device *dev = &adev->dev; 1699 1699 1700 - nfit_device_lock(dev->parent); 1700 + device_lock(dev->parent); 1701 1701 __acpi_nvdimm_notify(dev, event); 1702 - nfit_device_unlock(dev->parent); 1702 + device_unlock(dev->parent); 1703 1703 } 1704 1704 1705 1705 static bool acpi_nvdimm_has_method(struct acpi_device *adev, char *method) ··· 3152 3152 struct device *dev = acpi_desc->dev; 3153 3153 3154 3154 /* Bounce the device lock to flush acpi_nfit_add / acpi_nfit_notify */ 3155 - nfit_device_lock(dev); 3156 - nfit_device_unlock(dev); 3155 + device_lock(dev); 3156 + device_unlock(dev); 3157 3157 3158 3158 /* Bounce the init_mutex to complete initial registration */ 3159 3159 mutex_lock(&acpi_desc->init_mutex); ··· 3305 3305 * acpi_nfit_ars_rescan() submissions have had a chance to 3306 3306 * either submit or see ->cancel set. 3307 3307 */ 3308 - nfit_device_lock(bus_dev); 3309 - nfit_device_unlock(bus_dev); 3308 + device_lock(bus_dev); 3309 + device_unlock(bus_dev); 3310 3310 3311 3311 flush_workqueue(nfit_wq); 3312 3312 } ··· 3449 3449 3450 3450 static void acpi_nfit_notify(struct acpi_device *adev, u32 event) 3451 3451 { 3452 - nfit_device_lock(&adev->dev); 3452 + device_lock(&adev->dev); 3453 3453 __acpi_nfit_notify(&adev->dev, adev->handle, event); 3454 - nfit_device_unlock(&adev->dev); 3454 + device_unlock(&adev->dev); 3455 3455 } 3456 3456 3457 3457 static const struct acpi_device_id acpi_nfit_ids[] = {
-24
drivers/acpi/nfit/nfit.h
··· 337 337 return container_of(nd_desc, struct acpi_nfit_desc, nd_desc); 338 338 } 339 339 340 - #ifdef CONFIG_PROVE_LOCKING 341 - static inline void nfit_device_lock(struct device *dev) 342 - { 343 - device_lock(dev); 344 - mutex_lock(&dev->lockdep_mutex); 345 - } 346 - 347 - static inline void nfit_device_unlock(struct device *dev) 348 - { 349 - mutex_unlock(&dev->lockdep_mutex); 350 - device_unlock(dev); 351 - } 352 - #else 353 - static inline void nfit_device_lock(struct device *dev) 354 - { 355 - device_lock(dev); 356 - } 357 - 358 - static inline void nfit_device_unlock(struct device *dev) 359 - { 360 - device_unlock(dev); 361 - } 362 - #endif 363 - 364 340 const guid_t *to_nfit_uuid(enum nfit_uuids id); 365 341 int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz); 366 342 void acpi_nfit_shutdown(void *data);
+210 -30
drivers/acpi/pci_root.c
··· 140 140 { OSC_PCI_EXPRESS_DPC_CONTROL, "DPC" }, 141 141 }; 142 142 143 + static struct pci_osc_bit_struct cxl_osc_support_bit[] = { 144 + { OSC_CXL_1_1_PORT_REG_ACCESS_SUPPORT, "CXL11PortRegAccess" }, 145 + { OSC_CXL_2_0_PORT_DEV_REG_ACCESS_SUPPORT, "CXL20PortDevRegAccess" }, 146 + { OSC_CXL_PROTOCOL_ERR_REPORTING_SUPPORT, "CXLProtocolErrorReporting" }, 147 + { OSC_CXL_NATIVE_HP_SUPPORT, "CXLNativeHotPlug" }, 148 + }; 149 + 150 + static struct pci_osc_bit_struct cxl_osc_control_bit[] = { 151 + { OSC_CXL_ERROR_REPORTING_CONTROL, "CXLMemErrorReporting" }, 152 + }; 153 + 143 154 static void decode_osc_bits(struct acpi_pci_root *root, char *msg, u32 word, 144 155 struct pci_osc_bit_struct *table, int size) 145 156 { ··· 179 168 ARRAY_SIZE(pci_osc_control_bit)); 180 169 } 181 170 182 - static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; 171 + static void decode_cxl_osc_support(struct acpi_pci_root *root, char *msg, u32 word) 172 + { 173 + decode_osc_bits(root, msg, word, cxl_osc_support_bit, 174 + ARRAY_SIZE(cxl_osc_support_bit)); 175 + } 183 176 184 - static acpi_status acpi_pci_run_osc(acpi_handle handle, 185 - const u32 *capbuf, u32 *retval) 177 + static void decode_cxl_osc_control(struct acpi_pci_root *root, char *msg, u32 word) 178 + { 179 + decode_osc_bits(root, msg, word, cxl_osc_control_bit, 180 + ARRAY_SIZE(cxl_osc_control_bit)); 181 + } 182 + 183 + static inline bool is_pcie(struct acpi_pci_root *root) 184 + { 185 + return root->bridge_type == ACPI_BRIDGE_TYPE_PCIE; 186 + } 187 + 188 + static inline bool is_cxl(struct acpi_pci_root *root) 189 + { 190 + return root->bridge_type == ACPI_BRIDGE_TYPE_CXL; 191 + } 192 + 193 + static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; 194 + static u8 cxl_osc_uuid_str[] = "68F2D50B-C469-4d8A-BD3D-941A103FD3FC"; 195 + 196 + static char *to_uuid(struct acpi_pci_root *root) 197 + { 198 + if (is_cxl(root)) 199 + return cxl_osc_uuid_str; 200 + return pci_osc_uuid_str; 201 + } 202 + 203 + static int cap_length(struct acpi_pci_root *root) 204 + { 205 + if (is_cxl(root)) 206 + return sizeof(u32) * OSC_CXL_CAPABILITY_DWORDS; 207 + return sizeof(u32) * OSC_PCI_CAPABILITY_DWORDS; 208 + } 209 + 210 + static acpi_status acpi_pci_run_osc(struct acpi_pci_root *root, 211 + const u32 *capbuf, u32 *pci_control, 212 + u32 *cxl_control) 186 213 { 187 214 struct acpi_osc_context context = { 188 - .uuid_str = pci_osc_uuid_str, 215 + .uuid_str = to_uuid(root), 189 216 .rev = 1, 190 - .cap.length = 12, 217 + .cap.length = cap_length(root), 191 218 .cap.pointer = (void *)capbuf, 192 219 }; 193 220 acpi_status status; 194 221 195 - status = acpi_run_osc(handle, &context); 222 + status = acpi_run_osc(root->device->handle, &context); 196 223 if (ACPI_SUCCESS(status)) { 197 - *retval = *((u32 *)(context.ret.pointer + 8)); 224 + *pci_control = acpi_osc_ctx_get_pci_control(&context); 225 + if (is_cxl(root)) 226 + *cxl_control = acpi_osc_ctx_get_cxl_control(&context); 198 227 kfree(context.ret.pointer); 199 228 } 200 229 return status; 201 230 } 202 231 203 - static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, 204 - u32 support, 205 - u32 *control) 232 + static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 support, 233 + u32 *control, u32 cxl_support, 234 + u32 *cxl_control) 206 235 { 207 236 acpi_status status; 208 - u32 result, capbuf[3]; 237 + u32 pci_result, cxl_result, capbuf[OSC_CXL_CAPABILITY_DWORDS]; 209 238 210 239 support |= root->osc_support_set; 211 240 ··· 253 202 capbuf[OSC_SUPPORT_DWORD] = support; 254 203 capbuf[OSC_CONTROL_DWORD] = *control | root->osc_control_set; 255 204 256 - status = acpi_pci_run_osc(root->device->handle, capbuf, &result); 205 + if (is_cxl(root)) { 206 + cxl_support |= root->osc_ext_support_set; 207 + capbuf[OSC_EXT_SUPPORT_DWORD] = cxl_support; 208 + capbuf[OSC_EXT_CONTROL_DWORD] = *cxl_control | root->osc_ext_control_set; 209 + } 210 + 211 + retry: 212 + status = acpi_pci_run_osc(root, capbuf, &pci_result, &cxl_result); 257 213 if (ACPI_SUCCESS(status)) { 258 214 root->osc_support_set = support; 259 - *control = result; 215 + *control = pci_result; 216 + if (is_cxl(root)) { 217 + root->osc_ext_support_set = cxl_support; 218 + *cxl_control = cxl_result; 219 + } 220 + } else if (is_cxl(root)) { 221 + /* 222 + * CXL _OSC is optional on CXL 1.1 hosts. Fall back to PCIe _OSC 223 + * upon any failure using CXL _OSC. 224 + */ 225 + root->bridge_type = ACPI_BRIDGE_TYPE_PCIE; 226 + goto retry; 260 227 } 261 228 return status; 262 229 } ··· 390 321 * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex). 391 322 * @mask: Mask of _OSC bits to request control of, place to store control mask. 392 323 * @support: _OSC supported capability. 324 + * @cxl_mask: Mask of CXL _OSC control bits, place to store control mask. 325 + * @cxl_support: CXL _OSC supported capability. 393 326 * 394 327 * Run _OSC query for @mask and if that is successful, compare the returned 395 328 * mask of control bits with @req. If all of the @req bits are set in the ··· 402 331 * _OSC bits the BIOS has granted control of, but its contents are meaningless 403 332 * on failure. 404 333 **/ 405 - static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 support) 334 + static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, 335 + u32 support, u32 *cxl_mask, 336 + u32 cxl_support) 406 337 { 407 338 u32 req = OSC_PCI_EXPRESS_CAPABILITY_CONTROL; 408 339 struct acpi_pci_root *root; 409 340 acpi_status status; 410 - u32 ctrl, capbuf[3]; 341 + u32 ctrl, cxl_ctrl = 0, capbuf[OSC_CXL_CAPABILITY_DWORDS]; 411 342 412 343 if (!mask) 413 344 return AE_BAD_PARAMETER; ··· 421 348 ctrl = *mask; 422 349 *mask |= root->osc_control_set; 423 350 351 + if (is_cxl(root)) { 352 + cxl_ctrl = *cxl_mask; 353 + *cxl_mask |= root->osc_ext_control_set; 354 + } 355 + 424 356 /* Need to check the available controls bits before requesting them. */ 425 357 do { 426 - status = acpi_pci_query_osc(root, support, mask); 358 + u32 pci_missing = 0, cxl_missing = 0; 359 + 360 + status = acpi_pci_query_osc(root, support, mask, cxl_support, 361 + cxl_mask); 427 362 if (ACPI_FAILURE(status)) 428 363 return status; 429 - if (ctrl == *mask) 430 - break; 431 - decode_osc_control(root, "platform does not support", 432 - ctrl & ~(*mask)); 364 + if (is_cxl(root)) { 365 + if (ctrl == *mask && cxl_ctrl == *cxl_mask) 366 + break; 367 + pci_missing = ctrl & ~(*mask); 368 + cxl_missing = cxl_ctrl & ~(*cxl_mask); 369 + } else { 370 + if (ctrl == *mask) 371 + break; 372 + pci_missing = ctrl & ~(*mask); 373 + } 374 + if (pci_missing) 375 + decode_osc_control(root, "platform does not support", 376 + pci_missing); 377 + if (cxl_missing) 378 + decode_cxl_osc_control(root, "CXL platform does not support", 379 + cxl_missing); 433 380 ctrl = *mask; 434 - } while (*mask); 381 + cxl_ctrl = *cxl_mask; 382 + } while (*mask || *cxl_mask); 435 383 436 384 /* No need to request _OSC if the control was already granted. */ 437 - if ((root->osc_control_set & ctrl) == ctrl) 385 + if ((root->osc_control_set & ctrl) == ctrl && 386 + (root->osc_ext_control_set & cxl_ctrl) == cxl_ctrl) 438 387 return AE_OK; 439 388 440 389 if ((ctrl & req) != req) { ··· 468 373 capbuf[OSC_QUERY_DWORD] = 0; 469 374 capbuf[OSC_SUPPORT_DWORD] = root->osc_support_set; 470 375 capbuf[OSC_CONTROL_DWORD] = ctrl; 471 - status = acpi_pci_run_osc(handle, capbuf, mask); 376 + if (is_cxl(root)) { 377 + capbuf[OSC_EXT_SUPPORT_DWORD] = root->osc_ext_support_set; 378 + capbuf[OSC_EXT_CONTROL_DWORD] = cxl_ctrl; 379 + } 380 + 381 + status = acpi_pci_run_osc(root, capbuf, mask, cxl_mask); 472 382 if (ACPI_FAILURE(status)) 473 383 return status; 474 384 475 385 root->osc_control_set = *mask; 386 + root->osc_ext_control_set = *cxl_mask; 476 387 return AE_OK; 477 388 } 478 389 ··· 500 399 support |= OSC_PCI_MSI_SUPPORT; 501 400 if (IS_ENABLED(CONFIG_PCIE_EDR)) 502 401 support |= OSC_PCI_EDR_SUPPORT; 402 + 403 + return support; 404 + } 405 + 406 + /* 407 + * Background on hotplug support, and making it depend on only 408 + * CONFIG_HOTPLUG_PCI_PCIE vs. also considering CONFIG_MEMORY_HOTPLUG: 409 + * 410 + * CONFIG_ACPI_HOTPLUG_MEMORY does depend on CONFIG_MEMORY_HOTPLUG, but 411 + * there is no existing _OSC for memory hotplug support. The reason is that 412 + * ACPI memory hotplug requires the OS to acknowledge / coordinate with 413 + * memory plug events via a scan handler. On the CXL side the equivalent 414 + * would be if Linux supported the Mechanical Retention Lock [1], or 415 + * otherwise had some coordination for the driver of a PCI device 416 + * undergoing hotplug to be consulted on whether the hotplug should 417 + * proceed or not. 418 + * 419 + * The concern is that if Linux says no to supporting CXL hotplug then 420 + * the BIOS may say no to giving the OS hotplug control of any other PCIe 421 + * device. So the question here is not whether hotplug is enabled, it's 422 + * whether it is handled natively by the at all OS, and if 423 + * CONFIG_HOTPLUG_PCI_PCIE is enabled then the answer is "yes". 424 + * 425 + * Otherwise, the plan for CXL coordinated remove, since the kernel does 426 + * not support blocking hotplug, is to require the memory device to be 427 + * disabled before hotplug is attempted. When CONFIG_MEMORY_HOTPLUG is 428 + * disabled that step will fail and the remove attempt cancelled by the 429 + * user. If that is not honored and the card is removed anyway then it 430 + * does not matter if CONFIG_MEMORY_HOTPLUG is enabled or not, it will 431 + * cause a crash and other badness. 432 + * 433 + * Therefore, just say yes to CXL hotplug and require removal to 434 + * be coordinated by userspace unless and until the kernel grows better 435 + * mechanisms for doing "managed" removal of devices in consultation with 436 + * the driver. 437 + * 438 + * [1]: https://lore.kernel.org/all/20201122014203.4706-1-ashok.raj@intel.com/ 439 + */ 440 + static u32 calculate_cxl_support(void) 441 + { 442 + u32 support; 443 + 444 + support = OSC_CXL_2_0_PORT_DEV_REG_ACCESS_SUPPORT; 445 + if (pci_aer_available()) 446 + support |= OSC_CXL_PROTOCOL_ERR_REPORTING_SUPPORT; 447 + if (IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)) 448 + support |= OSC_CXL_NATIVE_HP_SUPPORT; 503 449 504 450 return support; 505 451 } ··· 582 434 return control; 583 435 } 584 436 437 + static u32 calculate_cxl_control(void) 438 + { 439 + u32 control = 0; 440 + 441 + if (IS_ENABLED(CONFIG_MEMORY_FAILURE)) 442 + control |= OSC_CXL_ERROR_REPORTING_CONTROL; 443 + 444 + return control; 445 + } 446 + 585 447 static bool os_control_query_checks(struct acpi_pci_root *root, u32 support) 586 448 { 587 449 struct acpi_device *device = root->device; ··· 610 452 return true; 611 453 } 612 454 613 - static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, 614 - bool is_pcie) 455 + static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm) 615 456 { 616 457 u32 support, control = 0, requested = 0; 458 + u32 cxl_support = 0, cxl_control = 0, cxl_requested = 0; 617 459 acpi_status status; 618 460 struct acpi_device *device = root->device; 619 461 acpi_handle handle = device->handle; ··· 637 479 if (os_control_query_checks(root, support)) 638 480 requested = control = calculate_control(); 639 481 640 - status = acpi_pci_osc_control_set(handle, &control, support); 482 + if (is_cxl(root)) { 483 + cxl_support = calculate_cxl_support(); 484 + decode_cxl_osc_support(root, "OS supports", cxl_support); 485 + cxl_requested = cxl_control = calculate_cxl_control(); 486 + } 487 + 488 + status = acpi_pci_osc_control_set(handle, &control, support, 489 + &cxl_control, cxl_support); 641 490 if (ACPI_SUCCESS(status)) { 642 491 if (control) 643 492 decode_osc_control(root, "OS now controls", control); 493 + if (cxl_control) 494 + decode_cxl_osc_control(root, "OS now controls", 495 + cxl_control); 644 496 645 497 if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { 646 498 /* ··· 672 504 *no_aspm = 1; 673 505 674 506 /* _OSC is optional for PCI host bridges */ 675 - if ((status == AE_NOT_FOUND) && !is_pcie) 507 + if (status == AE_NOT_FOUND && !is_pcie(root)) 676 508 return; 677 509 678 510 if (control) { 679 511 decode_osc_control(root, "OS requested", requested); 680 512 decode_osc_control(root, "platform willing to grant", control); 513 + } 514 + if (cxl_control) { 515 + decode_cxl_osc_control(root, "OS requested", cxl_requested); 516 + decode_cxl_osc_control(root, "platform willing to grant", 517 + cxl_control); 681 518 } 682 519 683 520 dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n", ··· 700 527 acpi_handle handle = device->handle; 701 528 int no_aspm = 0; 702 529 bool hotadd = system_state == SYSTEM_RUNNING; 703 - bool is_pcie; 530 + const char *acpi_hid; 704 531 705 532 root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); 706 533 if (!root) ··· 758 585 759 586 root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle); 760 587 761 - is_pcie = strcmp(acpi_device_hid(device), "PNP0A08") == 0; 762 - negotiate_os_control(root, &no_aspm, is_pcie); 588 + acpi_hid = acpi_device_hid(root->device); 589 + if (strcmp(acpi_hid, "PNP0A08") == 0) 590 + root->bridge_type = ACPI_BRIDGE_TYPE_PCIE; 591 + else if (strcmp(acpi_hid, "ACPI0016") == 0) 592 + root->bridge_type = ACPI_BRIDGE_TYPE_CXL; 593 + else 594 + dev_dbg(&device->dev, "Assuming non-PCIe host bridge\n"); 595 + 596 + negotiate_os_control(root, &no_aspm); 763 597 764 598 /* 765 599 * TBD: Need PCI interface for enumeration/configuration of roots.
-3
drivers/base/core.c
··· 2864 2864 kobject_init(&dev->kobj, &device_ktype); 2865 2865 INIT_LIST_HEAD(&dev->dma_pools); 2866 2866 mutex_init(&dev->mutex); 2867 - #ifdef CONFIG_PROVE_LOCKING 2868 - mutex_init(&dev->lockdep_mutex); 2869 - #endif 2870 2867 lockdep_set_novalidate_class(&dev->mutex); 2871 2868 spin_lock_init(&dev->devres_lock); 2872 2869 INIT_LIST_HEAD(&dev->devres_head);
+4
drivers/cxl/Kconfig
··· 98 98 default CXL_BUS 99 99 tristate 100 100 101 + config CXL_SUSPEND 102 + def_bool y 103 + depends on SUSPEND && CXL_MEM 104 + 101 105 endif
+1 -1
drivers/cxl/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - obj-$(CONFIG_CXL_BUS) += core/ 2 + obj-y += core/ 3 3 obj-$(CONFIG_CXL_PCI) += cxl_pci.o 4 4 obj-$(CONFIG_CXL_MEM) += cxl_mem.o 5 5 obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o
+13
drivers/cxl/acpi.c
··· 275 275 return 1; 276 276 } 277 277 278 + static struct lock_class_key cxl_root_key; 279 + 280 + static void cxl_acpi_lock_reset_class(void *dev) 281 + { 282 + device_lock_reset_class(dev); 283 + } 284 + 278 285 static int cxl_acpi_probe(struct platform_device *pdev) 279 286 { 280 287 int rc; ··· 289 282 struct device *host = &pdev->dev; 290 283 struct acpi_device *adev = ACPI_COMPANION(host); 291 284 struct cxl_cfmws_context ctx; 285 + 286 + device_lock_set_class(&pdev->dev, &cxl_root_key); 287 + rc = devm_add_action_or_reset(&pdev->dev, cxl_acpi_lock_reset_class, 288 + &pdev->dev); 289 + if (rc) 290 + return rc; 292 291 293 292 root_port = devm_cxl_add_port(host, host, CXL_RESOURCE_NONE, NULL); 294 293 if (IS_ERR(root_port))
+1
drivers/cxl/core/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-$(CONFIG_CXL_BUS) += cxl_core.o 3 + obj-$(CONFIG_CXL_SUSPEND) += suspend.o 3 4 4 5 ccflags-y += -I$(srctree)/drivers/cxl 5 6 cxl_core-y := port.o
+220 -144
drivers/cxl/core/mbox.c
··· 35 35 .flags = _flags, \ 36 36 } 37 37 38 + #define CXL_VARIABLE_PAYLOAD ~0U 38 39 /* 39 40 * This table defines the supported mailbox commands for the driver. This table 40 41 * is made up of a UAPI structure. Non-negative values as parameters in the ··· 45 44 static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = { 46 45 CXL_CMD(IDENTIFY, 0, 0x43, CXL_CMD_FLAG_FORCE_ENABLE), 47 46 #ifdef CONFIG_CXL_MEM_RAW_COMMANDS 48 - CXL_CMD(RAW, ~0, ~0, 0), 47 + CXL_CMD(RAW, CXL_VARIABLE_PAYLOAD, CXL_VARIABLE_PAYLOAD, 0), 49 48 #endif 50 - CXL_CMD(GET_SUPPORTED_LOGS, 0, ~0, CXL_CMD_FLAG_FORCE_ENABLE), 49 + CXL_CMD(GET_SUPPORTED_LOGS, 0, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE), 51 50 CXL_CMD(GET_FW_INFO, 0, 0x50, 0), 52 51 CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0), 53 - CXL_CMD(GET_LSA, 0x8, ~0, 0), 52 + CXL_CMD(GET_LSA, 0x8, CXL_VARIABLE_PAYLOAD, 0), 54 53 CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0), 55 - CXL_CMD(GET_LOG, 0x18, ~0, CXL_CMD_FLAG_FORCE_ENABLE), 54 + CXL_CMD(GET_LOG, 0x18, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE), 56 55 CXL_CMD(SET_PARTITION_INFO, 0x0a, 0, 0), 57 - CXL_CMD(SET_LSA, ~0, 0, 0), 56 + CXL_CMD(SET_LSA, CXL_VARIABLE_PAYLOAD, 0, 0), 58 57 CXL_CMD(GET_ALERT_CONFIG, 0, 0x10, 0), 59 58 CXL_CMD(SET_ALERT_CONFIG, 0xc, 0, 0), 60 59 CXL_CMD(GET_SHUTDOWN_STATE, 0, 0x1, 0), 61 60 CXL_CMD(SET_SHUTDOWN_STATE, 0x1, 0, 0), 62 - CXL_CMD(GET_POISON, 0x10, ~0, 0), 61 + CXL_CMD(GET_POISON, 0x10, CXL_VARIABLE_PAYLOAD, 0), 63 62 CXL_CMD(INJECT_POISON, 0x8, 0, 0), 64 63 CXL_CMD(CLEAR_POISON, 0x48, 0, 0), 65 64 CXL_CMD(GET_SCAN_MEDIA_CAPS, 0x10, 0x4, 0), 66 65 CXL_CMD(SCAN_MEDIA, 0x11, 0, 0), 67 - CXL_CMD(GET_SCAN_MEDIA, 0, ~0, 0), 66 + CXL_CMD(GET_SCAN_MEDIA, 0, CXL_VARIABLE_PAYLOAD, 0), 68 67 }; 69 68 70 69 /* ··· 128 127 return NULL; 129 128 } 130 129 130 + static const char *cxl_mem_opcode_to_name(u16 opcode) 131 + { 132 + struct cxl_mem_command *c; 133 + 134 + c = cxl_mem_find_command(opcode); 135 + if (!c) 136 + return NULL; 137 + 138 + return cxl_command_names[c->info.id].name; 139 + } 140 + 131 141 /** 132 142 * cxl_mbox_send_cmd() - Send a mailbox command to a device. 133 143 * @cxlds: The device data for the operation ··· 148 136 * @out: Caller allocated buffer for the output. 149 137 * @out_size: Expected size of output. 150 138 * 151 - * Context: Any context. Will acquire and release mbox_mutex. 139 + * Context: Any context. 152 140 * Return: 153 141 * * %>=0 - Number of bytes returned in @out. 154 142 * * %-E2BIG - Payload is too large for hardware. ··· 181 169 if (rc) 182 170 return rc; 183 171 184 - /* TODO: Map return code to proper kernel style errno */ 185 - if (mbox_cmd.return_code != CXL_MBOX_SUCCESS) 186 - return -ENXIO; 172 + if (mbox_cmd.return_code != CXL_MBOX_CMD_RC_SUCCESS) 173 + return cxl_mbox_cmd_rc2errno(&mbox_cmd); 187 174 188 175 /* 189 176 * Variable sized commands can't be validated and so it's up to the 190 177 * caller to do that if they wish. 191 178 */ 192 - if (cmd->info.size_out >= 0 && mbox_cmd.size_out != out_size) 193 - return -EIO; 194 - 179 + if (cmd->info.size_out != CXL_VARIABLE_PAYLOAD) { 180 + if (mbox_cmd.size_out != out_size) 181 + return -EIO; 182 + } 195 183 return 0; 196 184 } 197 185 EXPORT_SYMBOL_NS_GPL(cxl_mbox_send_cmd, CXL); ··· 220 208 } 221 209 222 210 /** 211 + * cxl_payload_from_user_allowed() - Check contents of in_payload. 212 + * @opcode: The mailbox command opcode. 213 + * @payload_in: Pointer to the input payload passed in from user space. 214 + * 215 + * Return: 216 + * * true - payload_in passes check for @opcode. 217 + * * false - payload_in contains invalid or unsupported values. 218 + * 219 + * The driver may inspect payload contents before sending a mailbox 220 + * command from user space to the device. The intent is to reject 221 + * commands with input payloads that are known to be unsafe. This 222 + * check is not intended to replace the users careful selection of 223 + * mailbox command parameters and makes no guarantee that the user 224 + * command will succeed, nor that it is appropriate. 225 + * 226 + * The specific checks are determined by the opcode. 227 + */ 228 + static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in) 229 + { 230 + switch (opcode) { 231 + case CXL_MBOX_OP_SET_PARTITION_INFO: { 232 + struct cxl_mbox_set_partition_info *pi = payload_in; 233 + 234 + if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG) 235 + return false; 236 + break; 237 + } 238 + default: 239 + break; 240 + } 241 + return true; 242 + } 243 + 244 + static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox, 245 + struct cxl_dev_state *cxlds, u16 opcode, 246 + size_t in_size, size_t out_size, u64 in_payload) 247 + { 248 + *mbox = (struct cxl_mbox_cmd) { 249 + .opcode = opcode, 250 + .size_in = in_size, 251 + }; 252 + 253 + if (in_size) { 254 + mbox->payload_in = vmemdup_user(u64_to_user_ptr(in_payload), 255 + in_size); 256 + if (IS_ERR(mbox->payload_in)) 257 + return PTR_ERR(mbox->payload_in); 258 + 259 + if (!cxl_payload_from_user_allowed(opcode, mbox->payload_in)) { 260 + dev_dbg(cxlds->dev, "%s: input payload not allowed\n", 261 + cxl_mem_opcode_to_name(opcode)); 262 + kvfree(mbox->payload_in); 263 + return -EBUSY; 264 + } 265 + } 266 + 267 + /* Prepare to handle a full payload for variable sized output */ 268 + if (out_size == CXL_VARIABLE_PAYLOAD) 269 + mbox->size_out = cxlds->payload_size; 270 + else 271 + mbox->size_out = out_size; 272 + 273 + if (mbox->size_out) { 274 + mbox->payload_out = kvzalloc(mbox->size_out, GFP_KERNEL); 275 + if (!mbox->payload_out) { 276 + kvfree(mbox->payload_in); 277 + return -ENOMEM; 278 + } 279 + } 280 + return 0; 281 + } 282 + 283 + static void cxl_mbox_cmd_dtor(struct cxl_mbox_cmd *mbox) 284 + { 285 + kvfree(mbox->payload_in); 286 + kvfree(mbox->payload_out); 287 + } 288 + 289 + static int cxl_to_mem_cmd_raw(struct cxl_mem_command *mem_cmd, 290 + const struct cxl_send_command *send_cmd, 291 + struct cxl_dev_state *cxlds) 292 + { 293 + if (send_cmd->raw.rsvd) 294 + return -EINVAL; 295 + 296 + /* 297 + * Unlike supported commands, the output size of RAW commands 298 + * gets passed along without further checking, so it must be 299 + * validated here. 300 + */ 301 + if (send_cmd->out.size > cxlds->payload_size) 302 + return -EINVAL; 303 + 304 + if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode)) 305 + return -EPERM; 306 + 307 + dev_WARN_ONCE(cxlds->dev, true, "raw command path used\n"); 308 + 309 + *mem_cmd = (struct cxl_mem_command) { 310 + .info = { 311 + .id = CXL_MEM_COMMAND_ID_RAW, 312 + .size_in = send_cmd->in.size, 313 + .size_out = send_cmd->out.size, 314 + }, 315 + .opcode = send_cmd->raw.opcode 316 + }; 317 + 318 + return 0; 319 + } 320 + 321 + static int cxl_to_mem_cmd(struct cxl_mem_command *mem_cmd, 322 + const struct cxl_send_command *send_cmd, 323 + struct cxl_dev_state *cxlds) 324 + { 325 + struct cxl_mem_command *c = &cxl_mem_commands[send_cmd->id]; 326 + const struct cxl_command_info *info = &c->info; 327 + 328 + if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK) 329 + return -EINVAL; 330 + 331 + if (send_cmd->rsvd) 332 + return -EINVAL; 333 + 334 + if (send_cmd->in.rsvd || send_cmd->out.rsvd) 335 + return -EINVAL; 336 + 337 + /* Check that the command is enabled for hardware */ 338 + if (!test_bit(info->id, cxlds->enabled_cmds)) 339 + return -ENOTTY; 340 + 341 + /* Check that the command is not claimed for exclusive kernel use */ 342 + if (test_bit(info->id, cxlds->exclusive_cmds)) 343 + return -EBUSY; 344 + 345 + /* Check the input buffer is the expected size */ 346 + if (info->size_in != send_cmd->in.size) 347 + return -ENOMEM; 348 + 349 + /* Check the output buffer is at least large enough */ 350 + if (send_cmd->out.size < info->size_out) 351 + return -ENOMEM; 352 + 353 + *mem_cmd = (struct cxl_mem_command) { 354 + .info = { 355 + .id = info->id, 356 + .flags = info->flags, 357 + .size_in = send_cmd->in.size, 358 + .size_out = send_cmd->out.size, 359 + }, 360 + .opcode = c->opcode 361 + }; 362 + 363 + return 0; 364 + } 365 + 366 + /** 223 367 * cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND. 368 + * @mbox_cmd: Sanitized and populated &struct cxl_mbox_cmd. 224 369 * @cxlds: The device data for the operation 225 370 * @send_cmd: &struct cxl_send_command copied in from userspace. 226 - * @out_cmd: Sanitized and populated &struct cxl_mem_command. 227 371 * 228 372 * Return: 229 373 * * %0 - @out_cmd is ready to send. ··· 389 221 * * %-EPERM - Attempted to use a protected command. 390 222 * * %-EBUSY - Kernel has claimed exclusive access to this opcode 391 223 * 392 - * The result of this command is a fully validated command in @out_cmd that is 224 + * The result of this command is a fully validated command in @mbox_cmd that is 393 225 * safe to send to the hardware. 394 - * 395 - * See handle_mailbox_cmd_from_user() 396 226 */ 397 - static int cxl_validate_cmd_from_user(struct cxl_dev_state *cxlds, 398 - const struct cxl_send_command *send_cmd, 399 - struct cxl_mem_command *out_cmd) 227 + static int cxl_validate_cmd_from_user(struct cxl_mbox_cmd *mbox_cmd, 228 + struct cxl_dev_state *cxlds, 229 + const struct cxl_send_command *send_cmd) 400 230 { 401 - const struct cxl_command_info *info; 402 - struct cxl_mem_command *c; 231 + struct cxl_mem_command mem_cmd; 232 + int rc; 403 233 404 234 if (send_cmd->id == 0 || send_cmd->id >= CXL_MEM_COMMAND_ID_MAX) 405 235 return -ENOTTY; ··· 410 244 if (send_cmd->in.size > cxlds->payload_size) 411 245 return -EINVAL; 412 246 413 - /* 414 - * Checks are bypassed for raw commands but a WARN/taint will occur 415 - * later in the callchain 416 - */ 417 - if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW) { 418 - const struct cxl_mem_command temp = { 419 - .info = { 420 - .id = CXL_MEM_COMMAND_ID_RAW, 421 - .flags = 0, 422 - .size_in = send_cmd->in.size, 423 - .size_out = send_cmd->out.size, 424 - }, 425 - .opcode = send_cmd->raw.opcode 426 - }; 247 + /* Sanitize and construct a cxl_mem_command */ 248 + if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW) 249 + rc = cxl_to_mem_cmd_raw(&mem_cmd, send_cmd, cxlds); 250 + else 251 + rc = cxl_to_mem_cmd(&mem_cmd, send_cmd, cxlds); 427 252 428 - if (send_cmd->raw.rsvd) 429 - return -EINVAL; 253 + if (rc) 254 + return rc; 430 255 431 - /* 432 - * Unlike supported commands, the output size of RAW commands 433 - * gets passed along without further checking, so it must be 434 - * validated here. 435 - */ 436 - if (send_cmd->out.size > cxlds->payload_size) 437 - return -EINVAL; 438 - 439 - if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode)) 440 - return -EPERM; 441 - 442 - memcpy(out_cmd, &temp, sizeof(temp)); 443 - 444 - return 0; 445 - } 446 - 447 - if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK) 448 - return -EINVAL; 449 - 450 - if (send_cmd->rsvd) 451 - return -EINVAL; 452 - 453 - if (send_cmd->in.rsvd || send_cmd->out.rsvd) 454 - return -EINVAL; 455 - 456 - /* Convert user's command into the internal representation */ 457 - c = &cxl_mem_commands[send_cmd->id]; 458 - info = &c->info; 459 - 460 - /* Check that the command is enabled for hardware */ 461 - if (!test_bit(info->id, cxlds->enabled_cmds)) 462 - return -ENOTTY; 463 - 464 - /* Check that the command is not claimed for exclusive kernel use */ 465 - if (test_bit(info->id, cxlds->exclusive_cmds)) 466 - return -EBUSY; 467 - 468 - /* Check the input buffer is the expected size */ 469 - if (info->size_in >= 0 && info->size_in != send_cmd->in.size) 470 - return -ENOMEM; 471 - 472 - /* Check the output buffer is at least large enough */ 473 - if (info->size_out >= 0 && send_cmd->out.size < info->size_out) 474 - return -ENOMEM; 475 - 476 - memcpy(out_cmd, c, sizeof(*c)); 477 - out_cmd->info.size_in = send_cmd->in.size; 478 - /* 479 - * XXX: out_cmd->info.size_out will be controlled by the driver, and the 480 - * specified number of bytes @send_cmd->out.size will be copied back out 481 - * to userspace. 482 - */ 483 - 484 - return 0; 256 + /* Sanitize and construct a cxl_mbox_cmd */ 257 + return cxl_mbox_cmd_ctor(mbox_cmd, cxlds, mem_cmd.opcode, 258 + mem_cmd.info.size_in, mem_cmd.info.size_out, 259 + send_cmd->in.payload); 485 260 } 486 261 487 262 int cxl_query_cmd(struct cxl_memdev *cxlmd, ··· 462 355 /** 463 356 * handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace. 464 357 * @cxlds: The device data for the operation 465 - * @cmd: The validated command. 466 - * @in_payload: Pointer to userspace's input payload. 358 + * @mbox_cmd: The validated mailbox command. 467 359 * @out_payload: Pointer to userspace's output payload. 468 360 * @size_out: (Input) Max payload size to copy out. 469 361 * (Output) Payload size hardware generated. ··· 477 371 * * %-EINTR - Mailbox acquisition interrupted. 478 372 * * %-EXXX - Transaction level failures. 479 373 * 480 - * Creates the appropriate mailbox command and dispatches it on behalf of a 481 - * userspace request. The input and output payloads are copied between 482 - * userspace. 374 + * Dispatches a mailbox command on behalf of a userspace request. 375 + * The output payload is copied to userspace. 483 376 * 484 377 * See cxl_send_cmd(). 485 378 */ 486 379 static int handle_mailbox_cmd_from_user(struct cxl_dev_state *cxlds, 487 - const struct cxl_mem_command *cmd, 488 - u64 in_payload, u64 out_payload, 489 - s32 *size_out, u32 *retval) 380 + struct cxl_mbox_cmd *mbox_cmd, 381 + u64 out_payload, s32 *size_out, 382 + u32 *retval) 490 383 { 491 384 struct device *dev = cxlds->dev; 492 - struct cxl_mbox_cmd mbox_cmd = { 493 - .opcode = cmd->opcode, 494 - .size_in = cmd->info.size_in, 495 - .size_out = cmd->info.size_out, 496 - }; 497 385 int rc; 498 - 499 - if (cmd->info.size_out) { 500 - mbox_cmd.payload_out = kvzalloc(cmd->info.size_out, GFP_KERNEL); 501 - if (!mbox_cmd.payload_out) 502 - return -ENOMEM; 503 - } 504 - 505 - if (cmd->info.size_in) { 506 - mbox_cmd.payload_in = vmemdup_user(u64_to_user_ptr(in_payload), 507 - cmd->info.size_in); 508 - if (IS_ERR(mbox_cmd.payload_in)) { 509 - kvfree(mbox_cmd.payload_out); 510 - return PTR_ERR(mbox_cmd.payload_in); 511 - } 512 - } 513 386 514 387 dev_dbg(dev, 515 388 "Submitting %s command for user\n" 516 389 "\topcode: %x\n" 517 - "\tsize: %ub\n", 518 - cxl_command_names[cmd->info.id].name, mbox_cmd.opcode, 519 - cmd->info.size_in); 390 + "\tsize: %zx\n", 391 + cxl_mem_opcode_to_name(mbox_cmd->opcode), 392 + mbox_cmd->opcode, mbox_cmd->size_in); 520 393 521 - dev_WARN_ONCE(dev, cmd->info.id == CXL_MEM_COMMAND_ID_RAW, 522 - "raw command path used\n"); 523 - 524 - rc = cxlds->mbox_send(cxlds, &mbox_cmd); 394 + rc = cxlds->mbox_send(cxlds, mbox_cmd); 525 395 if (rc) 526 396 goto out; 527 397 ··· 506 424 * to userspace. While the payload may have written more output than 507 425 * this it will have to be ignored. 508 426 */ 509 - if (mbox_cmd.size_out) { 510 - dev_WARN_ONCE(dev, mbox_cmd.size_out > *size_out, 427 + if (mbox_cmd->size_out) { 428 + dev_WARN_ONCE(dev, mbox_cmd->size_out > *size_out, 511 429 "Invalid return size\n"); 512 430 if (copy_to_user(u64_to_user_ptr(out_payload), 513 - mbox_cmd.payload_out, mbox_cmd.size_out)) { 431 + mbox_cmd->payload_out, mbox_cmd->size_out)) { 514 432 rc = -EFAULT; 515 433 goto out; 516 434 } 517 435 } 518 436 519 - *size_out = mbox_cmd.size_out; 520 - *retval = mbox_cmd.return_code; 437 + *size_out = mbox_cmd->size_out; 438 + *retval = mbox_cmd->return_code; 521 439 522 440 out: 523 - kvfree(mbox_cmd.payload_in); 524 - kvfree(mbox_cmd.payload_out); 441 + cxl_mbox_cmd_dtor(mbox_cmd); 525 442 return rc; 526 443 } 527 444 ··· 529 448 struct cxl_dev_state *cxlds = cxlmd->cxlds; 530 449 struct device *dev = &cxlmd->dev; 531 450 struct cxl_send_command send; 532 - struct cxl_mem_command c; 451 + struct cxl_mbox_cmd mbox_cmd; 533 452 int rc; 534 453 535 454 dev_dbg(dev, "Send IOCTL\n"); ··· 537 456 if (copy_from_user(&send, s, sizeof(send))) 538 457 return -EFAULT; 539 458 540 - rc = cxl_validate_cmd_from_user(cxlmd->cxlds, &send, &c); 459 + rc = cxl_validate_cmd_from_user(&mbox_cmd, cxlmd->cxlds, &send); 541 460 if (rc) 542 461 return rc; 543 462 544 - /* Prepare to handle a full payload for variable sized output */ 545 - if (c.info.size_out < 0) 546 - c.info.size_out = cxlds->payload_size; 547 - 548 - rc = handle_mailbox_cmd_from_user(cxlds, &c, send.in.payload, 549 - send.out.payload, &send.out.size, 550 - &send.retval); 463 + rc = handle_mailbox_cmd_from_user(cxlds, &mbox_cmd, send.out.payload, 464 + &send.out.size, &send.retval); 551 465 if (rc) 552 466 return rc; 553 467
+3
drivers/cxl/core/memdev.c
··· 228 228 put_device(&cxlmd->dev); 229 229 } 230 230 231 + static struct lock_class_key cxl_memdev_key; 232 + 231 233 static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds, 232 234 const struct file_operations *fops) 233 235 { ··· 249 247 250 248 dev = &cxlmd->dev; 251 249 device_initialize(dev); 250 + lockdep_set_class(&dev->mutex, &cxl_memdev_key); 252 251 dev->parent = cxlds->dev; 253 252 dev->bus = &cxl_bus_type; 254 253 dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
+364
drivers/cxl/core/pci.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* Copyright(c) 2021 Intel Corporation. All rights reserved. */ 3 + #include <linux/io-64-nonatomic-lo-hi.h> 3 4 #include <linux/device.h> 5 + #include <linux/delay.h> 4 6 #include <linux/pci.h> 5 7 #include <cxlpci.h> 8 + #include <cxlmem.h> 6 9 #include <cxl.h> 7 10 #include "core.h" 8 11 ··· 15 12 * Compute Express Link protocols are layered on top of PCIe. CXL core provides 16 13 * a set of helpers for CXL interactions which occur via PCIe. 17 14 */ 15 + 16 + static unsigned short media_ready_timeout = 60; 17 + module_param(media_ready_timeout, ushort, 0644); 18 + MODULE_PARM_DESC(media_ready_timeout, "seconds to wait for media ready"); 18 19 19 20 struct cxl_walk_context { 20 21 struct pci_bus *bus; ··· 101 94 return ctx.count; 102 95 } 103 96 EXPORT_SYMBOL_NS_GPL(devm_cxl_port_enumerate_dports, CXL); 97 + 98 + /* 99 + * Wait up to @media_ready_timeout for the device to report memory 100 + * active. 101 + */ 102 + int cxl_await_media_ready(struct cxl_dev_state *cxlds) 103 + { 104 + struct pci_dev *pdev = to_pci_dev(cxlds->dev); 105 + int d = cxlds->cxl_dvsec; 106 + bool active = false; 107 + u64 md_status; 108 + int rc, i; 109 + 110 + for (i = media_ready_timeout; i; i--) { 111 + u32 temp; 112 + 113 + rc = pci_read_config_dword( 114 + pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &temp); 115 + if (rc) 116 + return rc; 117 + 118 + active = FIELD_GET(CXL_DVSEC_MEM_ACTIVE, temp); 119 + if (active) 120 + break; 121 + msleep(1000); 122 + } 123 + 124 + if (!active) { 125 + dev_err(&pdev->dev, 126 + "timeout awaiting memory active after %d seconds\n", 127 + media_ready_timeout); 128 + return -ETIMEDOUT; 129 + } 130 + 131 + md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET); 132 + if (!CXLMDEV_READY(md_status)) 133 + return -EIO; 134 + 135 + return 0; 136 + } 137 + EXPORT_SYMBOL_NS_GPL(cxl_await_media_ready, CXL); 138 + 139 + static int wait_for_valid(struct cxl_dev_state *cxlds) 140 + { 141 + struct pci_dev *pdev = to_pci_dev(cxlds->dev); 142 + int d = cxlds->cxl_dvsec, rc; 143 + u32 val; 144 + 145 + /* 146 + * Memory_Info_Valid: When set, indicates that the CXL Range 1 Size high 147 + * and Size Low registers are valid. Must be set within 1 second of 148 + * deassertion of reset to CXL device. Likely it is already set by the 149 + * time this runs, but otherwise give a 1.5 second timeout in case of 150 + * clock skew. 151 + */ 152 + rc = pci_read_config_dword(pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &val); 153 + if (rc) 154 + return rc; 155 + 156 + if (val & CXL_DVSEC_MEM_INFO_VALID) 157 + return 0; 158 + 159 + msleep(1500); 160 + 161 + rc = pci_read_config_dword(pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &val); 162 + if (rc) 163 + return rc; 164 + 165 + if (val & CXL_DVSEC_MEM_INFO_VALID) 166 + return 0; 167 + 168 + return -ETIMEDOUT; 169 + } 170 + 171 + static int cxl_set_mem_enable(struct cxl_dev_state *cxlds, u16 val) 172 + { 173 + struct pci_dev *pdev = to_pci_dev(cxlds->dev); 174 + int d = cxlds->cxl_dvsec; 175 + u16 ctrl; 176 + int rc; 177 + 178 + rc = pci_read_config_word(pdev, d + CXL_DVSEC_CTRL_OFFSET, &ctrl); 179 + if (rc < 0) 180 + return rc; 181 + 182 + if ((ctrl & CXL_DVSEC_MEM_ENABLE) == val) 183 + return 1; 184 + ctrl &= ~CXL_DVSEC_MEM_ENABLE; 185 + ctrl |= val; 186 + 187 + rc = pci_write_config_word(pdev, d + CXL_DVSEC_CTRL_OFFSET, ctrl); 188 + if (rc < 0) 189 + return rc; 190 + 191 + return 0; 192 + } 193 + 194 + static void clear_mem_enable(void *cxlds) 195 + { 196 + cxl_set_mem_enable(cxlds, 0); 197 + } 198 + 199 + static int devm_cxl_enable_mem(struct device *host, struct cxl_dev_state *cxlds) 200 + { 201 + int rc; 202 + 203 + rc = cxl_set_mem_enable(cxlds, CXL_DVSEC_MEM_ENABLE); 204 + if (rc < 0) 205 + return rc; 206 + if (rc > 0) 207 + return 0; 208 + return devm_add_action_or_reset(host, clear_mem_enable, cxlds); 209 + } 210 + 211 + static bool range_contains(struct range *r1, struct range *r2) 212 + { 213 + return r1->start <= r2->start && r1->end >= r2->end; 214 + } 215 + 216 + /* require dvsec ranges to be covered by a locked platform window */ 217 + static int dvsec_range_allowed(struct device *dev, void *arg) 218 + { 219 + struct range *dev_range = arg; 220 + struct cxl_decoder *cxld; 221 + struct range root_range; 222 + 223 + if (!is_root_decoder(dev)) 224 + return 0; 225 + 226 + cxld = to_cxl_decoder(dev); 227 + 228 + if (!(cxld->flags & CXL_DECODER_F_LOCK)) 229 + return 0; 230 + if (!(cxld->flags & CXL_DECODER_F_RAM)) 231 + return 0; 232 + 233 + root_range = (struct range) { 234 + .start = cxld->platform_res.start, 235 + .end = cxld->platform_res.end, 236 + }; 237 + 238 + return range_contains(&root_range, dev_range); 239 + } 240 + 241 + static void disable_hdm(void *_cxlhdm) 242 + { 243 + u32 global_ctrl; 244 + struct cxl_hdm *cxlhdm = _cxlhdm; 245 + void __iomem *hdm = cxlhdm->regs.hdm_decoder; 246 + 247 + global_ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET); 248 + writel(global_ctrl & ~CXL_HDM_DECODER_ENABLE, 249 + hdm + CXL_HDM_DECODER_CTRL_OFFSET); 250 + } 251 + 252 + static int devm_cxl_enable_hdm(struct device *host, struct cxl_hdm *cxlhdm) 253 + { 254 + void __iomem *hdm = cxlhdm->regs.hdm_decoder; 255 + u32 global_ctrl; 256 + 257 + global_ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET); 258 + writel(global_ctrl | CXL_HDM_DECODER_ENABLE, 259 + hdm + CXL_HDM_DECODER_CTRL_OFFSET); 260 + 261 + return devm_add_action_or_reset(host, disable_hdm, cxlhdm); 262 + } 263 + 264 + static bool __cxl_hdm_decode_init(struct cxl_dev_state *cxlds, 265 + struct cxl_hdm *cxlhdm, 266 + struct cxl_endpoint_dvsec_info *info) 267 + { 268 + void __iomem *hdm = cxlhdm->regs.hdm_decoder; 269 + struct cxl_port *port = cxlhdm->port; 270 + struct device *dev = cxlds->dev; 271 + struct cxl_port *root; 272 + int i, rc, allowed; 273 + u32 global_ctrl; 274 + 275 + global_ctrl = readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET); 276 + 277 + /* 278 + * If the HDM Decoder Capability is already enabled then assume 279 + * that some other agent like platform firmware set it up. 280 + */ 281 + if (global_ctrl & CXL_HDM_DECODER_ENABLE) { 282 + rc = devm_cxl_enable_mem(&port->dev, cxlds); 283 + if (rc) 284 + return false; 285 + return true; 286 + } 287 + 288 + root = to_cxl_port(port->dev.parent); 289 + while (!is_cxl_root(root) && is_cxl_port(root->dev.parent)) 290 + root = to_cxl_port(root->dev.parent); 291 + if (!is_cxl_root(root)) { 292 + dev_err(dev, "Failed to acquire root port for HDM enable\n"); 293 + return false; 294 + } 295 + 296 + for (i = 0, allowed = 0; info->mem_enabled && i < info->ranges; i++) { 297 + struct device *cxld_dev; 298 + 299 + cxld_dev = device_find_child(&root->dev, &info->dvsec_range[i], 300 + dvsec_range_allowed); 301 + if (!cxld_dev) { 302 + dev_dbg(dev, "DVSEC Range%d denied by platform\n", i); 303 + continue; 304 + } 305 + dev_dbg(dev, "DVSEC Range%d allowed by platform\n", i); 306 + put_device(cxld_dev); 307 + allowed++; 308 + } 309 + 310 + if (!allowed) { 311 + cxl_set_mem_enable(cxlds, 0); 312 + info->mem_enabled = 0; 313 + } 314 + 315 + /* 316 + * Per CXL 2.0 Section 8.1.3.8.3 and 8.1.3.8.4 DVSEC CXL Range 1 Base 317 + * [High,Low] when HDM operation is enabled the range register values 318 + * are ignored by the device, but the spec also recommends matching the 319 + * DVSEC Range 1,2 to HDM Decoder Range 0,1. So, non-zero info->ranges 320 + * are expected even though Linux does not require or maintain that 321 + * match. If at least one DVSEC range is enabled and allowed, skip HDM 322 + * Decoder Capability Enable. 323 + */ 324 + if (info->mem_enabled) 325 + return false; 326 + 327 + rc = devm_cxl_enable_hdm(&port->dev, cxlhdm); 328 + if (rc) 329 + return false; 330 + 331 + rc = devm_cxl_enable_mem(&port->dev, cxlds); 332 + if (rc) 333 + return false; 334 + 335 + return true; 336 + } 337 + 338 + /** 339 + * cxl_hdm_decode_init() - Setup HDM decoding for the endpoint 340 + * @cxlds: Device state 341 + * @cxlhdm: Mapped HDM decoder Capability 342 + * 343 + * Try to enable the endpoint's HDM Decoder Capability 344 + */ 345 + int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm) 346 + { 347 + struct pci_dev *pdev = to_pci_dev(cxlds->dev); 348 + struct cxl_endpoint_dvsec_info info = { 0 }; 349 + int hdm_count, rc, i, ranges = 0; 350 + struct device *dev = &pdev->dev; 351 + int d = cxlds->cxl_dvsec; 352 + u16 cap, ctrl; 353 + 354 + if (!d) { 355 + dev_dbg(dev, "No DVSEC Capability\n"); 356 + return -ENXIO; 357 + } 358 + 359 + rc = pci_read_config_word(pdev, d + CXL_DVSEC_CAP_OFFSET, &cap); 360 + if (rc) 361 + return rc; 362 + 363 + rc = pci_read_config_word(pdev, d + CXL_DVSEC_CTRL_OFFSET, &ctrl); 364 + if (rc) 365 + return rc; 366 + 367 + if (!(cap & CXL_DVSEC_MEM_CAPABLE)) { 368 + dev_dbg(dev, "Not MEM Capable\n"); 369 + return -ENXIO; 370 + } 371 + 372 + /* 373 + * It is not allowed by spec for MEM.capable to be set and have 0 legacy 374 + * HDM decoders (values > 2 are also undefined as of CXL 2.0). As this 375 + * driver is for a spec defined class code which must be CXL.mem 376 + * capable, there is no point in continuing to enable CXL.mem. 377 + */ 378 + hdm_count = FIELD_GET(CXL_DVSEC_HDM_COUNT_MASK, cap); 379 + if (!hdm_count || hdm_count > 2) 380 + return -EINVAL; 381 + 382 + rc = wait_for_valid(cxlds); 383 + if (rc) { 384 + dev_dbg(dev, "Failure awaiting MEM_INFO_VALID (%d)\n", rc); 385 + return rc; 386 + } 387 + 388 + /* 389 + * The current DVSEC values are moot if the memory capability is 390 + * disabled, and they will remain moot after the HDM Decoder 391 + * capability is enabled. 392 + */ 393 + info.mem_enabled = FIELD_GET(CXL_DVSEC_MEM_ENABLE, ctrl); 394 + if (!info.mem_enabled) 395 + goto hdm_init; 396 + 397 + for (i = 0; i < hdm_count; i++) { 398 + u64 base, size; 399 + u32 temp; 400 + 401 + rc = pci_read_config_dword( 402 + pdev, d + CXL_DVSEC_RANGE_SIZE_HIGH(i), &temp); 403 + if (rc) 404 + return rc; 405 + 406 + size = (u64)temp << 32; 407 + 408 + rc = pci_read_config_dword( 409 + pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(i), &temp); 410 + if (rc) 411 + return rc; 412 + 413 + size |= temp & CXL_DVSEC_MEM_SIZE_LOW_MASK; 414 + 415 + rc = pci_read_config_dword( 416 + pdev, d + CXL_DVSEC_RANGE_BASE_HIGH(i), &temp); 417 + if (rc) 418 + return rc; 419 + 420 + base = (u64)temp << 32; 421 + 422 + rc = pci_read_config_dword( 423 + pdev, d + CXL_DVSEC_RANGE_BASE_LOW(i), &temp); 424 + if (rc) 425 + return rc; 426 + 427 + base |= temp & CXL_DVSEC_MEM_BASE_LOW_MASK; 428 + 429 + info.dvsec_range[i] = (struct range) { 430 + .start = base, 431 + .end = base + size - 1 432 + }; 433 + 434 + if (size) 435 + ranges++; 436 + } 437 + 438 + info.ranges = ranges; 439 + 440 + /* 441 + * If DVSEC ranges are being used instead of HDM decoder registers there 442 + * is no use in trying to manage those. 443 + */ 444 + hdm_init: 445 + if (!__cxl_hdm_decode_init(cxlds, cxlhdm, &info)) { 446 + dev_err(dev, 447 + "Legacy range registers configuration prevents HDM operation.\n"); 448 + return -EBUSY; 449 + } 450 + 451 + return 0; 452 + } 453 + EXPORT_SYMBOL_NS_GPL(cxl_hdm_decode_init, CXL);
+8 -2
drivers/cxl/core/pmem.c
··· 80 80 } 81 81 EXPORT_SYMBOL_NS_GPL(cxl_find_nvdimm_bridge, CXL); 82 82 83 + static struct lock_class_key cxl_nvdimm_bridge_key; 84 + 83 85 static struct cxl_nvdimm_bridge *cxl_nvdimm_bridge_alloc(struct cxl_port *port) 84 86 { 85 87 struct cxl_nvdimm_bridge *cxl_nvb; ··· 101 99 cxl_nvb->port = port; 102 100 cxl_nvb->state = CXL_NVB_NEW; 103 101 device_initialize(dev); 102 + lockdep_set_class(&dev->mutex, &cxl_nvdimm_bridge_key); 104 103 device_set_pm_not_required(dev); 105 104 dev->parent = &port->dev; 106 105 dev->bus = &cxl_bus_type; ··· 124 121 * work to flush. Once the state has been changed to 'dead' then no new 125 122 * work can be queued by user-triggered bind. 126 123 */ 127 - cxl_device_lock(&cxl_nvb->dev); 124 + device_lock(&cxl_nvb->dev); 128 125 flush = cxl_nvb->state != CXL_NVB_NEW; 129 126 cxl_nvb->state = CXL_NVB_DEAD; 130 - cxl_device_unlock(&cxl_nvb->dev); 127 + device_unlock(&cxl_nvb->dev); 131 128 132 129 /* 133 130 * Even though the device core will trigger device_release_driver() ··· 217 214 } 218 215 EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm, CXL); 219 216 217 + static struct lock_class_key cxl_nvdimm_key; 218 + 220 219 static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) 221 220 { 222 221 struct cxl_nvdimm *cxl_nvd; ··· 231 226 dev = &cxl_nvd->dev; 232 227 cxl_nvd->cxlmd = cxlmd; 233 228 device_initialize(dev); 229 + lockdep_set_class(&dev->mutex, &cxl_nvdimm_key); 234 230 device_set_pm_not_required(dev); 235 231 dev->parent = &cxlmd->dev; 236 232 dev->bus = &cxl_bus_type;
+32 -36
drivers/cxl/core/port.c
··· 312 312 struct cxl_port *port = to_cxl_port(dev); 313 313 struct cxl_ep *ep, *_e; 314 314 315 - cxl_device_lock(dev); 315 + device_lock(dev); 316 316 list_for_each_entry_safe(ep, _e, &port->endpoints, list) 317 317 cxl_ep_release(ep); 318 - cxl_device_unlock(dev); 318 + device_unlock(dev); 319 319 ida_free(&cxl_port_ida, port->id); 320 320 kfree(port); 321 321 } ··· 391 391 return devm_add_action_or_reset(host, cxl_unlink_uport, port); 392 392 } 393 393 394 + static struct lock_class_key cxl_port_key; 395 + 394 396 static struct cxl_port *cxl_port_alloc(struct device *uport, 395 397 resource_size_t component_reg_phys, 396 398 struct cxl_port *parent_port) ··· 417 415 * description. 418 416 */ 419 417 dev = &port->dev; 420 - if (parent_port) 418 + if (parent_port) { 421 419 dev->parent = &parent_port->dev; 422 - else 420 + port->depth = parent_port->depth + 1; 421 + } else 423 422 dev->parent = uport; 424 423 425 424 port->uport = uport; ··· 430 427 INIT_LIST_HEAD(&port->endpoints); 431 428 432 429 device_initialize(dev); 430 + lockdep_set_class_and_subclass(&dev->mutex, &cxl_port_key, port->depth); 433 431 device_set_pm_not_required(dev); 434 432 dev->bus = &cxl_bus_type; 435 433 dev->type = &cxl_port_type; ··· 461 457 if (IS_ERR(port)) 462 458 return port; 463 459 464 - if (parent_port) 465 - port->depth = parent_port->depth + 1; 466 460 dev = &port->dev; 467 461 if (is_cxl_memdev(uport)) 468 462 rc = dev_set_name(dev, "endpoint%d", port->id); ··· 556 554 return 0; 557 555 558 556 port = to_cxl_port(dev); 559 - cxl_device_lock(dev); 557 + device_lock(dev); 560 558 list_for_each_entry(dport, &port->dports, list) { 561 559 iter = match; 562 560 while (iter) { ··· 566 564 } 567 565 } 568 566 out: 569 - cxl_device_unlock(dev); 567 + device_unlock(dev); 570 568 571 569 return !!iter; 572 570 } ··· 625 623 static void cond_cxl_root_lock(struct cxl_port *port) 626 624 { 627 625 if (is_cxl_root(port)) 628 - cxl_device_lock(&port->dev); 626 + device_lock(&port->dev); 629 627 } 630 628 631 629 static void cond_cxl_root_unlock(struct cxl_port *port) 632 630 { 633 631 if (is_cxl_root(port)) 634 - cxl_device_unlock(&port->dev); 632 + device_unlock(&port->dev); 635 633 } 636 634 637 635 static void cxl_dport_remove(void *data) ··· 738 736 { 739 737 struct cxl_ep *dup; 740 738 741 - cxl_device_lock(&port->dev); 739 + device_lock(&port->dev); 742 740 if (port->dead) { 743 - cxl_device_unlock(&port->dev); 741 + device_unlock(&port->dev); 744 742 return -ENXIO; 745 743 } 746 744 dup = find_ep(port, new->ep); 747 745 if (!dup) 748 746 list_add_tail(&new->list, &port->endpoints); 749 - cxl_device_unlock(&port->dev); 747 + device_unlock(&port->dev); 750 748 751 749 return dup ? -EEXIST : 0; 752 750 } ··· 856 854 goto out; 857 855 parent = &parent_port->dev; 858 856 859 - cxl_device_lock(parent); 857 + device_lock(parent); 860 858 if (parent->driver && endpoint->uport) { 861 859 devm_release_action(parent, cxl_unlink_uport, endpoint); 862 860 devm_release_action(parent, unregister_port, endpoint); 863 861 } 864 - cxl_device_unlock(parent); 862 + device_unlock(parent); 865 863 put_device(parent); 866 864 out: 867 865 put_device(&endpoint->dev); ··· 922 920 } 923 921 924 922 parent_port = to_cxl_port(port->dev.parent); 925 - cxl_device_lock(&parent_port->dev); 923 + device_lock(&parent_port->dev); 926 924 if (!parent_port->dev.driver) { 927 925 /* 928 926 * The bottom-up race to delete the port lost to a ··· 930 928 * parent_port ->remove() will have cleaned up all 931 929 * descendants. 932 930 */ 933 - cxl_device_unlock(&parent_port->dev); 931 + device_unlock(&parent_port->dev); 934 932 put_device(&port->dev); 935 933 continue; 936 934 } 937 935 938 - cxl_device_lock(&port->dev); 936 + device_lock(&port->dev); 939 937 ep = find_ep(port, &cxlmd->dev); 940 938 dev_dbg(&cxlmd->dev, "disconnect %s from %s\n", 941 939 ep ? dev_name(ep->ep) : "", dev_name(&port->dev)); ··· 950 948 port->dead = true; 951 949 list_splice_init(&port->dports, &reap_dports); 952 950 } 953 - cxl_device_unlock(&port->dev); 951 + device_unlock(&port->dev); 954 952 955 953 if (!list_empty(&reap_dports)) { 956 954 dev_dbg(&cxlmd->dev, "delete %s\n", ··· 958 956 delete_switch_port(port, &reap_dports); 959 957 } 960 958 put_device(&port->dev); 961 - cxl_device_unlock(&parent_port->dev); 959 + device_unlock(&parent_port->dev); 962 960 } 963 961 } 964 962 ··· 1006 1004 return -EAGAIN; 1007 1005 } 1008 1006 1009 - cxl_device_lock(&parent_port->dev); 1007 + device_lock(&parent_port->dev); 1010 1008 if (!parent_port->dev.driver) { 1011 1009 dev_warn(&cxlmd->dev, 1012 1010 "port %s:%s disabled, failed to enumerate CXL.mem\n", ··· 1024 1022 get_device(&port->dev); 1025 1023 } 1026 1024 out: 1027 - cxl_device_unlock(&parent_port->dev); 1025 + device_unlock(&parent_port->dev); 1028 1026 1029 1027 if (IS_ERR(port)) 1030 1028 rc = PTR_ERR(port); ··· 1135 1133 { 1136 1134 struct cxl_dport *dport; 1137 1135 1138 - cxl_device_lock(&port->dev); 1136 + device_lock(&port->dev); 1139 1137 list_for_each_entry(dport, &port->dports, list) 1140 1138 if (dport->dport == dev) { 1141 - cxl_device_unlock(&port->dev); 1139 + device_unlock(&port->dev); 1142 1140 return dport; 1143 1141 } 1144 1142 1145 - cxl_device_unlock(&port->dev); 1143 + device_unlock(&port->dev); 1146 1144 return NULL; 1147 1145 } 1148 1146 EXPORT_SYMBOL_NS_GPL(cxl_find_dport_by_dev, CXL); ··· 1174 1172 1175 1173 return rc; 1176 1174 } 1175 + 1176 + static struct lock_class_key cxl_decoder_key; 1177 1177 1178 1178 /** 1179 1179 * cxl_decoder_alloc - Allocate a new CXL decoder ··· 1218 1214 seqlock_init(&cxld->target_lock); 1219 1215 dev = &cxld->dev; 1220 1216 device_initialize(dev); 1217 + lockdep_set_class(&dev->mutex, &cxl_decoder_key); 1221 1218 device_set_pm_not_required(dev); 1222 1219 dev->parent = &port->dev; 1223 1220 dev->bus = &cxl_bus_type; ··· 1384 1379 1385 1380 port = to_cxl_port(cxld->dev.parent); 1386 1381 1387 - cxl_device_lock(&port->dev); 1382 + device_lock(&port->dev); 1388 1383 rc = cxl_decoder_add_locked(cxld, target_map); 1389 - cxl_device_unlock(&port->dev); 1384 + device_unlock(&port->dev); 1390 1385 1391 1386 return rc; 1392 1387 } ··· 1457 1452 { 1458 1453 int rc; 1459 1454 1460 - /* 1461 - * Take the CXL nested lock since the driver core only holds 1462 - * @dev->mutex and not @dev->lockdep_mutex. 1463 - */ 1464 - cxl_nested_lock(dev); 1465 1455 rc = to_cxl_drv(dev->driver)->probe(dev); 1466 - cxl_nested_unlock(dev); 1467 - 1468 1456 dev_dbg(dev, "probe: %d\n", rc); 1469 1457 return rc; 1470 1458 } ··· 1466 1468 { 1467 1469 struct cxl_driver *cxl_drv = to_cxl_drv(dev->driver); 1468 1470 1469 - cxl_nested_lock(dev); 1470 1471 if (cxl_drv->remove) 1471 1472 cxl_drv->remove(dev); 1472 - cxl_nested_unlock(dev); 1473 1473 } 1474 1474 1475 1475 static struct workqueue_struct *cxl_bus_wq;
+24
drivers/cxl/core/suspend.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* Copyright(c) 2022 Intel Corporation. All rights reserved. */ 3 + #include <linux/atomic.h> 4 + #include <linux/export.h> 5 + #include "cxlmem.h" 6 + 7 + static atomic_t mem_active; 8 + 9 + bool cxl_mem_active(void) 10 + { 11 + return atomic_read(&mem_active) != 0; 12 + } 13 + 14 + void cxl_mem_active_inc(void) 15 + { 16 + atomic_inc(&mem_active); 17 + } 18 + EXPORT_SYMBOL_NS_GPL(cxl_mem_active_inc, CXL); 19 + 20 + void cxl_mem_active_dec(void) 21 + { 22 + atomic_dec(&mem_active); 23 + } 24 + EXPORT_SYMBOL_NS_GPL(cxl_mem_active_dec, CXL);
-78
drivers/cxl/cxl.h
··· 405 405 #define __mock static 406 406 #endif 407 407 408 - #ifdef CONFIG_PROVE_CXL_LOCKING 409 - enum cxl_lock_class { 410 - CXL_ANON_LOCK, 411 - CXL_NVDIMM_LOCK, 412 - CXL_NVDIMM_BRIDGE_LOCK, 413 - CXL_PORT_LOCK, 414 - /* 415 - * Be careful to add new lock classes here, CXL_PORT_LOCK is 416 - * extended by the port depth, so a maximum CXL port topology 417 - * depth would need to be defined first. 418 - */ 419 - }; 420 - 421 - static inline void cxl_nested_lock(struct device *dev) 422 - { 423 - if (is_cxl_port(dev)) { 424 - struct cxl_port *port = to_cxl_port(dev); 425 - 426 - mutex_lock_nested(&dev->lockdep_mutex, 427 - CXL_PORT_LOCK + port->depth); 428 - } else if (is_cxl_decoder(dev)) { 429 - struct cxl_port *port = to_cxl_port(dev->parent); 430 - 431 - /* 432 - * A decoder is the immediate child of a port, so set 433 - * its lock class equal to other child device siblings. 434 - */ 435 - mutex_lock_nested(&dev->lockdep_mutex, 436 - CXL_PORT_LOCK + port->depth + 1); 437 - } else if (is_cxl_nvdimm_bridge(dev)) 438 - mutex_lock_nested(&dev->lockdep_mutex, CXL_NVDIMM_BRIDGE_LOCK); 439 - else if (is_cxl_nvdimm(dev)) 440 - mutex_lock_nested(&dev->lockdep_mutex, CXL_NVDIMM_LOCK); 441 - else 442 - mutex_lock_nested(&dev->lockdep_mutex, CXL_ANON_LOCK); 443 - } 444 - 445 - static inline void cxl_nested_unlock(struct device *dev) 446 - { 447 - mutex_unlock(&dev->lockdep_mutex); 448 - } 449 - 450 - static inline void cxl_device_lock(struct device *dev) 451 - { 452 - /* 453 - * For double lock errors the lockup will happen before lockdep 454 - * warns at cxl_nested_lock(), so assert explicitly. 455 - */ 456 - lockdep_assert_not_held(&dev->lockdep_mutex); 457 - 458 - device_lock(dev); 459 - cxl_nested_lock(dev); 460 - } 461 - 462 - static inline void cxl_device_unlock(struct device *dev) 463 - { 464 - cxl_nested_unlock(dev); 465 - device_unlock(dev); 466 - } 467 - #else 468 - static inline void cxl_nested_lock(struct device *dev) 469 - { 470 - } 471 - 472 - static inline void cxl_nested_unlock(struct device *dev) 473 - { 474 - } 475 - 476 - static inline void cxl_device_lock(struct device *dev) 477 - { 478 - device_lock(dev); 479 - } 480 - 481 - static inline void cxl_device_unlock(struct device *dev) 482 - { 483 - device_unlock(dev); 484 - } 485 - #endif 486 408 #endif /* __CXL_H__ */
+71 -4
drivers/cxl/cxlmem.h
··· 85 85 size_t size_in; 86 86 size_t size_out; 87 87 u16 return_code; 88 - #define CXL_MBOX_SUCCESS 0 89 88 }; 89 + 90 + /* 91 + * Per CXL 2.0 Section 8.2.8.4.5.1 92 + */ 93 + #define CMD_CMD_RC_TABLE \ 94 + C(SUCCESS, 0, NULL), \ 95 + C(BACKGROUND, -ENXIO, "background cmd started successfully"), \ 96 + C(INPUT, -ENXIO, "cmd input was invalid"), \ 97 + C(UNSUPPORTED, -ENXIO, "cmd is not supported"), \ 98 + C(INTERNAL, -ENXIO, "internal device error"), \ 99 + C(RETRY, -ENXIO, "temporary error, retry once"), \ 100 + C(BUSY, -ENXIO, "ongoing background operation"), \ 101 + C(MEDIADISABLED, -ENXIO, "media access is disabled"), \ 102 + C(FWINPROGRESS, -ENXIO, "one FW package can be transferred at a time"), \ 103 + C(FWOOO, -ENXIO, "FW package content was transferred out of order"), \ 104 + C(FWAUTH, -ENXIO, "FW package authentication failed"), \ 105 + C(FWSLOT, -ENXIO, "FW slot is not supported for requested operation"), \ 106 + C(FWROLLBACK, -ENXIO, "rolled back to the previous active FW"), \ 107 + C(FWRESET, -ENXIO, "FW failed to activate, needs cold reset"), \ 108 + C(HANDLE, -ENXIO, "one or more Event Record Handles were invalid"), \ 109 + C(PADDR, -ENXIO, "physical address specified is invalid"), \ 110 + C(POISONLMT, -ENXIO, "poison injection limit has been reached"), \ 111 + C(MEDIAFAILURE, -ENXIO, "permanent issue with the media"), \ 112 + C(ABORT, -ENXIO, "background cmd was aborted by device"), \ 113 + C(SECURITY, -ENXIO, "not valid in the current security state"), \ 114 + C(PASSPHRASE, -ENXIO, "phrase doesn't match current set passphrase"), \ 115 + C(MBUNSUPPORTED, -ENXIO, "unsupported on the mailbox it was issued on"),\ 116 + C(PAYLOADLEN, -ENXIO, "invalid payload length") 117 + 118 + #undef C 119 + #define C(a, b, c) CXL_MBOX_CMD_RC_##a 120 + enum { CMD_CMD_RC_TABLE }; 121 + #undef C 122 + #define C(a, b, c) { b, c } 123 + struct cxl_mbox_cmd_rc { 124 + int err; 125 + const char *desc; 126 + }; 127 + 128 + static const 129 + struct cxl_mbox_cmd_rc cxl_mbox_cmd_rctable[] ={ CMD_CMD_RC_TABLE }; 130 + #undef C 131 + 132 + static inline const char *cxl_mbox_cmd_rc2str(struct cxl_mbox_cmd *mbox_cmd) 133 + { 134 + return cxl_mbox_cmd_rctable[mbox_cmd->return_code].desc; 135 + } 136 + 137 + static inline int cxl_mbox_cmd_rc2errno(struct cxl_mbox_cmd *mbox_cmd) 138 + { 139 + return cxl_mbox_cmd_rctable[mbox_cmd->return_code].err; 140 + } 90 141 91 142 /* 92 143 * CXL 2.0 - Memory capacity multiplier ··· 192 141 * @info: Cached DVSEC information about the device. 193 142 * @serial: PCIe Device Serial Number 194 143 * @mbox_send: @dev specific transport for transmitting mailbox commands 195 - * @wait_media_ready: @dev specific method to await media ready 196 144 * 197 145 * See section 8.2.9.5.2 Capacity Configuration and Label Storage for 198 146 * details on capacity parameters. ··· 222 172 u64 next_persistent_bytes; 223 173 224 174 resource_size_t component_reg_phys; 225 - struct cxl_endpoint_dvsec_info info; 226 175 u64 serial; 227 176 228 177 int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); 229 - int (*wait_media_ready)(struct cxl_dev_state *cxlds); 230 178 }; 231 179 232 180 enum cxl_opcode { ··· 310 262 u8 data[]; 311 263 } __packed; 312 264 265 + struct cxl_mbox_set_partition_info { 266 + __le64 volatile_capacity; 267 + u8 flags; 268 + } __packed; 269 + 270 + #define CXL_SET_PARTITION_IMMEDIATE_FLAG BIT(0) 271 + 313 272 /** 314 273 * struct cxl_mem_command - Driver representation of a memory device command 315 274 * @info: Command information as it exists for the UAPI ··· 345 290 int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in, 346 291 size_t in_size, void *out, size_t out_size); 347 292 int cxl_dev_state_identify(struct cxl_dev_state *cxlds); 293 + int cxl_await_media_ready(struct cxl_dev_state *cxlds); 348 294 int cxl_enumerate_cmds(struct cxl_dev_state *cxlds); 349 295 int cxl_mem_create_range_info(struct cxl_dev_state *cxlds); 350 296 struct cxl_dev_state *cxl_dev_state_create(struct device *dev); 351 297 void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); 352 298 void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); 299 + #ifdef CONFIG_CXL_SUSPEND 300 + void cxl_mem_active_inc(void); 301 + void cxl_mem_active_dec(void); 302 + #else 303 + static inline void cxl_mem_active_inc(void) 304 + { 305 + } 306 + static inline void cxl_mem_active_dec(void) 307 + { 308 + } 309 + #endif 353 310 354 311 struct cxl_hdm { 355 312 struct cxl_component_regs regs;
+2
drivers/cxl/cxlpci.h
··· 72 72 } 73 73 74 74 int devm_cxl_port_enumerate_dports(struct cxl_port *port); 75 + struct cxl_dev_state; 76 + int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm); 75 77 #endif /* __CXL_PCI_H__ */
+24 -124
drivers/cxl/mem.c
··· 24 24 * in higher level operations. 25 25 */ 26 26 27 - static int wait_for_media(struct cxl_memdev *cxlmd) 28 - { 29 - struct cxl_dev_state *cxlds = cxlmd->cxlds; 30 - struct cxl_endpoint_dvsec_info *info = &cxlds->info; 31 - int rc; 32 - 33 - if (!info->mem_enabled) 34 - return -EBUSY; 35 - 36 - rc = cxlds->wait_media_ready(cxlds); 37 - if (rc) 38 - return rc; 39 - 40 - /* 41 - * We know the device is active, and enabled, if any ranges are non-zero 42 - * we'll need to check later before adding the port since that owns the 43 - * HDM decoder registers. 44 - */ 45 - return 0; 46 - } 47 - 48 27 static int create_endpoint(struct cxl_memdev *cxlmd, 49 28 struct cxl_port *parent_port) 50 29 { ··· 46 67 return cxl_endpoint_autoremove(cxlmd, endpoint); 47 68 } 48 69 49 - /** 50 - * cxl_dvsec_decode_init() - Setup HDM decoding for the endpoint 51 - * @cxlds: Device state 52 - * 53 - * Additionally, enables global HDM decoding. Warning: don't call this outside 54 - * of probe. Once probe is complete, the port driver owns all access to the HDM 55 - * decoder registers. 56 - * 57 - * Returns: false if DVSEC Ranges are being used instead of HDM 58 - * decoders, or if it can not be determined if DVSEC Ranges are in use. 59 - * Otherwise, returns true. 60 - */ 61 - __mock bool cxl_dvsec_decode_init(struct cxl_dev_state *cxlds) 70 + static void enable_suspend(void *data) 62 71 { 63 - struct cxl_endpoint_dvsec_info *info = &cxlds->info; 64 - struct cxl_register_map map; 65 - struct cxl_component_reg_map *cmap = &map.component_map; 66 - bool global_enable, do_hdm_init = false; 67 - void __iomem *crb; 68 - u32 global_ctrl; 69 - 70 - /* map hdm decoder */ 71 - crb = ioremap(cxlds->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE); 72 - if (!crb) { 73 - dev_dbg(cxlds->dev, "Failed to map component registers\n"); 74 - return false; 75 - } 76 - 77 - cxl_probe_component_regs(cxlds->dev, crb, cmap); 78 - if (!cmap->hdm_decoder.valid) { 79 - dev_dbg(cxlds->dev, "Invalid HDM decoder registers\n"); 80 - goto out; 81 - } 82 - 83 - global_ctrl = readl(crb + cmap->hdm_decoder.offset + 84 - CXL_HDM_DECODER_CTRL_OFFSET); 85 - global_enable = global_ctrl & CXL_HDM_DECODER_ENABLE; 86 - if (!global_enable && info->ranges) { 87 - dev_dbg(cxlds->dev, 88 - "DVSEC ranges already programmed and HDM decoders not enabled.\n"); 89 - goto out; 90 - } 91 - 92 - do_hdm_init = true; 93 - 94 - /* 95 - * Permanently (for this boot at least) opt the device into HDM 96 - * operation. Individual HDM decoders still need to be enabled after 97 - * this point. 98 - */ 99 - if (!global_enable) { 100 - dev_dbg(cxlds->dev, "Enabling HDM decode\n"); 101 - writel(global_ctrl | CXL_HDM_DECODER_ENABLE, 102 - crb + cmap->hdm_decoder.offset + 103 - CXL_HDM_DECODER_CTRL_OFFSET); 104 - } 105 - 106 - out: 107 - iounmap(crb); 108 - return do_hdm_init; 72 + cxl_mem_active_dec(); 109 73 } 110 74 111 75 static int cxl_mem_probe(struct device *dev) 112 76 { 113 77 struct cxl_memdev *cxlmd = to_cxl_memdev(dev); 114 - struct cxl_dev_state *cxlds = cxlmd->cxlds; 115 78 struct cxl_port *parent_port; 116 79 int rc; 117 80 ··· 68 147 if (work_pending(&cxlmd->detach_work)) 69 148 return -EBUSY; 70 149 71 - rc = wait_for_media(cxlmd); 72 - if (rc) { 73 - dev_err(dev, "Media not active (%d)\n", rc); 74 - return rc; 75 - } 76 - 77 - /* 78 - * If DVSEC ranges are being used instead of HDM decoder registers there 79 - * is no use in trying to manage those. 80 - */ 81 - if (!cxl_dvsec_decode_init(cxlds)) { 82 - struct cxl_endpoint_dvsec_info *info = &cxlds->info; 83 - int i; 84 - 85 - /* */ 86 - for (i = 0; i < 2; i++) { 87 - u64 base, size; 88 - 89 - /* 90 - * Give a nice warning to the user that BIOS has really 91 - * botched things for them if it didn't place DVSEC 92 - * ranges in the memory map. 93 - */ 94 - base = info->dvsec_range[i].start; 95 - size = range_len(&info->dvsec_range[i]); 96 - if (size && !region_intersects(base, size, 97 - IORESOURCE_SYSTEM_RAM, 98 - IORES_DESC_NONE)) { 99 - dev_err(dev, 100 - "DVSEC range %#llx-%#llx must be reserved by BIOS, but isn't\n", 101 - base, base + size - 1); 102 - } 103 - } 104 - dev_err(dev, 105 - "Active DVSEC range registers in use. Will not bind.\n"); 106 - return -EBUSY; 107 - } 108 - 109 150 rc = devm_cxl_enumerate_ports(cxlmd); 110 151 if (rc) 111 152 return rc; ··· 78 195 return -ENXIO; 79 196 } 80 197 81 - cxl_device_lock(&parent_port->dev); 198 + device_lock(&parent_port->dev); 82 199 if (!parent_port->dev.driver) { 83 200 dev_err(dev, "CXL port topology %s not enabled\n", 84 201 dev_name(&parent_port->dev)); 85 202 rc = -ENXIO; 86 - goto out; 203 + goto unlock; 87 204 } 88 205 89 206 rc = create_endpoint(cxlmd, parent_port); 90 - out: 91 - cxl_device_unlock(&parent_port->dev); 207 + unlock: 208 + device_unlock(&parent_port->dev); 92 209 put_device(&parent_port->dev); 93 - return rc; 210 + if (rc) 211 + return rc; 212 + 213 + /* 214 + * The kernel may be operating out of CXL memory on this device, 215 + * there is no spec defined way to determine whether this device 216 + * preserves contents over suspend, and there is no simple way 217 + * to arrange for the suspend image to avoid CXL memory which 218 + * would setup a circular dependency between PCI resume and save 219 + * state restoration. 220 + * 221 + * TODO: support suspend when all the regions this device is 222 + * hosting are locked and covered by the system address map, 223 + * i.e. platform firmware owns restoring the HDM configuration 224 + * that it locked. 225 + */ 226 + cxl_mem_active_inc(); 227 + return devm_add_action_or_reset(dev, enable_suspend, NULL); 94 228 } 95 229 96 230 static struct cxl_driver cxl_mem_driver = {
+5 -170
drivers/cxl/pci.c
··· 48 48 */ 49 49 static unsigned short mbox_ready_timeout = 60; 50 50 module_param(mbox_ready_timeout, ushort, 0644); 51 - MODULE_PARM_DESC(mbox_ready_timeout, 52 - "seconds to wait for mailbox ready / memory active status"); 51 + MODULE_PARM_DESC(mbox_ready_timeout, "seconds to wait for mailbox ready"); 53 52 54 53 static int cxl_pci_mbox_wait_for_doorbell(struct cxl_dev_state *cxlds) 55 54 { ··· 176 177 mbox_cmd->return_code = 177 178 FIELD_GET(CXLDEV_MBOX_STATUS_RET_CODE_MASK, status_reg); 178 179 179 - if (mbox_cmd->return_code != 0) { 180 - dev_dbg(dev, "Mailbox operation had an error\n"); 181 - return 0; 180 + if (mbox_cmd->return_code != CXL_MBOX_CMD_RC_SUCCESS) { 181 + dev_dbg(dev, "Mailbox operation had an error: %s\n", 182 + cxl_mbox_cmd_rc2str(mbox_cmd)); 183 + return 0; /* completed but caller must check return_code */ 182 184 } 183 185 184 186 /* #7 */ ··· 386 386 return rc; 387 387 } 388 388 389 - static int wait_for_valid(struct cxl_dev_state *cxlds) 390 - { 391 - struct pci_dev *pdev = to_pci_dev(cxlds->dev); 392 - int d = cxlds->cxl_dvsec, rc; 393 - u32 val; 394 - 395 - /* 396 - * Memory_Info_Valid: When set, indicates that the CXL Range 1 Size high 397 - * and Size Low registers are valid. Must be set within 1 second of 398 - * deassertion of reset to CXL device. Likely it is already set by the 399 - * time this runs, but otherwise give a 1.5 second timeout in case of 400 - * clock skew. 401 - */ 402 - rc = pci_read_config_dword(pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &val); 403 - if (rc) 404 - return rc; 405 - 406 - if (val & CXL_DVSEC_MEM_INFO_VALID) 407 - return 0; 408 - 409 - msleep(1500); 410 - 411 - rc = pci_read_config_dword(pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &val); 412 - if (rc) 413 - return rc; 414 - 415 - if (val & CXL_DVSEC_MEM_INFO_VALID) 416 - return 0; 417 - 418 - return -ETIMEDOUT; 419 - } 420 - 421 - /* 422 - * Wait up to @mbox_ready_timeout for the device to report memory 423 - * active. 424 - */ 425 - static int wait_for_media_ready(struct cxl_dev_state *cxlds) 426 - { 427 - struct pci_dev *pdev = to_pci_dev(cxlds->dev); 428 - int d = cxlds->cxl_dvsec; 429 - bool active = false; 430 - u64 md_status; 431 - int rc, i; 432 - 433 - rc = wait_for_valid(cxlds); 434 - if (rc) 435 - return rc; 436 - 437 - for (i = mbox_ready_timeout; i; i--) { 438 - u32 temp; 439 - 440 - rc = pci_read_config_dword( 441 - pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &temp); 442 - if (rc) 443 - return rc; 444 - 445 - active = FIELD_GET(CXL_DVSEC_MEM_ACTIVE, temp); 446 - if (active) 447 - break; 448 - msleep(1000); 449 - } 450 - 451 - if (!active) { 452 - dev_err(&pdev->dev, 453 - "timeout awaiting memory active after %d seconds\n", 454 - mbox_ready_timeout); 455 - return -ETIMEDOUT; 456 - } 457 - 458 - md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET); 459 - if (!CXLMDEV_READY(md_status)) 460 - return -EIO; 461 - 462 - return 0; 463 - } 464 - 465 - static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds) 466 - { 467 - struct cxl_endpoint_dvsec_info *info = &cxlds->info; 468 - struct pci_dev *pdev = to_pci_dev(cxlds->dev); 469 - int d = cxlds->cxl_dvsec; 470 - int hdm_count, rc, i; 471 - u16 cap, ctrl; 472 - 473 - if (!d) 474 - return -ENXIO; 475 - 476 - rc = pci_read_config_word(pdev, d + CXL_DVSEC_CAP_OFFSET, &cap); 477 - if (rc) 478 - return rc; 479 - 480 - rc = pci_read_config_word(pdev, d + CXL_DVSEC_CTRL_OFFSET, &ctrl); 481 - if (rc) 482 - return rc; 483 - 484 - if (!(cap & CXL_DVSEC_MEM_CAPABLE)) 485 - return -ENXIO; 486 - 487 - /* 488 - * It is not allowed by spec for MEM.capable to be set and have 0 legacy 489 - * HDM decoders (values > 2 are also undefined as of CXL 2.0). As this 490 - * driver is for a spec defined class code which must be CXL.mem 491 - * capable, there is no point in continuing to enable CXL.mem. 492 - */ 493 - hdm_count = FIELD_GET(CXL_DVSEC_HDM_COUNT_MASK, cap); 494 - if (!hdm_count || hdm_count > 2) 495 - return -EINVAL; 496 - 497 - rc = wait_for_valid(cxlds); 498 - if (rc) 499 - return rc; 500 - 501 - info->mem_enabled = FIELD_GET(CXL_DVSEC_MEM_ENABLE, ctrl); 502 - 503 - for (i = 0; i < hdm_count; i++) { 504 - u64 base, size; 505 - u32 temp; 506 - 507 - rc = pci_read_config_dword( 508 - pdev, d + CXL_DVSEC_RANGE_SIZE_HIGH(i), &temp); 509 - if (rc) 510 - return rc; 511 - 512 - size = (u64)temp << 32; 513 - 514 - rc = pci_read_config_dword( 515 - pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(i), &temp); 516 - if (rc) 517 - return rc; 518 - 519 - size |= temp & CXL_DVSEC_MEM_SIZE_LOW_MASK; 520 - 521 - rc = pci_read_config_dword( 522 - pdev, d + CXL_DVSEC_RANGE_BASE_HIGH(i), &temp); 523 - if (rc) 524 - return rc; 525 - 526 - base = (u64)temp << 32; 527 - 528 - rc = pci_read_config_dword( 529 - pdev, d + CXL_DVSEC_RANGE_BASE_LOW(i), &temp); 530 - if (rc) 531 - return rc; 532 - 533 - base |= temp & CXL_DVSEC_MEM_BASE_LOW_MASK; 534 - 535 - info->dvsec_range[i] = (struct range) { 536 - .start = base, 537 - .end = base + size - 1 538 - }; 539 - 540 - if (size) 541 - info->ranges++; 542 - } 543 - 544 - return 0; 545 - } 546 - 547 389 static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 548 390 { 549 391 struct cxl_register_map map; ··· 414 572 if (!cxlds->cxl_dvsec) 415 573 dev_warn(&pdev->dev, 416 574 "Device DVSEC not present, skip CXL.mem init\n"); 417 - 418 - cxlds->wait_media_ready = wait_for_media_ready; 419 575 420 576 rc = cxl_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map); 421 577 if (rc) ··· 449 609 rc = cxl_mem_create_range_info(cxlds); 450 610 if (rc) 451 611 return rc; 452 - 453 - rc = cxl_dvsec_ranges(cxlds); 454 - if (rc) 455 - dev_warn(&pdev->dev, 456 - "Failed to get DVSEC range information (%d)\n", rc); 457 612 458 613 cxlmd = devm_cxl_add_memdev(cxlds); 459 614 if (IS_ERR(cxlmd))
+6 -7
drivers/cxl/pmem.c
··· 43 43 if (!cxl_nvb) 44 44 return -ENXIO; 45 45 46 - cxl_device_lock(&cxl_nvb->dev); 46 + device_lock(&cxl_nvb->dev); 47 47 if (!cxl_nvb->nvdimm_bus) { 48 48 rc = -ENXIO; 49 49 goto out; ··· 68 68 dev_set_drvdata(dev, nvdimm); 69 69 rc = devm_add_action_or_reset(dev, unregister_nvdimm, nvdimm); 70 70 out: 71 - cxl_device_unlock(&cxl_nvb->dev); 71 + device_unlock(&cxl_nvb->dev); 72 72 put_device(&cxl_nvb->dev); 73 73 74 74 return rc; ··· 233 233 struct nvdimm_bus *victim_bus = NULL; 234 234 bool release = false, rescan = false; 235 235 236 - cxl_device_lock(&cxl_nvb->dev); 236 + device_lock(&cxl_nvb->dev); 237 237 switch (cxl_nvb->state) { 238 238 case CXL_NVB_ONLINE: 239 239 if (!online_nvdimm_bus(cxl_nvb)) { ··· 251 251 default: 252 252 break; 253 253 } 254 - cxl_device_unlock(&cxl_nvb->dev); 254 + device_unlock(&cxl_nvb->dev); 255 255 256 256 if (release) 257 257 device_release_driver(&cxl_nvb->dev); ··· 327 327 return 0; 328 328 329 329 cxl_nvb = to_cxl_nvdimm_bridge(dev); 330 - cxl_device_lock(dev); 330 + device_lock(dev); 331 331 cxl_nvb->state = CXL_NVB_NEW; 332 - cxl_device_unlock(dev); 332 + device_unlock(dev); 333 333 334 334 return 0; 335 335 } ··· 344 344 { 345 345 int rc; 346 346 347 - set_bit(CXL_MEM_COMMAND_ID_SET_PARTITION_INFO, exclusive_cmds); 348 347 set_bit(CXL_MEM_COMMAND_ID_SET_SHUTDOWN_STATE, exclusive_cmds); 349 348 set_bit(CXL_MEM_COMMAND_ID_SET_LSA, exclusive_cmds); 350 349
+21 -7
drivers/cxl/port.c
··· 36 36 struct cxl_hdm *cxlhdm; 37 37 int rc; 38 38 39 - if (is_cxl_endpoint(port)) { 40 - struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport); 41 39 42 - get_device(&cxlmd->dev); 43 - rc = devm_add_action_or_reset(dev, schedule_detach, cxlmd); 44 - if (rc) 45 - return rc; 46 - } else { 40 + if (!is_cxl_endpoint(port)) { 47 41 rc = devm_cxl_port_enumerate_dports(port); 48 42 if (rc < 0) 49 43 return rc; ··· 48 54 cxlhdm = devm_cxl_setup_hdm(port); 49 55 if (IS_ERR(cxlhdm)) 50 56 return PTR_ERR(cxlhdm); 57 + 58 + if (is_cxl_endpoint(port)) { 59 + struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport); 60 + struct cxl_dev_state *cxlds = cxlmd->cxlds; 61 + 62 + get_device(&cxlmd->dev); 63 + rc = devm_add_action_or_reset(dev, schedule_detach, cxlmd); 64 + if (rc) 65 + return rc; 66 + 67 + rc = cxl_hdm_decode_init(cxlds, cxlhdm); 68 + if (rc) 69 + return rc; 70 + 71 + rc = cxl_await_media_ready(cxlds); 72 + if (rc) { 73 + dev_err(dev, "Media not active (%d)\n", rc); 74 + return rc; 75 + } 76 + } 51 77 52 78 rc = devm_cxl_enumerate_decoders(cxlhdm); 53 79 if (rc) {
+13 -10
drivers/nvdimm/btt_devs.c
··· 50 50 struct nd_btt *nd_btt = to_nd_btt(dev); 51 51 ssize_t rc; 52 52 53 - nd_device_lock(dev); 53 + device_lock(dev); 54 54 nvdimm_bus_lock(dev); 55 55 rc = nd_size_select_store(dev, buf, &nd_btt->lbasize, 56 56 btt_lbasize_supported); 57 57 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 58 58 buf[len - 1] == '\n' ? "" : "\n"); 59 59 nvdimm_bus_unlock(dev); 60 - nd_device_unlock(dev); 60 + device_unlock(dev); 61 61 62 62 return rc ? rc : len; 63 63 } ··· 79 79 struct nd_btt *nd_btt = to_nd_btt(dev); 80 80 ssize_t rc; 81 81 82 - nd_device_lock(dev); 82 + device_lock(dev); 83 83 rc = nd_uuid_store(dev, &nd_btt->uuid, buf, len); 84 84 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 85 85 buf[len - 1] == '\n' ? "" : "\n"); 86 - nd_device_unlock(dev); 86 + device_unlock(dev); 87 87 88 88 return rc ? rc : len; 89 89 } ··· 108 108 struct nd_btt *nd_btt = to_nd_btt(dev); 109 109 ssize_t rc; 110 110 111 - nd_device_lock(dev); 111 + device_lock(dev); 112 112 nvdimm_bus_lock(dev); 113 113 rc = nd_namespace_store(dev, &nd_btt->ndns, buf, len); 114 114 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 115 115 buf[len - 1] == '\n' ? "" : "\n"); 116 116 nvdimm_bus_unlock(dev); 117 - nd_device_unlock(dev); 117 + device_unlock(dev); 118 118 119 119 return rc; 120 120 } ··· 126 126 struct nd_btt *nd_btt = to_nd_btt(dev); 127 127 ssize_t rc; 128 128 129 - nd_device_lock(dev); 129 + device_lock(dev); 130 130 if (dev->driver) 131 131 rc = sprintf(buf, "%llu\n", nd_btt->size); 132 132 else { 133 133 /* no size to convey if the btt instance is disabled */ 134 134 rc = -ENXIO; 135 135 } 136 - nd_device_unlock(dev); 136 + device_unlock(dev); 137 137 138 138 return rc; 139 139 } ··· 178 178 } 179 179 EXPORT_SYMBOL(is_nd_btt); 180 180 181 + static struct lock_class_key nvdimm_btt_key; 182 + 181 183 static struct device *__nd_btt_create(struct nd_region *nd_region, 182 184 unsigned long lbasize, uuid_t *uuid, 183 185 struct nd_namespace_common *ndns) ··· 207 205 dev->parent = &nd_region->dev; 208 206 dev->type = &nd_btt_device_type; 209 207 device_initialize(&nd_btt->dev); 208 + lockdep_set_class(&nd_btt->dev.mutex, &nvdimm_btt_key); 210 209 if (ndns && !__nd_attach_ndns(&nd_btt->dev, ndns, &nd_btt->ndns)) { 211 210 dev_dbg(&ndns->dev, "failed, already claimed by %s\n", 212 211 dev_name(ndns->claim)); ··· 228 225 { 229 226 struct device *dev = __nd_btt_create(nd_region, 0, NULL, NULL); 230 227 231 - __nd_device_register(dev); 228 + nd_device_register(dev); 232 229 return dev; 233 230 } 234 231 ··· 327 324 if (!nd_btt->uuid) 328 325 return -ENOMEM; 329 326 330 - __nd_device_register(&nd_btt->dev); 327 + nd_device_register(&nd_btt->dev); 331 328 332 329 return 0; 333 330 }
+16 -22
drivers/nvdimm/bus.c
··· 88 88 dev->driver->name, dev_name(dev)); 89 89 90 90 nvdimm_bus_probe_start(nvdimm_bus); 91 - debug_nvdimm_lock(dev); 92 91 rc = nd_drv->probe(dev); 93 - debug_nvdimm_unlock(dev); 94 - 95 92 if ((rc == 0 || rc == -EOPNOTSUPP) && 96 93 dev->parent && is_nd_region(dev->parent)) 97 94 nd_region_advance_seeds(to_nd_region(dev->parent), dev); ··· 108 111 struct module *provider = to_bus_provider(dev); 109 112 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 110 113 111 - if (nd_drv->remove) { 112 - debug_nvdimm_lock(dev); 114 + if (nd_drv->remove) 113 115 nd_drv->remove(dev); 114 - debug_nvdimm_unlock(dev); 115 - } 116 116 117 117 dev_dbg(&nvdimm_bus->dev, "%s.remove(%s)\n", dev->driver->name, 118 118 dev_name(dev)); ··· 133 139 134 140 void nd_device_notify(struct device *dev, enum nvdimm_event event) 135 141 { 136 - nd_device_lock(dev); 142 + device_lock(dev); 137 143 if (dev->driver) { 138 144 struct nd_device_driver *nd_drv; 139 145 ··· 141 147 if (nd_drv->notify) 142 148 nd_drv->notify(dev, event); 143 149 } 144 - nd_device_unlock(dev); 150 + device_unlock(dev); 145 151 } 146 152 EXPORT_SYMBOL(nd_device_notify); 147 153 ··· 328 334 } 329 335 EXPORT_SYMBOL_GPL(nvdimm_to_bus); 330 336 337 + static struct lock_class_key nvdimm_bus_key; 338 + 331 339 struct nvdimm_bus *nvdimm_bus_register(struct device *parent, 332 340 struct nvdimm_bus_descriptor *nd_desc) 333 341 { ··· 356 360 nvdimm_bus->dev.bus = &nvdimm_bus_type; 357 361 nvdimm_bus->dev.of_node = nd_desc->of_node; 358 362 device_initialize(&nvdimm_bus->dev); 363 + lockdep_set_class(&nvdimm_bus->dev.mutex, &nvdimm_bus_key); 359 364 device_set_pm_not_required(&nvdimm_bus->dev); 360 365 rc = dev_set_name(&nvdimm_bus->dev, "ndbus%d", nvdimm_bus->id); 361 366 if (rc) ··· 508 511 put_device(dev); 509 512 } 510 513 511 - void __nd_device_register(struct device *dev) 514 + void nd_device_register(struct device *dev) 512 515 { 513 516 if (!dev) 514 517 return; ··· 533 536 534 537 async_schedule_dev_domain(nd_async_device_register, dev, 535 538 &nd_async_domain); 536 - } 537 - 538 - void nd_device_register(struct device *dev) 539 - { 540 - device_initialize(dev); 541 - __nd_device_register(dev); 542 539 } 543 540 EXPORT_SYMBOL(nd_device_register); 544 541 ··· 563 572 * or otherwise let the async path handle it if the 564 573 * unregistration was already queued. 565 574 */ 566 - nd_device_lock(dev); 575 + device_lock(dev); 567 576 killed = kill_device(dev); 568 - nd_device_unlock(dev); 577 + device_unlock(dev); 569 578 570 579 if (!killed) 571 580 return; ··· 715 724 kfree(dev); 716 725 } 717 726 727 + static struct lock_class_key nvdimm_ndctl_key; 728 + 718 729 int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus) 719 730 { 720 731 dev_t devt = MKDEV(nvdimm_bus_major, nvdimm_bus->id); ··· 727 734 if (!dev) 728 735 return -ENOMEM; 729 736 device_initialize(dev); 737 + lockdep_set_class(&dev->mutex, &nvdimm_ndctl_key); 730 738 device_set_pm_not_required(dev); 731 739 dev->class = nd_class; 732 740 dev->parent = &nvdimm_bus->dev; ··· 924 930 if (nvdimm_bus->probe_active == 0) 925 931 break; 926 932 nvdimm_bus_unlock(dev); 927 - nd_device_unlock(dev); 933 + device_unlock(dev); 928 934 wait_event(nvdimm_bus->wait, 929 935 nvdimm_bus->probe_active == 0); 930 - nd_device_lock(dev); 936 + device_lock(dev); 931 937 nvdimm_bus_lock(dev); 932 938 } while (true); 933 939 } ··· 1161 1167 goto out; 1162 1168 } 1163 1169 1164 - nd_device_lock(dev); 1170 + device_lock(dev); 1165 1171 nvdimm_bus_lock(dev); 1166 1172 rc = nd_cmd_clear_to_send(nvdimm_bus, nvdimm, func, buf); 1167 1173 if (rc) ··· 1183 1189 1184 1190 out_unlock: 1185 1191 nvdimm_bus_unlock(dev); 1186 - nd_device_unlock(dev); 1192 + device_unlock(dev); 1187 1193 out: 1188 1194 kfree(in_env); 1189 1195 kfree(out_env);
+5 -14
drivers/nvdimm/core.c
··· 215 215 * 216 216 * Enforce that uuids can only be changed while the device is disabled 217 217 * (driver detached) 218 - * LOCKING: expects nd_device_lock() is held on entry 218 + * LOCKING: expects device_lock() is held on entry 219 219 */ 220 220 int nd_uuid_store(struct device *dev, uuid_t **uuid_out, const char *buf, 221 221 size_t len) ··· 316 316 317 317 static int flush_namespaces(struct device *dev, void *data) 318 318 { 319 - nd_device_lock(dev); 320 - nd_device_unlock(dev); 319 + device_lock(dev); 320 + device_unlock(dev); 321 321 return 0; 322 322 } 323 323 324 324 static int flush_regions_dimms(struct device *dev, void *data) 325 325 { 326 - nd_device_lock(dev); 327 - nd_device_unlock(dev); 326 + device_lock(dev); 327 + device_unlock(dev); 328 328 device_for_each_child(dev, NULL, flush_namespaces); 329 329 return 0; 330 330 } ··· 368 368 if (!nd_desc->fw_ops) 369 369 return -EOPNOTSUPP; 370 370 371 - nvdimm_bus_lock(dev); 372 371 cap = nd_desc->fw_ops->capability(nd_desc); 373 - nvdimm_bus_unlock(dev); 374 372 375 373 switch (cap) { 376 374 case NVDIMM_FWA_CAP_QUIESCE: ··· 393 395 if (!nd_desc->fw_ops) 394 396 return -EOPNOTSUPP; 395 397 396 - nvdimm_bus_lock(dev); 397 398 cap = nd_desc->fw_ops->capability(nd_desc); 398 399 state = nd_desc->fw_ops->activate_state(nd_desc); 399 - nvdimm_bus_unlock(dev); 400 400 401 401 if (cap < NVDIMM_FWA_CAP_QUIESCE) 402 402 return -EOPNOTSUPP; ··· 439 443 else 440 444 return -EINVAL; 441 445 442 - nvdimm_bus_lock(dev); 443 446 state = nd_desc->fw_ops->activate_state(nd_desc); 444 447 445 448 switch (state) { ··· 456 461 default: 457 462 rc = -ENXIO; 458 463 } 459 - nvdimm_bus_unlock(dev); 460 464 461 465 if (rc == 0) 462 466 rc = len; ··· 478 484 if (!nd_desc->fw_ops) 479 485 return 0; 480 486 481 - nvdimm_bus_lock(dev); 482 487 cap = nd_desc->fw_ops->capability(nd_desc); 483 - nvdimm_bus_unlock(dev); 484 - 485 488 if (cap < NVDIMM_FWA_CAP_QUIESCE) 486 489 return 0; 487 490
+2 -2
drivers/nvdimm/dax_devs.c
··· 80 80 nd_dax = nd_dax_alloc(nd_region); 81 81 if (nd_dax) 82 82 dev = nd_pfn_devinit(&nd_dax->nd_pfn, NULL); 83 - __nd_device_register(dev); 83 + nd_device_register(dev); 84 84 return dev; 85 85 } 86 86 ··· 119 119 nd_detach_ndns(dax_dev, &nd_pfn->ndns); 120 120 put_device(dax_dev); 121 121 } else 122 - __nd_device_register(dax_dev); 122 + nd_device_register(dax_dev); 123 123 124 124 return rc; 125 125 }
+8 -4
drivers/nvdimm/dimm_devs.c
··· 341 341 { 342 342 ssize_t rc; 343 343 344 - nd_device_lock(dev); 344 + device_lock(dev); 345 345 rc = __available_slots_show(dev_get_drvdata(dev), buf); 346 - nd_device_unlock(dev); 346 + device_unlock(dev); 347 347 348 348 return rc; 349 349 } ··· 386 386 * done while probing is idle and the DIMM is not in active use 387 387 * in any region. 388 388 */ 389 - nd_device_lock(dev); 389 + device_lock(dev); 390 390 nvdimm_bus_lock(dev); 391 391 wait_nvdimm_bus_probe_idle(dev); 392 392 rc = nvdimm_security_store(dev, buf, len); 393 393 nvdimm_bus_unlock(dev); 394 - nd_device_unlock(dev); 394 + device_unlock(dev); 395 395 396 396 return rc; 397 397 } ··· 570 570 return dev->type == &nvdimm_device_type; 571 571 } 572 572 573 + static struct lock_class_key nvdimm_key; 574 + 573 575 struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus, 574 576 void *provider_data, const struct attribute_group **groups, 575 577 unsigned long flags, unsigned long cmd_mask, int num_flush, ··· 615 613 /* get security state and extended (master) state */ 616 614 nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); 617 615 nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER); 616 + device_initialize(dev); 617 + lockdep_set_class(&dev->mutex, &nvdimm_key); 618 618 nd_device_register(dev); 619 619 620 620 return nvdimm;
+27 -19
drivers/nvdimm/namespace_devs.c
··· 264 264 struct nd_region *nd_region = to_nd_region(dev->parent); 265 265 ssize_t rc; 266 266 267 - nd_device_lock(dev); 267 + device_lock(dev); 268 268 nvdimm_bus_lock(dev); 269 269 wait_nvdimm_bus_probe_idle(dev); 270 270 rc = __alt_name_store(dev, buf, len); ··· 272 272 rc = nd_namespace_label_update(nd_region, dev); 273 273 dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc); 274 274 nvdimm_bus_unlock(dev); 275 - nd_device_unlock(dev); 275 + device_unlock(dev); 276 276 277 277 return rc < 0 ? rc : len; 278 278 } ··· 846 846 if (rc) 847 847 return rc; 848 848 849 - nd_device_lock(dev); 849 + device_lock(dev); 850 850 nvdimm_bus_lock(dev); 851 851 wait_nvdimm_bus_probe_idle(dev); 852 852 rc = __size_store(dev, val); ··· 868 868 dev_dbg(dev, "%llx %s (%d)\n", val, rc < 0 ? "fail" : "success", rc); 869 869 870 870 nvdimm_bus_unlock(dev); 871 - nd_device_unlock(dev); 871 + device_unlock(dev); 872 872 873 873 return rc < 0 ? rc : len; 874 874 } ··· 1043 1043 } else 1044 1044 return -ENXIO; 1045 1045 1046 - nd_device_lock(dev); 1046 + device_lock(dev); 1047 1047 nvdimm_bus_lock(dev); 1048 1048 wait_nvdimm_bus_probe_idle(dev); 1049 1049 if (to_ndns(dev)->claim) ··· 1059 1059 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 1060 1060 buf[len - 1] == '\n' ? "" : "\n"); 1061 1061 nvdimm_bus_unlock(dev); 1062 - nd_device_unlock(dev); 1062 + device_unlock(dev); 1063 1063 1064 1064 return rc < 0 ? rc : len; 1065 1065 } ··· 1118 1118 } else 1119 1119 return -ENXIO; 1120 1120 1121 - nd_device_lock(dev); 1121 + device_lock(dev); 1122 1122 nvdimm_bus_lock(dev); 1123 1123 if (to_ndns(dev)->claim) 1124 1124 rc = -EBUSY; ··· 1129 1129 dev_dbg(dev, "result: %zd %s: %s%s", rc, rc < 0 ? "tried" : "wrote", 1130 1130 buf, buf[len - 1] == '\n' ? "" : "\n"); 1131 1131 nvdimm_bus_unlock(dev); 1132 - nd_device_unlock(dev); 1132 + device_unlock(dev); 1133 1133 1134 1134 return rc ? rc : len; 1135 1135 } ··· 1239 1239 struct nd_namespace_common *ndns = to_ndns(dev); 1240 1240 ssize_t rc; 1241 1241 1242 - nd_device_lock(dev); 1242 + device_lock(dev); 1243 1243 rc = sprintf(buf, "%s\n", ndns->claim ? dev_name(ndns->claim) : ""); 1244 - nd_device_unlock(dev); 1244 + device_unlock(dev); 1245 1245 1246 1246 return rc; 1247 1247 } ··· 1278 1278 struct nd_region *nd_region = to_nd_region(dev->parent); 1279 1279 int rc; 1280 1280 1281 - nd_device_lock(dev); 1281 + device_lock(dev); 1282 1282 nvdimm_bus_lock(dev); 1283 1283 wait_nvdimm_bus_probe_idle(dev); 1284 1284 rc = __holder_class_store(dev, buf); ··· 1286 1286 rc = nd_namespace_label_update(nd_region, dev); 1287 1287 dev_dbg(dev, "%s(%d)\n", rc < 0 ? "fail " : "", rc); 1288 1288 nvdimm_bus_unlock(dev); 1289 - nd_device_unlock(dev); 1289 + device_unlock(dev); 1290 1290 1291 1291 return rc < 0 ? rc : len; 1292 1292 } ··· 1297 1297 struct nd_namespace_common *ndns = to_ndns(dev); 1298 1298 ssize_t rc; 1299 1299 1300 - nd_device_lock(dev); 1300 + device_lock(dev); 1301 1301 if (ndns->claim_class == NVDIMM_CCLASS_NONE) 1302 1302 rc = sprintf(buf, "\n"); 1303 1303 else if ((ndns->claim_class == NVDIMM_CCLASS_BTT) || ··· 1309 1309 rc = sprintf(buf, "dax\n"); 1310 1310 else 1311 1311 rc = sprintf(buf, "<unknown>\n"); 1312 - nd_device_unlock(dev); 1312 + device_unlock(dev); 1313 1313 1314 1314 return rc; 1315 1315 } ··· 1323 1323 char *mode; 1324 1324 ssize_t rc; 1325 1325 1326 - nd_device_lock(dev); 1326 + device_lock(dev); 1327 1327 claim = ndns->claim; 1328 1328 if (claim && is_nd_btt(claim)) 1329 1329 mode = "safe"; ··· 1336 1336 else 1337 1337 mode = "raw"; 1338 1338 rc = sprintf(buf, "%s\n", mode); 1339 - nd_device_unlock(dev); 1339 + device_unlock(dev); 1340 1340 1341 1341 return rc; 1342 1342 } ··· 1456 1456 * Flush any in-progess probes / removals in the driver 1457 1457 * for the raw personality of this namespace. 1458 1458 */ 1459 - nd_device_lock(&ndns->dev); 1460 - nd_device_unlock(&ndns->dev); 1459 + device_lock(&ndns->dev); 1460 + device_unlock(&ndns->dev); 1461 1461 if (ndns->dev.driver) { 1462 1462 dev_dbg(&ndns->dev, "is active, can't bind %s\n", 1463 1463 dev_name(dev)); ··· 1830 1830 return dev; 1831 1831 } 1832 1832 1833 + static struct lock_class_key nvdimm_namespace_key; 1834 + 1833 1835 void nd_region_create_ns_seed(struct nd_region *nd_region) 1834 1836 { 1835 1837 WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev)); ··· 1847 1845 */ 1848 1846 if (!nd_region->ns_seed) 1849 1847 dev_err(&nd_region->dev, "failed to create namespace\n"); 1850 - else 1848 + else { 1849 + device_initialize(nd_region->ns_seed); 1850 + lockdep_set_class(&nd_region->ns_seed->mutex, 1851 + &nvdimm_namespace_key); 1851 1852 nd_device_register(nd_region->ns_seed); 1853 + } 1852 1854 } 1853 1855 1854 1856 void nd_region_create_dax_seed(struct nd_region *nd_region) ··· 2206 2200 if (id < 0) 2207 2201 break; 2208 2202 dev_set_name(dev, "namespace%d.%d", nd_region->id, id); 2203 + device_initialize(dev); 2204 + lockdep_set_class(&dev->mutex, &nvdimm_namespace_key); 2209 2205 nd_device_register(dev); 2210 2206 } 2211 2207 if (i)
+1 -67
drivers/nvdimm/nd-core.h
··· 106 106 int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus); 107 107 void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus); 108 108 void nd_synchronize(void); 109 - void __nd_device_register(struct device *dev); 109 + void nd_device_register(struct device *dev); 110 110 struct nd_label_id; 111 111 char *nd_label_gen_id(struct nd_label_id *label_id, const uuid_t *uuid, 112 112 u32 flags); ··· 158 158 159 159 static inline void devm_nsio_disable(struct device *dev, 160 160 struct nd_namespace_io *nsio) 161 - { 162 - } 163 - #endif 164 - 165 - #ifdef CONFIG_PROVE_NVDIMM_LOCKING 166 - extern struct class *nd_class; 167 - 168 - enum { 169 - LOCK_BUS, 170 - LOCK_NDCTL, 171 - LOCK_REGION, 172 - LOCK_DIMM = LOCK_REGION, 173 - LOCK_NAMESPACE, 174 - LOCK_CLAIM, 175 - }; 176 - 177 - static inline void debug_nvdimm_lock(struct device *dev) 178 - { 179 - if (is_nd_region(dev)) 180 - mutex_lock_nested(&dev->lockdep_mutex, LOCK_REGION); 181 - else if (is_nvdimm(dev)) 182 - mutex_lock_nested(&dev->lockdep_mutex, LOCK_DIMM); 183 - else if (is_nd_btt(dev) || is_nd_pfn(dev) || is_nd_dax(dev)) 184 - mutex_lock_nested(&dev->lockdep_mutex, LOCK_CLAIM); 185 - else if (dev->parent && (is_nd_region(dev->parent))) 186 - mutex_lock_nested(&dev->lockdep_mutex, LOCK_NAMESPACE); 187 - else if (is_nvdimm_bus(dev)) 188 - mutex_lock_nested(&dev->lockdep_mutex, LOCK_BUS); 189 - else if (dev->class && dev->class == nd_class) 190 - mutex_lock_nested(&dev->lockdep_mutex, LOCK_NDCTL); 191 - else 192 - dev_WARN(dev, "unknown lock level\n"); 193 - } 194 - 195 - static inline void debug_nvdimm_unlock(struct device *dev) 196 - { 197 - mutex_unlock(&dev->lockdep_mutex); 198 - } 199 - 200 - static inline void nd_device_lock(struct device *dev) 201 - { 202 - device_lock(dev); 203 - debug_nvdimm_lock(dev); 204 - } 205 - 206 - static inline void nd_device_unlock(struct device *dev) 207 - { 208 - debug_nvdimm_unlock(dev); 209 - device_unlock(dev); 210 - } 211 - #else 212 - static inline void nd_device_lock(struct device *dev) 213 - { 214 - device_lock(dev); 215 - } 216 - 217 - static inline void nd_device_unlock(struct device *dev) 218 - { 219 - device_unlock(dev); 220 - } 221 - 222 - static inline void debug_nvdimm_lock(struct device *dev) 223 - { 224 - } 225 - 226 - static inline void debug_nvdimm_unlock(struct device *dev) 227 161 { 228 162 } 229 163 #endif
+17 -14
drivers/nvdimm/pfn_devs.c
··· 55 55 struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); 56 56 ssize_t rc = 0; 57 57 58 - nd_device_lock(dev); 58 + device_lock(dev); 59 59 nvdimm_bus_lock(dev); 60 60 if (dev->driver) 61 61 rc = -EBUSY; ··· 77 77 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 78 78 buf[len - 1] == '\n' ? "" : "\n"); 79 79 nvdimm_bus_unlock(dev); 80 - nd_device_unlock(dev); 80 + device_unlock(dev); 81 81 82 82 return rc ? rc : len; 83 83 } ··· 123 123 unsigned long aligns[MAX_NVDIMM_ALIGN] = { [0] = 0, }; 124 124 ssize_t rc; 125 125 126 - nd_device_lock(dev); 126 + device_lock(dev); 127 127 nvdimm_bus_lock(dev); 128 128 rc = nd_size_select_store(dev, buf, &nd_pfn->align, 129 129 nd_pfn_supported_alignments(aligns)); 130 130 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 131 131 buf[len - 1] == '\n' ? "" : "\n"); 132 132 nvdimm_bus_unlock(dev); 133 - nd_device_unlock(dev); 133 + device_unlock(dev); 134 134 135 135 return rc ? rc : len; 136 136 } ··· 152 152 struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); 153 153 ssize_t rc; 154 154 155 - nd_device_lock(dev); 155 + device_lock(dev); 156 156 rc = nd_uuid_store(dev, &nd_pfn->uuid, buf, len); 157 157 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 158 158 buf[len - 1] == '\n' ? "" : "\n"); 159 - nd_device_unlock(dev); 159 + device_unlock(dev); 160 160 161 161 return rc ? rc : len; 162 162 } ··· 181 181 struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); 182 182 ssize_t rc; 183 183 184 - nd_device_lock(dev); 184 + device_lock(dev); 185 185 nvdimm_bus_lock(dev); 186 186 rc = nd_namespace_store(dev, &nd_pfn->ndns, buf, len); 187 187 dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, 188 188 buf[len - 1] == '\n' ? "" : "\n"); 189 189 nvdimm_bus_unlock(dev); 190 - nd_device_unlock(dev); 190 + device_unlock(dev); 191 191 192 192 return rc; 193 193 } ··· 199 199 struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); 200 200 ssize_t rc; 201 201 202 - nd_device_lock(dev); 202 + device_lock(dev); 203 203 if (dev->driver) { 204 204 struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; 205 205 u64 offset = __le64_to_cpu(pfn_sb->dataoff); ··· 213 213 /* no address to convey if the pfn instance is disabled */ 214 214 rc = -ENXIO; 215 215 } 216 - nd_device_unlock(dev); 216 + device_unlock(dev); 217 217 218 218 return rc; 219 219 } ··· 225 225 struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); 226 226 ssize_t rc; 227 227 228 - nd_device_lock(dev); 228 + device_lock(dev); 229 229 if (dev->driver) { 230 230 struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb; 231 231 u64 offset = __le64_to_cpu(pfn_sb->dataoff); ··· 241 241 /* no size to convey if the pfn instance is disabled */ 242 242 rc = -ENXIO; 243 243 } 244 - nd_device_unlock(dev); 244 + device_unlock(dev); 245 245 246 246 return rc; 247 247 } ··· 291 291 } 292 292 EXPORT_SYMBOL(is_nd_pfn); 293 293 294 + static struct lock_class_key nvdimm_pfn_key; 295 + 294 296 struct device *nd_pfn_devinit(struct nd_pfn *nd_pfn, 295 297 struct nd_namespace_common *ndns) 296 298 { ··· 305 303 nd_pfn->align = nd_pfn_default_alignment(); 306 304 dev = &nd_pfn->dev; 307 305 device_initialize(&nd_pfn->dev); 306 + lockdep_set_class(&nd_pfn->dev.mutex, &nvdimm_pfn_key); 308 307 if (ndns && !__nd_attach_ndns(&nd_pfn->dev, ndns, &nd_pfn->ndns)) { 309 308 dev_dbg(&ndns->dev, "failed, already claimed by %s\n", 310 309 dev_name(ndns->claim)); ··· 349 346 nd_pfn = nd_pfn_alloc(nd_region); 350 347 dev = nd_pfn_devinit(nd_pfn, NULL); 351 348 352 - __nd_device_register(dev); 349 + nd_device_register(dev); 353 350 return dev; 354 351 } 355 352 ··· 646 643 nd_detach_ndns(pfn_dev, &nd_pfn->ndns); 647 644 put_device(pfn_dev); 648 645 } else 649 - __nd_device_register(pfn_dev); 646 + nd_device_register(pfn_dev); 650 647 651 648 return rc; 652 649 }
+1 -1
drivers/nvdimm/pmem.c
··· 660 660 nvdimm_namespace_detach_btt(to_nd_btt(dev)); 661 661 else { 662 662 /* 663 - * Note, this assumes nd_device_lock() context to not 663 + * Note, this assumes device_lock() context to not 664 664 * race nd_pmem_notify() 665 665 */ 666 666 sysfs_put(pmem->bb_state);
+1 -1
drivers/nvdimm/region.c
··· 95 95 nvdimm_bus_unlock(dev); 96 96 97 97 /* 98 - * Note, this assumes nd_device_lock() context to not race 98 + * Note, this assumes device_lock() context to not race 99 99 * nd_region_notify() 100 100 */ 101 101 sysfs_put(nd_region->bb_state);
+12 -8
drivers/nvdimm/region_devs.c
··· 279 279 * the v1.1 namespace label cookie definition. To read all this 280 280 * data we need to wait for probing to settle. 281 281 */ 282 - nd_device_lock(dev); 282 + device_lock(dev); 283 283 nvdimm_bus_lock(dev); 284 284 wait_nvdimm_bus_probe_idle(dev); 285 285 if (nd_region->ndr_mappings) { ··· 296 296 } 297 297 } 298 298 nvdimm_bus_unlock(dev); 299 - nd_device_unlock(dev); 299 + device_unlock(dev); 300 300 301 301 if (rc) 302 302 return rc; ··· 353 353 * memory nvdimm_bus_lock() is dropped, but that's userspace's 354 354 * problem to not race itself. 355 355 */ 356 - nd_device_lock(dev); 356 + device_lock(dev); 357 357 nvdimm_bus_lock(dev); 358 358 wait_nvdimm_bus_probe_idle(dev); 359 359 available = nd_region_available_dpa(nd_region); 360 360 nvdimm_bus_unlock(dev); 361 - nd_device_unlock(dev); 361 + device_unlock(dev); 362 362 363 363 return sprintf(buf, "%llu\n", available); 364 364 } ··· 370 370 struct nd_region *nd_region = to_nd_region(dev); 371 371 unsigned long long available = 0; 372 372 373 - nd_device_lock(dev); 373 + device_lock(dev); 374 374 nvdimm_bus_lock(dev); 375 375 wait_nvdimm_bus_probe_idle(dev); 376 376 available = nd_region_allocatable_dpa(nd_region); 377 377 nvdimm_bus_unlock(dev); 378 - nd_device_unlock(dev); 378 + device_unlock(dev); 379 379 380 380 return sprintf(buf, "%llu\n", available); 381 381 } ··· 549 549 struct nd_region *nd_region = to_nd_region(dev); 550 550 ssize_t rc; 551 551 552 - nd_device_lock(dev); 552 + device_lock(dev); 553 553 if (dev->driver) 554 554 rc = badblocks_show(&nd_region->bb, buf, 0); 555 555 else 556 556 rc = -ENXIO; 557 - nd_device_unlock(dev); 557 + device_unlock(dev); 558 558 559 559 return rc; 560 560 } ··· 949 949 return align; 950 950 } 951 951 952 + static struct lock_class_key nvdimm_region_key; 953 + 952 954 static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, 953 955 struct nd_region_desc *ndr_desc, 954 956 const struct device_type *dev_type, const char *caller) ··· 1037 1035 else 1038 1036 nd_region->flush = NULL; 1039 1037 1038 + device_initialize(dev); 1039 + lockdep_set_class(&dev->mutex, &nvdimm_region_key); 1040 1040 nd_device_register(dev); 1041 1041 1042 1042 return nd_region;
+10 -2
include/acpi/acpi_bus.h
··· 585 585 int acpi_bind_one(struct device *dev, struct acpi_device *adev); 586 586 int acpi_unbind_one(struct device *dev); 587 587 588 + enum acpi_bridge_type { 589 + ACPI_BRIDGE_TYPE_PCIE = 1, 590 + ACPI_BRIDGE_TYPE_CXL, 591 + }; 592 + 588 593 struct acpi_pci_root { 589 594 struct acpi_device * device; 590 595 struct pci_bus *bus; 591 596 u16 segment; 597 + int bridge_type; 592 598 struct resource secondary; /* downstream bus range */ 593 599 594 - u32 osc_support_set; /* _OSC state of support bits */ 595 - u32 osc_control_set; /* _OSC state of control bits */ 600 + u32 osc_support_set; /* _OSC state of support bits */ 601 + u32 osc_control_set; /* _OSC state of control bits */ 602 + u32 osc_ext_support_set; /* _OSC state of extended support bits */ 603 + u32 osc_ext_control_set; /* _OSC state of extended control bits */ 596 604 phys_addr_t mcfg_addr; 597 605 }; 598 606
+41 -1
include/linux/acpi.h
··· 550 550 551 551 acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); 552 552 553 - /* Indexes into _OSC Capabilities Buffer (DWORDs 2 & 3 are device-specific) */ 553 + /* Number of _OSC capability DWORDS depends on bridge type */ 554 + #define OSC_PCI_CAPABILITY_DWORDS 3 555 + #define OSC_CXL_CAPABILITY_DWORDS 5 556 + 557 + /* Indexes into _OSC Capabilities Buffer (DWORDs 2 to 5 are device-specific) */ 554 558 #define OSC_QUERY_DWORD 0 /* DWORD 1 */ 555 559 #define OSC_SUPPORT_DWORD 1 /* DWORD 2 */ 556 560 #define OSC_CONTROL_DWORD 2 /* DWORD 3 */ 561 + #define OSC_EXT_SUPPORT_DWORD 3 /* DWORD 4 */ 562 + #define OSC_EXT_CONTROL_DWORD 4 /* DWORD 5 */ 557 563 558 564 /* _OSC Capabilities DWORD 1: Query/Control and Error Returns (generic) */ 559 565 #define OSC_QUERY_ENABLE 0x00000001 /* input */ ··· 615 609 #define OSC_PCI_EXPRESS_CAPABILITY_CONTROL 0x00000010 616 610 #define OSC_PCI_EXPRESS_LTR_CONTROL 0x00000020 617 611 #define OSC_PCI_EXPRESS_DPC_CONTROL 0x00000080 612 + 613 + /* CXL _OSC: Capabilities DWORD 4: Support Field */ 614 + #define OSC_CXL_1_1_PORT_REG_ACCESS_SUPPORT 0x00000001 615 + #define OSC_CXL_2_0_PORT_DEV_REG_ACCESS_SUPPORT 0x00000002 616 + #define OSC_CXL_PROTOCOL_ERR_REPORTING_SUPPORT 0x00000004 617 + #define OSC_CXL_NATIVE_HP_SUPPORT 0x00000008 618 + 619 + /* CXL _OSC: Capabilities DWORD 5: Control Field */ 620 + #define OSC_CXL_ERROR_REPORTING_CONTROL 0x00000001 621 + 622 + static inline u32 acpi_osc_ctx_get_pci_control(struct acpi_osc_context *context) 623 + { 624 + u32 *ret = context->ret.pointer; 625 + 626 + return ret[OSC_CONTROL_DWORD]; 627 + } 628 + 629 + static inline u32 acpi_osc_ctx_get_cxl_control(struct acpi_osc_context *context) 630 + { 631 + u32 *ret = context->ret.pointer; 632 + 633 + return ret[OSC_EXT_CONTROL_DWORD]; 634 + } 618 635 619 636 #define ACPI_GSB_ACCESS_ATTRIB_QUICK 0x00000002 620 637 #define ACPI_GSB_ACCESS_ATTRIB_SEND_RCV 0x00000004 ··· 1034 1005 1035 1006 static inline void acpi_unregister_wakeup_handler( 1036 1007 bool (*wakeup)(void *context), void *context) { } 1008 + 1009 + struct acpi_osc_context; 1010 + static inline u32 acpi_osc_ctx_get_pci_control(struct acpi_osc_context *context) 1011 + { 1012 + return 0; 1013 + } 1014 + 1015 + static inline u32 acpi_osc_ctx_get_cxl_control(struct acpi_osc_context *context) 1016 + { 1017 + return 0; 1018 + } 1037 1019 1038 1020 #endif /* !CONFIG_ACPI */ 1039 1021
+43 -5
include/linux/device.h
··· 400 400 * This identifies the device type and carries type-specific 401 401 * information. 402 402 * @mutex: Mutex to synchronize calls to its driver. 403 - * @lockdep_mutex: An optional debug lock that a subsystem can use as a 404 - * peer lock to gain localized lockdep coverage of the device_lock. 405 403 * @bus: Type of bus device is on. 406 404 * @driver: Which driver has allocated this 407 405 * @platform_data: Platform data specific to the device. ··· 497 499 core doesn't touch it */ 498 500 void *driver_data; /* Driver data, set and get with 499 501 dev_set_drvdata/dev_get_drvdata */ 500 - #ifdef CONFIG_PROVE_LOCKING 501 - struct mutex lockdep_mutex; 502 - #endif 503 502 struct mutex mutex; /* mutex to synchronize calls to 504 503 * its driver. 505 504 */ ··· 844 849 { 845 850 return dev->bus && dev->bus->offline && dev->bus->online; 846 851 } 852 + 853 + #define __device_lock_set_class(dev, name, key) \ 854 + do { \ 855 + struct device *__d2 __maybe_unused = dev; \ 856 + lock_set_class(&__d2->mutex.dep_map, name, key, 0, _THIS_IP_); \ 857 + } while (0) 858 + 859 + /** 860 + * device_lock_set_class - Specify a temporary lock class while a device 861 + * is attached to a driver 862 + * @dev: device to modify 863 + * @key: lock class key data 864 + * 865 + * This must be called with the device_lock() already held, for example 866 + * from driver ->probe(). Take care to only override the default 867 + * lockdep_no_validate class. 868 + */ 869 + #ifdef CONFIG_LOCKDEP 870 + #define device_lock_set_class(dev, key) \ 871 + do { \ 872 + struct device *__d = dev; \ 873 + dev_WARN_ONCE(__d, !lockdep_match_class(&__d->mutex, \ 874 + &__lockdep_no_validate__), \ 875 + "overriding existing custom lock class\n"); \ 876 + __device_lock_set_class(__d, #key, key); \ 877 + } while (0) 878 + #else 879 + #define device_lock_set_class(dev, key) __device_lock_set_class(dev, #key, key) 880 + #endif 881 + 882 + /** 883 + * device_lock_reset_class - Return a device to the default lockdep novalidate state 884 + * @dev: device to modify 885 + * 886 + * This must be called with the device_lock() already held, for example 887 + * from driver ->remove(). 888 + */ 889 + #define device_lock_reset_class(dev) \ 890 + do { \ 891 + struct device *__d __maybe_unused = dev; \ 892 + lock_set_novalidate_class(&__d->mutex.dep_map, "&dev->mutex", \ 893 + _THIS_IP_); \ 894 + } while (0) 847 895 848 896 void lock_device_hotplug(void); 849 897 void unlock_device_hotplug(void);
+5 -1
include/linux/lockdep.h
··· 286 286 struct lock_class_key *key, unsigned int subclass, 287 287 unsigned long ip); 288 288 289 + #define lock_set_novalidate_class(l, n, i) \ 290 + lock_set_class(l, n, &__lockdep_no_validate__, 0, i) 291 + 289 292 static inline void lock_set_subclass(struct lockdep_map *lock, 290 293 unsigned int subclass, unsigned long ip) 291 294 { ··· 356 353 # define lock_acquire(l, s, t, r, c, n, i) do { } while (0) 357 354 # define lock_release(l, i) do { } while (0) 358 355 # define lock_downgrade(l, i) do { } while (0) 359 - # define lock_set_class(l, n, k, s, i) do { } while (0) 356 + # define lock_set_class(l, n, key, s, i) do { (void)(key); } while (0) 357 + # define lock_set_novalidate_class(l, n, i) do { } while (0) 360 358 # define lock_set_subclass(l, s, i) do { } while (0) 361 359 # define lockdep_init() do { } while (0) 362 360 # define lockdep_init_map_type(lock, name, key, sub, inner, outer, type) \
+9
include/linux/pm.h
··· 36 36 } 37 37 #endif /* CONFIG_VT_CONSOLE_SLEEP */ 38 38 39 + #ifdef CONFIG_CXL_SUSPEND 40 + bool cxl_mem_active(void); 41 + #else 42 + static inline bool cxl_mem_active(void) 43 + { 44 + return false; 45 + } 46 + #endif 47 + 39 48 /* 40 49 * Device power management 41 50 */
+7 -7
include/uapi/linux/cxl_mem.h
··· 68 68 * struct cxl_command_info - Command information returned from a query. 69 69 * @id: ID number for the command. 70 70 * @flags: Flags that specify command behavior. 71 - * @size_in: Expected input size, or -1 if variable length. 72 - * @size_out: Expected output size, or -1 if variable length. 71 + * @size_in: Expected input size, or ~0 if variable length. 72 + * @size_out: Expected output size, or ~0 if variable length. 73 73 * 74 74 * Represents a single command that is supported by both the driver and the 75 75 * hardware. This is returned as part of an array from the query ioctl. The ··· 78 78 * 79 79 * - @id = 10 80 80 * - @flags = 0 81 - * - @size_in = -1 81 + * - @size_in = ~0 82 82 * - @size_out = 0 83 83 * 84 84 * See struct cxl_mem_query_commands. ··· 89 89 __u32 flags; 90 90 #define CXL_MEM_COMMAND_FLAG_MASK GENMASK(0, 0) 91 91 92 - __s32 size_in; 93 - __s32 size_out; 92 + __u32 size_in; 93 + __u32 size_out; 94 94 }; 95 95 96 96 /** ··· 169 169 __u32 retval; 170 170 171 171 struct { 172 - __s32 size; 172 + __u32 size; 173 173 __u32 rsvd; 174 174 __u64 payload; 175 175 } in; 176 176 177 177 struct { 178 - __s32 size; 178 + __u32 size; 179 179 __u32 rsvd; 180 180 __u64 payload; 181 181 } out;
+1 -1
kernel/power/hibernate.c
··· 83 83 { 84 84 return nohibernate == 0 && 85 85 !security_locked_down(LOCKDOWN_HIBERNATION) && 86 - !secretmem_active(); 86 + !secretmem_active() && !cxl_mem_active(); 87 87 } 88 88 89 89 /**
+4 -1
kernel/power/main.c
··· 127 127 char *s = buf; 128 128 suspend_state_t i; 129 129 130 - for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) 130 + for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) { 131 + if (i >= PM_SUSPEND_MEM && cxl_mem_active()) 132 + continue; 131 133 if (mem_sleep_states[i]) { 132 134 const char *label = mem_sleep_states[i]; 133 135 ··· 138 136 else 139 137 s += sprintf(s, "%s ", label); 140 138 } 139 + } 141 140 142 141 /* Convert the last space to a newline if needed. */ 143 142 if (s != buf)
+2 -1
kernel/power/suspend.c
··· 236 236 237 237 static bool sleep_state_supported(suspend_state_t state) 238 238 { 239 - return state == PM_SUSPEND_TO_IDLE || valid_state(state); 239 + return state == PM_SUSPEND_TO_IDLE || 240 + (valid_state(state) && !cxl_mem_active()); 240 241 } 241 242 242 243 static int platform_suspend_prepare(suspend_state_t state)
-23
lib/Kconfig.debug
··· 1490 1490 include the IPI handler function currently executing (if any) 1491 1491 and relevant stack traces. 1492 1492 1493 - choice 1494 - prompt "Lock debugging: prove subsystem device_lock() correctness" 1495 - depends on PROVE_LOCKING 1496 - help 1497 - For subsystems that have instrumented their usage of the device_lock() 1498 - with nested annotations, enable lock dependency checking. The locking 1499 - hierarchy 'subclass' identifiers are not compatible across 1500 - sub-systems, so only one can be enabled at a time. 1501 - 1502 - config PROVE_NVDIMM_LOCKING 1503 - bool "NVDIMM" 1504 - depends on LIBNVDIMM 1505 - help 1506 - Enable lockdep to validate nd_device_lock() usage. 1507 - 1508 - config PROVE_CXL_LOCKING 1509 - bool "CXL" 1510 - depends on CXL_BUS 1511 - help 1512 - Enable lockdep to validate cxl_device_lock() usage. 1513 - 1514 - endchoice 1515 - 1516 1493 endmenu # lock debugging 1517 1494 1518 1495 config TRACE_IRQFLAGS
+2 -1
tools/testing/cxl/Kbuild
··· 8 8 ldflags-y += --wrap=devm_cxl_setup_hdm 9 9 ldflags-y += --wrap=devm_cxl_add_passthrough_decoder 10 10 ldflags-y += --wrap=devm_cxl_enumerate_decoders 11 + ldflags-y += --wrap=cxl_await_media_ready 12 + ldflags-y += --wrap=cxl_hdm_decode_init 11 13 12 14 DRIVERS := ../../../drivers 13 15 CXL_SRC := $(DRIVERS)/cxl ··· 36 34 obj-m += cxl_mem.o 37 35 38 36 cxl_mem-y := $(CXL_SRC)/mem.o 39 - cxl_mem-y += mock_mem.o 40 37 cxl_mem-y += config_check.o 41 38 42 39 obj-m += cxl_core.o
-10
tools/testing/cxl/mock_mem.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright(c) 2022 Intel Corporation. All rights reserved. */ 3 - 4 - #include <linux/types.h> 5 - 6 - struct cxl_dev_state; 7 - bool cxl_dvsec_decode_init(struct cxl_dev_state *cxlds) 8 - { 9 - return true; 10 - }
-17
tools/testing/cxl/test/mem.c
··· 237 237 return rc; 238 238 } 239 239 240 - static int cxl_mock_wait_media_ready(struct cxl_dev_state *cxlds) 241 - { 242 - msleep(100); 243 - return 0; 244 - } 245 - 246 240 static void label_area_release(void *lsa) 247 241 { 248 242 vfree(lsa); 249 - } 250 - 251 - static void mock_validate_dvsec_ranges(struct cxl_dev_state *cxlds) 252 - { 253 - struct cxl_endpoint_dvsec_info *info; 254 - 255 - info = &cxlds->info; 256 - info->mem_enabled = true; 257 243 } 258 244 259 245 static int cxl_mock_mem_probe(struct platform_device *pdev) ··· 264 278 265 279 cxlds->serial = pdev->id; 266 280 cxlds->mbox_send = cxl_mock_mbox_send; 267 - cxlds->wait_media_ready = cxl_mock_wait_media_ready; 268 281 cxlds->payload_size = SZ_4K; 269 282 270 283 rc = cxl_enumerate_cmds(cxlds); ··· 277 292 rc = cxl_mem_create_range_info(cxlds); 278 293 if (rc) 279 294 return rc; 280 - 281 - mock_validate_dvsec_ranges(cxlds); 282 295 283 296 cxlmd = devm_cxl_add_memdev(cxlds); 284 297 if (IS_ERR(cxlmd))
+29
tools/testing/cxl/test/mock.c
··· 193 193 } 194 194 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL); 195 195 196 + int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds) 197 + { 198 + int rc, index; 199 + struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 200 + 201 + if (ops && ops->is_mock_dev(cxlds->dev)) 202 + rc = 0; 203 + else 204 + rc = cxl_await_media_ready(cxlds); 205 + put_cxl_mock_ops(index); 206 + 207 + return rc; 208 + } 209 + EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL); 210 + 211 + bool __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds, 212 + struct cxl_hdm *cxlhdm) 213 + { 214 + int rc = 0, index; 215 + struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 216 + 217 + if (!ops || !ops->is_mock_dev(cxlds->dev)) 218 + rc = cxl_hdm_decode_init(cxlds, cxlhdm); 219 + put_cxl_mock_ops(index); 220 + 221 + return rc; 222 + } 223 + EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL); 224 + 196 225 MODULE_LICENSE("GPL v2"); 197 226 MODULE_IMPORT_NS(ACPI); 198 227 MODULE_IMPORT_NS(CXL);