b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 353725d455cc27aa2008456c2711e7fae2b8a631 Mon Sep 17 00:00:00 2001 |
| 2 | From: Bharat Bhushan <Bharat.Bhushan@nxp.com> |
| 3 | Date: Wed, 7 Mar 2018 21:35:37 +0530 |
| 4 | Subject: [PATCH] soc: fsl: dpio: aligned access of qbman cacheable region |
| 5 | |
| 6 | Alignment requirement on ARM is lenient (In Linux) for regions |
| 7 | mapped as "Memory Type" but have very strict policy for regions |
| 8 | mapped as "Device Type". Unaligned access to regions mapped |
| 9 | as "Device Type" will always result to unaligned fault. |
| 10 | |
| 11 | DPIO driver have un-aligned access to QBman cacheable region |
| 12 | and the Linux driver maps the region as "Memory Type". On Host |
| 13 | Linux this works because MMU Stage-1 configured by driver allows |
| 14 | unaligned access. In Virtual Machine cases, final region mapping type |
| 15 | is governed by combination of Stage-1 and Stage-2 MMU mapping. |
| 16 | |
| 17 | Linux driver in VM controls maps the region as "Memory Type" in |
| 18 | Stage-1 MMU while Stage-2 is controlled by KVM. And current KVM |
| 19 | implementation does not allow device region to be mapped as |
| 20 | "Memory Type". Till we have a working/upstream-able solution |
| 21 | for Virtual Machine, we need to change un-aligned access in DPIO |
| 22 | driver to be aligned |
| 23 | |
| 24 | While we reached to this point as we observed below alignment |
| 25 | exception in Virtual Machine when accessing qbman cacheable region. |
| 26 | |
| 27 | kvm [2347]: Unsupported FSC: EC=0x24 xFSC=0x21 |
| 28 | ESR_EL2=0x92000061 |
| 29 | error: kvm run failed Bad address |
| 30 | PC=ffff000008398e78 SP=ffff800009bcb540 |
| 31 | X00=ffff000008041000 X01=ffff800009bcb580 X02=ffff800009bcb650 |
| 32 | X03=0000000000000180 |
| 33 | X04=ffff000008041001 X05=ffff800009bcb581 X06=0200000000000000 |
| 34 | X07=0000000000000000 |
| 35 | X08=0000000000000000 X09=ffff000008041000 X10=0000000000000001 |
| 36 | X11=0000000000de6cb0 |
| 37 | X12=00000000fa83b2da X13=0000000000000001 X14=000000007f605ec8 |
| 38 | X15=00000000e26f5d5e |
| 39 | X16=000000008521af1e X17=000000001076277e X18=ffff800009bcb5c0 |
| 40 | X19=ffff800079da2b00 |
| 41 | X20=ffff800009bcb650 X21=0000000000000002 X22=0000000000000000 |
| 42 | X23=0000000000000000 |
| 43 | X24=0000000000000000 X25=ffff8000099e7440 X26=ffff000008da6000 |
| 44 | X27=ffff000008e7f000 |
| 45 | X28=00000000499e7440 X29=ffff800009bcb540 X30=ffff00000839a160 |
| 46 | PSTATE=20000145 --C- EL1h |
| 47 | |
| 48 | Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com> |
| 49 | --- |
| 50 | drivers/soc/fsl/dpio/qbman-portal.c | 12 +++++++++++- |
| 51 | 1 file changed, 11 insertions(+), 1 deletion(-) |
| 52 | |
| 53 | --- a/drivers/soc/fsl/dpio/qbman-portal.c |
| 54 | +++ b/drivers/soc/fsl/dpio/qbman-portal.c |
| 55 | @@ -515,7 +515,17 @@ int qbman_swp_enqueue(struct qbman_swp * |
| 56 | return -EBUSY; |
| 57 | |
| 58 | p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); |
| 59 | - memcpy(&p->dca, &d->dca, 31); |
| 60 | + /* This is mapped as DEVICE type memory, writes are |
| 61 | + * with address alignment: |
| 62 | + * desc.dca address alignment = 1 |
| 63 | + * desc.seqnum address alignment = 2 |
| 64 | + * desc.orpid address alignment = 4 |
| 65 | + * desc.tgtid address alignment = 8 |
| 66 | + */ |
| 67 | + p->dca = d->dca; |
| 68 | + p->seqnum = d->seqnum; |
| 69 | + p->orpid = d->orpid; |
| 70 | + memcpy(&p->tgtid, &d->tgtid, 24); |
| 71 | memcpy(&p->fd, fd, sizeof(*fd)); |
| 72 | |
| 73 | if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { |