Skip to content

Commit

Permalink
[SPARC64]: Use inline patching for critical PTE operations.
Browse files Browse the repository at this point in the history
This handles the SUN4U vs SUN4V PTE layout differences
with near zero performance cost.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 20, 2006
1 parent ff02e0d commit cf62715
Show file tree
Hide file tree
Showing 2 changed files with 488 additions and 211 deletions.
211 changes: 3 additions & 208 deletions arch/sparc64/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1502,217 +1502,12 @@ unsigned long pte_sz_bits(unsigned long sz)
pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space, unsigned long page_size)
{
pte_t pte;
if (tlb_type == hypervisor) {
pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E_4V) &
~(unsigned long)_PAGE_CACHE_4V);
} else {
pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E_4U) &
~(unsigned long)_PAGE_CACHE_4U);
}

pte_val(pte) = page | pgprot_val(pgprot_noncached(prot));
pte_val(pte) |= (((unsigned long)space) << 32);
pte_val(pte) |= pte_sz_bits(page_size);
return pte;
}

unsigned long pte_present(pte_t pte)
{
return (pte_val(pte) &
((tlb_type == hypervisor) ?
_PAGE_PRESENT_4V : _PAGE_PRESENT_4U));
}

unsigned long pte_file(pte_t pte)
{
return (pte_val(pte) &
((tlb_type == hypervisor) ?
_PAGE_FILE_4V : _PAGE_FILE_4U));
}

unsigned long pte_read(pte_t pte)
{
return (pte_val(pte) &
((tlb_type == hypervisor) ?
_PAGE_READ_4V : _PAGE_READ_4U));
}

unsigned long pte_exec(pte_t pte)
{
return (pte_val(pte) &
((tlb_type == hypervisor) ?
_PAGE_EXEC_4V : _PAGE_EXEC_4U));
}

unsigned long pte_write(pte_t pte)
{
return (pte_val(pte) &
((tlb_type == hypervisor) ?
_PAGE_WRITE_4V : _PAGE_WRITE_4U));
}

unsigned long pte_dirty(pte_t pte)
{
return (pte_val(pte) &
((tlb_type == hypervisor) ?
_PAGE_MODIFIED_4V : _PAGE_MODIFIED_4U));
}

unsigned long pte_young(pte_t pte)
{
return (pte_val(pte) &
((tlb_type == hypervisor) ?
_PAGE_ACCESSED_4V : _PAGE_ACCESSED_4U));
}

pte_t pte_wrprotect(pte_t pte)
{
unsigned long mask = _PAGE_WRITE_4U | _PAGE_W_4U;

if (tlb_type == hypervisor)
mask = _PAGE_WRITE_4V | _PAGE_W_4V;

return __pte(pte_val(pte) & ~mask);
}

pte_t pte_rdprotect(pte_t pte)
{
unsigned long mask = _PAGE_R | _PAGE_READ_4U;

if (tlb_type == hypervisor)
mask = _PAGE_R | _PAGE_READ_4V;

return __pte(pte_val(pte) & ~mask);
}

pte_t pte_mkclean(pte_t pte)
{
unsigned long mask = _PAGE_MODIFIED_4U | _PAGE_W_4U;

if (tlb_type == hypervisor)
mask = _PAGE_MODIFIED_4V | _PAGE_W_4V;

return __pte(pte_val(pte) & ~mask);
}

pte_t pte_mkold(pte_t pte)
{
unsigned long mask = _PAGE_R | _PAGE_ACCESSED_4U;

if (tlb_type == hypervisor)
mask = _PAGE_R | _PAGE_ACCESSED_4V;

return __pte(pte_val(pte) & ~mask);
}

pte_t pte_mkyoung(pte_t pte)
{
unsigned long mask = _PAGE_R | _PAGE_ACCESSED_4U;

if (tlb_type == hypervisor)
mask = _PAGE_R | _PAGE_ACCESSED_4V;

return __pte(pte_val(pte) | mask);
}

pte_t pte_mkwrite(pte_t pte)
{
unsigned long mask = _PAGE_WRITE_4U;

if (tlb_type == hypervisor)
mask = _PAGE_WRITE_4V;

return __pte(pte_val(pte) | mask);
}

pte_t pte_mkdirty(pte_t pte)
{
unsigned long mask = _PAGE_MODIFIED_4U | _PAGE_W_4U;

if (tlb_type == hypervisor)
mask = _PAGE_MODIFIED_4V | _PAGE_W_4V;

return __pte(pte_val(pte) | mask);
}

pte_t pte_mkhuge(pte_t pte)
{
unsigned long mask = _PAGE_SZHUGE_4U;

if (tlb_type == hypervisor)
mask = _PAGE_SZHUGE_4V;

return __pte(pte_val(pte) | mask);
}

pte_t pgoff_to_pte(unsigned long off)
{
unsigned long bit = _PAGE_FILE_4U;

if (tlb_type == hypervisor)
bit = _PAGE_FILE_4V;

return __pte((off << PAGE_SHIFT) | bit);
}

pgprot_t pgprot_noncached(pgprot_t prot)
{
unsigned long val = pgprot_val(prot);
unsigned long off = _PAGE_CP_4U | _PAGE_CV_4U;
unsigned long on = _PAGE_E_4U;

if (tlb_type == hypervisor) {
off = _PAGE_CP_4V | _PAGE_CV_4V;
on = _PAGE_E_4V;
}

return __pgprot((val & ~off) | on);
}

pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
{
unsigned long sz_bits = _PAGE_SZBITS_4U;

if (tlb_type == hypervisor)
sz_bits = _PAGE_SZBITS_4V;

return __pte((pfn << PAGE_SHIFT) | pgprot_val(prot) | sz_bits);
}

unsigned long pte_pfn(pte_t pte)
{
unsigned long mask = _PAGE_PADDR_4U;

if (tlb_type == hypervisor)
mask = _PAGE_PADDR_4V;

return (pte_val(pte) & mask) >> PAGE_SHIFT;
}

pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
{
unsigned long preserve_mask;
unsigned long val;

preserve_mask = (_PAGE_PADDR_4U |
_PAGE_MODIFIED_4U |
_PAGE_ACCESSED_4U |
_PAGE_CP_4U |
_PAGE_CV_4U |
_PAGE_E_4U |
_PAGE_PRESENT_4U |
_PAGE_SZBITS_4U);
if (tlb_type == hypervisor)
preserve_mask = (_PAGE_PADDR_4V |
_PAGE_MODIFIED_4V |
_PAGE_ACCESSED_4V |
_PAGE_CP_4V |
_PAGE_CV_4V |
_PAGE_E_4V |
_PAGE_PRESENT_4V |
_PAGE_SZBITS_4V);

val = (pte_val(orig_pte) & preserve_mask);

return __pte(val | (pgprot_val(new_prot) & ~preserve_mask));
return pte;
}

static unsigned long kern_large_tte(unsigned long paddr)
Expand Down
Loading

0 comments on commit cf62715

Please sign in to comment.