ia64/xen-unstable

changeset 15696:5b19839d0365

[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>
author Alex Williamson <alex.williamson@hp.com>
date Sun Aug 12 12:19:13 2007 -0600 (2007-08-12)
parents 54c721bb6d45
children cd51fa91956b
files xen/arch/ia64/vmx/vmmu.c xen/arch/ia64/vmx/vmx_entry.S xen/arch/ia64/vmx/vtlb.c xen/include/asm-ia64/vmmu.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/vmmu.c	Sun Aug 12 12:13:22 2007 -0600
     1.2 +++ b/xen/arch/ia64/vmx/vmmu.c	Sun Aug 12 12:19:13 2007 -0600
     1.3 @@ -19,23 +19,48 @@
     1.4   *  Xuefei Xu (Anthony Xu) (Anthony.xu@intel.com)
     1.5   *  Yaozu Dong (Eddie Dong) (Eddie.dong@intel.com)
     1.6   */
     1.7 -#include <linux/sched.h>
     1.8 -#include <linux/mm.h>
     1.9 -#include <asm/tlb.h>
    1.10 -#include <asm/gcc_intrin.h>
    1.11 -#include <asm/vcpu.h>
    1.12 -#include <linux/interrupt.h>
    1.13  #include <asm/vmx_vcpu.h>
    1.14 -#include <asm/vmx_mm_def.h>
    1.15 -#include <asm/vmx.h>
    1.16 -#include <asm/hw_irq.h>
    1.17  #include <asm/vmx_pal_vsa.h>
    1.18 -#include <asm/kregs.h>
    1.19 -#include <asm/vcpu.h>
    1.20 -#include <xen/irq.h>
    1.21 -#include <xen/errno.h>
    1.22  #include <xen/sched-if.h>
    1.23  
    1.24 +static int default_vtlb_sz = DEFAULT_VTLB_SZ;
    1.25 +static int default_vhpt_sz = DEFAULT_VHPT_SZ;
    1.26 +
    1.27 +static void __init parse_vtlb_size(char *s)
    1.28 +{
    1.29 +    int sz = parse_size_and_unit(s, NULL);
    1.30 +
    1.31 +    if (sz > 0) {
    1.32 +        default_vtlb_sz = fls(sz - 1);
    1.33 +        /* minimum 256KB (since calculated tag might be broken) */
    1.34 +        if (default_vtlb_sz < 18)
    1.35 +            default_vtlb_sz = 18;
    1.36 +    }
    1.37 +}
    1.38 +
    1.39 +static int canonicalize_vhpt_size(int sz)
    1.40 +{
    1.41 +    /* minimum 32KB */
    1.42 +    if (sz < 15)
    1.43 +        return 15;
    1.44 +    /* maximum 8MB (since purging TR is hard coded) */
    1.45 +    if (sz > IA64_GRANULE_SHIFT - 1)
    1.46 +        return IA64_GRANULE_SHIFT - 1;
    1.47 +    return sz;
    1.48 +}
    1.49 +
    1.50 +static void __init parse_vhpt_size(char *s)
    1.51 +{
    1.52 +    int sz = parse_size_and_unit(s, NULL);
    1.53 +    if (sz > 0) {
    1.54 +        default_vhpt_sz = fls(sz - 1);
    1.55 +        default_vhpt_sz = canonicalize_vhpt_size(default_vhpt_sz);
    1.56 +    }
    1.57 +}
    1.58 +
    1.59 +custom_param("vti_vtlb_size", parse_vtlb_size);
    1.60 +custom_param("vti_vhpt_size", parse_vhpt_size);
    1.61 +
    1.62  /*
    1.63   * Get the machine page frame number in 16KB unit
    1.64   * Input:
    1.65 @@ -132,66 +157,33 @@ purge_machine_tc_by_domid(domid_t domid)
    1.66  
    1.67  static int init_domain_vhpt(struct vcpu *v)
    1.68  {
    1.69 -    struct page_info *page;
    1.70 -    void * vbase;
    1.71 -    page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0);
    1.72 -    if ( page == NULL ) {
    1.73 -        printk("No enough contiguous memory for init_domain_vhpt\n");
    1.74 -        return -ENOMEM;
    1.75 -    }
    1.76 -    vbase = page_to_virt(page);
    1.77 -    memset(vbase, 0, VCPU_VHPT_SIZE);
    1.78 -    printk(XENLOG_DEBUG "Allocate domain vhpt at 0x%p\n", vbase);
    1.79 -    
    1.80 -    VHPT(v,hash) = vbase;
    1.81 -    VHPT(v,hash_sz) = VCPU_VHPT_SIZE/2;
    1.82 -    VHPT(v,cch_buf) = (void *)((u64)vbase + VHPT(v,hash_sz));
    1.83 -    VHPT(v,cch_sz) = VCPU_VHPT_SIZE - VHPT(v,hash_sz);
    1.84 -    thash_init(&(v->arch.vhpt),VCPU_VHPT_SHIFT-1);
    1.85 +    int rc;
    1.86 +
    1.87 +    rc = thash_alloc(&(v->arch.vhpt), default_vhpt_sz, "vhpt");
    1.88      v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val;
    1.89 -
    1.90 -    return 0;
    1.91 +    return rc;
    1.92  }
    1.93  
    1.94  
    1.95  static void free_domain_vhpt(struct vcpu *v)
    1.96  {
    1.97 -    struct page_info *page;
    1.98 -
    1.99 -    if (v->arch.vhpt.hash) {
   1.100 -        page = virt_to_page(v->arch.vhpt.hash);
   1.101 -        free_domheap_pages(page, VCPU_VHPT_ORDER);
   1.102 -        v->arch.vhpt.hash = 0;
   1.103 -    }
   1.104 -
   1.105 -    return;
   1.106 +    if (v->arch.vhpt.hash)
   1.107 +        thash_free(&(v->arch.vhpt));
   1.108  }
   1.109  
   1.110  int init_domain_tlb(struct vcpu *v)
   1.111  {
   1.112 -    struct page_info *page;
   1.113 -    void * vbase;
   1.114      int rc;
   1.115  
   1.116      rc = init_domain_vhpt(v);
   1.117      if (rc)
   1.118          return rc;
   1.119  
   1.120 -    page = alloc_domheap_pages (NULL, VCPU_VTLB_ORDER, 0);
   1.121 -    if ( page == NULL ) {
   1.122 -        printk("No enough contiguous memory for init_domain_tlb\n");
   1.123 +    rc = thash_alloc(&(v->arch.vtlb), default_vtlb_sz, "vtlb");
   1.124 +    if (rc) {
   1.125          free_domain_vhpt(v);
   1.126 -        return -ENOMEM;
   1.127 +        return rc;
   1.128      }
   1.129 -    vbase = page_to_virt(page);
   1.130 -    memset(vbase, 0, VCPU_VTLB_SIZE);
   1.131 -    printk(XENLOG_DEBUG "Allocate domain vtlb at 0x%p\n", vbase);
   1.132 -    
   1.133 -    VTLB(v,hash) = vbase;
   1.134 -    VTLB(v,hash_sz) = VCPU_VTLB_SIZE/2;
   1.135 -    VTLB(v,cch_buf) = (void *)((u64)vbase + VTLB(v,hash_sz));
   1.136 -    VTLB(v,cch_sz) = VCPU_VTLB_SIZE - VTLB(v,hash_sz);
   1.137 -    thash_init(&(v->arch.vtlb),VCPU_VTLB_SHIFT-1);
   1.138      
   1.139      return 0;
   1.140  }
   1.141 @@ -199,12 +191,8 @@ int init_domain_tlb(struct vcpu *v)
   1.142  
   1.143  void free_domain_tlb(struct vcpu *v)
   1.144  {
   1.145 -    struct page_info *page;
   1.146 -
   1.147 -    if ( v->arch.vtlb.hash) {
   1.148 -        page = virt_to_page(v->arch.vtlb.hash);
   1.149 -        free_domheap_pages(page, VCPU_VTLB_ORDER);
   1.150 -    }
   1.151 +    if (v->arch.vtlb.hash)
   1.152 +        thash_free(&(v->arch.vtlb));
   1.153  
   1.154      free_domain_vhpt(v);
   1.155  }
     2.1 --- a/xen/arch/ia64/vmx/vmx_entry.S	Sun Aug 12 12:13:22 2007 -0600
     2.2 +++ b/xen/arch/ia64/vmx/vmx_entry.S	Sun Aug 12 12:19:13 2007 -0600
     2.3 @@ -20,21 +20,9 @@
     2.4   *  Kun Tian (Kevin Tian) (kevin.tian@intel.com)
     2.5   */
     2.6  
     2.7 -#ifndef VCPU_TLB_SHIFT
     2.8 -#define VCPU_TLB_SHIFT	22
     2.9 -#endif
    2.10  #include <linux/config.h>
    2.11  #include <asm/asmmacro.h>
    2.12 -#include <asm/cache.h>
    2.13 -#include <asm/kregs.h>
    2.14  #include <asm/offsets.h>
    2.15 -#include <asm/pgtable.h>
    2.16 -#include <asm/percpu.h>
    2.17 -#include <asm/processor.h>
    2.18 -#include <asm/thread_info.h>
    2.19 -#include <asm/unistd.h>
    2.20 -#include <asm/vhpt.h>
    2.21 -#include <asm/vmmu.h>
    2.22  #include "vmx_minstate.h"
    2.23  
    2.24  GLOBAL_ENTRY(ia64_leave_nested)
    2.25 @@ -719,7 +707,7 @@ 1:
    2.26     movl r25=PAGE_KERNEL
    2.27     ;;
    2.28     or loc5 = r25,loc5          // construct PA | page properties
    2.29 -   mov r23 = VCPU_VHPT_SHIFT <<2
    2.30 +   mov r23 = IA64_GRANULE_SHIFT <<2
    2.31     ;;
    2.32     ptr.d   in3,r23
    2.33     ;;
     3.1 --- a/xen/arch/ia64/vmx/vtlb.c	Sun Aug 12 12:13:22 2007 -0600
     3.2 +++ b/xen/arch/ia64/vmx/vtlb.c	Sun Aug 12 12:19:13 2007 -0600
     3.3 @@ -21,18 +21,7 @@
     3.4   *  XiaoYan Feng (Fleming Feng) (Fleming.feng@intel.com)
     3.5   */
     3.6  
     3.7 -#include <linux/sched.h>
     3.8 -#include <asm/tlb.h>
     3.9 -#include <xen/mm.h>
    3.10 -#include <asm/vmx_mm_def.h>
    3.11 -#include <asm/gcc_intrin.h>
    3.12 -#include <linux/interrupt.h>
    3.13  #include <asm/vmx_vcpu.h>
    3.14 -#include <asm/vmx_phy_mode.h>
    3.15 -#include <asm/vmmu.h>
    3.16 -#include <asm/tlbflush.h>
    3.17 -#include <asm/regionreg.h>
    3.18 -#define  MAX_CCH_LENGTH     40
    3.19  
    3.20  thash_data_t *__alloc_chain(thash_cb_t *);
    3.21  
    3.22 @@ -664,7 +653,7 @@ thash_data_t *vtlb_lookup(VCPU *v, u64 v
    3.23  /*
    3.24   * Initialize internal control data before service.
    3.25   */
    3.26 -void thash_init(thash_cb_t *hcb, u64 sz)
    3.27 +static void thash_init(thash_cb_t *hcb, u64 sz)
    3.28  {
    3.29      int num;
    3.30      thash_data_t *head;
    3.31 @@ -688,3 +677,43 @@ void thash_init(thash_cb_t *hcb, u64 sz)
    3.32      hcb->cch_free_idx = 0;
    3.33      hcb->cch_freelist = NULL;
    3.34  }
    3.35 +
    3.36 +int thash_alloc(thash_cb_t *hcb, u64 sz_log2, char *what)
    3.37 +{
    3.38 +    struct page_info *page;
    3.39 +    void * vbase;
    3.40 +    u64 sz = 1UL << sz_log2;
    3.41 +
    3.42 +    page = alloc_domheap_pages(NULL, (sz_log2 + 1 - PAGE_SHIFT), 0);
    3.43 +    if (page == NULL) {
    3.44 +        printk("No enough contiguous memory(%ldKB) for init_domain_%s\n", 
    3.45 +               sz >> (10 - 1), what);
    3.46 +        return -ENOMEM;
    3.47 +    }
    3.48 +    vbase = page_to_virt(page);
    3.49 +    memset(vbase, 0, sz + sz); // hash + collisions chain
    3.50 +    if (sz_log2 >= 20 - 1)
    3.51 +        printk(XENLOG_DEBUG "Allocate domain %s at 0x%p(%ldMB)\n", 
    3.52 +               what, vbase, sz >> (20 - 1));
    3.53 +    else
    3.54 +        printk(XENLOG_DEBUG "Allocate domain %s at 0x%p(%ldKB)\n",
    3.55 +               what, vbase, sz >> (10 - 1));
    3.56 +    
    3.57 +    hcb->hash = vbase;
    3.58 +    hcb->hash_sz = sz;
    3.59 +    hcb->cch_buf = (void *)((u64)vbase + hcb->hash_sz);
    3.60 +    hcb->cch_sz = sz;
    3.61 +    thash_init(hcb, sz_log2);
    3.62 +    return 0;
    3.63 +}
    3.64 +
    3.65 +void thash_free(thash_cb_t *hcb)
    3.66 +{
    3.67 +    struct page_info *page;
    3.68 +
    3.69 +    if (hcb->hash) {
    3.70 +        page = virt_to_page(hcb->hash);
    3.71 +        free_domheap_pages(page, hcb->pta.size + 1 - PAGE_SHIFT);
    3.72 +        hcb->hash = 0;
    3.73 +    }
    3.74 +}
     4.1 --- a/xen/include/asm-ia64/vmmu.h	Sun Aug 12 12:13:22 2007 -0600
     4.2 +++ b/xen/include/asm-ia64/vmmu.h	Sun Aug 12 12:19:13 2007 -0600
     4.3 @@ -24,12 +24,8 @@
     4.4  #define XEN_TLBthash_H
     4.5  
     4.6  #define     MAX_CCN_DEPTH       (15)       // collision chain depth
     4.7 -#define     VCPU_VTLB_SHIFT     (20)    // 1M for VTLB
     4.8 -#define     VCPU_VTLB_SIZE      (1UL<<VCPU_VTLB_SHIFT)
     4.9 -#define     VCPU_VTLB_ORDER     (VCPU_VTLB_SHIFT - PAGE_SHIFT)
    4.10 -#define     VCPU_VHPT_SHIFT     (24)    // 16M for VTLB
    4.11 -#define     VCPU_VHPT_SIZE      (1UL<<VCPU_VHPT_SHIFT)
    4.12 -#define     VCPU_VHPT_ORDER     (VCPU_VHPT_SHIFT - PAGE_SHIFT)
    4.13 +#define     DEFAULT_VTLB_SZ     (19) // 512K hash + 512K c-chain for VTLB
    4.14 +#define     DEFAULT_VHPT_SZ     (23) // 8M hash + 8M c-chain for VHPT
    4.15  #define     VTLB(v,_x)          (v->arch.vtlb._x)
    4.16  #define     VHPT(v,_x)          (v->arch.vhpt._x)
    4.17  #define     _PAGE_PL_PRIV       (CONFIG_CPL0_EMUL << 7)
    4.18 @@ -207,9 +203,11 @@ typedef struct thash_cb {
    4.19  } thash_cb_t;
    4.20  
    4.21  /*
    4.22 - * Initialize internal control data before service.
    4.23 + * Allocate and initialize internal control data before service.
    4.24   */
    4.25 -extern void thash_init(thash_cb_t *hcb, u64 sz);
    4.26 +extern int thash_alloc(thash_cb_t *hcb, u64 sz, char *what);
    4.27 +
    4.28 +extern void thash_free(thash_cb_t *hcb);
    4.29  
    4.30  /*
    4.31   * Insert an entry to hash table.