* [PATCH] parisc: Fix crash when calling PDC_PAT_MEM PDT firmware function
@ 2017-07-25 16:20 Helge Deller
0 siblings, 0 replies; only message in thread
From: Helge Deller @ 2017-07-25 16:20 UTC (permalink / raw)
To: linux-parisc, James Bottomley, John David Anglin
Commit c9c2877d08d9 ("parisc: Add Page Deallocation Table (PDT) support")
introduced the pdc_pat_mem_read_pd_pdt() firmware helper function, which
crashed the system because it trashed the stack if the
pdc_pat_mem_read_pd_retinfo struct was located on the stack (and which is
in size less than the required 32 64-bit values).
Fix it by using the pdc_result struct instead when calling firmware and copy
the return values back into the result struct when finished sucessfully.
While debugging this code I noticed that the pdc_type wasn't set correctly
either, so let's fix that too.
Fixes: c9c2877d08d9 ("parisc: Add Page Deallocation Table (PDT) support")
Signed-off-by: Helge Deller <deller@gmx.de>
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 9819025..526ed90 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1481,12 +1481,19 @@ int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
unsigned long offset)
{
int retval;
- unsigned long flags;
+ unsigned long flags, entries;
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_PD_READ,
- __pa(&pret), __pa(pdt_entries_ptr),
+ __pa(&pdc_result), __pa(pdt_entries_ptr),
count, offset);
+
+ if (retval == PDC_OK) {
+ entries = min(pdc_result[0], count);
+ pret->actual_count_bytes = entries;
+ pret->pdt_entries = entries / sizeof(unsigned long);
+ }
+
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c
index f3a797e..be8bed60 100644
--- a/arch/parisc/kernel/pdt.c
+++ b/arch/parisc/kernel/pdt.c
@@ -112,10 +112,12 @@ void __init pdc_pdt_init(void)
#ifdef CONFIG_64BIT
struct pdc_pat_mem_read_pd_retinfo pat_pret;
+ /* try old obsolete PAT firmware function first */
+ pdt_type = PDT_PAT_OLD;
ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry,
MAX_PDT_ENTRIES);
if (ret != PDC_OK) {
- pdt_type = PDT_PAT_OLD;
+ pdt_type = PDT_PAT_NEW;
ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry,
MAX_PDT_TABLE_SIZE, 0);
}
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2017-07-25 16:20 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-25 16:20 [PATCH] parisc: Fix crash when calling PDC_PAT_MEM PDT firmware function Helge Deller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox