# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 0bb486157ff5886c1593146169a17e91280f53e9
# Parent 7cfc7cb7cea7024352cc4ff9f185788e9f09920d
[IA64] expose p2m table. xen side part.
This patch introduces xen compile time option, xen_ia64_expose_p2m=y.
default is enabled.
Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
xen/arch/ia64/Rules.mk | 4 +
xen/arch/ia64/vmx/vmx_init.c | 3
xen/arch/ia64/xen/dom0_ops.c | 3
xen/arch/ia64/xen/mm.c | 135 +++++++++++++++++++++++++++++++++++++++--
xen/arch/ia64/xen/xensetup.c | 2
xen/include/asm-ia64/mm.h | 9 ++
xen/include/public/arch-ia64.h | 3
7 files changed, 151 insertions(+), 8 deletions(-)
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/Rules.mk
--- a/xen/arch/ia64/Rules.mk Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/Rules.mk Wed Oct 04 22:12:25 2006 -0600
@@ -5,6 +5,7 @@ HAS_VGA := y
HAS_VGA := y
VALIDATE_VT ?= n
no_warns ?= n
+xen_ia64_expose_p2m ?= y
ifneq ($(COMPILE_ARCH),$(TARGET_ARCH))
CROSS_COMPILE ?= /usr/local/sp_env/v2.2.5/i686/bin/ia64-unknown-linux-
@@ -36,6 +37,9 @@ ifeq ($(VALIDATE_VT),y)
ifeq ($(VALIDATE_VT),y)
CFLAGS += -DVALIDATE_VT
endif
+ifeq ($(xen_ia64_expose_p2m),y)
+CFLAGS += -DCONFIG_XEN_IA64_EXPOSE_P2M
+endif
ifeq ($(no_warns),y)
CFLAGS += -Wa,--fatal-warnings -Werror -Wno-uninitialized
endif
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_init.c Wed Oct 04 22:12:25 2006 -0600
@@ -378,7 +378,8 @@ static void vmx_build_physmap_table(stru
for (j = io_ranges[i].start;
j < io_ranges[i].start + io_ranges[i].size;
j += PAGE_SIZE)
- __assign_domain_page(d, j, io_ranges[i].type, ASSIGN_writable);
+ (void)__assign_domain_page(d, j, io_ranges[i].type,
+ ASSIGN_writable);
}
/* Map normal memory below 3G */
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c Wed Oct 04 22:12:25 2006 -0600
@@ -273,6 +273,9 @@ do_dom0vp_op(unsigned long cmd,
ret = dom0vp_add_physmap(d, arg0, arg1, (unsigned int)arg2,
(domid_t)arg3);
break;
+ case IA64_DOM0VP_expose_p2m:
+ ret = dom0vp_expose_p2m(d, arg0, arg1, arg2, arg3);
+ break;
default:
ret = -1;
printf("unknown dom0_vp_op 0x%lx\n", cmd);
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/xen/mm.c Wed Oct 04 22:12:25 2006 -0600
@@ -806,7 +806,7 @@ flags_to_prot (unsigned long flags)
// flags: currently only ASSIGN_readonly, ASSIGN_nocache
// This is called by assign_domain_mmio_page().
// So accessing to pte is racy.
-void
+int
__assign_domain_page(struct domain *d,
unsigned long mpaddr, unsigned long physaddr,
unsigned long flags)
@@ -822,8 +822,11 @@ __assign_domain_page(struct domain *d,
old_pte = __pte(0);
new_pte = pfn_pte(physaddr >> PAGE_SHIFT, __pgprot(prot));
ret_pte = ptep_cmpxchg_rel(&d->arch.mm, mpaddr, pte, old_pte, new_pte);
- if (pte_val(ret_pte) == pte_val(old_pte))
+ if (pte_val(ret_pte) == pte_val(old_pte)) {
smp_mb();
+ return 0;
+ }
+ return -EAGAIN;
}
/* get_page() and map a physical address to the specified metaphysical addr */
@@ -840,7 +843,7 @@ assign_domain_page(struct domain *d,
set_gpfn_from_mfn(physaddr >> PAGE_SHIFT, mpaddr >> PAGE_SHIFT);
// because __assign_domain_page() uses set_pte_rel() which has
// release semantics, smp_mb() isn't needed.
- __assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable);
+ (void)__assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable);
}
int
@@ -863,8 +866,8 @@ ioports_permit_access(struct domain *d,
lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp));
for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE)
- __assign_domain_page(d, IO_PORTS_PADDR + off,
- __pa(ia64_iobase) + off, ASSIGN_nocache);
+ (void)__assign_domain_page(d, IO_PORTS_PADDR + off,
+ __pa(ia64_iobase) + off, ASSIGN_nocache);
return 0;
}
@@ -933,7 +936,7 @@ assign_domain_same_page(struct domain *d
//XXX optimization
unsigned long end = PAGE_ALIGN(mpaddr + size);
for (mpaddr &= PAGE_MASK; mpaddr < end; mpaddr += PAGE_SIZE) {
- __assign_domain_page(d, mpaddr, mpaddr, flags);
+ (void)__assign_domain_page(d, mpaddr, mpaddr, flags);
}
}
@@ -1255,6 +1258,126 @@ out1:
put_domain(rd);
return error;
}
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
+static struct page_info* p2m_pte_zero_page = NULL;
+
+void
+expose_p2m_init(void)
+{
+ pte_t* pte;
+
+ pte = pte_alloc_one_kernel(NULL, 0);
+ BUG_ON(pte == NULL);
+ smp_mb();// make contents of the page visible.
+ p2m_pte_zero_page = virt_to_page(pte);
+}
+
+static int
+expose_p2m_page(struct domain* d, unsigned long mpaddr, struct page_info* page)
+{
+ // we can't get_page(page) here.
+ // pte page is allocated form xen heap.(see pte_alloc_one_kernel().)
+ // so that the page has NULL page owner and it's reference count
+ // is useless.
+ // see also relinquish_pte()'s page_get_owner() == NULL check.
+ BUG_ON(page_get_owner(page) != NULL);
+
+ return __assign_domain_page(d, mpaddr, page_to_maddr(page),
+ ASSIGN_readonly);
+}
+
+// It is possible to optimize loop, But this isn't performance critical.
+unsigned long
+dom0vp_expose_p2m(struct domain* d,
+ unsigned long conv_start_gpfn,
+ unsigned long assign_start_gpfn,
+ unsigned long expose_size, unsigned long granule_pfn)
+{
+ unsigned long expose_num_pfn = expose_size >> PAGE_SHIFT;
+ unsigned long i;
+ volatile pte_t* conv_pte;
+ volatile pte_t* assign_pte;
+
+ if ((expose_size % PAGE_SIZE) != 0 ||
+ (granule_pfn % PTRS_PER_PTE) != 0 ||
+ (expose_num_pfn % PTRS_PER_PTE) != 0 ||
+ (conv_start_gpfn % granule_pfn) != 0 ||
+ (assign_start_gpfn % granule_pfn) != 0 ||
+ (expose_num_pfn % granule_pfn) != 0) {
+ DPRINTK("%s conv_start_gpfn 0x%016lx assign_start_gpfn 0x%016lx "
+ "expose_size 0x%016lx granulte_pfn 0x%016lx\n", __func__,
+ conv_start_gpfn, assign_start_gpfn, expose_size, granule_pfn);
+ return -EINVAL;
+ }
+
+ if (granule_pfn != PTRS_PER_PTE) {
+ DPRINTK("%s granule_pfn 0x%016lx PTRS_PER_PTE 0x%016lx\n",
+ __func__, granule_pfn, PTRS_PER_PTE);
+ return -ENOSYS;
+ }
+
+ // allocate pgd, pmd.
+ i = conv_start_gpfn;
+ while (i < expose_num_pfn) {
+ conv_pte = lookup_noalloc_domain_pte(d, (conv_start_gpfn + i) <<
+ PAGE_SHIFT);
+ if (conv_pte == NULL) {
+ i++;
+ continue;
+ }
+
+ assign_pte = lookup_alloc_domain_pte(d, (assign_start_gpfn <<
+ PAGE_SHIFT) + i * sizeof(pte_t));
+ if (assign_pte == NULL) {
+ DPRINTK("%s failed to allocate pte page\n", __func__);
+ return -ENOMEM;
+ }
+
+ // skip to next pte page
+ i += PTRS_PER_PTE;
+ i &= ~(PTRS_PER_PTE - 1);
+ }
+
+ // expose pte page
+ i = 0;
+ while (i < expose_num_pfn) {
+ conv_pte = lookup_noalloc_domain_pte(d, (conv_start_gpfn + i) <<
+ PAGE_SHIFT);
+ if (conv_pte == NULL) {
+ i++;
+ continue;
+ }
+
+ if (expose_p2m_page(d, (assign_start_gpfn << PAGE_SHIFT) +
+ i * sizeof(pte_t), virt_to_page(conv_pte)) < 0) {
+ DPRINTK("%s failed to assign page\n", __func__);
+ return -EAGAIN;
+ }
+
+ // skip to next pte page
+ i += PTRS_PER_PTE;
+ i &= ~(PTRS_PER_PTE - 1);
+ }
+
+ // expose p2m_pte_zero_page
+ for (i = 0; i < expose_num_pfn / PTRS_PER_PTE + 1; i++) {
+ assign_pte = lookup_noalloc_domain_pte(d, (assign_start_gpfn + i) <<
+ PAGE_SHIFT);
+ BUG_ON(assign_pte == NULL);
+ if (pte_present(*assign_pte)) {
+ continue;
+ }
+ if (expose_p2m_page(d, (assign_start_gpfn + i) << PAGE_SHIFT,
+ p2m_pte_zero_page) < 0) {
+ DPRINTK("%s failed to assign zero-pte page\n", __func__);
+ return -EAGAIN;
+ }
+ }
+
+ return 0;
+}
+#endif
// grant table host mapping
// mpaddr: host_addr: pseudo physical address
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/xen/xensetup.c Wed Oct 04 22:12:25 2006 -0600
@@ -499,6 +499,8 @@ printk("num_online_cpus=%d, max_cpus=%d\
efi.hcdp = NULL;
}
+ expose_p2m_init();
+
/* Create initial domain 0. */
dom0 = domain_create(0);
if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/include/asm-ia64/mm.h Wed Oct 04 22:12:25 2006 -0600
@@ -424,7 +424,7 @@ extern void relinquish_mm(struct domain*
extern void relinquish_mm(struct domain* d);
extern struct page_info * assign_new_domain_page(struct domain *d, unsigned
long mpaddr);
extern void assign_new_domain0_page(struct domain *d, unsigned long mpaddr);
-extern void __assign_domain_page(struct domain *d, unsigned long mpaddr,
unsigned long physaddr, unsigned long flags);
+extern int __assign_domain_page(struct domain *d, unsigned long mpaddr,
unsigned long physaddr, unsigned long flags);
extern void assign_domain_page(struct domain *d, unsigned long mpaddr,
unsigned long physaddr);
extern void assign_domain_io_page(struct domain *d, unsigned long mpaddr,
unsigned long flags);
struct p2m_entry;
@@ -439,6 +439,13 @@ extern unsigned long do_dom0vp_op(unsign
extern unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0,
unsigned long arg1, unsigned long arg2, unsigned long arg3);
extern unsigned long dom0vp_zap_physmap(struct domain *d, unsigned long gpfn,
unsigned int extent_order);
extern unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn,
unsigned long mfn, unsigned long flags, domid_t domid);
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
+extern void expose_p2m_init(void);
+extern unsigned long dom0vp_expose_p2m(struct domain* d, unsigned long
conv_start_gpfn, unsigned long assign_start_gpfn, unsigned long expose_size,
unsigned long granule_pfn);
+#else
+#define expose_p2m_init() do { } while (0)
+#define dom0vp_expose_p2m(d, conv_start_gpfn, assign_start_gpfn, expose_size,
granule_pfn) (-ENOSYS)
+#endif
extern volatile unsigned long *mpt_table;
extern unsigned long gmfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/include/public/arch-ia64.h Wed Oct 04 22:12:25 2006 -0600
@@ -348,6 +348,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
/* Assign machine page frame to dom0's pseudo physical address space. */
#define IA64_DOM0VP_add_physmap 6
+/* expose the p2m table into domain */
+#define IA64_DOM0VP_expose_p2m 7
+
// flags for page assignement to pseudo physical address space
#define _ASSIGN_readonly 0
#define ASSIGN_readonly (1UL << _ASSIGN_readonly)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|