static void stage2_op_pte()

in kvm/mmu.c [227:266]


static void stage2_op_pte(struct kvm *kvm, gpa_t addr,
			  pte_t *ptep, u32 ptep_level, enum stage2_op op)
{
	int i, ret;
	pte_t *next_ptep;
	u32 next_ptep_level;
	unsigned long next_page_size, page_size;

	ret = stage2_level_to_page_size(ptep_level, &page_size);
	if (ret)
		return;

	BUG_ON(addr & (page_size - 1));

	if (!pte_val(*ptep))
		return;

	if (ptep_level && !stage2_pte_leaf(ptep)) {
		next_ptep = (pte_t *)stage2_pte_page_vaddr(*ptep);
		next_ptep_level = ptep_level - 1;
		ret = stage2_level_to_page_size(next_ptep_level,
						&next_page_size);
		if (ret)
			return;

		if (op == STAGE2_OP_CLEAR)
			set_pte(ptep, __pte(0));
		for (i = 0; i < PTRS_PER_PTE; i++)
			stage2_op_pte(kvm, addr + i * next_page_size,
					&next_ptep[i], next_ptep_level, op);
		if (op == STAGE2_OP_CLEAR)
			put_page(virt_to_page(next_ptep));
	} else {
		if (op == STAGE2_OP_CLEAR)
			set_pte(ptep, __pte(0));
		else if (op == STAGE2_OP_WP)
			set_pte(ptep, __pte(pte_val(*ptep) & ~_PAGE_WRITE));
		stage2_remote_tlb_flush(kvm, ptep_level, addr);
	}
}