|
@@ -1324,6 +1324,33 @@ static void update_domain(struct protection_domain *domain)
|
|
|
domain->updated = false;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * This function is used to add another level to an IO page table. Adding
|
|
|
+ * another level increases the size of the address space by 9 bits to a size up
|
|
|
+ * to 64 bits.
|
|
|
+ */
|
|
|
+static bool increase_address_space(struct protection_domain *domain,
|
|
|
+ gfp_t gfp)
|
|
|
+{
|
|
|
+ u64 *pte;
|
|
|
+
|
|
|
+ if (domain->mode == PAGE_MODE_6_LEVEL)
|
|
|
+ /* address space already 64 bit large */
|
|
|
+ return false;
|
|
|
+
|
|
|
+ pte = (void *)get_zeroed_page(gfp);
|
|
|
+ if (!pte)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ *pte = PM_LEVEL_PDE(domain->mode,
|
|
|
+ virt_to_phys(domain->pt_root));
|
|
|
+ domain->pt_root = pte;
|
|
|
+ domain->mode += 1;
|
|
|
+ domain->updated = true;
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* If the pte_page is not yet allocated this function is called
|
|
|
*/
|