[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] expose p2m table. xen side part.
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |