/*H:360 * (ii) Making sure the Guest stack is mapped. * * Remember that direct traps into the Guest need a mapped Guest kernel stack. * pin_stack_pages() calls us here: we could simply call demand_page(), but as * we've seen that logic is quite long, and usually the stack pages are already * mapped, so it's overkill. * * This is a quick version which answers the question: is this virtual address * mapped by the shadow page tables, and is it writable? */ static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr) { pgd_t *spgd; unsigned long flags; #ifdef CONFIG_X86_PAE pmd_t *spmd; #endif /* Look at the current top level entry: is it present? */ spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr); if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) return false; #ifdef CONFIG_X86_PAE spmd = spmd_addr(cpu, *spgd, vaddr); if (!(pmd_flags(*spmd) & _PAGE_PRESENT)) return false; #endif /* * Check the flags on the pte entry itself: it must be present and * writable. */ flags = pte_flags(*(spte_addr(cpu, *spgd, vaddr))); return (flags & (_PAGE_PRESENT|_PAGE_RW)) == (_PAGE_PRESENT|_PAGE_RW); }
/*H:340 * Converting a Guest page table entry to a shadow (ie. real) page table * entry can be a little tricky. The flags are (almost) the same, but the * Guest PTE contains a virtual page number: the CPU needs the real page * number. */ static pte_t gpte_to_spte(struct lg_cpu *cpu, pte_t gpte, int write) { unsigned long pfn, base, flags; /* * The Guest sets the global flag, because it thinks that it is using * PGE. We only told it to use PGE so it would tell us whether it was * flushing a kernel mapping or a userspace mapping. We don't actually * use the global bit, so throw it away. */ flags = (pte_flags(gpte) & ~_PAGE_GLOBAL); /* The Guest's pages are offset inside the Launcher. */ base = (unsigned long)cpu->lg->mem_base / PAGE_SIZE; /* * We need a temporary "unsigned long" variable to hold the answer from * get_pfn(), because it returns 0xFFFFFFFF on failure, which wouldn't * fit in spte.pfn. get_pfn() finds the real physical number of the * page, given the virtual number. */ pfn = get_pfn(base + pte_pfn(gpte), write); if (pfn == -1UL) { kill_guest(cpu, "failed to get page %lu", pte_pfn(gpte)); /* * When we destroy the Guest, we'll go through the shadow page * tables and release_pte() them. Make sure we don't think * this one is valid! */ flags = 0; } /* Now we assemble our shadow PTE from the page number and flags. */ return pfn_pte(pfn, __pgprot(flags)); }
/*H:501 * We do need the Switcher code mapped at all times, so we allocate that * part of the Guest page table here. We map the Switcher code immediately, * but defer mapping of the guest register page and IDT/LDT etc page until * just before we run the guest in map_switcher_in_guest(). * * We *could* do this setup in map_switcher_in_guest(), but at that point * we've interrupts disabled, and allocating pages like that is fraught: we * can't sleep if we need to free up some memory. */ static bool allocate_switcher_mapping(struct lg_cpu *cpu) { int i; for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) { pte_t *pte = find_spte(cpu, switcher_addr + i * PAGE_SIZE, true, CHECK_GPGD_MASK, _PAGE_TABLE); if (!pte) return false; /* * Map the switcher page if not already there. It might * already be there because we call allocate_switcher_mapping() * in guest_set_pgd() just in case it did discard our Switcher * mapping, but it probably didn't. */ if (i == 0 && !(pte_flags(*pte) & _PAGE_PRESENT)) { /* Get a reference to the Switcher page. */ get_page(lg_switcher_pages[0]); /* Create a read-only, exectuable, kernel-style PTE */ set_pte(pte, mk_pte(lg_switcher_pages[0], PAGE_KERNEL_RX)); } } cpu->lg->pgdirs[cpu->cpu_pgd].switcher_mapped = true; return true; }
/* We walk down the guest page tables to get a guest-physical address */ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr) { pgd_t gpgd; pte_t gpte; #ifdef CONFIG_X86_PAE pmd_t gpmd; #endif /* Still not set up? Just map 1:1. */ if (unlikely(cpu->linear_pages)) return vaddr; /* First step: get the top-level Guest page table entry. */ gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t); /* Toplevel not present? We can't map it in. */ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) { kill_guest(cpu, "Bad address %#lx", vaddr); return -1UL; } #ifdef CONFIG_X86_PAE gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t); if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) kill_guest(cpu, "Bad address %#lx", vaddr); gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t); #else gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t); #endif if (!(pte_flags(gpte) & _PAGE_PRESENT)) kill_guest(cpu, "Bad address %#lx", vaddr); return pte_pfn(gpte) * PAGE_SIZE | (vaddr & ~PAGE_MASK); }
/*H:460 And to complete the chain, release_pte() looks like this: */ static void release_pte(pte_t pte) { /* * Remember that get_user_pages_fast() took a reference to the page, in * get_pfn()? We have to put it back now. */ if (pte_flags(pte) & _PAGE_PRESENT) put_page(pte_page(pte)); }
static bool check_gpte(struct lg_cpu *cpu, pte_t gpte) { if ((pte_flags(gpte) & _PAGE_PSE) || pte_pfn(gpte) >= cpu->lg->pfn_limit) { kill_guest(cpu, "bad page table entry"); return false; } return true; }
static bool gpte_in_iomem(struct lg_cpu *cpu, pte_t gpte) { /* We don't handle large pages. */ if (pte_flags(gpte) & _PAGE_PSE) return false; return (pte_pfn(gpte) >= cpu->lg->pfn_limit && pte_pfn(gpte) < cpu->lg->device_limit); }
/*H:420 * This is the routine which actually sets the page table entry for then * "idx"'th shadow page table. * * Normally, we can just throw out the old entry and replace it with 0: if they * use it demand_page() will put the new entry in. We need to do this anyway: * The Guest expects _PAGE_ACCESSED to be set on its PTE the first time a page * is read from, and _PAGE_DIRTY when it's written to. * * But Avi Kivity pointed out that most Operating Systems (Linux included) set * these bits on PTEs immediately anyway. This is done to save the CPU from * having to update them, but it helps us the same way: if they set * _PAGE_ACCESSED then we can put a read-only PTE entry in immediately, and if * they set _PAGE_DIRTY then we can put a writable PTE entry in immediately. */ static void __guest_set_pte(struct lg_cpu *cpu, int idx, unsigned long vaddr, pte_t gpte) { /* Look up the matching shadow page directory entry. */ pgd_t *spgd = spgd_addr(cpu, idx, vaddr); #ifdef CONFIG_X86_PAE pmd_t *spmd; #endif /* If the top level isn't present, there's no entry to update. */ if (pgd_flags(*spgd) & _PAGE_PRESENT) { #ifdef CONFIG_X86_PAE spmd = spmd_addr(cpu, *spgd, vaddr); if (pmd_flags(*spmd) & _PAGE_PRESENT) { #endif /* Otherwise, start by releasing the existing entry. */ pte_t *spte = spte_addr(cpu, *spgd, vaddr); release_pte(*spte); /* * If they're setting this entry as dirty or accessed, * we might as well put that entry they've given us in * now. This shaves 10% off a copy-on-write * micro-benchmark. */ if ((pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) && !gpte_in_iomem(cpu, gpte)) { if (!check_gpte(cpu, gpte)) return; set_pte(spte, gpte_to_spte(cpu, gpte, pte_flags(gpte) & _PAGE_DIRTY)); } else { /* * Otherwise kill it and we can demand_page() * it in later. */ set_pte(spte, __pte(0)); } #ifdef CONFIG_X86_PAE } #endif } }
static void ept_mmu_notifier_change_pte(struct mmu_notifier *mn, struct mm_struct *mm, unsigned long address, pte_t pte) { struct vmx_vcpu *vcpu = mmu_notifier_to_vmx(mn); pr_debug("ept: change_pte addr %lx flags %lx\n", address, pte_flags(pte)); /* * NOTE: Recent linux kernels (seen on 3.7 at least) hold a lock * while calling this notifier, making it impossible to call * get_user_pages_fast(). As a result, we just invalidate the * page so that the mapping can be recreated later during a fault. */ ept_invalidate_page(vcpu, mm, address); }
/*H:360 * (ii) Making sure the Guest stack is mapped. * * Remember that direct traps into the Guest need a mapped Guest kernel stack. * pin_stack_pages() calls us here: we could simply call demand_page(), but as * we've seen that logic is quite long, and usually the stack pages are already * mapped, so it's overkill. * * This is a quick version which answers the question: is this virtual address * mapped by the shadow page tables, and is it writable? */ static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr) { pte_t *spte; unsigned long flags; /* You can't put your stack in the Switcher! */ if (vaddr >= switcher_addr) return false; /* If there's no shadow PTE, it's not writable. */ spte = find_spte(cpu, vaddr, false, 0, 0); if (!spte) return false; /* * Check the flags on the pte entry itself: it must be present and * writable. */ flags = pte_flags(*spte); return (flags & (_PAGE_PRESENT|_PAGE_RW)) == (_PAGE_PRESENT|_PAGE_RW); }
Pml4e * copyuvm(Pml4e *oldmap, usize sz) { uintptr a; Pml4e *newmap; Pte *pte; uchar *oldmem, *newmem; uint flags; newmap = setupkvm(); if (newmap == nil) return nil; for (a = 0; a < sz; a += PGSIZE) { pte = walkpgmap(oldmap, (void *)a, 0); if (pte == nil) panic("copyuvm - nil pte"); if (!*pte & PTE_P) panic("copyuvm - page not present"); oldmem = p2v(pte_addr(*pte)); flags = pte_flags(*pte); newmem = kalloc(); if (newmem == nil) goto bad; memmove(newmem, oldmem, PGSIZE); if (mappages(newmap, (void *)a, PGSIZE, v2p(newmem), flags) < 0) goto bad; } return newmap; bad: freeuvm(newmap); return nil; }
/* We walk down the guest page tables to get a guest-physical address */ bool __guest_pa(struct lg_cpu *cpu, unsigned long vaddr, unsigned long *paddr) { pgd_t gpgd; pte_t gpte; #ifdef CONFIG_X86_PAE pmd_t gpmd; #endif /* Still not set up? Just map 1:1. */ if (unlikely(cpu->linear_pages)) { *paddr = vaddr; return true; } /* First step: get the top-level Guest page table entry. */ gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t); /* Toplevel not present? We can't map it in. */ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) goto fail; #ifdef CONFIG_X86_PAE gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t); if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) goto fail; gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t); #else gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t); #endif if (!(pte_flags(gpte) & _PAGE_PRESENT)) goto fail; *paddr = pte_pfn(gpte) * PAGE_SIZE | (vaddr & ~PAGE_MASK); return true; fail: *paddr = -1UL; return false; }
static int pte_testbit(pte_t pte) { return pte_flags(pte) & _PAGE_UNUSED1; }
/*H:330 * (i) Looking up a page table entry when the Guest faults. * * We saw this call in run_guest(): when we see a page fault in the Guest, we * come here. That's because we only set up the shadow page tables lazily as * they're needed, so we get page faults all the time and quietly fix them up * and return to the Guest without it knowing. * * If we fixed up the fault (ie. we mapped the address), this routine returns * true. Otherwise, it was a real fault and we need to tell the Guest. * * There's a corner case: they're trying to access memory between * pfn_limit and device_limit, which is I/O memory. In this case, we * return false and set @iomem to the physical address, so the the * Launcher can handle the instruction manually. */ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode, unsigned long *iomem) { unsigned long gpte_ptr; pte_t gpte; pte_t *spte; pmd_t gpmd; pgd_t gpgd; *iomem = 0; /* We never demand page the Switcher, so trying is a mistake. */ if (vaddr >= switcher_addr) return false; /* First step: get the top-level Guest page table entry. */ if (unlikely(cpu->linear_pages)) { /* Faking up a linear mapping. */ gpgd = __pgd(CHECK_GPGD_MASK); } else { gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t); /* Toplevel not present? We can't map it in. */ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) return false; /* * This kills the Guest if it has weird flags or tries to * refer to a "physical" address outside the bounds. */ if (!check_gpgd(cpu, gpgd)) return false; } /* This "mid-level" entry is only used for non-linear, PAE mode. */ gpmd = __pmd(_PAGE_TABLE); #ifdef CONFIG_X86_PAE if (likely(!cpu->linear_pages)) { gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t); /* Middle level not present? We can't map it in. */ if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) return false; /* * This kills the Guest if it has weird flags or tries to * refer to a "physical" address outside the bounds. */ if (!check_gpmd(cpu, gpmd)) return false; } /* * OK, now we look at the lower level in the Guest page table: keep its * address, because we might update it later. */ gpte_ptr = gpte_addr(cpu, gpmd, vaddr); #else /* * OK, now we look at the lower level in the Guest page table: keep its * address, because we might update it later. */ gpte_ptr = gpte_addr(cpu, gpgd, vaddr); #endif if (unlikely(cpu->linear_pages)) { /* Linear? Make up a PTE which points to same page. */ gpte = __pte((vaddr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); } else { /* Read the actual PTE value. */ gpte = lgread(cpu, gpte_ptr, pte_t); } /* If this page isn't in the Guest page tables, we can't page it in. */ if (!(pte_flags(gpte) & _PAGE_PRESENT)) return false; /* * Check they're not trying to write to a page the Guest wants * read-only (bit 2 of errcode == write). */ if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW)) return false; /* User access to a kernel-only page? (bit 3 == user access) */ if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER)) return false; /* If they're accessing io memory, we expect a fault. */ if (gpte_in_iomem(cpu, gpte)) { *iomem = (pte_pfn(gpte) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK); return false; } /* * Check that the Guest PTE flags are OK, and the page number is below * the pfn_limit (ie. not mapping the Launcher binary). */ if (!check_gpte(cpu, gpte)) return false; /* Add the _PAGE_ACCESSED and (for a write) _PAGE_DIRTY flag */ gpte = pte_mkyoung(gpte); if (errcode & 2) gpte = pte_mkdirty(gpte); /* Get the pointer to the shadow PTE entry we're going to set. */ spte = find_spte(cpu, vaddr, true, pgd_flags(gpgd), pmd_flags(gpmd)); if (!spte) return false; /* * If there was a valid shadow PTE entry here before, we release it. * This can happen with a write to a previously read-only entry. */ release_pte(*spte); /* * If this is a write, we insist that the Guest page is writable (the * final arg to gpte_to_spte()). */ if (pte_dirty(gpte)) *spte = gpte_to_spte(cpu, gpte, 1); else /* * If this is a read, don't set the "writable" bit in the page * table entry, even if the Guest says it's writable. That way * we will come back here when a write does actually occur, so * we can update the Guest's _PAGE_DIRTY flag. */ set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0)); /* * Finally, we write the Guest PTE entry back: we've set the * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags. */ if (likely(!cpu->linear_pages)) lgwrite(cpu, gpte_ptr, pte_t, gpte); /* * The fault is fixed, the page table is populated, the mapping * manipulated, the result returned and the code complete. A small * delay and a trace of alliteration are the only indications the Guest * has that a page fault occurred at all. */ return true; }
/*H:330 * (i) Looking up a page table entry when the Guest faults. * * We saw this call in run_guest(): when we see a page fault in the Guest, we * come here. That's because we only set up the shadow page tables lazily as * they're needed, so we get page faults all the time and quietly fix them up * and return to the Guest without it knowing. * * If we fixed up the fault (ie. we mapped the address), this routine returns * true. Otherwise, it was a real fault and we need to tell the Guest. */ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) { pgd_t gpgd; pgd_t *spgd; unsigned long gpte_ptr; pte_t gpte; pte_t *spte; /* Mid level for PAE. */ #ifdef CONFIG_X86_PAE pmd_t *spmd; pmd_t gpmd; #endif /* First step: get the top-level Guest page table entry. */ if (unlikely(cpu->linear_pages)) { /* Faking up a linear mapping. */ gpgd = __pgd(CHECK_GPGD_MASK); } else { gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t); /* Toplevel not present? We can't map it in. */ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) return false; } /* Now look at the matching shadow entry. */ spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr); if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) { /* No shadow entry: allocate a new shadow PTE page. */ unsigned long ptepage = get_zeroed_page(GFP_KERNEL); /* * This is not really the Guest's fault, but killing it is * simple for this corner case. */ if (!ptepage) { kill_guest(cpu, "out of memory allocating pte page"); return false; } /* We check that the Guest pgd is OK. */ check_gpgd(cpu, gpgd); /* * And we copy the flags to the shadow PGD entry. The page * number in the shadow PGD is the page we just allocated. */ set_pgd(spgd, __pgd(__pa(ptepage) | pgd_flags(gpgd))); } #ifdef CONFIG_X86_PAE if (unlikely(cpu->linear_pages)) { /* Faking up a linear mapping. */ gpmd = __pmd(_PAGE_TABLE); } else { gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t); /* Middle level not present? We can't map it in. */ if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) return false; } /* Now look at the matching shadow entry. */ spmd = spmd_addr(cpu, *spgd, vaddr); if (!(pmd_flags(*spmd) & _PAGE_PRESENT)) { /* No shadow entry: allocate a new shadow PTE page. */ unsigned long ptepage = get_zeroed_page(GFP_KERNEL); /* * This is not really the Guest's fault, but killing it is * simple for this corner case. */ if (!ptepage) { kill_guest(cpu, "out of memory allocating pte page"); return false; } /* We check that the Guest pmd is OK. */ check_gpmd(cpu, gpmd); /* * And we copy the flags to the shadow PMD entry. The page * number in the shadow PMD is the page we just allocated. */ set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd))); } /* * OK, now we look at the lower level in the Guest page table: keep its * address, because we might update it later. */ gpte_ptr = gpte_addr(cpu, gpmd, vaddr); #else /* * OK, now we look at the lower level in the Guest page table: keep its * address, because we might update it later. */ gpte_ptr = gpte_addr(cpu, gpgd, vaddr); #endif if (unlikely(cpu->linear_pages)) { /* Linear? Make up a PTE which points to same page. */ gpte = __pte((vaddr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); } else { /* Read the actual PTE value. */ gpte = lgread(cpu, gpte_ptr, pte_t); } /* If this page isn't in the Guest page tables, we can't page it in. */ if (!(pte_flags(gpte) & _PAGE_PRESENT)) return false; /* * Check they're not trying to write to a page the Guest wants * read-only (bit 2 of errcode == write). */ if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW)) return false; /* User access to a kernel-only page? (bit 3 == user access) */ if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER)) return false; /* * Check that the Guest PTE flags are OK, and the page number is below * the pfn_limit (ie. not mapping the Launcher binary). */ check_gpte(cpu, gpte); /* Add the _PAGE_ACCESSED and (for a write) _PAGE_DIRTY flag */ gpte = pte_mkyoung(gpte); if (errcode & 2) gpte = pte_mkdirty(gpte); /* Get the pointer to the shadow PTE entry we're going to set. */ spte = spte_addr(cpu, *spgd, vaddr); /* * If there was a valid shadow PTE entry here before, we release it. * This can happen with a write to a previously read-only entry. */ release_pte(*spte); /* * If this is a write, we insist that the Guest page is writable (the * final arg to gpte_to_spte()). */ if (pte_dirty(gpte)) *spte = gpte_to_spte(cpu, gpte, 1); else /* * If this is a read, don't set the "writable" bit in the page * table entry, even if the Guest says it's writable. That way * we will come back here when a write does actually occur, so * we can update the Guest's _PAGE_DIRTY flag. */ set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0)); /* * Finally, we write the Guest PTE entry back: we've set the * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags. */ if (likely(!cpu->linear_pages)) lgwrite(cpu, gpte_ptr, pte_t, gpte); /* * The fault is fixed, the page table is populated, the mapping * manipulated, the result returned and the code complete. A small * delay and a trace of alliteration are the only indications the Guest * has that a page fault occurred at all. */ return true; }
static void check_gpte(struct lg_cpu *cpu, pte_t gpte) { if ((pte_flags(gpte) & _PAGE_PSE) || pte_pfn(gpte) >= cpu->lg->pfn_limit) kill_guest(cpu, "bad page table entry"); }
void __init adjust_boot_vcpu_info(void) { unsigned long lpfn, rpfn, lmfn, rmfn; pte_t *lpte, *rpte; unsigned int level; mmu_update_t mmu[2]; /* * setup_vcpu_info() cannot be used more than once for a given (v)CPU, * hence we must swap the underlying MFNs of the two pages holding old * and new vcpu_info of the boot CPU. * * Do *not* use __get_cpu_var() or percpu_{write,...}() here, as the per- * CPU segment didn't get reloaded yet. Using percpu_read(), as in * arch_use_lazy_mmu_mode(), though undesirable, is safe except for the * accesses to variables that were updated in setup_percpu_areas(). */ lpte = lookup_address((unsigned long)&per_cpu_var(vcpu_info) + (__per_cpu_load - __per_cpu_start), &level); rpte = lookup_address((unsigned long)&per_cpu(vcpu_info, 0), &level); BUG_ON(!lpte || !(pte_flags(*lpte) & _PAGE_PRESENT)); BUG_ON(!rpte || !(pte_flags(*rpte) & _PAGE_PRESENT)); lmfn = __pte_mfn(*lpte); rmfn = __pte_mfn(*rpte); if (lmfn == rmfn) return; lpfn = mfn_to_local_pfn(lmfn); rpfn = mfn_to_local_pfn(rmfn); printk(KERN_INFO "Swapping MFNs for PFN %lx and %lx (MFN %lx and %lx)\n", lpfn, rpfn, lmfn, rmfn); xen_l1_entry_update(lpte, pfn_pte_ma(rmfn, pte_pgprot(*lpte))); xen_l1_entry_update(rpte, pfn_pte_ma(lmfn, pte_pgprot(*rpte))); #ifdef CONFIG_X86_64 if (HYPERVISOR_update_va_mapping((unsigned long)__va(lpfn<<PAGE_SHIFT), pfn_pte_ma(rmfn, PAGE_KERNEL_RO), 0)) BUG(); #endif if (HYPERVISOR_update_va_mapping((unsigned long)__va(rpfn<<PAGE_SHIFT), pfn_pte_ma(lmfn, PAGE_KERNEL), UVMF_TLB_FLUSH)) BUG(); set_phys_to_machine(lpfn, rmfn); set_phys_to_machine(rpfn, lmfn); mmu[0].ptr = ((uint64_t)lmfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; mmu[0].val = rpfn; mmu[1].ptr = ((uint64_t)rmfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; mmu[1].val = lpfn; if (HYPERVISOR_mmu_update(mmu, 2, NULL, DOMID_SELF)) BUG(); /* * Copy over all contents of the page just replaced, except for the * vcpu_info itself, as it may have got updated after having been * copied from __per_cpu_load[]. */ memcpy(__va(rpfn << PAGE_SHIFT), __va(lpfn << PAGE_SHIFT), (unsigned long)&per_cpu_var(vcpu_info) & (PAGE_SIZE - 1)); level = (unsigned long)(&per_cpu_var(vcpu_info) + 1) & (PAGE_SIZE - 1); if (level) memcpy(__va(rpfn << PAGE_SHIFT) + level, __va(lpfn << PAGE_SHIFT) + level, PAGE_SIZE - level); }