|
@@ -1408,7 +1408,6 @@ static void __xen_write_cr3(bool kernel, unsigned long cr3)
|
|
|
xen_mc_callback(set_current_cr3, (void *)cr3);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
static void xen_write_cr3(unsigned long cr3)
|
|
|
{
|
|
|
BUG_ON(preemptible());
|
|
@@ -1434,6 +1433,45 @@ static void xen_write_cr3(unsigned long cr3)
|
|
|
xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
+/*
|
|
|
+ * At the start of the day - when Xen launches a guest, it has already
|
|
|
+ * built pagetables for the guest. We diligently look over them
|
|
|
+ * in xen_setup_kernel_pagetable and graft as appropiate them in the
|
|
|
+ * init_level4_pgt and its friends. Then when we are happy we load
|
|
|
+ * the new init_level4_pgt - and continue on.
|
|
|
+ *
|
|
|
+ * The generic code starts (start_kernel) and 'init_mem_mapping' sets
|
|
|
+ * up the rest of the pagetables. When it has completed it loads the cr3.
|
|
|
+ * N.B. that baremetal would start at 'start_kernel' (and the early
|
|
|
+ * #PF handler would create bootstrap pagetables) - so we are running
|
|
|
+ * with the same assumptions as what to do when write_cr3 is executed
|
|
|
+ * at this point.
|
|
|
+ *
|
|
|
+ * Since there are no user-page tables at all, we have two variants
|
|
|
+ * of xen_write_cr3 - the early bootup (this one), and the late one
|
|
|
+ * (xen_write_cr3). The reason we have to do that is that in 64-bit
|
|
|
+ * the Linux kernel and user-space are both in ring 3 while the
|
|
|
+ * hypervisor is in ring 0.
|
|
|
+ */
|
|
|
+static void __init xen_write_cr3_init(unsigned long cr3)
|
|
|
+{
|
|
|
+ BUG_ON(preemptible());
|
|
|
+
|
|
|
+ xen_mc_batch(); /* disables interrupts */
|
|
|
+
|
|
|
+ /* Update while interrupts are disabled, so its atomic with
|
|
|
+ respect to ipis */
|
|
|
+ this_cpu_write(xen_cr3, cr3);
|
|
|
+
|
|
|
+ __xen_write_cr3(true, cr3);
|
|
|
+
|
|
|
+ xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */
|
|
|
+
|
|
|
+ pv_mmu_ops.write_cr3 = &xen_write_cr3;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static int xen_pgd_alloc(struct mm_struct *mm)
|
|
|
{
|
|
|
pgd_t *pgd = mm->pgd;
|
|
@@ -2102,11 +2140,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
|
|
|
.write_cr2 = xen_write_cr2,
|
|
|
|
|
|
.read_cr3 = xen_read_cr3,
|
|
|
-#ifdef CONFIG_X86_32
|
|
|
.write_cr3 = xen_write_cr3_init,
|
|
|
-#else
|
|
|
- .write_cr3 = xen_write_cr3,
|
|
|
-#endif
|
|
|
|
|
|
.flush_tlb_user = xen_flush_tlb,
|
|
|
.flush_tlb_kernel = xen_flush_tlb,
|