diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/Kconfig | 3 | ||||
-rw-r--r-- | drivers/acpi/numa/srat.c | 59 | ||||
-rw-r--r-- | drivers/acpi/tables.c | 87 | ||||
-rw-r--r-- | drivers/cxl/Kconfig | 1 | ||||
-rw-r--r-- | drivers/cxl/acpi.c | 237 | ||||
-rw-r--r-- | drivers/cxl/core/Makefile | 2 | ||||
-rw-r--r-- | drivers/cxl/core/bus.c | 26 | ||||
-rw-r--r-- | drivers/cxl/core/mbox.c | 186 | ||||
-rw-r--r-- | drivers/cxl/core/memdev.c | 55 | ||||
-rw-r--r-- | drivers/cxl/core/pmem.c | 20 | ||||
-rw-r--r-- | drivers/cxl/core/regs.c | 8 | ||||
-rw-r--r-- | drivers/cxl/cxl.h | 10 | ||||
-rw-r--r-- | drivers/cxl/cxlmem.h | 37 | ||||
-rw-r--r-- | drivers/cxl/pci.c | 120 | ||||
-rw-r--r-- | drivers/cxl/pmem.c | 85 |
15 files changed, 515 insertions, 421 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 60b5424bd318..705331e3d87a 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -59,6 +59,9 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT config ACPI_CCA_REQUIRED bool +config ACPI_TABLE_LIB + bool + config ACPI_DEBUGGER bool "AML debugger interface" select ACPI_DEBUG diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c index 6c884f3e8332..3b818ab186be 100644 --- a/drivers/acpi/numa/srat.c +++ b/drivers/acpi/numa/srat.c @@ -297,6 +297,47 @@ out_err_bad_srat: out_err: return -EINVAL; } + +static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, + void *arg, const unsigned long table_end) +{ + struct acpi_cedt_cfmws *cfmws; + int *fake_pxm = arg; + u64 start, end; + int node; + + cfmws = (struct acpi_cedt_cfmws *)header; + start = cfmws->base_hpa; + end = cfmws->base_hpa + cfmws->window_size; + + /* Skip if the SRAT already described the NUMA details for this HPA */ + node = phys_to_target_node(start); + if (node != NUMA_NO_NODE) + return 0; + + node = acpi_map_pxm_to_node(*fake_pxm); + + if (node == NUMA_NO_NODE) { + pr_err("ACPI NUMA: Too many proximity domains while processing CFMWS.\n"); + return -EINVAL; + } + + if (numa_add_memblk(node, start, end) < 0) { + /* CXL driver must handle the NUMA_NO_NODE case */ + pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n", + node, start, end); + } + + /* Set the next available fake_pxm value */ + (*fake_pxm)++; + return 0; +} +#else +static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, + void *arg, const unsigned long table_end) +{ + return 0; +} #endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */ static int __init acpi_parse_slit(struct acpi_table_header *table) @@ -441,7 +482,7 @@ acpi_table_parse_srat(enum acpi_srat_type id, int __init acpi_numa_init(void) { - int cnt = 0; + int i, fake_pxm, cnt = 0; if (acpi_disabled) return -EINVAL; @@ -477,6 +518,22 @@ int __init acpi_numa_init(void) /* SLIT: System Locality Information Table */ acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); + /* + * CXL Fixed Memory Window Structures (CFMWS) must be parsed + * after the SRAT. Create NUMA Nodes for CXL memory ranges that + * are defined in the CFMWS and not already defined in the SRAT. + * Initialize a fake_pxm as the first available PXM to emulate. + */ + + /* fake_pxm is the next unused PXM value after SRAT parsing */ + for (i = 0, fake_pxm = -1; i < MAX_NUMNODES - 1; i++) { + if (node_to_pxm_map[i] > fake_pxm) + fake_pxm = node_to_pxm_map[i]; + } + fake_pxm++; + acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, acpi_parse_cfmws, + &fake_pxm); + if (cnt < 0) return cnt; else if (!parsed_numa_memblks) diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 682a3ea9cb40..0741a4933f62 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -35,12 +35,13 @@ static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; -static int acpi_apic_instance __initdata; +static int acpi_apic_instance __initdata_or_acpilib; enum acpi_subtable_type { ACPI_SUBTABLE_COMMON, ACPI_SUBTABLE_HMAT, ACPI_SUBTABLE_PRMT, + ACPI_SUBTABLE_CEDT, }; struct acpi_subtable_entry { @@ -52,7 +53,7 @@ struct acpi_subtable_entry { * Disable table checksum verification for the early stage due to the size * limitation of the current x86 early mapping implementation. */ -static bool acpi_verify_table_checksum __initdata = false; +static bool acpi_verify_table_checksum __initdata_or_acpilib = false; void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { @@ -216,7 +217,7 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) } } -static unsigned long __init +static unsigned long __init_or_acpilib acpi_get_entry_type(struct acpi_subtable_entry *entry) { switch (entry->type) { @@ -226,11 +227,13 @@ acpi_get_entry_type(struct acpi_subtable_entry *entry) return entry->hdr->hmat.type; case ACPI_SUBTABLE_PRMT: return 0; + case ACPI_SUBTABLE_CEDT: + return entry->hdr->cedt.type; } return 0; } -static unsigned long __init +static unsigned long __init_or_acpilib acpi_get_entry_length(struct acpi_subtable_entry *entry) { switch (entry->type) { @@ -240,11 +243,13 @@ acpi_get_entry_length(struct acpi_subtable_entry *entry) return entry->hdr->hmat.length; case ACPI_SUBTABLE_PRMT: return entry->hdr->prmt.length; + case ACPI_SUBTABLE_CEDT: + return entry->hdr->cedt.length; } return 0; } -static unsigned long __init +static unsigned long __init_or_acpilib acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) { switch (entry->type) { @@ -254,20 +259,40 @@ acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) return sizeof(entry->hdr->hmat); case ACPI_SUBTABLE_PRMT: return sizeof(entry->hdr->prmt); + case ACPI_SUBTABLE_CEDT: + return sizeof(entry->hdr->cedt); } return 0; } -static enum acpi_subtable_type __init +static enum acpi_subtable_type __init_or_acpilib acpi_get_subtable_type(char *id) { if (strncmp(id, ACPI_SIG_HMAT, 4) == 0) return ACPI_SUBTABLE_HMAT; if (strncmp(id, ACPI_SIG_PRMT, 4) == 0) return ACPI_SUBTABLE_PRMT; + if (strncmp(id, ACPI_SIG_CEDT, 4) == 0) + return ACPI_SUBTABLE_CEDT; return ACPI_SUBTABLE_COMMON; } +static __init_or_acpilib bool has_handler(struct acpi_subtable_proc *proc) +{ + return proc->handler || proc->handler_arg; +} + +static __init_or_acpilib int call_handler(struct acpi_subtable_proc *proc, + union acpi_subtable_headers *hdr, + unsigned long end) +{ + if (proc->handler) + return proc->handler(hdr, end); + if (proc->handler_arg) + return proc->handler_arg(hdr, proc->arg, end); + return -EINVAL; +} + /** * acpi_parse_entries_array - for each proc_num find a suitable subtable * @@ -291,10 +316,10 @@ acpi_get_subtable_type(char *id) * On success returns sum of all matching entries for all proc handlers. * Otherwise, -ENODEV or -EINVAL is returned. */ -static int __init acpi_parse_entries_array(char *id, unsigned long table_size, - struct acpi_table_header *table_header, - struct acpi_subtable_proc *proc, int proc_num, - unsigned int max_entries) +static int __init_or_acpilib acpi_parse_entries_array( + char *id, unsigned long table_size, + struct acpi_table_header *table_header, struct acpi_subtable_proc *proc, + int proc_num, unsigned int max_entries) { struct acpi_subtable_entry entry; unsigned long table_end, subtable_len, entry_len; @@ -318,8 +343,9 @@ static int __init acpi_parse_entries_array(char *id, unsigned long table_size, for (i = 0; i < proc_num; i++) { if (acpi_get_entry_type(&entry) != proc[i].id) continue; - if (!proc[i].handler || - (!errs && proc[i].handler(entry.hdr, table_end))) { + if (!has_handler(&proc[i]) || + (!errs && + call_handler(&proc[i], entry.hdr, table_end))) { errs++; continue; } @@ -352,10 +378,9 @@ static int __init acpi_parse_entries_array(char *id, unsigned long table_size, return errs ? -EINVAL : count; } -int __init acpi_table_parse_entries_array(char *id, - unsigned long table_size, - struct acpi_subtable_proc *proc, int proc_num, - unsigned int max_entries) +int __init_or_acpilib acpi_table_parse_entries_array( + char *id, unsigned long table_size, struct acpi_subtable_proc *proc, + int proc_num, unsigned int max_entries) { struct acpi_table_header *table_header = NULL; int count; @@ -386,21 +411,41 @@ int __init acpi_table_parse_entries_array(char *id, return count; } -int __init acpi_table_parse_entries(char *id, - unsigned long table_size, - int entry_id, - acpi_tbl_entry_handler handler, - unsigned int max_entries) +static int __init_or_acpilib __acpi_table_parse_entries( + char *id, unsigned long table_size, int entry_id, + acpi_tbl_entry_handler handler, acpi_tbl_entry_handler_arg handler_arg, + void *arg, unsigned int max_entries) { struct acpi_subtable_proc proc = { .id = entry_id, .handler = handler, + .handler_arg = handler_arg, + .arg = arg, }; return acpi_table_parse_entries_array(id, table_size, &proc, 1, max_entries); } +int __init_or_acpilib +acpi_table_parse_cedt(enum acpi_cedt_type id, + acpi_tbl_entry_handler_arg handler_arg, void *arg) +{ + return __acpi_table_parse_entries(ACPI_SIG_CEDT, + sizeof(struct acpi_table_cedt), id, + NULL, handler_arg, arg, 0); +} +EXPORT_SYMBOL_ACPI_LIB(acpi_table_parse_cedt); + +int __init acpi_table_parse_entries(char *id, unsigned long table_size, + int entry_id, + acpi_tbl_entry_handler handler, + unsigned int max_entries) +{ + return __acpi_table_parse_entries(id, table_size, entry_id, handler, + NULL, NULL, max_entries); +} + int __init acpi_table_parse_madt(enum acpi_madt_type id, acpi_tbl_entry_handler handler, unsigned int max_entries) { diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig index e6de221cc568..67c91378f2dd 100644 --- a/drivers/cxl/Kconfig +++ b/drivers/cxl/Kconfig @@ -51,6 +51,7 @@ config CXL_ACPI tristate "CXL ACPI: Platform Support" depends on ACPI default CXL_BUS + select ACPI_TABLE_LIB help Enable support for host managed device memory (HDM) resources published by a platform's ACPI CXL memory layout description. See diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index dadc7f64b9ff..3163167ecc3a 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -8,8 +8,6 @@ #include <linux/pci.h> #include "cxl.h" -static struct acpi_table_header *acpi_cedt; - /* Encode defined in CXL 2.0 8.2.5.12.7 HDM Decoder Control Register */ #define CFMWS_INTERLEAVE_WAYS(x) (1 << (x)->interleave_ways) #define CFMWS_INTERLEAVE_GRANULARITY(x) ((x)->granularity + 8) @@ -74,134 +72,64 @@ static int cxl_acpi_cfmws_verify(struct device *dev, return 0; } -static void cxl_add_cfmws_decoders(struct device *dev, - struct cxl_port *root_port) +struct cxl_cfmws_context { + struct device *dev; + struct cxl_port *root_port; +}; + +static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg, + const unsigned long end) { int target_map[CXL_DECODER_MAX_INTERLEAVE]; + struct cxl_cfmws_context *ctx = arg; + struct cxl_port *root_port = ctx->root_port; + struct device *dev = ctx->dev; struct acpi_cedt_cfmws *cfmws; struct cxl_decoder *cxld; - acpi_size len, cur = 0; - void *cedt_subtable; - int rc; - - len = acpi_cedt->length - sizeof(*acpi_cedt); - cedt_subtable = acpi_cedt + 1; - - while (cur < len) { - struct acpi_cedt_header *c = cedt_subtable + cur; - int i; - - if (c->type != ACPI_CEDT_TYPE_CFMWS) { - cur += c->length; - continue; - } + int rc, i; - cfmws = cedt_subtable + cur; + cfmws = (struct acpi_cedt_cfmws *) header; - if (cfmws->header.length < sizeof(*cfmws)) { - dev_warn_once(dev, - "CFMWS entry skipped:invalid length:%u\n", - cfmws->header.length); - cur += c->length; - continue; - } - - rc = cxl_acpi_cfmws_verify(dev, cfmws); - if (rc) { - dev_err(dev, "CFMWS range %#llx-%#llx not registered\n", - cfmws->base_hpa, cfmws->base_hpa + - cfmws->window_size - 1); - cur += c->length; - continue; - } - - for (i = 0; i < CFMWS_INTERLEAVE_WAYS(cfmws); i++) - target_map[i] = cfmws->interleave_targets[i]; - - cxld = cxl_decoder_alloc(root_port, - CFMWS_INTERLEAVE_WAYS(cfmws)); - if (IS_ERR(cxld)) - goto next; - - cxld->flags = cfmws_to_decoder_flags(cfmws->restrictions); - cxld->target_type = CXL_DECODER_EXPANDER; - cxld->range = (struct range) { - .start = cfmws->base_hpa, - .end = cfmws->base_hpa + cfmws->window_size - 1, - }; - cxld->interleave_ways = CFMWS_INTERLEAVE_WAYS(cfmws); - cxld->interleave_granularity = - CFMWS_INTERLEAVE_GRANULARITY(cfmws); - - rc = cxl_decoder_add(cxld, target_map); - if (rc) - put_device(&cxld->dev); - else - rc = cxl_decoder_autoremove(dev, cxld); - if (rc) { - dev_err(dev, "Failed to add decoder for %#llx-%#llx\n", - cfmws->base_hpa, cfmws->base_hpa + - cfmws->window_size - 1); - goto next; - } - dev_dbg(dev, "add: %s range %#llx-%#llx\n", - dev_name(&cxld->dev), cfmws->base_hpa, + rc = cxl_acpi_cfmws_verify(dev, cfmws); + if (rc) { + dev_err(dev, "CFMWS range %#llx-%#llx not registered\n", + cfmws->base_hpa, cfmws->base_hpa + cfmws->window_size - 1); -next: - cur += c->length; + return 0; } -} - -static struct acpi_cedt_chbs *cxl_acpi_match_chbs(struct device *dev, u32 uid) -{ - struct acpi_cedt_chbs *chbs, *chbs_match = NULL; - acpi_size len, cur = 0; - void *cedt_subtable; - len = acpi_cedt->length - sizeof(*acpi_cedt); - cedt_subtable = acpi_cedt + 1; + for (i = 0; i < CFMWS_INTERLEAVE_WAYS(cfmws); i++) + target_map[i] = cfmws->interleave_targets[i]; - while (cur < len) { - struct acpi_cedt_header *c = cedt_subtable + cur; - - if (c->type != ACPI_CEDT_TYPE_CHBS) { - cur += c->length; - continue; - } - - chbs = cedt_subtable + cur; - - if (chbs->header.length < sizeof(*chbs)) { - dev_warn_once(dev, - "CHBS entry skipped: invalid length:%u\n", - chbs->header.length); - cur += c->length; - continue; - } - - if (chbs->uid != uid) { - cur += c->length; - continue; - } + cxld = cxl_decoder_alloc(root_port, CFMWS_INTERLEAVE_WAYS(cfmws)); + if (IS_ERR(cxld)) + return 0; - if (chbs_match) { - dev_warn_once(dev, - "CHBS entry skipped: duplicate UID:%u\n", - uid); - cur += c->length; - continue; - } + cxld->flags = cfmws_to_decoder_flags(cfmws->restrictions); + cxld->target_type = CXL_DECODER_EXPANDER; + cxld->range = (struct range){ + .start = cfmws->base_hpa, + .end = cfmws->base_hpa + cfmws->window_size - 1, + }; + cxld->interleave_ways = CFMWS_INTERLEAVE_WAYS(cfmws); + cxld->interleave_granularity = CFMWS_INTERLEAVE_GRANULARITY(cfmws); - chbs_match = chbs; - cur += c->length; + rc = cxl_decoder_add(cxld, target_map); + if (rc) + put_device(&cxld->dev); + else + rc = cxl_decoder_autoremove(dev, cxld); + if (rc) { + dev_err(dev, "Failed to add decoder for %#llx-%#llx\n", + cfmws->base_hpa, + cfmws->base_hpa + cfmws->window_size - 1); + return 0; } + dev_dbg(dev, "add: %s node: %d range %#llx-%#llx\n", + dev_name(&cxld->dev), phys_to_target_node(cxld->range.start), + cfmws->base_hpa, cfmws->base_hpa + cfmws->window_size - 1); - return chbs_match ? chbs_match : ERR_PTR(-ENODEV); -} - -static resource_size_t get_chbcr(struct acpi_cedt_chbs *chbs) -{ - return IS_ERR(chbs) ? CXL_RESOURCE_NONE : chbs->base; + return 0; } __mock int match_add_root_ports(struct pci_dev *pdev, void *data) @@ -355,12 +283,36 @@ static int add_host_bridge_uport(struct device *match, void *arg) return rc; } +struct cxl_chbs_context { + struct device *dev; + unsigned long long uid; + resource_size_t chbcr; +}; + +static int cxl_get_chbcr(union acpi_subtable_headers *header, void *arg, + const unsigned long end) +{ + struct cxl_chbs_context *ctx = arg; + struct acpi_cedt_chbs *chbs; + + if (ctx->chbcr) + return 0; + + chbs = (struct acpi_cedt_chbs *) header; + + if (ctx->uid != chbs->uid) + return 0; + ctx->chbcr = chbs->base; + + return 0; +} + static int add_host_bridge_dport(struct device *match, void *arg) { int rc; acpi_status status; unsigned long long uid; - struct acpi_cedt_chbs *chbs; + struct cxl_chbs_context ctx; struct cxl_port *root_port = arg; struct device *host = root_port->dev.parent; struct acpi_device *bridge = to_cxl_host_bridge(host, match); @@ -376,14 +328,19 @@ static int add_host_bridge_dport(struct device *match, void *arg) return -ENODEV; } - chbs = cxl_acpi_match_chbs(host, uid); - if (IS_ERR(chbs)) { + ctx = (struct cxl_chbs_context) { + .dev = host, + .uid = uid, + }; + acpi_table_parse_cedt(ACPI_CEDT_TYPE_CHBS, cxl_get_chbcr, &ctx); + + if (ctx.chbcr == 0) { dev_warn(host, "No CHBS found for Host Bridge: %s\n", dev_name(match)); return 0; } - rc = cxl_add_dport(root_port, match, uid, get_chbcr(chbs)); + rc = cxl_add_dport(root_port, match, uid, ctx.chbcr); if (rc) { dev_err(host, "failed to add downstream port: %s\n", dev_name(match)); @@ -417,40 +374,29 @@ static int add_root_nvdimm_bridge(struct device *match, void *data) return 1; } -static u32 cedt_instance(struct platform_device *pdev) -{ - const bool *native_acpi0017 = acpi_device_get_match_data(&pdev->dev); - - if (native_acpi0017 && *native_acpi0017) - return 0; - - /* for cxl_test request a non-canonical instance */ - return U32_MAX; -} - static int cxl_acpi_probe(struct platform_device *pdev) { int rc; - acpi_status status; struct cxl_port *root_port; struct device *host = &pdev->dev; struct acpi_device *adev = ACPI_COMPANION(host); + struct cxl_cfmws_context ctx; root_port = devm_cxl_add_port(host, host, CXL_RESOURCE_NONE, NULL); if (IS_ERR(root_port)) return PTR_ERR(root_port); dev_dbg(host, "add: %s\n", dev_name(&root_port->dev)); - status = acpi_get_table(ACPI_SIG_CEDT, cedt_instance(pdev), &acpi_cedt); - if (ACPI_FAILURE(status)) - return -ENXIO; - rc = bus_for_each_dev(adev->dev.bus, NULL, root_port, add_host_bridge_dport); - if (rc) - goto out; + if (rc < 0) + return rc; - cxl_add_cfmws_decoders(host, root_port); + ctx = (struct cxl_cfmws_context) { + .dev = host, + .root_port = root_port, + }; + acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, cxl_parse_cfmws, &ctx); /* * Root level scanned with host-bridge as dports, now scan host-bridges @@ -458,24 +404,20 @@ static int cxl_acpi_probe(struct platform_device *pdev) */ rc = bus_for_each_dev(adev->dev.bus, NULL, root_port, add_host_bridge_uport); - if (rc) - goto out; + if (rc < 0) + return rc; if (IS_ENABLED(CONFIG_CXL_PMEM)) rc = device_for_each_child(&root_port->dev, root_port, add_root_nvdimm_bridge); - -out: - acpi_put_table(acpi_cedt); if (rc < 0) return rc; + return 0; } -static bool native_acpi0017 = true; - static const struct acpi_device_id cxl_acpi_ids[] = { - { "ACPI0017", (unsigned long) &native_acpi0017 }, + { "ACPI0017" }, { }, }; MODULE_DEVICE_TABLE(acpi, cxl_acpi_ids); @@ -491,3 +433,4 @@ static struct platform_driver cxl_acpi_driver = { module_platform_driver(cxl_acpi_driver); MODULE_LICENSE("GPL v2"); MODULE_IMPORT_NS(CXL); +MODULE_IMPORT_NS(ACPI); diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile index 07eb8e1fb8a6..40ab50318daf 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CXL_BUS) += cxl_core.o -ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CXL -I$(srctree)/drivers/cxl +ccflags-y += -I$(srctree)/drivers/cxl cxl_core-y := bus.o cxl_core-y += pmem.o cxl_core-y += regs.o diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c index ebd061d03950..3f9b98ecd18b 100644 --- a/drivers/cxl/core/bus.c +++ b/drivers/cxl/core/bus.c @@ -200,7 +200,7 @@ bool is_root_decoder(struct device *dev) { return dev->type == &cxl_decoder_root_type; } -EXPORT_SYMBOL_GPL(is_root_decoder); +EXPORT_SYMBOL_NS_GPL(is_root_decoder, CXL); struct cxl_decoder *to_cxl_decoder(struct device *dev) { @@ -209,7 +209,7 @@ struct cxl_decoder *to_cxl_decoder(struct device *dev) return NULL; return container_of(dev, struct cxl_decoder, dev); } -EXPORT_SYMBOL_GPL(to_cxl_decoder); +EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, CXL); static void cxl_dport_release(struct cxl_dport *dport) { @@ -376,7 +376,7 @@ err: put_device(dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_GPL(devm_cxl_add_port); +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_port, CXL); static struct cxl_dport *find_dport(struct cxl_port *port, int id) { @@ -451,7 +451,7 @@ err: cxl_dport_release(dport); return rc; } -EXPORT_SYMBOL_GPL(cxl_add_dport); +EXPORT_SYMBOL_NS_GPL(cxl_add_dport, CXL); static int decoder_populate_targets(struct cxl_decoder *cxld, struct cxl_port *port, int *target_map) @@ -485,9 +485,7 @@ out_unlock: struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port, int nr_targets) { - struct cxl_decoder *cxld, cxld_const_init = { - .nr_targets = nr_targets, - }; + struct cxl_decoder *cxld; struct device *dev; int rc = 0; @@ -497,13 +495,13 @@ struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port, int nr_targets) cxld = kzalloc(struct_size(cxld, target, nr_targets), GFP_KERNEL); if (!cxld) return ERR_PTR(-ENOMEM); - memcpy(cxld, &cxld_const_init, sizeof(cxld_const_init)); rc = ida_alloc(&port->decoder_ida, GFP_KERNEL); if (rc < 0) goto err; cxld->id = rc; + cxld->nr_targets = nr_targets; dev = &cxld->dev; device_initialize(dev); device_set_pm_not_required(dev); @@ -521,7 +519,7 @@ err: kfree(cxld); return ERR_PTR(rc); } -EXPORT_SYMBOL_GPL(cxl_decoder_alloc); +EXPORT_SYMBOL_NS_GPL(cxl_decoder_alloc, CXL); int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map) { @@ -550,7 +548,7 @@ int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map) return device_add(dev); } -EXPORT_SYMBOL_GPL(cxl_decoder_add); +EXPORT_SYMBOL_NS_GPL(cxl_decoder_add, CXL); static void cxld_unregister(void *dev) { @@ -561,7 +559,7 @@ int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld) { return devm_add_action_or_reset(host, cxld_unregister, &cxld->dev); } -EXPORT_SYMBOL_GPL(cxl_decoder_autoremove); +EXPORT_SYMBOL_NS_GPL(cxl_decoder_autoremove, CXL); /** * __cxl_driver_register - register a driver for the cxl bus @@ -594,13 +592,13 @@ int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner, return driver_register(&cxl_drv->drv); } -EXPORT_SYMBOL_GPL(__cxl_driver_register); +EXPORT_SYMBOL_NS_GPL(__cxl_driver_register, CXL); void cxl_driver_unregister(struct cxl_driver *cxl_drv) { driver_unregister(&cxl_drv->drv); } -EXPORT_SYMBOL_GPL(cxl_driver_unregister); +EXPORT_SYMBOL_NS_GPL(cxl_driver_unregister, CXL); static int cxl_device_id(struct device *dev) { @@ -642,7 +640,7 @@ struct bus_type cxl_bus_type = { .probe = cxl_bus_probe, .remove = cxl_bus_remove, }; -EXPORT_SYMBOL_GPL(cxl_bus_type); +EXPORT_SYMBOL_NS_GPL(cxl_bus_type, CXL); static __init int cxl_core_init(void) { diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 576796a5d9f3..be61a0d8016b 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -128,8 +128,8 @@ static struct cxl_mem_command *cxl_mem_find_command(u16 opcode) } /** - * cxl_mem_mbox_send_cmd() - Send a mailbox command to a memory device. - * @cxlm: The CXL memory device to communicate with. + * cxl_mbox_send_cmd() - Send a mailbox command to a device. + * @cxlds: The device data for the operation * @opcode: Opcode for the mailbox command. * @in: The input payload for the mailbox command. * @in_size: The length of the input payload @@ -148,11 +148,9 @@ static struct cxl_mem_command *cxl_mem_find_command(u16 opcode) * Mailbox commands may execute successfully yet the device itself reported an * error. While this distinction can be useful for commands from userspace, the * kernel will only be able to use results when both are successful. - * - * See __cxl_mem_mbox_send_cmd() */ -int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode, void *in, - size_t in_size, void *out, size_t out_size) +int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in, + size_t in_size, void *out, size_t out_size) { const struct cxl_mem_command *cmd = cxl_mem_find_command(opcode); struct cxl_mbox_cmd mbox_cmd = { @@ -164,10 +162,10 @@ int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode, void *in, }; int rc; - if (out_size > cxlm->payload_size) + if (out_size > cxlds->payload_size) return -E2BIG; - rc = cxlm->mbox_send(cxlm, &mbox_cmd); + rc = cxlds->mbox_send(cxlds, &mbox_cmd); if (rc) return rc; @@ -184,7 +182,7 @@ int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode, void *in, return 0; } -EXPORT_SYMBOL_GPL(cxl_mem_mbox_send_cmd); +EXPORT_SYMBOL_NS_GPL(cxl_mbox_send_cmd, CXL); static bool cxl_mem_raw_command_allowed(u16 opcode) { @@ -211,7 +209,7 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) /** * cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND. - * @cxlm: &struct cxl_mem device whose mailbox will be used. + * @cxlds: The device data for the operation * @send_cmd: &struct cxl_send_command copied in from userspace. * @out_cmd: Sanitized and populated &struct cxl_mem_command. * @@ -228,7 +226,7 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) * * See handle_mailbox_cmd_from_user() */ -static int cxl_validate_cmd_from_user(struct cxl_mem *cxlm, +static int cxl_validate_cmd_from_user(struct cxl_dev_state *cxlds, const struct cxl_send_command *send_cmd, struct cxl_mem_command *out_cmd) { @@ -243,7 +241,7 @@ static int cxl_validate_cmd_from_user(struct cxl_mem *cxlm, * supports, but output can be arbitrarily large (simply write out as * much data as the hardware provides). */ - if (send_cmd->in.size > cxlm->payload_size) + if (send_cmd->in.size > cxlds->payload_size) return -EINVAL; /* @@ -269,7 +267,7 @@ static int cxl_validate_cmd_from_user(struct cxl_mem *cxlm, * gets passed along without further checking, so it must be * validated here. */ - if (send_cmd->out.size > cxlm->payload_size) + if (send_cmd->out.size > cxlds->payload_size) return -EINVAL; if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode)) @@ -294,11 +292,11 @@ static int cxl_validate_cmd_from_user(struct cxl_mem *cxlm, info = &c->info; /* Check that the command is enabled for hardware */ - if (!test_bit(info->id, cxlm->enabled_cmds)) + if (!test_bit(info->id, cxlds->enabled_cmds)) return -ENOTTY; /* Check that the command is not claimed for exclusive kernel use */ - if (test_bit(info->id, cxlm->exclusive_cmds)) + if (test_bit(info->id, cxlds->exclusive_cmds)) return -EBUSY; /* Check the input buffer is the expected size */ @@ -356,7 +354,7 @@ int cxl_query_cmd(struct cxl_memdev *cxlmd, /** * handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace. - * @cxlm: The CXL memory device to communicate with. + * @cxlds: The device data for the operation * @cmd: The validated command. * @in_payload: Pointer to userspace's input payload. * @out_payload: Pointer to userspace's output payload. @@ -379,12 +377,12 @@ int cxl_query_cmd(struct cxl_memdev *cxlmd, * * See cxl_send_cmd(). */ -static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm, +static int handle_mailbox_cmd_from_user(struct cxl_dev_state *cxlds, const struct cxl_mem_command *cmd, u64 in_payload, u64 out_payload, s32 *size_out, u32 *retval) { - struct device *dev = cxlm->dev; + struct device *dev = cxlds->dev; struct cxl_mbox_cmd mbox_cmd = { .opcode = cmd->opcode, .size_in = cmd->info.size_in, @@ -417,7 +415,7 @@ static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm, dev_WARN_ONCE(dev, cmd->info.id == CXL_MEM_COMMAND_ID_RAW, "raw command path used\n"); - rc = cxlm->mbox_send(cxlm, &mbox_cmd); + rc = cxlds->mbox_send(cxlds, &mbox_cmd); if (rc) goto out; @@ -447,7 +445,7 @@ out: int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s) { - struct cxl_mem *cxlm = cxlmd->cxlm; + struct cxl_dev_state *cxlds = cxlmd->cxlds; struct device *dev = &cxlmd->dev; struct cxl_send_command send; struct cxl_mem_command c; @@ -458,15 +456,15 @@ int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s) if (copy_from_user(&send, s, sizeof(send))) return -EFAULT; - rc = cxl_validate_cmd_from_user(cxlmd->cxlm, &send, &c); + rc = cxl_validate_cmd_from_user(cxlmd->cxlds, &send, &c); if (rc) return rc; /* Prepare to handle a full payload for variable sized output */ if (c.info.size_out < 0) - c.info.size_out = cxlm->payload_size; + c.info.size_out = cxlds->payload_size; - rc = handle_mailbox_cmd_from_user(cxlm, &c, send.in.payload, + rc = handle_mailbox_cmd_from_user(cxlds, &c, send.in.payload, send.out.payload, &send.out.size, &send.retval); if (rc) @@ -478,13 +476,13 @@ int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s) return 0; } -static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out) +static int cxl_xfer_log(struct cxl_dev_state *cxlds, uuid_t *uuid, u32 size, u8 *out) { u32 remaining = size; u32 offset = 0; while (remaining) { - u32 xfer_size = min_t(u32, remaining, cxlm->payload_size); + u32 xfer_size = min_t(u32, remaining, cxlds->payload_size); struct cxl_mbox_get_log log = { .uuid = *uuid, .offset = cpu_to_le32(offset), @@ -492,8 +490,8 @@ static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out) }; int rc; - rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_LOG, &log, - sizeof(log), out, xfer_size); + rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_LOG, &log, sizeof(log), + out, xfer_size); if (rc < 0) return rc; @@ -507,14 +505,14 @@ static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out) /** * cxl_walk_c |