[RFC][PATCH] Fix HPMC handler by increasing size to multiple of 16 bytes
* John David Anglin <firstname.lastname@example.org>:
> On 2018-03-17 7:36 AM, Helge Deller wrote:
> > Can you maybe try to localize where in the drivers/ata/sata_via.c driver
> > triggers the HPMC ?
> > --- arch/parisc/kernel/hpmc.S 2018-01-28 22:20:33.000000000 +0100
> > +++ arch/parisc/kernel/hpmc.S 2018-03-15 14:13:46.611969815 +0100
> > @@ -308,4 +290,5 @@
> > .align 4
> > .export os_hpmc_size
> > os_hpmc_size:
> > - .word .os_hpmc_end-.os_hpmc
> > + /* .word .os_hpmc_end-.os_hpmc */
> > + .word (.os_hpmc_end - .os_hpmc) * 4 /* sizeof(u32) */
> > This one seems wrong.
> > I think you just didn't hit a HPMC with your first patch, and as such
> > this patch has no influence...
> Helge, did you check that os_hpmc is correctly entered after you added
> the ".align 4" statement (e.g., trigger hpmc by accessing page 0 or
> such)? I looked at one of my builds and the size is correct as is.
> Is it possible that the length needs to be a multiple of 16? Current
> length is 0x194.
Good point. I changed that in the patch below.
> There are a couple of minor issues with assembly code. There are no .type
> and .size directives for os_hpmc_size.
Fixed as well.
> I think we should investigate further as I have never seen hpmc
> handler entered on rp3440 or c8000. On rp3440, there are messages
> about the branch failing in the SL log. However, this might have been
> fixed by your alignment fix.
No, the problem still exists in existing code.
Below patch is build-tested only.
[PATCH] Fix HPMC handler by increasing size to multiple of 16 bytes
Make sure that the HPMC handler is 16-byte aligned and that it's length
in the IVT is a multiple of 16 bytes. Otherwise PDC may decide not
to jump to HPMC handler.
Signed-off-by: Helge Deller <email@example.com>
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
index 8d072c44f300..f09f54f8042e 100644
@@ -84,6 +84,7 @@ END(hpmc_pim_data)
.import intr_save, code
+ .align 16
@@ -305,7 +306,9 @@ ENDPROC_CFI(os_hpmc)
- .export os_hpmc_size
+ .type os_hpmc_size, @object
+ .size os_hpmc_size, 4
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index c919e6c0a687..ca6e8722fffb 100644
@@ -837,8 +837,8 @@ void __init initialize_ivt(const void *iva)
ivap = instr;
/* Compute Checksum for HPMC handler */
- length = os_hpmc_size;
- ivap = length;
+ length = ALIGN(os_hpmc_size, 16);
+ ivap = length; /* length needs to be multiple of 16. */
hpmcp = (u32 *)os_hpmc;