From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Byrne Subject: Re: [RFC][PATCH]Large Page Support for HAP Date: Thu, 06 Dec 2007 17:43:12 -0800 Message-ID: <4758A530.2040103@hp.com> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------070407090709020908030708" Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Keir Fraser Cc: Tim Deegan , "Huang2, Wei" , "xen-devel@lists.xensource.com" List-Id: xen-devel@lists.xenproject.org This is a multi-part message in MIME format. --------------070407090709020908030708 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Keir, I'm very late replying to this. I wanted to make sure I something that worked first before continuing the discussion and things took longer than I'd hoped. Wei has asked me to send along my patch (against 16256) for discussion. (Maybe just to make his look good.) Mine is less complete --- it doesn't handle page shattering when pages are removed --- but it works well enough to start Linux HAP guests with 1G super-pages, which was my primary interest. My original thought for modifying just populate_physmap() to opportunistically use super-pages was that my try_larger_extents() function in memory.c could be made mode-specific and that the hypervisor was the easiest place to have this kind of policy. (Will IOMMU DMA support for PV guests benefit from super-page allocations?) I did end up modifying xc_hvm_build, because I wanted to optimize the guest to use 1G pages by using as little memory under 1G as possible. So, the memsize_low variable I define is meant to become a parameter to allow the domain config to specify a low memory size (I'm using 32MB for now) and the rest of the memory allocated starting at the 1G boundary. Perhaps some general method of specifying the guest memory layout could be developed. For p2m, I assumed that gfn_to_mfn_current() was an infrequent operation under HAP and it was not worth doing any direct mapping of the L2/L3 page tables to support this. So gfn_to_mfn_current() in HAP mode just calls gfn_to_mfn_foreign() (modified to note PSE pages) and walks the HAP pagetable. Perhaps there is a useful idea in this that could be used with Wei's changes. John Byrne Keir Fraser wrote: > To my mind populate_physmap() should do what it is told w.r.t. extent sizes. I don't mind some modification of xc_hvm_build to support this feature. > > -- Keir > > On 16/11/07 17:53, "Huang2, Wei" wrote: > > John, > > If you have a better design, share with us and I will be happy to work with you. :-) I agree that xc_hvm_build.c does not have to be modified, if memory.c is smart enough to scan all page_array information. But one concern is that sometimes Xen tools really want to create mapping at 4KB boundary instead of using large page. That requires extra information passed from tools (e.g., xc_hvm_build.c) to memory.c > > -Wei > > ________________________________ > From: Byrne, John (HP Labs) [mailto:john.l.byrne@hp.com] > Sent: Friday, November 16, 2007 11:41 AM > To: Huang2, Wei; xen-devel@lists.xensource.com > Cc: Tim Deegan > Subject: RE: [Xen-devel] [RFC][PATCH]Large Page Support for HAP > > Wei, > > I have been hacking at this, too, since I am interested in trying 1GB pages to see what they can do. After I dug myself into a hole, I restarted from the beginning and am trying a different approach than modifying xc_hvm_build.c: modify populate_physmap() to opportunistically allocate large pages, if possible. I just thought I'd mention it. > > John Byrne > > > ________________________________ > From: xen-devel-bounces@lists.xensource.com [mailto:xen-devel-bounces@lists.xensource.com] On Behalf Of Huang2, Wei > Sent: Thursday, November 15, 2007 8:26 AM > To: xen-devel@lists.xensource.com > Cc: Tim Deegan > Subject: [Xen-devel] [RFC][PATCH]Large Page Support for HAP > > I implemented a preliminary version of HAP large page support. My testings showed that 32bit PAE and 64bit worked well. Also I saw decent performance improvement for certain benchmarks. > > So before I go too far, I send this patch to community for reviews/comments. This patch goes with xen-unstable changeset 16281. I will redo it after collecting all ideas. > > Thanks, > > -Wei > > ============ > DESIGN IDEAS: > 1. Large page requests > - xc_hvm_build.c requests large page (2MB for now) while starting guests > - memory.c handles large page requests. If it can not handle it, falls back to 4KB pages. > > 2. P2M table > - P2M table takes page size order as a parameter; It builds P2M table (setting PSE bit, etc.) according to page size. > - Other related functions (such as p2m_audit()) handles the table based on page size too. > - Page split/merge > ** Large page will be split into 4KB page in P2M table if needed. For instance, if set_p2m_entry() handles 4KB page but finds PSE/PRESENT bits are on, it will further split large page to 4KB pages. > ** There is NO merge from 4KB pages to large page. Since large page is only used at the very beginning, guest_physmap_add(), this is OK for now. > > 3. HAP > - To access the PSE bit, L2 pages of P2M table is installed in linear mapping on SH_LINEAR_PT_VIRT_START. We borrow this address space since it was not used. > > 4. gfn_to_mfn translation (P2M) > - gfn_to_mfn_foreign() traverses P2M table and handles address translation correctly based on PSE bit. > - gfn_to_mfn_current() accesses SH_LINEAR_PT_VIRT_START to check PSE bit. If is on, we handle translation using large page. Otherwise, it falls back to normal RO_MPT_VIRT_START address space to access P2M L1 pages. > > 5. M2P translation > - Same as before, M2P translation still happens on 4KB level. > > AREAS NEEDS COMMENTS: > 1. Large page for 32bit mode > - 32bit use 4MB for large page. This is very annoying for xc_hvm_build.c. I don't want to create another 4MB page_array for it. > - Because of this, this area has not been tested very well. I expect changes soon. > > 2. Shadow paging > - This implementation will affect shadow mode, especially at xc_hvm_build.c and memory.c. > - Where and how to avoid affecting shadow? > > 3. Turn it on/off > - Do we want to turn this feature on/off through option (kernel option or anything else)? > > 4. Other missing areas? > =========== > > ________________________________ > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel > > --------------070407090709020908030708 Content-Type: text/x-patch; name="1gpages.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="1gpages.patch" diff -r 1b863ae2bf1e tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Wed Dec 05 09:59:23 2007 +0000 +++ b/tools/libxc/xc_hvm_build.c Thu Dec 06 19:27:24 2007 -0600 @@ -21,7 +21,8 @@ #define SCRATCH_PFN 0xFFFFF -static void build_e820map(void *e820_page, unsigned long long mem_size) +static void build_e820map(void *e820_page, unsigned long long mem_size, + unsigned long long mem_size_low) { struct e820entry *e820entry = (struct e820entry *)(((unsigned char *)e820_page) + HVM_E820_OFFSET); @@ -77,17 +78,25 @@ static void build_e820map(void *e820_pag e820entry[nr_map].type = E820_RESERVED; nr_map++; - /* Low RAM goes here. Remove 3 pages for ioreq, bufioreq, and xenstore. */ + /* Low RAM goes here. */ e820entry[nr_map].addr = 0x100000; - e820entry[nr_map].size = mem_size - 0x100000 - PAGE_SIZE * 3; + e820entry[nr_map].size = mem_size_low - 0x100000 - PAGE_SIZE * 3; e820entry[nr_map].type = E820_RAM; nr_map++; /* Explicitly reserve space for special pages (ioreq and xenstore). */ - e820entry[nr_map].addr = mem_size - PAGE_SIZE * 3; + e820entry[nr_map].addr = mem_size_low; e820entry[nr_map].size = PAGE_SIZE * 3; e820entry[nr_map].type = E820_RESERVED; nr_map++; + + if (mem_size > mem_size_low) + { + e820entry[nr_map].addr = 0x40000000; + e820entry[nr_map].size = mem_size - 0x40000000; + e820entry[nr_map].type = E820_RAM; + nr_map++; + } if ( extra_mem_size ) { @@ -158,16 +167,30 @@ static int setup_guest(int xc_handle, uint64_t v_start, v_end; int rc; xen_capabilities_info_t caps; + int memsize_low = 32; + unsigned long nr_pages_low, nr_pages_1g; /* An HVM guest must be initialised with at least 2MB memory. */ if ( memsize < 2 ) goto error_out; + /* Align memory on 1G pages, if possible. */ + nr_pages += 3; + nr_pages_low = nr_pages; + nr_pages_1g = 0; + v_start = 0; + v_end = nr_pages << PAGE_SHIFT; + if ( memsize_low && memsize_low < 1024 && memsize >= 1024 + memsize_low ) + { + nr_pages_low = (unsigned long)memsize_low << (20 - PAGE_SHIFT); + nr_pages_low += 3; + nr_pages_1g = nr_pages - nr_pages_low; + v_end = (1024UL << 20) + (nr_pages_1g << PAGE_SHIFT); + } + nr_pages = v_end >> PAGE_SHIFT; if ( elf_init(&elf, image, image_size) != 0 ) goto error_out; elf_parse_binary(&elf); - v_start = 0; - v_end = (unsigned long long)memsize << 20; if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 ) { @@ -203,9 +226,15 @@ static int setup_guest(int xc_handle, /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */ rc = xc_domain_memory_populate_physmap( xc_handle, dom, 0xa0, 0, 0, &page_array[0x00]); + /* Allocate first chunk. ("low memory") */ if ( rc == 0 ) rc = xc_domain_memory_populate_physmap( - xc_handle, dom, nr_pages - 0xc0, 0, 0, &page_array[0xc0]); + xc_handle, dom, nr_pages_low - 0xc0, 0, 0, &page_array[0xc0]); + /* Allocate second chunk. ("high memory") */ + if ( rc == 0 && nr_pages_1g ) + rc = xc_domain_memory_populate_physmap( + xc_handle, dom, nr_pages_1g, 0, 0, + &page_array[0x40000]); if ( rc != 0 ) { PERROR("Could not allocate memory for HVM guest.\n"); @@ -220,7 +249,8 @@ static int setup_guest(int xc_handle, HVM_E820_PAGE >> PAGE_SHIFT)) == NULL ) goto error_out; memset(e820_page, 0, PAGE_SIZE); - build_e820map(e820_page, v_end); + build_e820map(e820_page, v_end, + nr_pages_1g ? (nr_pages_low << PAGE_SHIFT) : v_end); munmap(e820_page, PAGE_SIZE); /* Map and initialise shared_info page. */ @@ -239,7 +269,9 @@ static int setup_guest(int xc_handle, sizeof(shared_info->evtchn_mask)); munmap(shared_info, PAGE_SIZE); - if ( v_end > HVM_BELOW_4G_RAM_END ) + if ( nr_pages_1g ) + shared_page_nr = nr_pages_low - 1; + else if ( v_end > HVM_BELOW_4G_RAM_END ) shared_page_nr = (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT) - 1; else shared_page_nr = (v_end >> PAGE_SHIFT) - 1; diff -r 1b863ae2bf1e xen/arch/x86/mm/p2m.c --- a/xen/arch/x86/mm/p2m.c Wed Dec 05 09:59:23 2007 +0000 +++ b/xen/arch/x86/mm/p2m.c Thu Dec 06 19:27:24 2007 -0600 @@ -202,7 +202,8 @@ p2m_next_level(struct domain *d, mfn_t * // Returns 0 on error (out of memory) static int -set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, p2m_type_t p2mt) +__set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, + p2m_type_t p2mt, unsigned int order) { // XXX -- this might be able to be faster iff current->domain == d mfn_t table_mfn = pagetable_get_mfn(d->arch.phys_table); @@ -217,6 +218,18 @@ set_p2m_entry(struct domain *d, unsigned L4_PAGETABLE_SHIFT - PAGE_SHIFT, L4_PAGETABLE_ENTRIES, PGT_l3_page_table) ) goto out; + if (order == 18) { + if ((gfn & ((1 << order) - 1)) != 0 || (mfn & ((1 << order) - 1)) != 0) + goto out; + p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn, + L3_PAGETABLE_SHIFT - PAGE_SHIFT, + L3_PAGETABLE_ENTRIES); + entry_content = l1e_from_pfn(mfn_x(mfn), + p2m_type_to_flags(p2mt) | _PAGE_PSE); + paging_write_p2m_entry(d, gfn, p2m_entry, table_mfn, entry_content, 3); + rv = 1; + goto out; + } #endif #if CONFIG_PAGING_LEVELS >= 3 /* @@ -233,6 +246,18 @@ set_p2m_entry(struct domain *d, unsigned : L3_PAGETABLE_ENTRIES), PGT_l2_page_table) ) goto out; + if (order == 9) { + if ((gfn & ((1 << order) - 1)) != 0 || (mfn & ((1 << order) - 1)) != 0) + goto out; + p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn, + L2_PAGETABLE_SHIFT - PAGE_SHIFT, + L2_PAGETABLE_ENTRIES); + entry_content = l1e_from_pfn(mfn_x(mfn), + p2m_type_to_flags(p2mt) | _PAGE_PSE); + paging_write_p2m_entry(d, gfn, p2m_entry, table_mfn, entry_content, 2); + rv = 1; + goto out; + } #endif if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn, L2_PAGETABLE_SHIFT - PAGE_SHIFT, @@ -266,6 +291,11 @@ set_p2m_entry(struct domain *d, unsigned return rv; } +static inline int +set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, p2m_type_t p2mt) +{ + return __set_p2m_entry(d, gfn, mfn, p2mt, 0); +} /* Init the datastructures for later use by the p2m code */ void p2m_init(struct domain *d) @@ -400,6 +430,7 @@ gfn_to_mfn_foreign(struct domain *d, uns paddr_t addr = ((paddr_t)gfn) << PAGE_SHIFT; l2_pgentry_t *l2e; l1_pgentry_t *l1e; + unsigned long flags; ASSERT(paging_mode_translate(d)); @@ -441,25 +472,39 @@ gfn_to_mfn_foreign(struct domain *d, uns #else l3e += l3_table_offset(addr); #endif - if ( (l3e_get_flags(*l3e) & _PAGE_PRESENT) == 0 ) + flags = l3e_get_flags(*l3e); + if ( (flags & _PAGE_PRESENT) == 0 ) { unmap_domain_page(l3e); return _mfn(INVALID_MFN); } mfn = _mfn(l3e_get_pfn(*l3e)); unmap_domain_page(l3e); + if ( (flags & _PAGE_PSE) != 0 ) + { + mfn += (gfn & ((1UL << (L3_PAGETABLE_SHIFT - PAGE_SHIFT)) - 1)); + *t = p2m_flags_to_type(flags); + return mfn; + } } #endif l2e = map_domain_page(mfn_x(mfn)); l2e += l2_table_offset(addr); - if ( (l2e_get_flags(*l2e) & _PAGE_PRESENT) == 0 ) + flags = l2e_get_flags(*l2e); + if ( (flags & _PAGE_PRESENT) == 0 ) { unmap_domain_page(l2e); return _mfn(INVALID_MFN); } mfn = _mfn(l2e_get_pfn(*l2e)); unmap_domain_page(l2e); + if ( (flags & _PAGE_PSE) != 0 ) + { + mfn += (gfn & ((1UL << (L2_PAGETABLE_SHIFT - PAGE_SHIFT)) - 1)); + *t = p2m_flags_to_type(flags); + return mfn; + } l1e = map_domain_page(mfn_x(mfn)); l1e += l1_table_offset(addr); @@ -689,8 +734,8 @@ guest_physmap_remove_page(struct domain } int -guest_physmap_add_entry(struct domain *d, unsigned long gfn, - unsigned long mfn, p2m_type_t t) +__guest_physmap_add_entry(struct domain *d, unsigned long gfn, + unsigned long mfn, p2m_type_t t, unsigned int order) { unsigned long ogfn; p2m_type_t ot; @@ -747,9 +792,13 @@ guest_physmap_add_entry(struct domain *d if ( mfn_valid(_mfn(mfn)) ) { - if ( !set_p2m_entry(d, gfn, _mfn(mfn), t) ) + if ( !__set_p2m_entry(d, gfn, _mfn(mfn), t, order) ) rc = -EINVAL; - set_gpfn_from_mfn(mfn, gfn); + { + unsigned int i; + for (i = 0; i < (1 << order); i++) + set_gpfn_from_mfn(mfn + i, gfn + i); + } } else { diff -r 1b863ae2bf1e xen/common/memory.c --- a/xen/common/memory.c Wed Dec 05 09:59:23 2007 +0000 +++ b/xen/common/memory.c Thu Dec 06 19:27:24 2007 -0600 @@ -90,6 +90,81 @@ static void increase_reservation(struct a->nr_done = i; } +static int try_extent(xen_pfn_t gpfn, XEN_GUEST_HANDLE(xen_pfn_t) list, + unsigned int off, unsigned int maxoff, + unsigned int order) +{ + unsigned int i; + unsigned int o = 1 << order; + xen_pfn_t cgpfn; + + if ( (gpfn & (o - 1)) != 0 ) + return 0; + if ( off + o > maxoff) + return 0; + + for (i = off + 1; i < o; i++) + { + if ( unlikely(__copy_from_guest_offset(&cgpfn, list, i, 1)) ) + return -1; + if ( gpfn + i - off != cgpfn) + return 0; + } + + return 1; +} + +static unsigned int try_larger_extents(struct domain *d, xen_pfn_t gpfn, + XEN_GUEST_HANDLE(xen_pfn_t) list, + unsigned int off, unsigned int maxoff, + unsigned int order) +{ + unsigned int ret_order; + int ret; + + if (!paging_mode_hap(d)) + return 0; + switch (order) + { + case 18: + ret_order = 9; + break; + + case 9: + ret_order = 0; + break; + + case 0: + ret = 0; + ret_order = 18; + ret = try_extent(gpfn, list, off, maxoff, ret_order); + if (ret > 0) + break; + if (ret < 0) + { + ret_order = ~0; + break; + } + ret_order = 9; + ret = try_extent(gpfn, list, off, maxoff, ret_order); + if (ret > 0) + break; + if (ret < 0) + { + ret_order = ~0; + break; + } + ret_order = 0; + break; + + default: + ret_order = 0; + BUG(); + } + + return ret_order; +} + static void populate_physmap(struct memop_args *a) { struct page_info *page; @@ -97,6 +172,9 @@ static void populate_physmap(struct memo xen_pfn_t gpfn, mfn; struct domain *d = a->domain; unsigned int cpu = select_local_cpu(d); + unsigned int extent_order; + unsigned long incr; + unsigned long o; if ( !guest_handle_okay(a->extent_list, a->nr_extents) ) return; @@ -105,7 +183,7 @@ static void populate_physmap(struct memo !multipage_allocation_permitted(current->domain) ) return; - for ( i = a->nr_done; i < a->nr_extents; i++ ) + for ( i = a->nr_done; i < a->nr_extents; i += incr ) { if ( hypercall_preempt_check() ) { @@ -115,33 +193,67 @@ static void populate_physmap(struct memo if ( unlikely(__copy_from_guest_offset(&gpfn, a->extent_list, i, 1)) ) goto out; - - page = __alloc_domheap_pages(d, cpu, a->extent_order, a->memflags); + extent_order = a->extent_order; + if (!extent_order) + { + extent_order = try_larger_extents(d, gpfn, a->extent_list, + i, a->nr_extents, 0); + if (extent_order == ~0) + goto out; + } + + page = __alloc_domheap_pages(d, cpu, extent_order, a->memflags); if ( unlikely(page == NULL) ) { - gdprintk(XENLOG_INFO, "Could not allocate order=%d extent: " - "id=%d memflags=%x (%ld of %d)\n", - a->extent_order, d->domain_id, a->memflags, - i, a->nr_extents); - goto out; - } + if (extent_order != a->extent_order) + { + do + { + extent_order = try_larger_extents(d, gpfn, a->extent_list, + i, a->nr_extents, + extent_order); + page = __alloc_domheap_pages(d, cpu, extent_order, + a->memflags); + if (page) + break; + } + while (extent_order); + } + if ( unlikely(page == NULL) ) + { + gdprintk(XENLOG_INFO, "Could not allocate order=%d extent: " + "id=%d memflags=%x (%ld of %d)\n", + a->extent_order, d->domain_id, a->memflags, + i, a->nr_extents); + goto out; + } + } + o = 1 << extent_order; + if (extent_order == a->extent_order) + incr = 1; + else + incr = o; mfn = page_to_mfn(page); if ( unlikely(paging_mode_translate(d)) ) { - for ( j = 0; j < (1 << a->extent_order); j++ ) - if ( guest_physmap_add_page(d, gpfn + j, mfn + j) ) + if ( guest_physmap_add_page_order(d, gpfn, mfn, extent_order) ) + goto out; + } + else + { + for ( j = 0; j < o; j++ ) + set_gpfn_from_mfn(mfn + j, gpfn + j); + + /* Inform the domain of the new page's machine address. */ + for ( j = 0; j < incr; j++ ) + { + if ( unlikely(__copy_to_guest_offset(a->extent_list, i + j, + &mfn, 1)) ) goto out; - } - else - { - for ( j = 0; j < (1 << a->extent_order); j++ ) - set_gpfn_from_mfn(mfn + j, gpfn + j); - - /* Inform the domain of the new page's machine address. */ - if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) ) - goto out; + mfn++; + } } } diff -r 1b863ae2bf1e xen/include/asm-x86/p2m.h --- a/xen/include/asm-x86/p2m.h Wed Dec 05 09:59:23 2007 +0000 +++ b/xen/include/asm-x86/p2m.h Thu Dec 06 19:27:24 2007 -0600 @@ -93,6 +93,9 @@ static inline p2m_type_t p2m_flags_to_ty return (flags >> 9) & 0x7; } +/* Read another domain's P2M table, mapping pages as we go */ +mfn_t gfn_to_mfn_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t); + /* Read the current domain's p2m table (through the linear mapping). */ static inline mfn_t gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t) { @@ -102,6 +105,9 @@ static inline mfn_t gfn_to_mfn_current(u * XXX marked as RAM was considered to be emulated MMIO space. * XXX Once we start explicitly registering MMIO regions in the p2m * XXX we will return p2m_invalid for unmapped gfns */ + + if ( paging_mode_hap(current->domain) ) + return gfn_to_mfn_foreign(current->domain, gfn, t); if ( gfn <= current->domain->arch.p2m.max_mapped_pfn ) { @@ -131,9 +137,6 @@ static inline mfn_t gfn_to_mfn_current(u *t = p2mt; return mfn; } - -/* Read another domain's P2M table, mapping pages as we go */ -mfn_t gfn_to_mfn_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t); /* General conversion function from gfn to mfn */ #define gfn_to_mfn(d, g, t) _gfn_to_mfn((d), (g), (t)) @@ -201,8 +204,16 @@ void p2m_teardown(struct domain *d); void p2m_teardown(struct domain *d); /* Add a page to a domain's p2m table */ -int guest_physmap_add_entry(struct domain *d, unsigned long gfn, - unsigned long mfn, p2m_type_t t); +int __guest_physmap_add_entry(struct domain *d, unsigned long gfn, + unsigned long mfn, p2m_type_t t, + unsigned int order); + +static inline int +guest_physmap_add_entry(struct domain *d, unsigned long gfn, + unsigned long mfn, p2m_type_t t) +{ + return __guest_physmap_add_entry(d, gfn, mfn, t, 0); +} /* Untyped version for RAM only, for compatibility * @@ -212,6 +223,14 @@ static inline int guest_physmap_add_page unsigned long mfn) { return guest_physmap_add_entry(d, gfn, mfn, p2m_ram_rw); +} + +static inline int guest_physmap_add_page_order(struct domain *d, + unsigned long gfn, + unsigned long mfn, + unsigned int order) +{ + return __guest_physmap_add_entry(d, gfn, mfn, p2m_ram_rw, order); } /* Remove a page from a domain's p2m table */ --------------070407090709020908030708 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --------------070407090709020908030708--