示例#1
0
int huge_ptep_set_access_flags(struct vm_area_struct *vma,
			       unsigned long addr, pte_t *ptep,
			       pte_t pte, int dirty)
{
	pte_t *cpte;

	if (pte_cont(pte)) {
		int ncontig, i, changed = 0;
		size_t pgsize = 0;
		unsigned long pfn = pte_pfn(pte);
		/* Select all bits except the pfn */
		pgprot_t hugeprot =
			__pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^
				 pte_val(pte));

		cpte = huge_pte_offset(vma->vm_mm, addr);
		pfn = pte_pfn(*cpte);
		ncontig = find_num_contig(vma->vm_mm, addr, cpte,
					  *cpte, &pgsize);
		for (i = 0; i < ncontig; ++i, ++cpte) {
			changed = ptep_set_access_flags(vma, addr, cpte,
							pfn_pte(pfn,
								hugeprot),
							dirty);
			pfn += pgsize >> PAGE_SHIFT;
		}
		return changed;
	} else {
		return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
示例#2
0
int huge_ptep_set_access_flags(struct vm_area_struct *vma,
			       unsigned long addr, pte_t *ptep,
			       pte_t pte, int dirty)
{
	int ncontig, i, changed = 0;
	size_t pgsize = 0;
	unsigned long pfn = pte_pfn(pte), dpfn;
	pgprot_t hugeprot;
	pte_t orig_pte;

	if (!pte_cont(pte))
		return ptep_set_access_flags(vma, addr, ptep, pte, dirty);

	ncontig = find_num_contig(vma->vm_mm, addr, ptep, &pgsize);
	dpfn = pgsize >> PAGE_SHIFT;

	orig_pte = get_clear_flush(vma->vm_mm, addr, ptep, pgsize, ncontig);
	if (!pte_same(orig_pte, pte))
		changed = 1;

	/* Make sure we don't lose the dirty state */
	if (pte_dirty(orig_pte))
		pte = pte_mkdirty(pte);

	hugeprot = pte_pgprot(pte);
	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
		set_pte_at(vma->vm_mm, addr, ptep, pfn_pte(pfn, hugeprot));

	return changed;
}
示例#3
0
extern int huge_ptep_set_access_flags(struct vm_area_struct *vma,
				      unsigned long addr, pte_t *ptep,
				      pte_t pte, int dirty)
{
#ifdef HUGETLB_NEED_PRELOAD
	/*
	 * The "return 1" forces a call of update_mmu_cache, which will write a
	 * TLB entry.  Without this, platforms that don't do a write of the TLB
	 * entry in the TLB miss handler asm will fault ad infinitum.
	 */
	ptep_set_access_flags(vma, addr, ptep, pte, dirty);
	return 1;
#else
	int changed, psize;

	pte = set_access_flags_filter(pte, vma, dirty);
	changed = !pte_same(*(ptep), pte);
	if (changed) {

#ifdef CONFIG_PPC_BOOK3S_64
		struct hstate *h = hstate_vma(vma);

		psize = hstate_get_psize(h);
#ifdef CONFIG_DEBUG_VM
		assert_spin_locked(huge_pte_lockptr(h, vma->vm_mm, ptep));
#endif

#else
		/*
		 * Not used on non book3s64 platforms. But 8xx
		 * can possibly use tsize derived from hstate.
		 */
		psize = 0;
#endif
		__ptep_set_access_flags(vma, ptep, pte, addr, psize);
	}
	return changed;
#endif
}