This patch adds support to Linux for hugepages as a Xen guest. It is
against the linux-2.6.18-xen on xenbits.xensource.com.
It currently assumes that the guest memory is physically aligned and
contiguous. Detection and avoidance of non-aligned memory will be
available in a future patch.
Signed-off-by: Dave McCracken <dave.mccracken@xxxxxxxxxx>
----
--- linux-2.6.18-xen//./fs/Kconfig 2008-07-17 09:54:14.000000000 -0500
+++ linux-hpage/./fs/Kconfig 2008-10-02 15:07:54.000000000 -0500
@@ -870,7 +870,7 @@ config TMPFS
config HUGETLBFS
bool "HugeTLB file system support"
depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
- depends on !XEN
+# depends on !XEN
help
hugetlbfs is a filesystem backing for HugeTLB pages, based on
ramfs. For architectures that support it, say Y here and read
--- linux-2.6.18-xen//./include/asm-x86_64/mach-xen/asm/page.h 2008-07-17
09:54:18.000000000 -0500
+++ linux-hpage/./include/asm-x86_64/mach-xen/asm/page.h 2008-10-02
15:07:54.000000000 -0500
@@ -62,6 +62,8 @@
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+#define ARCH_HAS_SETCLEAR_HUGE_PTE
+
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
--- linux-2.6.18-xen//./include/asm-x86_64/mach-xen/asm/pgtable.h
2008-08-14 10:06:46.000000000 -0500
+++ linux-hpage/./include/asm-x86_64/mach-xen/asm/pgtable.h 2008-10-02
15:07:54.000000000 -0500
@@ -261,6 +261,12 @@ static inline unsigned long pud_bad(pud_
set_pte((ptep), (pteval)); \
} while (0)
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval) {
+ if ((mm != current->mm && mm != &init_mm) ||
+ HYPERVISOR_update_va_mapping(addr, pteval, 0))
+ set_pmd((pmd_t *)ptep, (pmd_t){__pte_val(pteval)});
+}
+
#define pte_none(x) (!(x).pte)
#define pte_present(x) ((x).pte & (_PAGE_PRESENT | _PAGE_PROTNONE))
#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); }
while (0)
@@ -296,6 +302,19 @@ static inline pte_t ptep_get_and_clear(s
return pte;
}
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned
long addr, pte_t *ptep)
+{
+ pte_t pte = *ptep;
+ if (!pte_none(pte)) {
+ if ((mm != &init_mm) ||
+ HYPERVISOR_update_va_mapping(addr, __pte(0), 0)) {
+ pte = *ptep;
+ set_pmd((pmd_t *)ptep, __pmd(0));
+ }
+ }
+ return pte;
+}
+
static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned
long addr, pte_t *ptep, int full)
{
if (full) {
--- linux-2.6.18-xen//./arch/x86_64/mm/pageattr-xen.c 2008-07-17
09:54:10.000000000 -0500
+++ linux-hpage/./arch/x86_64/mm/pageattr-xen.c 2008-10-02 15:07:54.000000000
-0500
@@ -62,6 +62,8 @@ static void _pin_lock(struct mm_struct *
if (pmd_none(*pmd))
continue;
+ if (pte_huge(*(pte_t *)pmd))
+ continue;
ptl = pte_lockptr(0, pmd);
if (lock)
spin_lock(ptl);
--- linux-2.6.18-xen//./mm/hugetlb.c 2008-07-17 09:54:19.000000000 -0500
+++ linux-hpage/./mm/hugetlb.c 2008-10-02 15:07:54.000000000 -0500
@@ -294,12 +294,14 @@ static pte_t make_huge_pte(struct vm_are
int writable)
{
pte_t entry;
+ pgprot_t pgprot;
+ pgprot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_PRESENT);
if (writable) {
entry =
- pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
+ pte_mkwrite(pte_mkdirty(mk_pte(page, pgprot)));
} else {
- entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
+ entry = pte_wrprotect(mk_pte(page, pgprot));
}
entry = pte_mkyoung(entry);
entry = pte_mkhuge(entry);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|