public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Ingo Molnar <mingo@elte.hu>
Cc: LKML <linux-kernel@vger.kernel.org>,
	x86@kernel.org, Stephen Tweedie <sct@redhat.com>,
	Eduardo Habkost <ehabkost@redhat.com>,
	Mark McLoughlin <markmc@redhat.com>,
	x86@kernel.org
Subject: [PATCH 51 of 55] xen64: allocate and manage user pagetables
Date: Tue, 08 Jul 2008 15:07:13 -0700	[thread overview]
Message-ID: <280393bc32413b3f08d6.1215554833@localhost> (raw)
In-Reply-To: <patchbomb.1215554782@localhost>

Because the x86_64 architecture does not enforce segment limits, Xen
cannot protect itself with them as it does in 32-bit mode.  Therefore,
to protect itself, it runs the guest kernel in ring 3.  Since it also
runs the guest userspace in ring3, the guest kernel must maintain a
second pagetable for its userspace, which does not map kernel space.
Naturally, the guest kernel pagetables map both kernel and userspace.

The userspace pagetable is attached to the corresponding kernel
pagetable via the pgd's page->private field.  It is allocated and
freed at the same time as the kernel pgd via the
paravirt_pgd_alloc/free hooks.

Fortunately, the user pagetable is almost entirely shared with the
kernel pagetable; the only difference is the pgd page itself.  set_pgd
will populate all entries in the kernel pagetable, and also set the
corresponding user pgd entry if the address is less than
STACK_TOP_MAX.

The user pagetable must be pinned and unpinned with the kernel one,
but because the pagetables are aliased, pgd_walk() only needs to be
called on the kernel pagetable.  The user pgd page is then
pinned/unpinned along with the kernel pgd page.

xen_write_cr3 must write both the kernel and user cr3s.

The init_mm.pgd pagetable never has a user pagetable allocated for it,
because it can never be used while running usermode.

One awkward area is that early in boot the page structures are not
available.  No user pagetable can exist at that point, but it
complicates the logic to avoid looking at the page structure.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
---
 arch/x86/xen/enlighten.c |   99 +++++++++++++++++++++++++++++++++++++++-------
 arch/x86/xen/mmu.c       |   91 ++++++++++++++++++++++++++++++++++++++----
 arch/x86/xen/mmu.h       |    2
 3 files changed, 168 insertions(+), 24 deletions(-)

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -46,7 +46,6 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/reboot.h>
-#include <asm/pgalloc.h>
 
 #include "xen-ops.h"
 #include "mmu.h"
@@ -711,29 +710,57 @@
 	x86_write_percpu(xen_current_cr3, (unsigned long)v);
 }
 
-static void xen_write_cr3(unsigned long cr3)
+static void __xen_write_cr3(bool kernel, unsigned long cr3)
 {
 	struct mmuext_op *op;
 	struct multicall_space mcs;
-	unsigned long mfn = pfn_to_mfn(PFN_DOWN(cr3));
+	unsigned long mfn;
 
+	if (cr3)
+		mfn = pfn_to_mfn(PFN_DOWN(cr3));
+	else
+		mfn = 0;
+
+	WARN_ON(mfn == 0 && kernel);
+
+	mcs = __xen_mc_entry(sizeof(*op));
+
+	op = mcs.args;
+	op->cmd = kernel ? MMUEXT_NEW_BASEPTR : MMUEXT_NEW_USER_BASEPTR;
+	op->arg1.mfn = mfn;
+
+	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+
+	if (kernel) {
+		x86_write_percpu(xen_cr3, cr3);
+
+		/* Update xen_current_cr3 once the batch has actually
+		   been submitted. */
+		xen_mc_callback(set_current_cr3, (void *)cr3);
+	}
+}
+
+static void xen_write_cr3(unsigned long cr3)
+{
 	BUG_ON(preemptible());
 
-	mcs = xen_mc_entry(sizeof(*op));  /* disables interrupts */
+	xen_mc_batch();  /* disables interrupts */
 
 	/* Update while interrupts are disabled, so its atomic with
 	   respect to ipis */
 	x86_write_percpu(xen_cr3, cr3);
 
-	op = mcs.args;
-	op->cmd = MMUEXT_NEW_BASEPTR;
-	op->arg1.mfn = mfn;
+	__xen_write_cr3(true, cr3);
 
-	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
-
-	/* Update xen_update_cr3 once the batch has actually
-	   been submitted. */
-	xen_mc_callback(set_current_cr3, (void *)cr3);
+#ifdef CONFIG_X86_64
+	{
+		pgd_t *user_pgd = xen_get_user_pgd(__va(cr3));
+		if (user_pgd)
+			__xen_write_cr3(false, __pa(user_pgd));
+		else
+			__xen_write_cr3(false, 0);
+	}
+#endif
 
 	xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */
 }
@@ -792,6 +819,40 @@
 static void xen_alloc_pmd(struct mm_struct *mm, u32 pfn)
 {
 	xen_alloc_ptpage(mm, pfn, PT_PMD);
+}
+
+static int xen_pgd_alloc(struct mm_struct *mm)
+{
+	pgd_t *pgd = mm->pgd;
+	int ret = 0;
+
+	BUG_ON(PagePinned(virt_to_page(pgd)));
+
+#ifdef CONFIG_X86_64
+	{
+		struct page *page = virt_to_page(pgd);
+
+		BUG_ON(page->private != 0);
+
+		page->private = __get_free_page(GFP_KERNEL | __GFP_ZERO);
+		if (page->private == 0)
+			ret = -ENOMEM;
+
+		BUG_ON(PagePinned(virt_to_page(xen_get_user_pgd(pgd))));
+	}
+#endif
+
+	return ret;
+}
+
+static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+#ifdef CONFIG_X86_64
+	pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
+	if (user_pgd)
+		free_page((unsigned long)user_pgd);
+#endif
 }
 
 /* This should never happen until we're OK to use struct page */
@@ -1168,8 +1229,8 @@
 	.pte_update = paravirt_nop,
 	.pte_update_defer = paravirt_nop,
 
-	.pgd_alloc = __paravirt_pgd_alloc,
-	.pgd_free = paravirt_nop,
+	.pgd_alloc = xen_pgd_alloc,
+	.pgd_free = xen_pgd_free,
 
 	.alloc_pte = xen_alloc_pte_init,
 	.release_pte = xen_release_pte_init,
@@ -1480,7 +1541,15 @@
 
 	/* Switch over */
 	pgd = init_level4_pgt;
-	xen_write_cr3(__pa(pgd));
+
+	/*
+	 * At this stage there can be no user pgd, and no page
+	 * structure to attach it to, so make sure we just set kernel
+	 * pgd.
+	 */
+	xen_mc_batch();
+	__xen_write_cr3(true, __pa(pgd));
+	xen_mc_issue(PARAVIRT_LAZY_CPU);
 
 	reserve_early(__pa(xen_start_info->pt_base),
 		      __pa(xen_start_info->pt_base +
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -57,6 +57,13 @@
 
 #include "multicalls.h"
 #include "mmu.h"
+
+/*
+ * Just beyond the highest usermode address.  STACK_TOP_MAX has a
+ * redzone above it, so round it up to a PGD boundary.
+ */
+#define USER_LIMIT	((STACK_TOP_MAX + PGDIR_SIZE - 1) & PGDIR_MASK)
+
 
 #define P2M_ENTRIES_PER_PAGE	(PAGE_SIZE / sizeof(unsigned long))
 #define TOP_ENTRIES		(MAX_DOMAIN_PAGES / P2M_ENTRIES_PER_PAGE)
@@ -461,17 +468,45 @@
 	return native_make_pud(pud);
 }
 
-void xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
+pgd_t *xen_get_user_pgd(pgd_t *pgd)
+{
+	pgd_t *pgd_page = (pgd_t *)(((unsigned long)pgd) & PAGE_MASK);
+	unsigned offset = pgd - pgd_page;
+	pgd_t *user_ptr = NULL;
+
+	if (offset < pgd_index(USER_LIMIT)) {
+		struct page *page = virt_to_page(pgd_page);
+		user_ptr = (pgd_t *)page->private;
+		if (user_ptr)
+			user_ptr += offset;
+	}
+
+	return user_ptr;
+}
+
+static void __xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
 {
 	struct mmu_update u;
 
+	u.ptr = virt_to_machine(ptr).maddr;
+	u.val = pgd_val_ma(val);
+	extend_mmu_update(&u);
+}
+
+/*
+ * Raw hypercall-based set_pgd, intended for in early boot before
+ * there's a page structure.  This implies:
+ *  1. The only existing pagetable is the kernel's
+ *  2. It is always pinned
+ *  3. It has no user pagetable attached to it
+ */
+void __init xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
+{
 	preempt_disable();
 
 	xen_mc_batch();
 
-	u.ptr = virt_to_machine(ptr).maddr;
-	u.val = pgd_val_ma(val);
-	extend_mmu_update(&u);
+	__xen_set_pgd_hyper(ptr, val);
 
 	xen_mc_issue(PARAVIRT_LAZY_MMU);
 
@@ -480,14 +515,28 @@
 
 void xen_set_pgd(pgd_t *ptr, pgd_t val)
 {
+	pgd_t *user_ptr = xen_get_user_pgd(ptr);
+
 	/* If page is not pinned, we can just update the entry
 	   directly */
 	if (!page_pinned(ptr)) {
 		*ptr = val;
+		if (user_ptr) {
+			WARN_ON(page_pinned(user_ptr));
+			*user_ptr = val;
+		}
 		return;
 	}
 
-	xen_set_pgd_hyper(ptr, val);
+	/* If it's pinned, then we can at least batch the kernel and
+	   user updates together. */
+	xen_mc_batch();
+
+	__xen_set_pgd_hyper(ptr, val);
+	if (user_ptr)
+		__xen_set_pgd_hyper(user_ptr, val);
+
+	xen_mc_issue(PARAVIRT_LAZY_MMU);
 }
 #endif	/* PAGETABLE_LEVELS == 4 */
 
@@ -526,7 +575,7 @@
 	 * space, which contains the Xen mappings.  On 32-bit these
 	 * will end up making a zero-sized hole and so is a no-op.
 	 */
-	hole_low = pgd_index(STACK_TOP_MAX + PGDIR_SIZE - 1);
+	hole_low = pgd_index(USER_LIMIT);
 	hole_high = pgd_index(PAGE_OFFSET);
 
 	pgdidx_limit = pgd_index(limit);
@@ -670,19 +719,31 @@
 {
 	xen_mc_batch();
 
-	if (pgd_walk(pgd, pin_page, TASK_SIZE)) {
+	if (pgd_walk(pgd, pin_page, USER_LIMIT)) {
 		/* re-enable interrupts for kmap_flush_unused */
 		xen_mc_issue(0);
 		kmap_flush_unused();
 		xen_mc_batch();
 	}
 
+#ifdef CONFIG_X86_64
+	{
+		pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
+		xen_do_pin(MMUEXT_PIN_L4_TABLE, PFN_DOWN(__pa(pgd)));
+
+		if (user_pgd) {
+			pin_page(virt_to_page(user_pgd), PT_PGD);
+			xen_do_pin(MMUEXT_PIN_L4_TABLE, PFN_DOWN(__pa(user_pgd)));
+		}
+	}
+#else /* CONFIG_X86_32 */
 #ifdef CONFIG_X86_PAE
 	/* Need to make sure unshared kernel PMD is pinnable */
 	pin_page(virt_to_page(pgd_page(pgd[pgd_index(TASK_SIZE)])), PT_PMD);
 #endif
-
 	xen_do_pin(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(pgd)));
+#endif /* CONFIG_X86_64 */
 	xen_mc_issue(0);
 }
 
@@ -763,11 +824,23 @@
 
 	xen_do_pin(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
 
+#ifdef CONFIG_X86_64
+	{
+		pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
+		if (user_pgd) {
+			xen_do_pin(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(user_pgd)));
+			unpin_page(virt_to_page(user_pgd), PT_PGD);
+		}
+	}
+#endif
+
 #ifdef CONFIG_X86_PAE
 	/* Need to make sure unshared kernel PMD is unpinned */
 	pin_page(virt_to_page(pgd_page(pgd[pgd_index(TASK_SIZE)])), PT_PMD);
 #endif
-	pgd_walk(pgd, unpin_page, TASK_SIZE);
+
+	pgd_walk(pgd, unpin_page, USER_LIMIT);
 
 	xen_mc_issue(0);
 }
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
--- a/arch/x86/xen/mmu.h
+++ b/arch/x86/xen/mmu.h
@@ -51,6 +51,8 @@
 void xen_set_pgd_hyper(pgd_t *pgdp, pgd_t pgd);
 #endif
 
+pgd_t *xen_get_user_pgd(pgd_t *pgd);
+
 pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
 void  xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
 				  pte_t *ptep, pte_t pte);



  parent reply	other threads:[~2008-07-08 23:29 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-08 22:06 [PATCH 00 of 55] xen64: implement 64-bit Xen support Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 01 of 55] x86/paravirt: Call paravirt_pagetable_setup_{start, done} Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 02 of 55] pvops-64: call paravirt_post_allocator_init() on setup_arch() Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 03 of 55] x86_64: there's no need to preallocate level1_fixmap_pgt Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 04 of 55] x86: clean up formatting of __switch_to Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 05 of 55] x86: use __page_aligned_data/bss Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 06 of 55] x86_64: adjust exception frame in ia32entry Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 07 of 55] x86_64: unstatic get_local_pda Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 08 of 55] xen: print backtrace on multicall failure Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 09 of 55] xen-netfront: fix xennet_release_tx_bufs() Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 10 of 55] xen: add xen_arch_resume()/xen_timer_resume hook for ia64 support Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 11 of 55] xen: define set_pte from the outset Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 12 of 55] xen64: define asm/xen/interface for 64-bit Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 13 of 55] xen: make ELF notes work for 32 and 64 bit Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 14 of 55] xen: fix 64-bit hypercall variants Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 15 of 55] xen64: fix calls into hypercall page Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 16 of 55] xen64: add extra pv_mmu_ops Jeremy Fitzhardinge
2008-07-09  7:55   ` Mark McLoughlin
2008-07-09  8:02     ` Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 17 of 55] xen64: random ifdefs to mask out 32-bit only code Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 18 of 55] xen64: get active_mm from the pda Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 19 of 55] xen: move smp setup into smp.c Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 20 of 55] x86_64: add workaround for no %gs-based percpu Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 21 of 55] xen64: smp.c compile hacking Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 22 of 55] xen64: add xen-head code to head_64.S Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 23 of 55] xen64: add asm-offsets Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 24 of 55] xen64: add 64-bit assembler Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 25 of 55] xen64: use set_fixmap for shared_info structure Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 26 of 55] xen: cpu_detect is 32-bit only Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 27 of 55] xen64: add hypervisor callbacks for events, etc Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 28 of 55] xen64: early mapping setup Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 29 of 55] xen64: 64-bit starts using set_pte from very early Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 30 of 55] xen64: map an initial chunk of physical memory Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 31 of 55] xen32: create initial mappings like 64-bit Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 32 of 55] xen: fix truncation of machine address Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 33 of 55] xen64: use arbitrary_virt_to_machine for xen_set_pmd Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 34 of 55] xen: set num_processors Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 35 of 55] xen64: defer setting pagetable alloc/release ops Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 36 of 55] xen: use set_pte_vaddr Jeremy Fitzhardinge
2008-07-08 22:06 ` [PATCH 37 of 55] xen64: xen_write_idt_entry() and cvt_gate_to_trap() Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 38 of 55] xen64: deal with extra words Xen pushes onto exception frames Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 39 of 55] xen64: add pvop for swapgs Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 40 of 55] xen64: register callbacks in arch-independent way Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 41 of 55] xen64: add identity irq->vector map Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 42 of 55] Xen64: HYPERVISOR_set_segment_base() implementation Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 43 of 55] xen64: implement xen_load_gs_index() Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 44 of 55] xen: rework pgd_walk to deal with 32/64 bit Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 45 of 55] xen: make sure the kernel command line is right Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 46 of 55] xen: enable PM_SLEEP for CONFIG_XEN Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 47 of 55] xen64: implement failsafe callback Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 48 of 55] xen64: Clear %fs on xen_load_tls() Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 49 of 55] xen64: implement 64-bit update_descriptor Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 50 of 55] xen64: save lots of registers Jeremy Fitzhardinge
2008-07-08 22:07 ` Jeremy Fitzhardinge [this message]
2008-07-08 22:07 ` [PATCH 52 of 55] xen64: set up syscall and sysenter entrypoints for 64-bit Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 53 of 55] xen64: set up userspace syscall patch Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 54 of 55] xen: implement Xen write_msr operation Jeremy Fitzhardinge
2008-07-08 22:07 ` [PATCH 55 of 55] xen: update Kconfig to allow 64-bit Xen Jeremy Fitzhardinge
2008-07-09 11:12 ` [PATCH 00 of 55] xen64: implement 64-bit Xen support Ingo Molnar
2008-07-09 11:16   ` [patch] power, xen64: fix PM_SLEEP build dependencies (was: Re: [PATCH 00 of 55] xen64: implement 64-bit Xen support) Ingo Molnar
2008-07-09 19:47     ` Ingo Molnar
2008-07-09 19:52       ` Ingo Molnar
2008-07-09 19:59         ` Rafael J. Wysocki
2008-07-09 20:02           ` Rafael J. Wysocki
2008-07-09 20:04             ` Ingo Molnar
2008-07-09 20:17               ` [patch] power, xen64: fix PM_SLEEP build dependencies Jeremy Fitzhardinge
2008-07-09 20:17               ` [patch] power, xen64: fix PM_SLEEP build dependencies (was: Re: [PATCH 00 of 55] xen64: implement 64-bit Xen support) Rafael J. Wysocki
2008-07-09 20:23                 ` [patch] power, xen64: fix PM_SLEEP build dependencies Jeremy Fitzhardinge
2008-07-09 20:26                   ` Ingo Molnar
2008-07-09 20:33                   ` Rafael J. Wysocki
2008-07-09 20:39                     ` Jeremy Fitzhardinge
2008-07-09 20:42                       ` Ingo Molnar
2008-07-09 20:53                       ` Rafael J. Wysocki
2008-07-09 20:23                 ` [patch] power, xen64: fix PM_SLEEP build dependencies (was: Re: [PATCH 00 of 55] xen64: implement 64-bit Xen support) Ingo Molnar
2008-07-09 20:40                   ` [patch] power, xen64: fix PM_SLEEP build dependencies Jeremy Fitzhardinge
2008-07-09 11:21   ` [patch] xen64: fix !HVC_XEN build dependency (was: Re: [PATCH 00 of 55] xen64: implement 64-bit Xen support) Ingo Molnar
2008-07-09 16:07     ` [patch] xen64: fix !HVC_XEN build dependency Jeremy Fitzhardinge
2008-07-09 11:47   ` [patch] xen64: fix build error on 32-bit + !HIGHMEM (was: Re: [PATCH 00 of 55] xen64: implement 64-bit Xen support) Ingo Molnar
2008-07-09 16:07     ` [patch] xen64: fix build error on 32-bit + !HIGHMEM Jeremy Fitzhardinge
2008-07-09 16:12   ` [PATCH 00 of 55] xen64: implement 64-bit Xen support Jeremy Fitzhardinge

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=280393bc32413b3f08d6.1215554833@localhost \
    --to=jeremy@goop.org \
    --cc=ehabkost@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=markmc@redhat.com \
    --cc=mingo@elte.hu \
    --cc=sct@redhat.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox