sparc64: Fix executable bit testing in set_pmd_at() paths.
This code was mistakenly using the exec bit from the PMD in all cases, even when the PMD isn't a huge PMD. If it's not a huge PMD, test the exec bit in the individual ptes down in tlb_batch_pmd_scan(). Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
16ce8a30e6
commit
5b1e94fa43
1 changed files with 9 additions and 6 deletions
|
@ -134,7 +134,7 @@ no_cache_flush:
|
||||||
|
|
||||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||||
static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
|
static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
|
||||||
pmd_t pmd, bool exec)
|
pmd_t pmd)
|
||||||
{
|
{
|
||||||
unsigned long end;
|
unsigned long end;
|
||||||
pte_t *pte;
|
pte_t *pte;
|
||||||
|
@ -142,8 +142,11 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
|
||||||
pte = pte_offset_map(&pmd, vaddr);
|
pte = pte_offset_map(&pmd, vaddr);
|
||||||
end = vaddr + HPAGE_SIZE;
|
end = vaddr + HPAGE_SIZE;
|
||||||
while (vaddr < end) {
|
while (vaddr < end) {
|
||||||
if (pte_val(*pte) & _PAGE_VALID)
|
if (pte_val(*pte) & _PAGE_VALID) {
|
||||||
|
bool exec = pte_exec(*pte);
|
||||||
|
|
||||||
tlb_batch_add_one(mm, vaddr, exec);
|
tlb_batch_add_one(mm, vaddr, exec);
|
||||||
|
}
|
||||||
pte++;
|
pte++;
|
||||||
vaddr += PAGE_SIZE;
|
vaddr += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -177,15 +180,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pmd_none(orig)) {
|
if (!pmd_none(orig)) {
|
||||||
pte_t orig_pte = __pte(pmd_val(orig));
|
|
||||||
bool exec = pte_exec(orig_pte);
|
|
||||||
|
|
||||||
addr &= HPAGE_MASK;
|
addr &= HPAGE_MASK;
|
||||||
if (pmd_trans_huge(orig)) {
|
if (pmd_trans_huge(orig)) {
|
||||||
|
pte_t orig_pte = __pte(pmd_val(orig));
|
||||||
|
bool exec = pte_exec(orig_pte);
|
||||||
|
|
||||||
tlb_batch_add_one(mm, addr, exec);
|
tlb_batch_add_one(mm, addr, exec);
|
||||||
tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec);
|
tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec);
|
||||||
} else {
|
} else {
|
||||||
tlb_batch_pmd_scan(mm, addr, orig, exec);
|
tlb_batch_pmd_scan(mm, addr, orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue