Fix the issue that guest cannot be launched by using
balloon driver.
- In current version, when using balloon driver
to balloon memory,it
did not balloon the memory for vhpt.
vhpt needs the continuous memory.But it allocates the
memory for vhpt
after it finished allocating the memory for guest. So
the vhpt usually
can not get the continuous memory and guest cannot be
launched. Now
i change the sequence.Before it allocates the memory
for guest, i save
the continuous memory for vhpt.when boot the vcpu, it
allocate the saved
memory for vhpt.
Signed-off-by: Yang Zhang <yang.zhang@xxxxxxxxx>
diff -r b432c632ebe8 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Fri
Feb 13 19:11:38 2009 +0900
+++ b/tools/python/xen/xend/image.py Tue
Feb 17 20:36:43 2009 -0600
@@ -870,6 +870,9 @@ class
IA64_HVM_ImageHandler(HVMImageHand
extra_pages = 1024 + 5
mem_kb += extra_pages * page_kb
mem_kb += self.vramsize
+ # per-vcpu
need 16M for max vhpt size
+ vhpt_kb =
16 * 1024
+ mem_kb +=
self.vm.getVCpuCount() * vhpt_kb
return mem_kb
def
getRequiredInitialReservation(self):
diff -r b432c632ebe8 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Fri
Feb 13 19:11:38 2009 +0900
+++ b/xen/arch/ia64/vmx/vmmu.c Tue
Feb 17 20:35:39 2009 -0600
@@ -62,7 +62,7 @@ static int init_domain_vhpt(struct
vcpu
else
size
= canonicalize_vhpt_size(size);
- rc =
thash_alloc(&(v->arch.vhpt), size, "vhpt");
+ rc = thash_alloc(v, size,
"vhpt");
v->arch.arch_vmx.mpta =
v->arch.vhpt.pta.val;
return rc;
}
@@ -70,8 +70,10 @@ static int init_domain_vhpt(struct
vcpu
static void free_domain_vhpt(struct vcpu *v)
{
- if (v->arch.vhpt.hash)
+ if (v->arch.vhpt.hash) {
thash_free(&(v->arch.vhpt));
+
v->domain->arch.hvm_domain.vhpt_page[v->vcpu_id] = NULL;
+ }
}
int init_domain_tlb(struct vcpu *v)
@@ -82,7 +84,7 @@ int init_domain_tlb(struct vcpu *v)
if (rc)
return rc;
- rc = thash_alloc(&(v->arch.vtlb),
default_vtlb_sz, "vtlb");
+ rc = thash_alloc(v,
default_vtlb_sz, "vtlb");
if (rc) {
free_domain_vhpt(v);
return rc;
diff -r b432c632ebe8 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Fri Feb
13 19:11:38 2009 +0900
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Tue
Feb 17 20:35:39 2009 -0600
@@ -147,6 +147,9 @@ do_hvm_op(unsigned long op,
XEN_GUEST_HA
a.value = current->domain->domain_id;
rc = a.value ? -EINVAL : 0; /* no stub domain support */
break;
+
case HVM_PARAM_VHPT_SIZE:
+
rc = domain_pre_alloc_vhpt(d, a.value);
+
break;
default:
/* nothing */
break;
diff -r b432c632ebe8 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c Fri
Feb 13 19:11:38 2009 +0900
+++ b/xen/arch/ia64/vmx/vmx_init.c Tue Feb 17 20:42:02
2009 -0600
@@ -541,6 +541,7 @@ vmx_relinquish_guest_resources(struct
do
for_each_vcpu(d,
v)
vmx_release_assist_channel(v);
+ domain_pre_free_vhpt(d);
vacpi_relinquish_resources(d);
vmx_destroy_ioreq_page(d,
&d->arch.vmx_platform.ioreq);
diff -r b432c632ebe8 xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c Fri
Feb 13 19:11:38 2009 +0900
+++ b/xen/arch/ia64/vmx/vtlb.c Tue Feb 17 20:38:23
2009 -0600
@@ -723,13 +723,30 @@ static void
thash_init(thash_cb_t *hcb,
hcb->cch_freelist = NULL;
}
-int thash_alloc(thash_cb_t *hcb, u64 sz_log2, char
*what)
+int thash_alloc(struct vcpu *v, u64 sz_log2, char
*what)
{
struct page_info *page;
void * vbase;
+ thash_cb_t *hcb;
u64 sz = 1UL <<
sz_log2;
- page = alloc_domheap_pages(NULL,
(sz_log2 + 1 - PAGE_SHIFT), 0);
+ if (!strcmp(what,
"vhpt")) {
+ hcb =
&(v->arch.vhpt);
+ page =
v->domain->arch.hvm_domain.vhpt_page[v->vcpu_id];
+
v->domain->arch.hvm_domain.vhpt_page[v->vcpu_id] = NULL;
+ /* retry
again */
+ if (page
== NULL)
+
page = alloc_domheap_pages(NULL, (sz_log2 + 1 - PAGE_SHIFT), 0);
+
+ if (page
!= NULL)
+
printk("alloc %s\n, addr=0x%lx, vcpuid=%d\n, domainid=%d\n",
+
what, (u64)page, v->vcpu_id, v->domain->domain_id);
+ }
+ else {
+ hcb =
&(v->arch.vtlb);
+ page =
alloc_domheap_pages(NULL, (sz_log2 + 1 - PAGE_SHIFT), 0);
+ }
+
if (page == NULL) {
printk("No enough contiguous memory(%ldKB) for init_domain_%s\n",
sz >> (10 - 1), what);
diff -r b432c632ebe8 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Fri
Feb 13 19:11:38 2009 +0900
+++ b/xen/arch/ia64/xen/domain.c Tue
Feb 17 20:35:39 2009 -0600
@@ -2455,3 +2455,63 @@ domain_opt_feature(struct
domain *d, str
return rc;
}
+static inline int get_vhpt_size(unsigned long size)
+{
+ switch (size) {
+ case 0:
+ size =
DEFAULT_VHPT_SZ;
+ break;
+ case 1 ... 15:
+ size = 15;
+ break;
+ case 16 ... (IA64_GRANULE_SHIFT -
1):
+ break;
+ default:
+ size =
IA64_GRANULE_SHIFT - 1;
+ }
+ return size;
+}
+int domain_pre_alloc_vhpt(struct domain *d, unsigned
long size)
+{
+ struct vcpu *v;
+ struct page_info *pg = NULL;
+ int rc = 0;
+
+ size = get_vhpt_size(size);
+ for_each_vcpu(d, v) {
+ if
(!v->is_initialised) {
+
pg = alloc_domheap_pages(NULL, (size + 1 - PAGE_SHIFT), 0);
+
if (pg == NULL) {
+
printk("No enough contiguous memory(%ldKB) for alloc vhpt\n",
+
size >> 9);
+
rc = -ENOMEM;
+
goto fail;
+
}
+
d->arch.hvm_domain.vhpt_page[v->vcpu_id] = pg;
+ }
+ }
+ return rc;
+
+fail:
+ domain_pre_free_vhpt(d);
+ return rc;
+}
+
+void domain_pre_free_vhpt(struct domain *d)
+{
+ struct vcpu *v;
+ unsigned long size;
+ struct page_info *pg = NULL;
+
+ size =
d->arch.hvm_domain.params[HVM_PARAM_VHPT_SIZE];
+ size = get_vhpt_size(size);
+
+ for_each_vcpu(d, v) {
+ pg =
d->arch.hvm_domain.vhpt_page[v->vcpu_id];
+ if (pg !=
NULL) {
+
free_domheap_pages(pg, size + 1 - PAGE_SHIFT);
+
v->arch.vhpt.hash = NULL;
+ }
+ }
+}
+
diff -r b432c632ebe8 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h Fri
Feb 13 19:11:38 2009 +0900
+++ b/xen/include/asm-ia64/domain.h Tue
Feb 17 20:35:39 2009 -0600
@@ -43,6 +43,10 @@ extern int
shadow_mode_control(struct do
/* Cleanly crash the current domain with a
message. */
extern void panic_domain(struct pt_regs *, const
char *, ...)
__attribute__
((noreturn, format (printf, 2, 3)));
+
+extern int domain_pre_alloc_vhpt(struct domain *d,
unsigned long size);
+
+extern void domain_pre_free_vhpt(struct domain *d);
#define has_arch_pdevs(d)
(!list_empty(&(d)->arch.pdev_list))
diff -r b432c632ebe8 xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h Fri Feb 13
19:11:38 2009 +0900
+++ b/xen/include/asm-ia64/vmmu.h Tue
Feb 17 20:35:39 2009 -0600
@@ -136,7 +136,7 @@ typedef struct thash_cb {
/*
* Allocate and initialize internal control data
before service.
*/
-extern int thash_alloc(thash_cb_t *hcb, u64 sz, char
*what);
+extern int thash_alloc(struct vcpu *v, u64 sz, char
*what);
extern void thash_free(thash_cb_t *hcb);
diff -r b432c632ebe8
xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h Fri
Feb 13 19:11:38 2009 +0900
+++ b/xen/include/asm-ia64/vmx_platform.h Tue
Feb 17 20:35:39 2009 -0600
@@ -46,6 +46,8 @@ typedef struct virtual_platform_def
{
/* Pass-throgh VT-d */
struct
hvm_irq
irq;
struct hvm_iommu
hvm_iommu;
+ /* pre-alloc pervcpu vhpt */
+ struct
page_info
*vhpt_page[MAX_VIRT_CPUS];
} vir_plat_t;
static inline int __fls(uint32_t word)