{
pte_t *ptep;
unsigned int shift;
- unsigned long flags;
+ unsigned long pfn, flags;
struct mm_struct *mm;
if (user_mode(regs))
local_irq_save(flags);
ptep = __find_linux_pte(mm->pgd, addr, NULL, &shift);
- local_irq_restore(flags);
- if (!ptep || pte_special(*ptep))
- return ULONG_MAX;
+ if (!ptep || pte_special(*ptep)) {
+ pfn = ULONG_MAX;
+ goto out;
+ }
- if (shift > PAGE_SHIFT) {
+ if (shift <= PAGE_SHIFT)
+ pfn = pte_pfn(*ptep);
+ else {
unsigned long rpnmask = (1ul << shift) - PAGE_SIZE;
-
- return pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask)));
+ pfn = pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask)));
}
- return pte_pfn(*ptep);
+out:
+ local_irq_restore(flags);
+ return pfn;
}
static void flush_tlb_206(unsigned int num_sets, unsigned int action)