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

Merge tag 'cxl-fixes-6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl

Pull Compute Express Link (CXL) fixes from Dave Jiang:

- Recognize all ZONE_DEVICE users as physaddr consumers

- Fix format string for extended_linear_cache_size_show()

- Fix target list setup for multiple decoders sharing the same
downstream port

- Restore HBIW check before derefernce platform data

- Fix potential infinite loop in __cxl_dpa_reserve()

- Check for invalid addresses returned from translation functions on
error

* tag 'cxl-fixes-6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl:
cxl: Check for invalid addresses returned from translation functions on errors
cxl/hdm: Fix potential infinite loop in __cxl_dpa_reserve()
cxl/acpi: Restore HBIW check before dereferencing platform_data
cxl/port: Fix target list setup for multiple decoders sharing the same dport
cxl/region: fix format string for resource_size_t
x86/kaslr: Recognize all ZONE_DEVICE users as physaddr consumers

+67 -38
+5 -5
arch/x86/mm/kaslr.c
··· 115 115 116 116 /* 117 117 * Adapt physical memory region size based on available memory, 118 - * except when CONFIG_PCI_P2PDMA is enabled. P2PDMA exposes the 119 - * device BAR space assuming the direct map space is large enough 120 - * for creating a ZONE_DEVICE mapping in the direct map corresponding 121 - * to the physical BAR address. 118 + * except when CONFIG_ZONE_DEVICE is enabled. ZONE_DEVICE wants to map 119 + * any physical address into the direct-map. KASLR wants to reliably 120 + * steal some physical address bits. Those design choices are in direct 121 + * conflict. 122 122 */ 123 - if (!IS_ENABLED(CONFIG_PCI_P2PDMA) && (memory_tb < kaslr_regions[0].size_tb)) 123 + if (!IS_ENABLED(CONFIG_ZONE_DEVICE) && (memory_tb < kaslr_regions[0].size_tb)) 124 124 kaslr_regions[0].size_tb = memory_tb; 125 125 126 126 /*
+9 -2
drivers/cxl/acpi.c
··· 75 75 76 76 static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr) 77 77 { 78 - struct cxl_cxims_data *cximsd = cxlrd->platform_data; 78 + int hbiw = cxlrd->cxlsd.nr_targets; 79 + struct cxl_cxims_data *cximsd; 79 80 80 - return cxl_do_xormap_calc(cximsd, addr, cxlrd->cxlsd.nr_targets); 81 + /* No xormaps for host bridge interleave ways of 1 or 3 */ 82 + if (hbiw == 1 || hbiw == 3) 83 + return addr; 84 + 85 + cximsd = cxlrd->platform_data; 86 + 87 + return cxl_do_xormap_calc(cximsd, addr, hbiw); 81 88 } 82 89 83 90 struct cxl_cxims_context {
+2 -2
drivers/cxl/core/hdm.c
··· 403 403 * is not set. 404 404 */ 405 405 if (cxled->part < 0) 406 - for (int i = 0; cxlds->nr_partitions; i++) 406 + for (int i = 0; i < cxlds->nr_partitions; i++) 407 407 if (resource_contains(&cxlds->part[i].res, res)) { 408 408 cxled->part = i; 409 409 break; ··· 530 530 531 531 resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled) 532 532 { 533 - resource_size_t base = -1; 533 + resource_size_t base = RESOURCE_SIZE_MAX; 534 534 535 535 lockdep_assert_held(&cxl_rwsem.dpa); 536 536 if (cxled->dpa_res)
+1 -1
drivers/cxl/core/port.c
··· 1590 1590 cxlsd->target[i] = dport; 1591 1591 dev_dbg(dev, "dport%d found in target list, index %d\n", 1592 1592 dport->port_id, i); 1593 - return 1; 1593 + return 0; 1594 1594 } 1595 1595 } 1596 1596
+27 -9
drivers/cxl/core/region.c
··· 759 759 ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region); 760 760 if ((rc = ACQUIRE_ERR(rwsem_read_intr, &rwsem))) 761 761 return rc; 762 - return sysfs_emit(buf, "%#llx\n", p->cache_size); 762 + return sysfs_emit(buf, "%pap\n", &p->cache_size); 763 763 } 764 764 static DEVICE_ATTR_RO(extended_linear_cache_size); 765 765 ··· 3118 3118 struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); 3119 3119 struct cxl_region_params *p = &cxlr->params; 3120 3120 struct cxl_endpoint_decoder *cxled = NULL; 3121 - u64 dpa_offset, hpa_offset, hpa; 3121 + u64 base, dpa_offset, hpa_offset, hpa; 3122 3122 u16 eig = 0; 3123 3123 u8 eiw = 0; 3124 3124 int pos; ··· 3136 3136 ways_to_eiw(p->interleave_ways, &eiw); 3137 3137 granularity_to_eig(p->interleave_granularity, &eig); 3138 3138 3139 - dpa_offset = dpa - cxl_dpa_resource_start(cxled); 3139 + base = cxl_dpa_resource_start(cxled); 3140 + if (base == RESOURCE_SIZE_MAX) 3141 + return ULLONG_MAX; 3142 + 3143 + dpa_offset = dpa - base; 3140 3144 hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, eiw, eig); 3145 + if (hpa_offset == ULLONG_MAX) 3146 + return ULLONG_MAX; 3141 3147 3142 3148 /* Apply the hpa_offset to the region base address */ 3143 3149 hpa = hpa_offset + p->res->start + p->cache_size; ··· 3151 3145 /* Root decoder translation overrides typical modulo decode */ 3152 3146 if (cxlrd->ops.hpa_to_spa) 3153 3147 hpa = cxlrd->ops.hpa_to_spa(cxlrd, hpa); 3148 + 3149 + if (hpa == ULLONG_MAX) 3150 + return ULLONG_MAX; 3154 3151 3155 3152 if (!cxl_resource_contains_addr(p->res, hpa)) { 3156 3153 dev_dbg(&cxlr->dev, ··· 3179 3170 struct cxl_region_params *p = &cxlr->params; 3180 3171 struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); 3181 3172 struct cxl_endpoint_decoder *cxled; 3182 - u64 hpa, hpa_offset, dpa_offset; 3173 + u64 hpa_offset = offset; 3174 + u64 dpa, dpa_offset; 3183 3175 u16 eig = 0; 3184 3176 u8 eiw = 0; 3185 3177 int pos; ··· 3197 3187 * CXL HPA is assumed to equal SPA. 3198 3188 */ 3199 3189 if (cxlrd->ops.spa_to_hpa) { 3200 - hpa = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset); 3201 - hpa_offset = hpa - p->res->start; 3202 - } else { 3203 - hpa_offset = offset; 3190 + hpa_offset = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset); 3191 + if (hpa_offset == ULLONG_MAX) { 3192 + dev_dbg(&cxlr->dev, "HPA not found for %pr offset %#llx\n", 3193 + p->res, offset); 3194 + return -ENXIO; 3195 + } 3196 + hpa_offset -= p->res->start; 3204 3197 } 3205 3198 3206 3199 pos = cxl_calculate_position(hpa_offset, eiw, eig); ··· 3220 3207 cxled = p->targets[i]; 3221 3208 if (cxled->pos != pos) 3222 3209 continue; 3210 + 3211 + dpa = cxl_dpa_resource_start(cxled); 3212 + if (dpa != RESOURCE_SIZE_MAX) 3213 + dpa += dpa_offset; 3214 + 3223 3215 result->cxlmd = cxled_to_memdev(cxled); 3224 - result->dpa = cxl_dpa_resource_start(cxled) + dpa_offset; 3216 + result->dpa = dpa; 3225 3217 3226 3218 return 0; 3227 3219 }
-6
drivers/pci/Kconfig
··· 225 225 P2P DMA transactions must be between devices behind the same root 226 226 port. 227 227 228 - Enabling this option will reduce the entropy of x86 KASLR memory 229 - regions. For example - on a 46 bit system, the entropy goes down 230 - from 16 bits to 15 bits. The actual reduction in entropy depends 231 - on the physical address bits, on processor features, kernel config 232 - (5 level page table) and physical memory present on the system. 233 - 234 228 If unsure, say N. 235 229 236 230 config PCI_LABEL
+7 -3
mm/Kconfig
··· 1220 1220 Device memory hotplug support allows for establishing pmem, 1221 1221 or other device driver discovered memory regions, in the 1222 1222 memmap. This allows pfn_to_page() lookups of otherwise 1223 - "device-physical" addresses which is needed for using a DAX 1224 - mapping in an O_DIRECT operation, among other things. 1223 + "device-physical" addresses which is needed for DAX, PCI_P2PDMA, and 1224 + DEVICE_PRIVATE features among others. 1225 1225 1226 - If FS_DAX is enabled, then say Y. 1226 + Enabling this option will reduce the entropy of x86 KASLR memory 1227 + regions. For example - on a 46 bit system, the entropy goes down 1228 + from 16 bits to 15 bits. The actual reduction in entropy depends 1229 + on the physical address bits, on processor features, kernel config 1230 + (5 level page table) and physical memory present on the system. 1227 1231 1228 1232 # 1229 1233 # Helpers to mirror range of the CPU page tables of a process into device page
+16 -10
tools/testing/cxl/test/cxl_translate.c
··· 68 68 69 69 /* Calculate base HPA offset from DPA and position */ 70 70 hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, r_eiw, r_eig); 71 + if (hpa_offset == ULLONG_MAX) 72 + return ULLONG_MAX; 71 73 72 74 if (math == XOR_MATH) { 73 75 cximsd->nr_maps = hbiw_to_nr_maps[hb_ways]; ··· 260 258 pos = get_random_u32() % ways; 261 259 dpa = get_random_u64() >> 12; 262 260 261 + reverse_dpa = ULLONG_MAX; 262 + reverse_pos = -1; 263 + 263 264 hpa = cxl_calculate_hpa_offset(dpa, pos, eiw, eig); 264 - reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig); 265 - reverse_pos = cxl_calculate_position(hpa, eiw, eig); 265 + if (hpa != ULLONG_MAX) { 266 + reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig); 267 + reverse_pos = cxl_calculate_position(hpa, eiw, eig); 268 + if (reverse_dpa == dpa && reverse_pos == pos) 269 + continue; 270 + } 266 271 267 - if (reverse_dpa != dpa || reverse_pos != pos) { 268 - pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n", 269 - i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw, 270 - eig); 272 + pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n", 273 + i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw, eig); 271 274 272 - if (failures++ > 10) { 273 - pr_err("test random too many failures, stop\n"); 274 - break; 275 - } 275 + if (failures++ > 10) { 276 + pr_err("test random too many failures, stop\n"); 277 + break; 276 278 } 277 279 } 278 280 pr_info("..... test random: PASS %d FAIL %d\n", i - failures, failures);