aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/mce_power.c')
-rw-r--r--arch/powerpc/kernel/mce_power.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index 37a110b8e7e1..ecb375040637 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -40,7 +40,7 @@ static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
40{ 40{
41 pte_t *ptep; 41 pte_t *ptep;
42 unsigned int shift; 42 unsigned int shift;
43 unsigned long flags; 43 unsigned long pfn, flags;
44 struct mm_struct *mm; 44 struct mm_struct *mm;
45 45
46 if (user_mode(regs)) 46 if (user_mode(regs))
@@ -50,18 +50,22 @@ static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
50 50
51 local_irq_save(flags); 51 local_irq_save(flags);
52 ptep = __find_linux_pte(mm->pgd, addr, NULL, &shift); 52 ptep = __find_linux_pte(mm->pgd, addr, NULL, &shift);
53 local_irq_restore(flags);
54 53
55 if (!ptep || pte_special(*ptep)) 54 if (!ptep || pte_special(*ptep)) {
56 return ULONG_MAX; 55 pfn = ULONG_MAX;
56 goto out;
57 }
57 58
58 if (shift > PAGE_SHIFT) { 59 if (shift <= PAGE_SHIFT)
60 pfn = pte_pfn(*ptep);
61 else {
59 unsigned long rpnmask = (1ul << shift) - PAGE_SIZE; 62 unsigned long rpnmask = (1ul << shift) - PAGE_SIZE;
60 63 pfn = pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask)));
61 return pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask)));
62 } 64 }
63 65
64 return pte_pfn(*ptep); 66out:
67 local_irq_restore(flags);
68 return pfn;
65} 69}
66 70
67/* flush SLBs and reload */ 71/* flush SLBs and reload */