WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-ia64-devel] [PATCH 2/2][IA64] configure VHPT size per domain: ia64

IA64 part.

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>

# HG changeset patch
# User Kouya Shimura <kouya@xxxxxxxxxxxxxx>
# Date 1192770850 -32400
# Node ID 630a8cf763c0a00766ea2c5528ad148740edad8a
# Parent  b4278beaf3549f410a5a6086dbd8af93c495aeac
IA64 part.

diff -r b4278beaf354 -r 630a8cf763c0 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c  Wed Oct 17 13:12:03 2007 +0100
+++ b/xen/arch/ia64/vmx/vmmu.c  Fri Oct 19 14:14:10 2007 +0900
@@ -22,6 +22,7 @@
 #include <asm/vmx_vcpu.h>
 #include <asm/vmx_pal_vsa.h>
 #include <xen/sched-if.h>
+#include <asm/vhpt.h>
 
 static int default_vtlb_sz = DEFAULT_VTLB_SZ;
 static int default_vhpt_sz = DEFAULT_VHPT_SZ;
@@ -38,17 +39,6 @@ static void __init parse_vtlb_size(char 
     }
 }
 
-static int canonicalize_vhpt_size(int sz)
-{
-    /* minimum 32KB */
-    if (sz < 15)
-        return 15;
-    /* maximum 8MB (since purging TR is hard coded) */
-    if (sz > IA64_GRANULE_SHIFT - 1)
-        return IA64_GRANULE_SHIFT - 1;
-    return sz;
-}
-
 static void __init parse_vhpt_size(char *s)
 {
     int sz = parse_size_and_unit(s, NULL);
@@ -96,8 +86,14 @@ static int init_domain_vhpt(struct vcpu 
 static int init_domain_vhpt(struct vcpu *v)
 {
     int rc;
-
-    rc = thash_alloc(&(v->arch.vhpt), default_vhpt_sz, "vhpt");
+    u64 size = v->domain->arch.hvm_domain.params[HVM_PARAM_VHPT_SIZE];
+
+    if (size == 0)
+        size = default_vhpt_sz;
+    else
+        size = canonicalize_vhpt_size(size);
+
+    rc = thash_alloc(&(v->arch.vhpt), size, "vhpt");
     v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val;
     return rc;
 }
diff -r b4278beaf354 -r 630a8cf763c0 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Wed Oct 17 13:12:03 2007 +0100
+++ b/xen/arch/ia64/xen/dom0_ops.c      Fri Oct 19 14:14:10 2007 +0900
@@ -93,6 +93,9 @@ long arch_do_domctl(xen_domctl_t *op, XE
             ds->maxmem = d->arch.convmem_end;
             ds->xsi_va = d->arch.shared_info_va;
             ds->hypercall_imm = d->arch.breakimm;
+#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
+            ds->vhpt_size_log2 = d->arch.vhpt_size_log2;
+#endif
             /* Copy back.  */
             if ( copy_to_guest(u_domctl, op, 1) )
                 ret = -EFAULT;
@@ -116,6 +119,20 @@ long arch_do_domctl(xen_domctl_t *op, XE
                     for_each_vcpu (d, v)
                         v->arch.breakimm = d->arch.breakimm;
                 }
+#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
+                if (ds->vhpt_size_log2 == -1) {
+                    d->arch.has_pervcpu_vhpt = 0;
+                    ds->vhpt_size_log2 = -1;
+                    printk(XENLOG_INFO "XEN_DOMCTL_arch_setup: "
+                           "domain %d VHPT is global.\n", d->domain_id);
+                } else {
+                    d->arch.has_pervcpu_vhpt = 1;
+                    d->arch.vhpt_size_log2 = ds->vhpt_size_log2;
+                    printk(XENLOG_INFO "XEN_DOMCTL_arch_setup: "
+                           "domain %d VHPT is per vcpu. size=2**%d\n",
+                           d->domain_id, ds->vhpt_size_log2);
+                }
+#endif
                 if (ds->xsi_va)
                     d->arch.shared_info_va = ds->xsi_va;
                 ret = dom_fw_setup(d, ds->bp, ds->maxmem);
diff -r b4278beaf354 -r 630a8cf763c0 xen/arch/ia64/xen/vhpt.c
--- a/xen/arch/ia64/xen/vhpt.c  Wed Oct 17 13:12:03 2007 +0100
+++ b/xen/arch/ia64/xen/vhpt.c  Fri Oct 19 14:14:10 2007 +0900
@@ -28,12 +28,13 @@ DEFINE_PER_CPU(volatile u32, vhpt_tlbflu
 #endif
 
 static void
-__vhpt_flush(unsigned long vhpt_maddr)
+__vhpt_flush(unsigned long vhpt_maddr, unsigned long vhpt_size_log2)
 {
        struct vhpt_lf_entry *v = (struct vhpt_lf_entry*)__va(vhpt_maddr);
+       unsigned long num_entries = 1 << (vhpt_size_log2 - 5);
        int i;
 
-       for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++)
+       for (i = 0; i < num_entries; i++, v++)
                v->ti_tag = INVALID_TI_TAG;
 }
 
@@ -42,7 +43,7 @@ local_vhpt_flush(void)
 {
        /* increment flush clock before flush */
        u32 flush_time = tlbflush_clock_inc_and_return();
-       __vhpt_flush(__ia64_per_cpu_var(vhpt_paddr));
+       __vhpt_flush(__ia64_per_cpu_var(vhpt_paddr), VHPT_SIZE_LOG2);
        /* this must be after flush */
        tlbflush_update_time(&__get_cpu_var(vhpt_tlbflush_timestamp),
                             flush_time);
@@ -52,17 +53,23 @@ void
 void
 vcpu_vhpt_flush(struct vcpu* v)
 {
-       __vhpt_flush(vcpu_vhpt_maddr(v));
+       unsigned long vhpt_size_log2 = VHPT_SIZE_LOG2;
+#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
+       if (HAS_PERVCPU_VHPT(v->domain))
+               vhpt_size_log2 = v->arch.pta.size;
+#endif
+       __vhpt_flush(vcpu_vhpt_maddr(v), vhpt_size_log2);
        perfc_incr(vcpu_vhpt_flush);
 }
 
 static void
-vhpt_erase(unsigned long vhpt_maddr)
+vhpt_erase(unsigned long vhpt_maddr, unsigned long vhpt_size_log2)
 {
        struct vhpt_lf_entry *v = (struct vhpt_lf_entry*)__va(vhpt_maddr);
+       unsigned long num_entries = 1 << (vhpt_size_log2 - 5);
        int i;
 
-       for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++) {
+       for (i = 0; i < num_entries; i++, v++) {
                v->itir = 0;
                v->CChain = 0;
                v->page_flags = 0;
@@ -140,7 +147,7 @@ void __init vhpt_init(void)
        __get_cpu_var(vhpt_pend) = paddr + (1 << VHPT_SIZE_LOG2) - 1;
        printk(XENLOG_DEBUG "vhpt_init: vhpt paddr=0x%lx, end=0x%lx\n",
               paddr, __get_cpu_var(vhpt_pend));
-       vhpt_erase(paddr);
+       vhpt_erase(paddr, VHPT_SIZE_LOG2);
        // we don't enable VHPT here.
        // context_switch() or schedule_tail() does it.
 }
@@ -151,6 +158,11 @@ pervcpu_vhpt_alloc(struct vcpu *v)
 {
        unsigned long vhpt_size_log2 = VHPT_SIZE_LOG2;
 
+       if (v->domain->arch.vhpt_size_log2 > 0)
+           vhpt_size_log2 =
+               canonicalize_vhpt_size(v->domain->arch.vhpt_size_log2);
+       printk(XENLOG_DEBUG "%s vhpt_size_log2=%ld\n",
+              __func__, vhpt_size_log2);
        v->arch.vhpt_entries =
                (1UL << vhpt_size_log2) / sizeof(struct vhpt_lf_entry);
        v->arch.vhpt_page =
@@ -164,11 +176,11 @@ pervcpu_vhpt_alloc(struct vcpu *v)
 
        v->arch.pta.val = 0; // to zero reserved bits
        v->arch.pta.ve = 1; // enable vhpt
-       v->arch.pta.size = VHPT_SIZE_LOG2;
+       v->arch.pta.size = vhpt_size_log2;
        v->arch.pta.vf = 1; // long format
        v->arch.pta.base = __va_ul(v->arch.vhpt_maddr) >> 15;
 
-       vhpt_erase(v->arch.vhpt_maddr);
+       vhpt_erase(v->arch.vhpt_maddr, vhpt_size_log2);
        smp_mb(); // per vcpu vhpt may be used by another physical cpu.
        return 0;
 }
@@ -178,7 +190,7 @@ pervcpu_vhpt_free(struct vcpu *v)
 {
        if (likely(v->arch.vhpt_page != NULL))
                free_domheap_pages(v->arch.vhpt_page,
-                                  VHPT_SIZE_LOG2 - PAGE_SHIFT);
+                                  v->arch.pta.size - PAGE_SHIFT);
 }
 #endif
 
diff -r b4278beaf354 -r 630a8cf763c0 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Wed Oct 17 13:12:03 2007 +0100
+++ b/xen/include/asm-ia64/domain.h     Fri Oct 19 14:14:10 2007 +0900
@@ -123,6 +123,7 @@ struct arch_domain {
             unsigned int is_vti : 1;
 #ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
             unsigned int has_pervcpu_vhpt : 1;
+            unsigned int vhpt_size_log2 : 6;
 #endif
         };
     };
diff -r b4278beaf354 -r 630a8cf763c0 xen/include/asm-ia64/vhpt.h
--- a/xen/include/asm-ia64/vhpt.h       Wed Oct 17 13:12:03 2007 +0100
+++ b/xen/include/asm-ia64/vhpt.h       Fri Oct 19 14:14:10 2007 +0900
@@ -84,5 +84,18 @@ vcpu_pta(struct vcpu* v)
         (VHPT_SIZE_LOG2 << 2) | VHPT_ENABLED;
 }
 
+static inline int
+canonicalize_vhpt_size(int sz)
+{
+    /* minimum 32KB */
+    if (sz < 15)
+        return 15;
+    /* maximum 8MB (since purging TR is hard coded) */
+    if (sz > IA64_GRANULE_SHIFT - 1)
+        return IA64_GRANULE_SHIFT - 1;
+    return sz;
+}
+
+
 #endif /* !__ASSEMBLY */
 #endif
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel