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

Commit 71b390e9 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

iommu/amd: Optimize iommu_unmap_page for new fetch_pte interface



Now that fetch_pte returns the page-size of the pte, this
function can be optimized a lot.

Tested-by: default avatarSuravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 3039ca1b
Loading
Loading
Loading
Loading
+8 −24
Original line number Original line Diff line number Diff line
@@ -1428,8 +1428,8 @@ static unsigned long iommu_unmap_page(struct protection_domain *dom,
				      unsigned long bus_addr,
				      unsigned long bus_addr,
				      unsigned long page_size)
				      unsigned long page_size)
{
{
	unsigned long long unmap_size, unmapped;
	unsigned long long unmapped;
	unsigned long pte_pgsize;
	unsigned long unmap_size;
	u64 *pte;
	u64 *pte;


	BUG_ON(!is_power_of_2(page_size));
	BUG_ON(!is_power_of_2(page_size));
@@ -1438,27 +1438,11 @@ static unsigned long iommu_unmap_page(struct protection_domain *dom,


	while (unmapped < page_size) {
	while (unmapped < page_size) {


		pte = fetch_pte(dom, bus_addr, &pte_pgsize);
		pte = fetch_pte(dom, bus_addr, &unmap_size);


		if (!pte) {
		if (pte) {
			/*
			int i, count;
			 * No PTE for this address
			 * move forward in 4kb steps
			 */
			unmap_size = PAGE_SIZE;
		} else if (PM_PTE_LEVEL(*pte) == 0) {
			/* 4kb PTE found for this address */
			unmap_size = PAGE_SIZE;
			*pte       = 0ULL;
		} else {
			int count, i;

			/* Large PTE found which maps this address */
			unmap_size = PTE_PAGE_SIZE(*pte);


			/* Only unmap from the first pte in the page */
			if ((unmap_size - 1) & bus_addr)
				break;
			count = PAGE_SIZE_PTE_COUNT(unmap_size);
			count = PAGE_SIZE_PTE_COUNT(unmap_size);
			for (i = 0; i < count; i++)
			for (i = 0; i < count; i++)
				pte[i] = 0ULL;
				pte[i] = 0ULL;