Mailing List Archive

[xen-unstable] [IA64] Make MMU setting of domVTi configurable
# HG changeset patch
# User Alex Williamson <alex.williamson@hp.com>
# Date 1186942753 21600
# Node ID 5b19839d036508fb2721a567798359dd11f68916
# Parent 54c721bb6d452d8eb97a151c847c9276868ae5c5
[IA64] Make MMU setting of domVTi configurable

This patch makes MMU setting of domVTi configurable.
The size of VTLB and VHPT can be set by boot option.
(e.g. "vti_vtlb_size=256k vti_vhpt_size=1m")

Also some cleanups.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
---
xen/arch/ia64/vmx/vmmu.c | 112 ++++++++++++++++++------------------------
xen/arch/ia64/vmx/vmx_entry.S | 14 -----
xen/arch/ia64/vmx/vtlb.c | 53 +++++++++++++++----
xen/include/asm-ia64/vmmu.h | 16 ++----
4 files changed, 99 insertions(+), 96 deletions(-)

diff -r 54c721bb6d45 -r 5b19839d0365 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Sun Aug 12 12:13:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c Sun Aug 12 12:19:13 2007 -0600
@@ -19,22 +19,47 @@
* Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com)
* Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com)
*/
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/tlb.h>
-#include <asm/gcc_intrin.h>
-#include <asm/vcpu.h>
-#include <linux/interrupt.h>
#include <asm/vmx_vcpu.h>
-#include <asm/vmx_mm_def.h>
-#include <asm/vmx.h>
-#include <asm/hw_irq.h>
#include <asm/vmx_pal_vsa.h>
-#include <asm/kregs.h>
-#include <asm/vcpu.h>
-#include <xen/irq.h>
-#include <xen/errno.h>
#include <xen/sched-if.h>
+
+static int default_vtlb_sz = DEFAULT_VTLB_SZ;
+static int default_vhpt_sz = DEFAULT_VHPT_SZ;
+
+static void __init parse_vtlb_size(char *s)
+{
+ int sz = parse_size_and_unit(s, NULL);
+
+ if (sz > 0) {
+ default_vtlb_sz = fls(sz - 1);
+ /* minimum 256KB (since calculated tag might be broken) */
+ if (default_vtlb_sz < 18)
+ default_vtlb_sz = 18;
+ }
+}
+
+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);
+ if (sz > 0) {
+ default_vhpt_sz = fls(sz - 1);
+ default_vhpt_sz = canonicalize_vhpt_size(default_vhpt_sz);
+ }
+}
+
+custom_param("vti_vtlb_size", parse_vtlb_size);
+custom_param("vti_vhpt_size", parse_vhpt_size);

/*
* Get the machine page frame number in 16KB unit
@@ -132,66 +157,33 @@ purge_machine_tc_by_domid(domid_t domid)

static int init_domain_vhpt(struct vcpu *v)
{
- struct page_info *page;
- void * vbase;
- page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0);
- if ( page == NULL ) {
- printk("No enough contiguous memory for init_domain_vhpt\n");
- return -ENOMEM;
- }
- vbase = page_to_virt(page);
- memset(vbase, 0, VCPU_VHPT_SIZE);
- printk(XENLOG_DEBUG "Allocate domain vhpt at 0x%p\n", vbase);
-
- VHPT(v,hash) = vbase;
- VHPT(v,hash_sz) = VCPU_VHPT_SIZE/2;
- VHPT(v,cch_buf) = (void *)((u64)vbase + VHPT(v,hash_sz));
- VHPT(v,cch_sz) = VCPU_VHPT_SIZE - VHPT(v,hash_sz);
- thash_init(&(v->arch.vhpt),VCPU_VHPT_SHIFT-1);
+ int rc;
+
+ rc = thash_alloc(&(v->arch.vhpt), default_vhpt_sz, "vhpt");
v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val;
-
- return 0;
+ return rc;
}


static void free_domain_vhpt(struct vcpu *v)
{
- struct page_info *page;
-
- if (v->arch.vhpt.hash) {
- page = virt_to_page(v->arch.vhpt.hash);
- free_domheap_pages(page, VCPU_VHPT_ORDER);
- v->arch.vhpt.hash = 0;
- }
-
- return;
+ if (v->arch.vhpt.hash)
+ thash_free(&(v->arch.vhpt));
}

int init_domain_tlb(struct vcpu *v)
{
- struct page_info *page;
- void * vbase;
int rc;

rc = init_domain_vhpt(v);
if (rc)
return rc;

- page = alloc_domheap_pages (NULL, VCPU_VTLB_ORDER, 0);
- if ( page == NULL ) {
- printk("No enough contiguous memory for init_domain_tlb\n");
+ rc = thash_alloc(&(v->arch.vtlb), default_vtlb_sz, "vtlb");
+ if (rc) {
free_domain_vhpt(v);
- return -ENOMEM;
- }
- vbase = page_to_virt(page);
- memset(vbase, 0, VCPU_VTLB_SIZE);
- printk(XENLOG_DEBUG "Allocate domain vtlb at 0x%p\n", vbase);
-
- VTLB(v,hash) = vbase;
- VTLB(v,hash_sz) = VCPU_VTLB_SIZE/2;
- VTLB(v,cch_buf) = (void *)((u64)vbase + VTLB(v,hash_sz));
- VTLB(v,cch_sz) = VCPU_VTLB_SIZE - VTLB(v,hash_sz);
- thash_init(&(v->arch.vtlb),VCPU_VTLB_SHIFT-1);
+ return rc;
+ }

return 0;
}
@@ -199,12 +191,8 @@ int init_domain_tlb(struct vcpu *v)

void free_domain_tlb(struct vcpu *v)
{
- struct page_info *page;
-
- if ( v->arch.vtlb.hash) {
- page = virt_to_page(v->arch.vtlb.hash);
- free_domheap_pages(page, VCPU_VTLB_ORDER);
- }
+ if (v->arch.vtlb.hash)
+ thash_free(&(v->arch.vtlb));

free_domain_vhpt(v);
}
diff -r 54c721bb6d45 -r 5b19839d0365 xen/arch/ia64/vmx/vmx_entry.S
--- a/xen/arch/ia64/vmx/vmx_entry.S Sun Aug 12 12:13:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_entry.S Sun Aug 12 12:19:13 2007 -0600
@@ -20,21 +20,9 @@
* Kun Tian (Kevin Tian) (kevin.tian@intel.com)
*/

-#ifndef VCPU_TLB_SHIFT
-#define VCPU_TLB_SHIFT 22
-#endif
#include <linux/config.h>
#include <asm/asmmacro.h>
-#include <asm/cache.h>
-#include <asm/kregs.h>
#include <asm/offsets.h>
-#include <asm/pgtable.h>
-#include <asm/percpu.h>
-#include <asm/processor.h>
-#include <asm/thread_info.h>
-#include <asm/unistd.h>
-#include <asm/vhpt.h>
-#include <asm/vmmu.h>
#include "vmx_minstate.h"

GLOBAL_ENTRY(ia64_leave_nested)
@@ -719,7 +707,7 @@ 1:
movl r25=PAGE_KERNEL
;;
or loc5 = r25,loc5 // construct PA | page properties
- mov r23 = VCPU_VHPT_SHIFT <<2
+ mov r23 = IA64_GRANULE_SHIFT <<2
;;
ptr.d in3,r23
;;
diff -r 54c721bb6d45 -r 5b19839d0365 xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c Sun Aug 12 12:13:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vtlb.c Sun Aug 12 12:19:13 2007 -0600
@@ -21,18 +21,7 @@
* XiaoYan Feng (Fleming Feng) (Fleming.feng@intel.com)
*/

-#include <linux/sched.h>
-#include <asm/tlb.h>
-#include <xen/mm.h>
-#include <asm/vmx_mm_def.h>
-#include <asm/gcc_intrin.h>
-#include <linux/interrupt.h>
#include <asm/vmx_vcpu.h>
-#include <asm/vmx_phy_mode.h>
-#include <asm/vmmu.h>
-#include <asm/tlbflush.h>
-#include <asm/regionreg.h>
-#define MAX_CCH_LENGTH 40

thash_data_t *__alloc_chain(thash_cb_t *);

@@ -664,7 +653,7 @@ thash_data_t *vtlb_lookup(VCPU *v, u64 v
/*
* Initialize internal control data before service.
*/
-void thash_init(thash_cb_t *hcb, u64 sz)
+static void thash_init(thash_cb_t *hcb, u64 sz)
{
int num;
thash_data_t *head;
@@ -688,3 +677,43 @@ void thash_init(thash_cb_t *hcb, u64 sz)
hcb->cch_free_idx = 0;
hcb->cch_freelist = NULL;
}
+
+int thash_alloc(thash_cb_t *hcb, u64 sz_log2, char *what)
+{
+ struct page_info *page;
+ void * vbase;
+ u64 sz = 1UL << sz_log2;
+
+ 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);
+ return -ENOMEM;
+ }
+ vbase = page_to_virt(page);
+ memset(vbase, 0, sz + sz); // hash + collisions chain
+ if (sz_log2 >= 20 - 1)
+ printk(XENLOG_DEBUG "Allocate domain %s at 0x%p(%ldMB)\n",
+ what, vbase, sz >> (20 - 1));
+ else
+ printk(XENLOG_DEBUG "Allocate domain %s at 0x%p(%ldKB)\n",
+ what, vbase, sz >> (10 - 1));
+
+ hcb->hash = vbase;
+ hcb->hash_sz = sz;
+ hcb->cch_buf = (void *)((u64)vbase + hcb->hash_sz);
+ hcb->cch_sz = sz;
+ thash_init(hcb, sz_log2);
+ return 0;
+}
+
+void thash_free(thash_cb_t *hcb)
+{
+ struct page_info *page;
+
+ if (hcb->hash) {
+ page = virt_to_page(hcb->hash);
+ free_domheap_pages(page, hcb->pta.size + 1 - PAGE_SHIFT);
+ hcb->hash = 0;
+ }
+}
diff -r 54c721bb6d45 -r 5b19839d0365 xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h Sun Aug 12 12:13:22 2007 -0600
+++ b/xen/include/asm-ia64/vmmu.h Sun Aug 12 12:19:13 2007 -0600
@@ -24,12 +24,8 @@
#define XEN_TLBthash_H

#define MAX_CCN_DEPTH (15) // collision chain depth
-#define VCPU_VTLB_SHIFT (20) // 1M for VTLB
-#define VCPU_VTLB_SIZE (1UL<<VCPU_VTLB_SHIFT)
-#define VCPU_VTLB_ORDER (VCPU_VTLB_SHIFT - PAGE_SHIFT)
-#define VCPU_VHPT_SHIFT (24) // 16M for VTLB
-#define VCPU_VHPT_SIZE (1UL<<VCPU_VHPT_SHIFT)
-#define VCPU_VHPT_ORDER (VCPU_VHPT_SHIFT - PAGE_SHIFT)
+#define DEFAULT_VTLB_SZ (19) // 512K hash + 512K c-chain for VTLB
+#define DEFAULT_VHPT_SZ (23) // 8M hash + 8M c-chain for VHPT
#define VTLB(v,_x) (v->arch.vtlb._x)
#define VHPT(v,_x) (v->arch.vhpt._x)
#define _PAGE_PL_PRIV (CONFIG_CPL0_EMUL << 7)
@@ -207,9 +203,11 @@ typedef struct thash_cb {
} thash_cb_t;

/*
- * Initialize internal control data before service.
- */
-extern void thash_init(thash_cb_t *hcb, u64 sz);
+ * Allocate and initialize internal control data before service.
+ */
+extern int thash_alloc(thash_cb_t *hcb, u64 sz, char *what);
+
+extern void thash_free(thash_cb_t *hcb);

/*
* Insert an entry to hash table.

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog