unsigned long nr_mfns,
unsigned int flags)
{
- int rc;
+ int rc = 0;
unsigned long addr = virt, addr_end = addr + nr_mfns * PAGE_SIZE;
lpae_t pte, *entry;
lpae_t *third = NULL;
{
printk("%s: trying to replace an existing mapping addr=%lx mfn=%"PRI_mfn"\n",
__func__, addr, mfn_x(mfn));
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
if ( op == RESERVE )
break;
{
printk("%s: trying to %s a non-existing mapping addr=%lx\n",
__func__, op == REMOVE ? "remove" : "modify", addr);
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
if ( op == REMOVE )
pte.bits = 0;
{
printk("%s: Incorrect combination for addr=%lx\n",
__func__, addr);
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
}
write_pte(entry, pte);
BUG();
}
}
+out:
+ /*
+ * Flush the TLBs even in case of failure because we may have
+ * partially modified the PT. This will prevent any unexpected
+ * behavior afterwards.
+ */
flush_xen_data_tlb_range_va(virt, PAGE_SIZE * nr_mfns);
- rc = 0;
-
-out:
return rc;
}