# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 7877e25e2b23d24852b45499d80a2dffbaaf90aa
# Parent 6374af16a8a3c27d107fe9145f28bf08020fda28
[HVM] getmemlist hypercall returns pages in strict
physmap order.
From: Ke Yu <ke.yu@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/domctl.c | 58 +++++++++++++++++++++++++++++++++++++-------------
1 files changed, 44 insertions(+), 14 deletions(-)
diff -r 6374af16a8a3 -r 7877e25e2b23 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Tue Sep 19 10:50:10 2006 +0100
+++ b/xen/arch/x86/domctl.c Tue Sep 19 11:01:05 2006 +0100
@@ -22,6 +22,7 @@
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
#include <asm/processor.h>
+#include <public/hvm/e820.h>
long arch_do_domctl(
struct xen_domctl *domctl,
@@ -213,7 +214,7 @@ long arch_do_domctl(
int i;
struct domain *d = find_domain_by_id(domctl->domain);
unsigned long max_pfns = domctl->u.getmemlist.max_pfns;
- unsigned long mfn;
+ unsigned long mfn, gmfn;
struct list_head *list_ent;
ret = -EINVAL;
@@ -222,19 +223,48 @@ long arch_do_domctl(
ret = 0;
spin_lock(&d->page_alloc_lock);
- list_ent = d->page_list.next;
- for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
- {
- mfn = page_to_mfn(list_entry(
- list_ent, struct page_info, list));
- if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
- i, &mfn, 1) )
- {
- ret = -EFAULT;
- break;
- }
- list_ent = mfn_to_page(mfn)->list.next;
- }
+
+ if ( hvm_guest(d->vcpu[0]) && shadow_mode_translate(d) )
+ {
+ /* HVM domain: scan P2M to get guaranteed physmap order. */
+ for ( i = 0, gmfn = 0;
+ (i < max_pfns) && (i < d->tot_pages);
+ i++, gmfn++ )
+ {
+ if ( unlikely(i == (HVM_BELOW_4G_MMIO_START>>PAGE_SHIFT)) )
+ {
+ /* skip MMIO range */
+ gmfn += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
+ }
+ mfn = gmfn_to_mfn(d, gmfn);
+ if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
+ i, &mfn, 1) )
+ {
+ ret = -EFAULT;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Other guests: return in order of ownership list. */
+ list_ent = d->page_list.next;
+ for ( i = 0;
+ (i < max_pfns) && (list_ent != &d->page_list);
+ i++ )
+ {
+ mfn = page_to_mfn(list_entry(
+ list_ent, struct page_info, list));
+ if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
+ i, &mfn, 1) )
+ {
+ ret = -EFAULT;
+ break;
+ }
+ list_ent = mfn_to_page(mfn)->list.next;
+ }
+ }
+
spin_unlock(&d->page_alloc_lock);
domctl->u.getmemlist.num_pfns = i;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|