Skip to content

Commit 6782a30

Browse files
committed
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
2 parents d815858 + 8441c7d commit 6782a30

8 files changed

Lines changed: 70 additions & 41 deletions

File tree

arch/x86/mm/kaslr.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,12 @@ void __init kernel_randomize_memory(void)
115115

116116
/*
117117
* 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.
122122
*/
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))
124124
kaslr_regions[0].size_tb = memory_tb;
125125

126126
/*

drivers/cxl/acpi.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,16 @@ EXPORT_SYMBOL_FOR_MODULES(cxl_do_xormap_calc, "cxl_translate");
7575

7676
static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr)
7777
{
78-
struct cxl_cxims_data *cximsd = cxlrd->platform_data;
78+
int hbiw = cxlrd->cxlsd.nr_targets;
79+
struct cxl_cxims_data *cximsd;
80+
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;
7986

80-
return cxl_do_xormap_calc(cximsd, addr, cxlrd->cxlsd.nr_targets);
87+
return cxl_do_xormap_calc(cximsd, addr, hbiw);
8188
}
8289

8390
struct cxl_cxims_context {

drivers/cxl/core/hdm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
403403
* is not set.
404404
*/
405405
if (cxled->part < 0)
406-
for (int i = 0; cxlds->nr_partitions; i++)
406+
for (int i = 0; i < cxlds->nr_partitions; i++)
407407
if (resource_contains(&cxlds->part[i].res, res)) {
408408
cxled->part = i;
409409
break;
@@ -530,7 +530,7 @@ resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled)
530530

531531
resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled)
532532
{
533-
resource_size_t base = -1;
533+
resource_size_t base = RESOURCE_SIZE_MAX;
534534

535535
lockdep_assert_held(&cxl_rwsem.dpa);
536536
if (cxled->dpa_res)

drivers/cxl/core/port.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,7 @@ static int update_decoder_targets(struct device *dev, void *data)
15901590
cxlsd->target[i] = dport;
15911591
dev_dbg(dev, "dport%d found in target list, index %d\n",
15921592
dport->port_id, i);
1593-
return 1;
1593+
return 0;
15941594
}
15951595
}
15961596

drivers/cxl/core/region.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ static ssize_t extended_linear_cache_size_show(struct device *dev,
759759
ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region);
760760
if ((rc = ACQUIRE_ERR(rwsem_read_intr, &rwsem)))
761761
return rc;
762-
return sysfs_emit(buf, "%#llx\n", p->cache_size);
762+
return sysfs_emit(buf, "%pap\n", &p->cache_size);
763763
}
764764
static DEVICE_ATTR_RO(extended_linear_cache_size);
765765

@@ -3118,7 +3118,7 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
31183118
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
31193119
struct cxl_region_params *p = &cxlr->params;
31203120
struct cxl_endpoint_decoder *cxled = NULL;
3121-
u64 dpa_offset, hpa_offset, hpa;
3121+
u64 base, dpa_offset, hpa_offset, hpa;
31223122
u16 eig = 0;
31233123
u8 eiw = 0;
31243124
int pos;
@@ -3136,8 +3136,14 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
31363136
ways_to_eiw(p->interleave_ways, &eiw);
31373137
granularity_to_eig(p->interleave_granularity, &eig);
31383138

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;
31403144
hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, eiw, eig);
3145+
if (hpa_offset == ULLONG_MAX)
3146+
return ULLONG_MAX;
31413147

31423148
/* Apply the hpa_offset to the region base address */
31433149
hpa = hpa_offset + p->res->start + p->cache_size;
@@ -3146,6 +3152,9 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
31463152
if (cxlrd->ops.hpa_to_spa)
31473153
hpa = cxlrd->ops.hpa_to_spa(cxlrd, hpa);
31483154

3155+
if (hpa == ULLONG_MAX)
3156+
return ULLONG_MAX;
3157+
31493158
if (!cxl_resource_contains_addr(p->res, hpa)) {
31503159
dev_dbg(&cxlr->dev,
31513160
"Addr trans fail: hpa 0x%llx not in region\n", hpa);
@@ -3170,7 +3179,8 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset,
31703179
struct cxl_region_params *p = &cxlr->params;
31713180
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
31723181
struct cxl_endpoint_decoder *cxled;
3173-
u64 hpa, hpa_offset, dpa_offset;
3182+
u64 hpa_offset = offset;
3183+
u64 dpa, dpa_offset;
31743184
u16 eig = 0;
31753185
u8 eiw = 0;
31763186
int pos;
@@ -3187,10 +3197,13 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset,
31873197
* CXL HPA is assumed to equal SPA.
31883198
*/
31893199
if (cxlrd->ops.spa_to_hpa) {
3190-
hpa = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset);
3191-
hpa_offset = hpa - p->res->start;
3192-
} else {
3193-
hpa_offset = offset;
3200+
hpa_offset = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset);
3201+
if (hpa_offset == ULLONG_MAX) {
3202+
dev_dbg(&cxlr->dev, "HPA not found for %pr offset %#llx\n",
3203+
p->res, offset);
3204+
return -ENXIO;
3205+
}
3206+
hpa_offset -= p->res->start;
31943207
}
31953208

31963209
pos = cxl_calculate_position(hpa_offset, eiw, eig);
@@ -3207,8 +3220,13 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset,
32073220
cxled = p->targets[i];
32083221
if (cxled->pos != pos)
32093222
continue;
3223+
3224+
dpa = cxl_dpa_resource_start(cxled);
3225+
if (dpa != RESOURCE_SIZE_MAX)
3226+
dpa += dpa_offset;
3227+
32103228
result->cxlmd = cxled_to_memdev(cxled);
3211-
result->dpa = cxl_dpa_resource_start(cxled) + dpa_offset;
3229+
result->dpa = dpa;
32123230

32133231
return 0;
32143232
}

drivers/pci/Kconfig

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,6 @@ config PCI_P2PDMA
225225
P2P DMA transactions must be between devices behind the same root
226226
port.
227227

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-
234228
If unsure, say N.
235229

236230
config PCI_LABEL

mm/Kconfig

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,10 +1220,14 @@ config ZONE_DEVICE
12201220
Device memory hotplug support allows for establishing pmem,
12211221
or other device driver discovered memory regions, in the
12221222
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.
1225-
1226-
If FS_DAX is enabled, then say Y.
1223+
"device-physical" addresses which is needed for DAX, PCI_P2PDMA, and
1224+
DEVICE_PRIVATE features among others.
1225+
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.
12271231

12281232
#
12291233
# Helpers to mirror range of the CPU page tables of a process into device page

tools/testing/cxl/test/cxl_translate.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ static u64 to_hpa(u64 dpa_offset, int pos, u8 r_eiw, u16 r_eig, u8 hb_ways,
6868

6969
/* Calculate base HPA offset from DPA and position */
7070
hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, r_eiw, r_eig);
71+
if (hpa_offset == ULLONG_MAX)
72+
return ULLONG_MAX;
7173

7274
if (math == XOR_MATH) {
7375
cximsd->nr_maps = hbiw_to_nr_maps[hb_ways];
@@ -258,19 +260,23 @@ static int test_random_params(void)
258260
pos = get_random_u32() % ways;
259261
dpa = get_random_u64() >> 12;
260262

263+
reverse_dpa = ULLONG_MAX;
264+
reverse_pos = -1;
265+
261266
hpa = cxl_calculate_hpa_offset(dpa, pos, eiw, eig);
262-
reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig);
263-
reverse_pos = cxl_calculate_position(hpa, eiw, eig);
264-
265-
if (reverse_dpa != dpa || reverse_pos != pos) {
266-
pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n",
267-
i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw,
268-
eig);
269-
270-
if (failures++ > 10) {
271-
pr_err("test random too many failures, stop\n");
272-
break;
273-
}
267+
if (hpa != ULLONG_MAX) {
268+
reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig);
269+
reverse_pos = cxl_calculate_position(hpa, eiw, eig);
270+
if (reverse_dpa == dpa && reverse_pos == pos)
271+
continue;
272+
}
273+
274+
pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n",
275+
i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw, eig);
276+
277+
if (failures++ > 10) {
278+
pr_err("test random too many failures, stop\n");
279+
break;
274280
}
275281
}
276282
pr_info("..... test random: PASS %d FAIL %d\n", i - failures, failures);

0 commit comments

Comments
 (0)