Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24157aaf authored by Avi Kivity's avatar Avi Kivity
Browse files

KVM: MMU: Eliminate redundant temporaries in FNAME(fetch)



'level' and 'sptep' are aliases for 'interator.level' and 'iterator.sptep', no
need for them.

Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 5991b332
Loading
Loading
Loading
Loading
+24 −35
Original line number Diff line number Diff line
@@ -320,12 +320,10 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
{
	unsigned access = gw->pt_access;
	struct kvm_mmu_page *sp = NULL;
	u64 *sptep = NULL;
	int uninitialized_var(level);
	bool dirty = is_dirty_gpte(gw->ptes[gw->level - 1]);
	int top_level;
	unsigned direct_access;
	struct kvm_shadow_walk_iterator iterator;
	struct kvm_shadow_walk_iterator it;

	if (!is_present_gpte(gw->ptes[gw->level - 1]))
		return NULL;
@@ -346,68 +344,59 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
	if (FNAME(gpte_changed)(vcpu, gw, top_level))
		goto out_gpte_changed;

	for (shadow_walk_init(&iterator, vcpu, addr);
	     shadow_walk_okay(&iterator) && iterator.level > gw->level;
	     shadow_walk_next(&iterator)) {
	for (shadow_walk_init(&it, vcpu, addr);
	     shadow_walk_okay(&it) && it.level > gw->level;
	     shadow_walk_next(&it)) {
		gfn_t table_gfn;

		level = iterator.level;
		sptep = iterator.sptep;

		drop_large_spte(vcpu, sptep);
		drop_large_spte(vcpu, it.sptep);

		sp = NULL;
		if (!is_shadow_present_pte(*sptep)) {
			table_gfn = gw->table_gfn[level - 2];
			sp = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
					      false, access, sptep);
		if (!is_shadow_present_pte(*it.sptep)) {
			table_gfn = gw->table_gfn[it.level - 2];
			sp = kvm_mmu_get_page(vcpu, table_gfn, addr, it.level-1,
					      false, access, it.sptep);
		}

		/*
		 * Verify that the gpte in the page we've just write
		 * protected is still there.
		 */
		if (FNAME(gpte_changed)(vcpu, gw, level - 1))
		if (FNAME(gpte_changed)(vcpu, gw, it.level - 1))
			goto out_gpte_changed;

		if (sp)
			link_shadow_page(sptep, sp);
			link_shadow_page(it.sptep, sp);
	}

	for (;
	     shadow_walk_okay(&iterator) && iterator.level > hlevel;
	     shadow_walk_next(&iterator)) {
	     shadow_walk_okay(&it) && it.level > hlevel;
	     shadow_walk_next(&it)) {
		gfn_t direct_gfn;

		level = iterator.level;
		sptep = iterator.sptep;

		validate_direct_spte(vcpu, sptep, direct_access);
		validate_direct_spte(vcpu, it.sptep, direct_access);

		drop_large_spte(vcpu, sptep);
		drop_large_spte(vcpu, it.sptep);

		if (is_shadow_present_pte(*sptep))
		if (is_shadow_present_pte(*it.sptep))
			continue;

		direct_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1);
		direct_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE(it.level) - 1);

		sp = kvm_mmu_get_page(vcpu, direct_gfn, addr, level-1,
				      true, direct_access, sptep);
		link_shadow_page(sptep, sp);
		sp = kvm_mmu_get_page(vcpu, direct_gfn, addr, it.level-1,
				      true, direct_access, it.sptep);
		link_shadow_page(it.sptep, sp);
	}

	sptep = iterator.sptep;
	level = iterator.level;

	mmu_set_spte(vcpu, sptep, access, gw->pte_access & access,
		     user_fault, write_fault, dirty, ptwrite, level,
	mmu_set_spte(vcpu, it.sptep, access, gw->pte_access & access,
		     user_fault, write_fault, dirty, ptwrite, it.level,
		     gw->gfn, pfn, false, true);

	return sptep;
	return it.sptep;

out_gpte_changed:
	if (sp)
		kvm_mmu_put_page(sp, sptep);
		kvm_mmu_put_page(sp, it.sptep);
	kvm_release_pfn_clean(pfn);
	return NULL;
}