Skip to content

Commit 3c936e0

Browse files
floatiouskwilczynski
authored andcommitted
PCI: endpoint: pci-epf-test: Handle endianness properly
The struct pci_epf_test_reg is the actual data in pci-epf-test's test_reg BAR (usually BAR0), which the host uses to send commands (etc.), and which pci-epf-test uses to send back status codes. pci-epf-test currently reads and writes this data without any endianness conversion functions, which means that pci-epf-test is completely broken on big-endian endpoint systems. PCI devices are inherently little-endian, and the data stored in the PCI BARs should be in little-endian. Use endianness conversion functions when reading and writing data to struct pci_epf_test_reg so that pci-epf-test will behave correctly on big-endian endpoint systems. Fixes: 349e7a8 ("PCI: endpoint: functions: Add an EP function to test PCI") Reviewed-by: Frank Li <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Niklas Cassel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Krzysztof Wilczyński <[email protected]>
1 parent 2014c95 commit 3c936e0

File tree

1 file changed

+73
-53
lines changed

1 file changed

+73
-53
lines changed

drivers/pci/endpoint/functions/pci-epf-test.c

Lines changed: 73 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,17 @@ struct pci_epf_test {
6666
};
6767

6868
struct pci_epf_test_reg {
69-
u32 magic;
70-
u32 command;
71-
u32 status;
72-
u64 src_addr;
73-
u64 dst_addr;
74-
u32 size;
75-
u32 checksum;
76-
u32 irq_type;
77-
u32 irq_number;
78-
u32 flags;
79-
u32 caps;
69+
__le32 magic;
70+
__le32 command;
71+
__le32 status;
72+
__le64 src_addr;
73+
__le64 dst_addr;
74+
__le32 size;
75+
__le32 checksum;
76+
__le32 irq_type;
77+
__le32 irq_number;
78+
__le32 flags;
79+
__le32 caps;
8080
} __packed;
8181

8282
static struct pci_epf_header test_header = {
@@ -324,13 +324,17 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
324324
struct pci_epc *epc = epf->epc;
325325
struct device *dev = &epf->dev;
326326
struct pci_epc_map src_map, dst_map;
327-
u64 src_addr = reg->src_addr;
328-
u64 dst_addr = reg->dst_addr;
329-
size_t copy_size = reg->size;
327+
u64 src_addr = le64_to_cpu(reg->src_addr);
328+
u64 dst_addr = le64_to_cpu(reg->dst_addr);
329+
size_t orig_size, copy_size;
330330
ssize_t map_size = 0;
331+
u32 flags = le32_to_cpu(reg->flags);
332+
u32 status = 0;
331333
void *copy_buf = NULL, *buf;
332334

333-
if (reg->flags & FLAG_USE_DMA) {
335+
orig_size = copy_size = le32_to_cpu(reg->size);
336+
337+
if (flags & FLAG_USE_DMA) {
334338
if (!dma_has_cap(DMA_MEMCPY, epf_test->dma_chan_tx->device->cap_mask)) {
335339
dev_err(dev, "DMA controller doesn't support MEMCPY\n");
336340
ret = -EINVAL;
@@ -350,15 +354,15 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
350354
src_addr, copy_size, &src_map);
351355
if (ret) {
352356
dev_err(dev, "Failed to map source address\n");
353-
reg->status = STATUS_SRC_ADDR_INVALID;
357+
status = STATUS_SRC_ADDR_INVALID;
354358
goto free_buf;
355359
}
356360

357361
ret = pci_epc_mem_map(epf->epc, epf->func_no, epf->vfunc_no,
358362
dst_addr, copy_size, &dst_map);
359363
if (ret) {
360364
dev_err(dev, "Failed to map destination address\n");
361-
reg->status = STATUS_DST_ADDR_INVALID;
365+
status = STATUS_DST_ADDR_INVALID;
362366
pci_epc_mem_unmap(epc, epf->func_no, epf->vfunc_no,
363367
&src_map);
364368
goto free_buf;
@@ -367,7 +371,7 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
367371
map_size = min_t(size_t, dst_map.pci_size, src_map.pci_size);
368372

369373
ktime_get_ts64(&start);
370-
if (reg->flags & FLAG_USE_DMA) {
374+
if (flags & FLAG_USE_DMA) {
371375
ret = pci_epf_test_data_transfer(epf_test,
372376
dst_map.phys_addr, src_map.phys_addr,
373377
map_size, 0, DMA_MEM_TO_MEM);
@@ -391,8 +395,8 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
391395
map_size = 0;
392396
}
393397

394-
pci_epf_test_print_rate(epf_test, "COPY", reg->size, &start,
395-
&end, reg->flags & FLAG_USE_DMA);
398+
pci_epf_test_print_rate(epf_test, "COPY", orig_size, &start, &end,
399+
flags & FLAG_USE_DMA);
396400

397401
unmap:
398402
if (map_size) {
@@ -405,9 +409,10 @@ static void pci_epf_test_copy(struct pci_epf_test *epf_test,
405409

406410
set_status:
407411
if (!ret)
408-
reg->status |= STATUS_COPY_SUCCESS;
412+
status |= STATUS_COPY_SUCCESS;
409413
else
410-
reg->status |= STATUS_COPY_FAIL;
414+
status |= STATUS_COPY_FAIL;
415+
reg->status = cpu_to_le32(status);
411416
}
412417

413418
static void pci_epf_test_read(struct pci_epf_test *epf_test,
@@ -423,9 +428,14 @@ static void pci_epf_test_read(struct pci_epf_test *epf_test,
423428
struct pci_epc *epc = epf->epc;
424429
struct device *dev = &epf->dev;
425430
struct device *dma_dev = epf->epc->dev.parent;
426-
u64 src_addr = reg->src_addr;
427-
size_t src_size = reg->size;
431+
u64 src_addr = le64_to_cpu(reg->src_addr);
432+
size_t orig_size, src_size;
428433
ssize_t map_size = 0;
434+
u32 flags = le32_to_cpu(reg->flags);
435+
u32 checksum = le32_to_cpu(reg->checksum);
436+
u32 status = 0;
437+
438+
orig_size = src_size = le32_to_cpu(reg->size);
429439

430440
src_buf = kzalloc(src_size, GFP_KERNEL);
431441
if (!src_buf) {
@@ -439,12 +449,12 @@ static void pci_epf_test_read(struct pci_epf_test *epf_test,
439449
src_addr, src_size, &map);
440450
if (ret) {
441451
dev_err(dev, "Failed to map address\n");
442-
reg->status = STATUS_SRC_ADDR_INVALID;
452+
status = STATUS_SRC_ADDR_INVALID;
443453
goto free_buf;
444454
}
445455

446456
map_size = map.pci_size;
447-
if (reg->flags & FLAG_USE_DMA) {
457+
if (flags & FLAG_USE_DMA) {
448458
dst_phys_addr = dma_map_single(dma_dev, buf, map_size,
449459
DMA_FROM_DEVICE);
450460
if (dma_mapping_error(dma_dev, dst_phys_addr)) {
@@ -481,11 +491,11 @@ static void pci_epf_test_read(struct pci_epf_test *epf_test,
481491
map_size = 0;
482492
}
483493

484-
pci_epf_test_print_rate(epf_test, "READ", reg->size, &start,
485-
&end, reg->flags & FLAG_USE_DMA);
494+
pci_epf_test_print_rate(epf_test, "READ", orig_size, &start, &end,
495+
flags & FLAG_USE_DMA);
486496

487-
crc32 = crc32_le(~0, src_buf, reg->size);
488-
if (crc32 != reg->checksum)
497+
crc32 = crc32_le(~0, src_buf, orig_size);
498+
if (crc32 != checksum)
489499
ret = -EIO;
490500

491501
unmap:
@@ -497,9 +507,10 @@ static void pci_epf_test_read(struct pci_epf_test *epf_test,
497507

498508
set_status:
499509
if (!ret)
500-
reg->status |= STATUS_READ_SUCCESS;
510+
status |= STATUS_READ_SUCCESS;
501511
else
502-
reg->status |= STATUS_READ_FAIL;
512+
status |= STATUS_READ_FAIL;
513+
reg->status = cpu_to_le32(status);
503514
}
504515

505516
static void pci_epf_test_write(struct pci_epf_test *epf_test,
@@ -514,30 +525,34 @@ static void pci_epf_test_write(struct pci_epf_test *epf_test,
514525
struct pci_epc *epc = epf->epc;
515526
struct device *dev = &epf->dev;
516527
struct device *dma_dev = epf->epc->dev.parent;
517-
u64 dst_addr = reg->dst_addr;
518-
size_t dst_size = reg->size;
528+
u64 dst_addr = le64_to_cpu(reg->dst_addr);
529+
size_t orig_size, dst_size;
519530
ssize_t map_size = 0;
531+
u32 flags = le32_to_cpu(reg->flags);
532+
u32 status = 0;
533+
534+
orig_size = dst_size = le32_to_cpu(reg->size);
520535

521536
dst_buf = kzalloc(dst_size, GFP_KERNEL);
522537
if (!dst_buf) {
523538
ret = -ENOMEM;
524539
goto set_status;
525540
}
526541
get_random_bytes(dst_buf, dst_size);
527-
reg->checksum = crc32_le(~0, dst_buf, dst_size);
542+
reg->checksum = cpu_to_le32(crc32_le(~0, dst_buf, dst_size));
528543
buf = dst_buf;
529544

530545
while (dst_size) {
531546
ret = pci_epc_mem_map(epc, epf->func_no, epf->vfunc_no,
532547
dst_addr, dst_size, &map);
533548
if (ret) {
534549
dev_err(dev, "Failed to map address\n");
535-
reg->status = STATUS_DST_ADDR_INVALID;
550+
status = STATUS_DST_ADDR_INVALID;
536551
goto free_buf;
537552
}
538553

539554
map_size = map.pci_size;
540-
if (reg->flags & FLAG_USE_DMA) {
555+
if (flags & FLAG_USE_DMA) {
541556
src_phys_addr = dma_map_single(dma_dev, buf, map_size,
542557
DMA_TO_DEVICE);
543558
if (dma_mapping_error(dma_dev, src_phys_addr)) {
@@ -576,8 +591,8 @@ static void pci_epf_test_write(struct pci_epf_test *epf_test,
576591
map_size = 0;
577592
}
578593

579-
pci_epf_test_print_rate(epf_test, "WRITE", reg->size, &start,
580-
&end, reg->flags & FLAG_USE_DMA);
594+
pci_epf_test_print_rate(epf_test, "WRITE", orig_size, &start, &end,
595+
flags & FLAG_USE_DMA);
581596

582597
/*
583598
* wait 1ms inorder for the write to complete. Without this delay L3
@@ -594,9 +609,10 @@ static void pci_epf_test_write(struct pci_epf_test *epf_test,
594609

595610
set_status:
596611
if (!ret)
597-
reg->status |= STATUS_WRITE_SUCCESS;
612+
status |= STATUS_WRITE_SUCCESS;
598613
else
599-
reg->status |= STATUS_WRITE_FAIL;
614+
status |= STATUS_WRITE_FAIL;
615+
reg->status = cpu_to_le32(status);
600616
}
601617

602618
static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test,
@@ -605,39 +621,42 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test,
605621
struct pci_epf *epf = epf_test->epf;
606622
struct device *dev = &epf->dev;
607623
struct pci_epc *epc = epf->epc;
608-
u32 status = reg->status | STATUS_IRQ_RAISED;
624+
u32 status = le32_to_cpu(reg->status);
625+
u32 irq_number = le32_to_cpu(reg->irq_number);
626+
u32 irq_type = le32_to_cpu(reg->irq_type);
609627
int count;
610628

611629
/*
612630
* Set the status before raising the IRQ to ensure that the host sees
613631
* the updated value when it gets the IRQ.
614632
*/
615-
WRITE_ONCE(reg->status, status);
633+
status |= STATUS_IRQ_RAISED;
634+
WRITE_ONCE(reg->status, cpu_to_le32(status));
616635

617-
switch (reg->irq_type) {
636+
switch (irq_type) {
618637
case IRQ_TYPE_INTX:
619638
pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
620639
PCI_IRQ_INTX, 0);
621640
break;
622641
case IRQ_TYPE_MSI:
623642
count = pci_epc_get_msi(epc, epf->func_no, epf->vfunc_no);
624-
if (reg->irq_number > count || count <= 0) {
643+
if (irq_number > count || count <= 0) {
625644
dev_err(dev, "Invalid MSI IRQ number %d / %d\n",
626-
reg->irq_number, count);
645+
irq_number, count);
627646
return;
628647
}
629648
pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
630-
PCI_IRQ_MSI, reg->irq_number);
649+
PCI_IRQ_MSI, irq_number);
631650
break;
632651
case IRQ_TYPE_MSIX:
633652
count = pci_epc_get_msix(epc, epf->func_no, epf->vfunc_no);
634-
if (reg->irq_number > count || count <= 0) {
653+
if (irq_number > count || count <= 0) {
635654
dev_err(dev, "Invalid MSIX IRQ number %d / %d\n",
636-
reg->irq_number, count);
655+
irq_number, count);
637656
return;
638657
}
639658
pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
640-
PCI_IRQ_MSIX, reg->irq_number);
659+
PCI_IRQ_MSIX, irq_number);
641660
break;
642661
default:
643662
dev_err(dev, "Failed to raise IRQ, unknown type\n");
@@ -654,21 +673,22 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
654673
struct device *dev = &epf->dev;
655674
enum pci_barno test_reg_bar = epf_test->test_reg_bar;
656675
struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
676+
u32 irq_type = le32_to_cpu(reg->irq_type);
657677

658-
command = READ_ONCE(reg->command);
678+
command = le32_to_cpu(READ_ONCE(reg->command));
659679
if (!command)
660680
goto reset_handler;
661681

662682
WRITE_ONCE(reg->command, 0);
663683
WRITE_ONCE(reg->status, 0);
664684

665-
if ((READ_ONCE(reg->flags) & FLAG_USE_DMA) &&
685+
if ((le32_to_cpu(READ_ONCE(reg->flags)) & FLAG_USE_DMA) &&
666686
!epf_test->dma_supported) {
667687
dev_err(dev, "Cannot transfer data using DMA\n");
668688
goto reset_handler;
669689
}
670690

671-
if (reg->irq_type > IRQ_TYPE_MSIX) {
691+
if (irq_type > IRQ_TYPE_MSIX) {
672692
dev_err(dev, "Failed to detect IRQ type\n");
673693
goto reset_handler;
674694
}

0 commit comments

Comments
 (0)