From d143455ee92126c9647a11c67b6db13ae50fc5d8 Mon Sep 17 00:00:00 2001
From: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Date: Wed, 7 Mar 2018 21:35:37 +0530
Subject: [PATCH 76/80] fsl-mc/dpio: aligned access of qbman cacheable region

Alignment requirement on ARM is lenient (In Linux) for regions
mapped as "Memory Type" but have very strict policy for regions
mapped as "Device Type". Unaligned access to regions mapped
as "Device Type" will always result to unaligned fault.

DPIO driver have un-aligned access to QBman cacheable region
and the Linux driver maps the region as "Memory Type". On Host
Linux this works because MMU Stage-1 configured by driver allows
unaligned access. In Virtual Machine cases, final region mapping type
is governed by combination of Stage-1 and Stage-2 MMU mapping.

Linux driver in VM controls maps the region as "Memory Type" in
Stage-1 MMU while Stage-2 is controlled by KVM. And current KVM
implementation does not allow device region to be mapped as
"Memory Type". Till we have a working/upstream-able solution
for Virtual Machine, we need to change un-aligned access in DPIO
driver to be aligned

While we reached to this point as we observed below alignment
exception in Virtual Machine when accessing qbman cacheable region.

  kvm [2347]: Unsupported FSC: EC=0x24 xFSC=0x21
  ESR_EL2=0x92000061
  error: kvm run failed Bad address
  PC=ffff000008398e78  SP=ffff800009bcb540
  X00=ffff000008041000 X01=ffff800009bcb580 X02=ffff800009bcb650
  X03=0000000000000180
  X04=ffff000008041001 X05=ffff800009bcb581 X06=0200000000000000
  X07=0000000000000000
  X08=0000000000000000 X09=ffff000008041000 X10=0000000000000001
  X11=0000000000de6cb0
  X12=00000000fa83b2da X13=0000000000000001 X14=000000007f605ec8
  X15=00000000e26f5d5e
  X16=000000008521af1e X17=000000001076277e X18=ffff800009bcb5c0
  X19=ffff800079da2b00
  X20=ffff800009bcb650 X21=0000000000000002 X22=0000000000000000
  X23=0000000000000000
  X24=0000000000000000 X25=ffff8000099e7440 X26=ffff000008da6000
  X27=ffff000008e7f000
  X28=00000000499e7440 X29=ffff800009bcb540 X30=ffff00000839a160
  PSTATE=20000145 --C- EL1h

Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
---
 drivers/staging/fsl-mc/bus/dpio/qbman-portal.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
index 71a98ba..97fd356 100644
--- a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
+++ b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
@@ -439,7 +439,17 @@ int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
 		return -EBUSY;
 
 	p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
-	memcpy(&p->dca, &d->dca, 31);
+	/* This is mapped as DEVICE type memory, writes are
+	 * with address alignment:
+	 * desc.dca address alignment = 1
+	 * desc.seqnum address alignment = 2
+	 * desc.orpid address alignment = 4
+	 * desc.tgtid address alignment = 8
+	 */
+	p->dca = d->dca;
+	p->seqnum = d->seqnum;
+	p->orpid = d->orpid;
+	memcpy(&p->tgtid, &d->tgtid, 24);
 	memcpy(&p->fd, fd, sizeof(*fd));
 
 	/* Set the verb byte, have to substitute in the valid-bit */
-- 
1.7.1

