PCI: pci-bridge-emul: fix big-endian support
diff mbox series

Message ID 1563200177-8380-1-git-send-email-jaz@semihalf.com
State Superseded
Delegated to: Lorenzo Pieralisi
Headers show
Series
  • PCI: pci-bridge-emul: fix big-endian support
Related show

Commit Message

Grzegorz Jaszczyk July 15, 2019, 2:16 p.m. UTC
Perform conversion to little-endian before every write to configuration
space and converse back to cpu endianness during read. Additionally
initialise every not-byte wide fields of config space with proper
cpu_to_le* macro.

This is required since the structure describing config space of emulated
bridge assumes little-endian convention.

Signed-off-by: Grzegorz Jaszczyk <jaz@semihalf.com>
---
 drivers/pci/pci-bridge-emul.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Comments

Russell King - ARM Linux admin July 15, 2019, 2:30 p.m. UTC | #1
On Mon, Jul 15, 2019 at 04:16:17PM +0200, Grzegorz Jaszczyk wrote:
> Perform conversion to little-endian before every write to configuration
> space and converse back to cpu endianness during read. Additionally
> initialise every not-byte wide fields of config space with proper
> cpu_to_le* macro.
> 
> This is required since the structure describing config space of emulated
> bridge assumes little-endian convention.

This is insufficient - pci-bridge-emul.h needs to be fixed up to use
__le32 and __le16.

It is a good idea to check such changes with sparse - a tool originally
written by Linus, which is able to detect incorrect endian accesses
(iow, access to LE members without using a LE accessor.)  Such checks
rely on using the right types.
Grzegorz Jaszczyk July 16, 2019, 8:33 a.m. UTC | #2
Hi Russell

pon., 15 lip 2019 o 16:30 Russell King - ARM Linux admin
<linux@armlinux.org.uk> napisaƂ(a):
> This is insufficient - pci-bridge-emul.h needs to be fixed up to use
> __le32 and __le16.
>
> It is a good idea to check such changes with sparse - a tool originally
> written by Linus, which is able to detect incorrect endian accesses
> (iow, access to LE members without using a LE accessor.)  Such checks
> rely on using the right types.

Thank you for pointing this out - it is really usefully tool. I will
send v2 soon.

regards,
Grzegorz

Patch
diff mbox series

diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 83fb077..d1235d2 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -270,10 +270,10 @@  const static struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = {
 int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
 			 unsigned int flags)
 {
-	bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16;
+	bridge->conf.class_revision |= cpu_to_le32(PCI_CLASS_BRIDGE_PCI << 16);
 	bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
 	bridge->conf.cache_line_size = 0x10;
-	bridge->conf.status = PCI_STATUS_CAP_LIST;
+	bridge->conf.status = cpu_to_le16(PCI_STATUS_CAP_LIST);
 	bridge->pci_regs_behavior = kmemdup(pci_regs_behavior,
 					    sizeof(pci_regs_behavior),
 					    GFP_KERNEL);
@@ -357,7 +357,7 @@  int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 		ret = PCI_BRIDGE_EMUL_NOT_HANDLED;
 
 	if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED)
-		*value = cfgspace[reg / 4];
+		*value = le32_to_cpu(cfgspace[reg / 4]);
 
 	/*
 	 * Make sure we never return any reserved bit with a value
@@ -431,7 +431,7 @@  int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 	/* Clear the W1C bits */
 	new &= ~((value << shift) & (behavior[reg / 4].w1c & mask));
 
-	cfgspace[reg / 4] = new;
+	cfgspace[reg / 4] = cpu_to_le32(new);
 
 	if (write_op)
 		write_op(bridge, reg, old, new, mask);