mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
bitkeeper revision 1.1159.17.18 (411b7a4clSlwGNpVa4jPTa9wgDjfmw)
Add compile-time option to use writable pagetables.
This commit is contained in:
1 parent
cc0ffed6b8
commit
b9d828099b
6 files changed
+36
-10
No files matched your search
@@ -36,6 +36,12 @@ config XEN_PHYSDEV_ACCESS
|
||||
help
|
||||
Device-driver domain (physical device access)
|
||||
|
||||
config XEN_WRITABLE_PAGETABLES
|
||||
bool "Use writable pagetables"
|
||||
default n
|
||||
help
|
||||
Use writable L1 pagetables
|
||||
|
||||
endmenu
|
||||
|
||||
# Xen's block device backend driver needs 2^12 pages
|
||||
|
||||
@@ -1104,7 +1104,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
HYPERVISOR_vm_assist(VMASST_CMD_enable,
|
||||
VMASST_TYPE_4gb_segments);
|
||||
#if 0
|
||||
#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
|
||||
HYPERVISOR_vm_assist(VMASST_CMD_enable,
|
||||
VMASST_TYPE_writeable_pagetables);
|
||||
#endif
|
||||
|
||||
@@ -95,7 +95,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
|
||||
static inline unsigned long pmd_val(pmd_t x)
|
||||
{
|
||||
unsigned long ret = x.pmd;
|
||||
if ( (ret & 1) ) ret = machine_to_phys(ret);
|
||||
if ( (ret) ) ret = machine_to_phys(ret);
|
||||
return ret;
|
||||
}
|
||||
#define pgd_val(x) ({ BUG(); (unsigned long)0; })
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <asm/fixmap.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/mm.h> /* for struct page */
|
||||
#include <asm/io.h> /* for phys_to_virt and page_to_pseudophys */
|
||||
|
||||
#define pmd_populate_kernel(mm, pmd, pte) \
|
||||
set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
|
||||
@@ -15,7 +16,8 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *p
|
||||
set_pmd(pmd, __pmd(_PAGE_TABLE +
|
||||
((unsigned long long)page_to_pfn(pte) <<
|
||||
(unsigned long long) PAGE_SHIFT)));
|
||||
flush_page_update_queue(); /* XXXcl flush */
|
||||
flush_page_update_queue();
|
||||
/* XXXcl queue */
|
||||
}
|
||||
/*
|
||||
* Allocate and free page tables.
|
||||
@@ -30,17 +32,25 @@ extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
|
||||
static inline void pte_free_kernel(pte_t *pte)
|
||||
{
|
||||
free_page((unsigned long)pte);
|
||||
__make_page_writeable(pte);
|
||||
}
|
||||
|
||||
static inline void pte_free(struct page *pte)
|
||||
{
|
||||
__free_page(pte);
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
if (pte < highmem_start_page)
|
||||
#endif
|
||||
{
|
||||
__make_page_writeable(phys_to_virt(page_to_pseudophys(pte)));
|
||||
__free_page(pte);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define __pte_free_tlb(tlb,pte) do { \
|
||||
tlb_remove_page((tlb),(pte)); \
|
||||
flush_page_update_queue(); /* XXXcl flush */ \
|
||||
flush_page_update_queue(); \
|
||||
/* XXXcl queue */ \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
|
||||
@@ -40,8 +40,13 @@ static inline int pgd_present(pgd_t pgd) { return 1; }
|
||||
* within a page table are directly modified. Thus, the following
|
||||
* hook is made available.
|
||||
*/
|
||||
#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
|
||||
#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
|
||||
#define set_pte_atomic(pteptr, pteval) (*(pteptr) = pteval)
|
||||
#else
|
||||
#define set_pte(pteptr, pteval) queue_l1_entry_update(pteptr, (pteval).pte_low)
|
||||
#define set_pte_atomic(pteptr, pteval) queue_l1_entry_update(pteptr, (pteval).pte_low)
|
||||
#endif
|
||||
/*
|
||||
* (pmds are folded into pgds so this doesn't get actually called,
|
||||
* but the define is needed for a generic inline function.)
|
||||
@@ -70,7 +75,7 @@ static inline pte_t ptep_get_and_clear(pte_t *xp)
|
||||
{
|
||||
pte_t pte = *xp;
|
||||
if (pte.pte_low)
|
||||
queue_l1_entry_update(xp, 0);
|
||||
set_pte(xp, __pte_ma(0));
|
||||
return pte;
|
||||
}
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ extern unsigned long pg0[];
|
||||
#define pmd_none(x) (!pmd_val(x))
|
||||
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
|
||||
/* pmd_clear below */
|
||||
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
|
||||
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
|
||||
|
||||
|
||||
#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
|
||||
@@ -241,9 +241,9 @@ static inline int ptep_test_and_clear_young(pte_t *ptep)
|
||||
}
|
||||
static inline void ptep_set_wrprotect(pte_t *ptep)
|
||||
{
|
||||
unsigned long pteval = *(unsigned long *)ptep;
|
||||
if ((pteval & _PAGE_RW))
|
||||
queue_l1_entry_update(ptep, pteval & ~_PAGE_RW);
|
||||
pte_t pte = *ptep;
|
||||
if (pte_write(pte))
|
||||
set_pte(ptep, pte_wrprotect(pte));
|
||||
}
|
||||
static inline void ptep_mkdirty(pte_t *ptep)
|
||||
{
|
||||
@@ -283,6 +283,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
pmd_t p = *(xp); \
|
||||
set_pmd(xp, __pmd(0)); \
|
||||
__make_page_writeable((void *)pmd_page_kernel(p)); \
|
||||
/* XXXcl queue */ \
|
||||
} while (0)
|
||||
|
||||
#ifndef CONFIG_DISCONTIGMEM
|
||||
@@ -401,6 +402,7 @@ static inline void make_page_readonly(void *va)
|
||||
if ( (unsigned long)va >= VMALLOC_START )
|
||||
__make_page_readonly(machine_to_virt(
|
||||
*(unsigned long *)pte&PAGE_MASK));
|
||||
/* XXXcl queue */
|
||||
}
|
||||
|
||||
static inline void make_page_writeable(void *va)
|
||||
@@ -412,6 +414,7 @@ static inline void make_page_writeable(void *va)
|
||||
if ( (unsigned long)va >= VMALLOC_START )
|
||||
__make_page_writeable(machine_to_virt(
|
||||
*(unsigned long *)pte&PAGE_MASK));
|
||||
/* XXXcl queue */
|
||||
}
|
||||
|
||||
static inline void make_pages_readonly(void *va, unsigned int nr)
|
||||
@@ -421,6 +424,7 @@ static inline void make_pages_readonly(void *va, unsigned int nr)
|
||||
make_page_readonly(va);
|
||||
va = (void *)((unsigned long)va + PAGE_SIZE);
|
||||
}
|
||||
/* XXXcl queue */
|
||||
}
|
||||
|
||||
static inline void make_pages_writeable(void *va, unsigned int nr)
|
||||
@@ -430,6 +434,7 @@ static inline void make_pages_writeable(void *va, unsigned int nr)
|
||||
make_page_writeable(va);
|
||||
va = (void *)((unsigned long)va + PAGE_SIZE);
|
||||
}
|
||||
/* XXXcl queue */
|
||||
}
|
||||
|
||||
static inline unsigned long arbitrary_virt_to_phys(void *va)
|
||||
|
||||