Merge branches 'stable/p2m-identity.v4.9.1' and 'stable/e820' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
* 'stable/p2m-identity.v4.9.1' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen/m2p: Check whether the MFN has IDENTITY_FRAME bit set.. xen/m2p: No need to catch exceptions when we know that there is no RAM xen/debug: WARN_ON when identity PFN has no _PAGE_IOMAP flag set. xen/debugfs: Add 'p2m' file for printing out the P2M layout. xen/setup: Set identity mapping for non-RAM E820 and E820 gaps. xen/mmu: WARN_ON when racing to swap middle leaf. xen/mmu: Set _PAGE_IOMAP if PFN is an identity PFN. xen/mmu: Add the notion of identity (1-1) mapping. xen: Mark all initial reserved pages for the balloon as INVALID_P2M_ENTRY. * 'stable/e820' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen/e820: Don't mark balloon memory as E820_UNUSABLE when running as guest and fix overflow. xen/setup: Inhibit resource API from using System RAM E820 gaps as PCI mem gaps.
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/tlbflush.h>
|
||||
@@ -416,8 +417,12 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
|
||||
if (val & _PAGE_PRESENT) {
|
||||
unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
|
||||
pteval_t flags = val & PTE_FLAGS_MASK;
|
||||
unsigned long mfn = pfn_to_mfn(pfn);
|
||||
unsigned long mfn;
|
||||
|
||||
if (!xen_feature(XENFEAT_auto_translated_physmap))
|
||||
mfn = get_phys_to_machine(pfn);
|
||||
else
|
||||
mfn = pfn;
|
||||
/*
|
||||
* If there's no mfn for the pfn, then just create an
|
||||
* empty non-present pte. Unfortunately this loses
|
||||
@@ -427,8 +432,18 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
|
||||
if (unlikely(mfn == INVALID_P2M_ENTRY)) {
|
||||
mfn = 0;
|
||||
flags = 0;
|
||||
} else {
|
||||
/*
|
||||
* Paramount to do this test _after_ the
|
||||
* INVALID_P2M_ENTRY as INVALID_P2M_ENTRY &
|
||||
* IDENTITY_FRAME_BIT resolves to true.
|
||||
*/
|
||||
mfn &= ~FOREIGN_FRAME_BIT;
|
||||
if (mfn & IDENTITY_FRAME_BIT) {
|
||||
mfn &= ~IDENTITY_FRAME_BIT;
|
||||
flags |= _PAGE_IOMAP;
|
||||
}
|
||||
}
|
||||
|
||||
val = ((pteval_t)mfn << PAGE_SHIFT) | flags;
|
||||
}
|
||||
|
||||
@@ -532,6 +547,41 @@ pte_t xen_make_pte(pteval_t pte)
|
||||
}
|
||||
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte);
|
||||
|
||||
#ifdef CONFIG_XEN_DEBUG
|
||||
pte_t xen_make_pte_debug(pteval_t pte)
|
||||
{
|
||||
phys_addr_t addr = (pte & PTE_PFN_MASK);
|
||||
phys_addr_t other_addr;
|
||||
bool io_page = false;
|
||||
pte_t _pte;
|
||||
|
||||
if (pte & _PAGE_IOMAP)
|
||||
io_page = true;
|
||||
|
||||
_pte = xen_make_pte(pte);
|
||||
|
||||
if (!addr)
|
||||
return _pte;
|
||||
|
||||
if (io_page &&
|
||||
(xen_initial_domain() || addr >= ISA_END_ADDRESS)) {
|
||||
other_addr = pfn_to_mfn(addr >> PAGE_SHIFT) << PAGE_SHIFT;
|
||||
WARN(addr != other_addr,
|
||||
"0x%lx is using VM_IO, but it is 0x%lx!\n",
|
||||
(unsigned long)addr, (unsigned long)other_addr);
|
||||
} else {
|
||||
pteval_t iomap_set = (_pte.pte & PTE_FLAGS_MASK) & _PAGE_IOMAP;
|
||||
other_addr = (_pte.pte & PTE_PFN_MASK);
|
||||
WARN((addr == other_addr) && (!io_page) && (!iomap_set),
|
||||
"0x%lx is missing VM_IO (and wasn't fixed)!\n",
|
||||
(unsigned long)addr);
|
||||
}
|
||||
|
||||
return _pte;
|
||||
}
|
||||
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte_debug);
|
||||
#endif
|
||||
|
||||
pgd_t xen_make_pgd(pgdval_t pgd)
|
||||
{
|
||||
pgd = pte_pfn_to_mfn(pgd);
|
||||
@@ -1940,6 +1990,9 @@ __init void xen_ident_map_ISA(void)
|
||||
|
||||
static __init void xen_post_allocator_init(void)
|
||||
{
|
||||
#ifdef CONFIG_XEN_DEBUG
|
||||
pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug);
|
||||
#endif
|
||||
pv_mmu_ops.set_pte = xen_set_pte;
|
||||
pv_mmu_ops.set_pmd = xen_set_pmd;
|
||||
pv_mmu_ops.set_pud = xen_set_pud;
|
||||
@@ -2072,7 +2125,7 @@ static void xen_zap_pfn_range(unsigned long vaddr, unsigned int order,
|
||||
in_frames[i] = virt_to_mfn(vaddr);
|
||||
|
||||
MULTI_update_va_mapping(mcs.mc, vaddr, VOID_PTE, 0);
|
||||
set_phys_to_machine(virt_to_pfn(vaddr), INVALID_P2M_ENTRY);
|
||||
__set_phys_to_machine(virt_to_pfn(vaddr), INVALID_P2M_ENTRY);
|
||||
|
||||
if (out_frames)
|
||||
out_frames[i] = virt_to_pfn(vaddr);
|
||||
@@ -2351,6 +2404,18 @@ EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
|
||||
|
||||
#ifdef CONFIG_XEN_DEBUG_FS
|
||||
|
||||
static int p2m_dump_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
return single_open(filp, p2m_dump_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations p2m_dump_fops = {
|
||||
.open = p2m_dump_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static struct dentry *d_mmu_debug;
|
||||
|
||||
static int __init xen_mmu_debugfs(void)
|
||||
@@ -2406,6 +2471,7 @@ static int __init xen_mmu_debugfs(void)
|
||||
debugfs_create_u32("prot_commit_batched", 0444, d_mmu_debug,
|
||||
&mmu_stats.prot_commit_batched);
|
||||
|
||||
debugfs_create_file("p2m", 0600, d_mmu_debug, NULL, &p2m_dump_fops);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(xen_mmu_debugfs);
|
||||
|
Reference in New Issue
Block a user