direct-io.hg

changeset 6146:719841477514

This patch fixes the booting problems on machines with >4GB memory, and
is applicable to both x86_64 and x86 PAE.

Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Aug 14 09:06:32 2005 +0000 (2005-08-14)
parents dc27fd3392b1
children e03ffa8839ab
files xen/arch/x86/mm.c
line diff
     1.1 --- a/xen/arch/x86/mm.c	Sun Aug 14 08:09:06 2005 +0000
     1.2 +++ b/xen/arch/x86/mm.c	Sun Aug 14 09:06:32 2005 +0000
     1.3 @@ -736,7 +736,7 @@ static int create_pae_xen_mappings(l3_pg
     1.4          pl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i] =
     1.5              (l3e_get_flags(pl3e[i]) & _PAGE_PRESENT) ?
     1.6              l2e_from_pfn(l3e_get_pfn(pl3e[i]), __PAGE_HYPERVISOR) :
     1.7 -            l2e_empty();
     1.8 +        l2e_empty();
     1.9      unmap_domain_page(pl2e);
    1.10  
    1.11      return 1;
    1.12 @@ -764,7 +764,7 @@ static inline int l1_backptr(
    1.13      unsigned long l2_backptr = l2_type & PGT_va_mask;
    1.14      BUG_ON(l2_backptr == PGT_va_unknown);
    1.15  
    1.16 -     *backptr = ((l2_backptr >> PGT_va_shift) << L3_PAGETABLE_SHIFT) | 
    1.17 +    *backptr = ((l2_backptr >> PGT_va_shift) << L3_PAGETABLE_SHIFT) | 
    1.18          (offset_in_l2 << L2_PAGETABLE_SHIFT);
    1.19      return 1;
    1.20  }
    1.21 @@ -872,7 +872,7 @@ static int alloc_l3_table(struct pfn_inf
    1.22          if ( !l2_backptr(&vaddr, i, type) )
    1.23              goto fail;
    1.24  #else
    1.25 -      vaddr = (unsigned long)i << L3_PAGETABLE_SHIFT;
    1.26 +        vaddr = (unsigned long)i << L3_PAGETABLE_SHIFT;
    1.27  #endif
    1.28          if ( is_guest_l3_slot(i) &&
    1.29               unlikely(!get_page_from_l3e(pl3e[i], pfn, d, vaddr)) )
    1.30 @@ -1246,7 +1246,7 @@ static int mod_l4_entry(l4_pgentry_t *pl
    1.31          if (!l4e_has_changed(ol4e, nl4e, _PAGE_PRESENT))
    1.32              return UPDATE_ENTRY(l4, pl4e, ol4e, nl4e);
    1.33  
    1.34 -         if ( unlikely(!l3_backptr(&vaddr, pgentry_ptr_to_slot(pl4e), type)) ||
    1.35 +        if ( unlikely(!l3_backptr(&vaddr, pgentry_ptr_to_slot(pl4e), type)) ||
    1.36               unlikely(!get_page_from_l4e(nl4e, pfn, current->domain, vaddr)) )
    1.37              return 0;
    1.38  
    1.39 @@ -2270,9 +2270,9 @@ int do_mmu_update(
    1.40  
    1.41  
    1.42  int update_grant_va_mapping_pte(unsigned long pte_addr,
    1.43 -                            l1_pgentry_t _nl1e, 
    1.44 -                            struct domain *d,
    1.45 -                            struct vcpu *v)
    1.46 +                                l1_pgentry_t _nl1e, 
    1.47 +                                struct domain *d,
    1.48 +                                struct vcpu *v)
    1.49  {
    1.50      /* Caller must:
    1.51       * . own d's BIGLOCK 
    1.52 @@ -2872,59 +2872,53 @@ ptwr_eip_stat_t ptwr_eip_stats[ptwr_eip_
    1.53  static inline unsigned int ptwr_eip_stat_hash( unsigned long eip, domid_t id )
    1.54  {
    1.55      return (((unsigned long) id) ^ eip ^ (eip>>8) ^ (eip>>16) ^ (eip>24)) % 
    1.56 -	ptwr_eip_buckets;
    1.57 +        ptwr_eip_buckets;
    1.58  }
    1.59  
    1.60  static void ptwr_eip_stat_inc(u32 *n)
    1.61  {
    1.62 -    (*n)++;
    1.63 -    if(*n == 0)
    1.64 -    {
    1.65 -	(*n)=~0;
    1.66 -	/* rescale all buckets */
    1.67 -	int i;
    1.68 -	for(i=0;i<ptwr_eip_buckets;i++)
    1.69 -	{
    1.70 -	    int j;
    1.71 -	    for(j=0;j<ptwr_eip_stat_thresholdN;j++)
    1.72 -		ptwr_eip_stats[i].val[j] = 
    1.73 -		    (((u64)ptwr_eip_stats[i].val[j])+1)>>1;
    1.74 -	}
    1.75 -    }
    1.76 +    int i, j;
    1.77 +
    1.78 +    if ( ++(*n) != 0 )
    1.79 +        return;
    1.80 +
    1.81 +    *n = ~0;
    1.82 +
    1.83 +    /* Re-scale all buckets. */
    1.84 +    for ( i = 0; i <ptwr_eip_buckets; i++ )
    1.85 +        for ( j = 0; j < ptwr_eip_stat_thresholdN; j++ )
    1.86 +            ptwr_eip_stats[i].val[j] >>= 1;
    1.87  }
    1.88  
    1.89 -static void ptwr_eip_stat_update( unsigned long eip, domid_t id, int modified )
    1.90 +static void ptwr_eip_stat_update(unsigned long eip, domid_t id, int modified)
    1.91  {
    1.92 -    int i, b;
    1.93 -
    1.94 -    i = b = ptwr_eip_stat_hash( eip, id );
    1.95 +    int i, j, b;
    1.96 +
    1.97 +    i = b = ptwr_eip_stat_hash(eip, id);
    1.98  
    1.99      do
   1.100      {
   1.101 -	if (!ptwr_eip_stats[i].eip)
   1.102 -	{ /* doesn't exist */
   1.103 -	    ptwr_eip_stats[i].eip = eip;
   1.104 -	    ptwr_eip_stats[i].id = id;
   1.105 -	    memset(ptwr_eip_stats[i].val,0, sizeof(ptwr_eip_stats[i].val));
   1.106 -	}
   1.107 -
   1.108 -	if (ptwr_eip_stats[i].eip == eip)
   1.109 -	{
   1.110 -	    int j;
   1.111 -	    for(j=0;j<ptwr_eip_stat_thresholdN;j++)
   1.112 -	    {
   1.113 -		if(modified <= ptwr_eip_stat_threshold[j])
   1.114 -		{
   1.115 -		    break;
   1.116 -		}
   1.117 -	    }
   1.118 -	    BUG_ON(j>=ptwr_eip_stat_thresholdN);
   1.119 -	    ptwr_eip_stat_inc(&(ptwr_eip_stats[i].val[j]));    
   1.120 -	    return;
   1.121 -	}
   1.122 -	i = (i+1) % ptwr_eip_buckets;
   1.123 +        if ( !ptwr_eip_stats[i].eip )
   1.124 +        {
   1.125 +            /* doesn't exist */
   1.126 +            ptwr_eip_stats[i].eip = eip;
   1.127 +            ptwr_eip_stats[i].id = id;
   1.128 +            memset(ptwr_eip_stats[i].val,0, sizeof(ptwr_eip_stats[i].val));
   1.129 +        }
   1.130 +
   1.131 +        if ( ptwr_eip_stats[i].eip == eip )
   1.132 +        {
   1.133 +            for ( j = 0; j < ptwr_eip_stat_thresholdN; j++ )
   1.134 +                if ( modified <= ptwr_eip_stat_threshold[j] )
   1.135 +                    break;
   1.136 +            BUG_ON(j >= ptwr_eip_stat_thresholdN);
   1.137 +            ptwr_eip_stat_inc(&ptwr_eip_stats[i].val[j]);
   1.138 +            return;
   1.139 +        }
   1.140 +
   1.141 +        i = (i+1) % ptwr_eip_buckets;
   1.142      }
   1.143 -    while(i!=b);
   1.144 +    while ( i != b );
   1.145     
   1.146      printk("ptwr_eip_stat: too many EIPs in use!\n");
   1.147      
   1.148 @@ -2932,42 +2926,41 @@ static void ptwr_eip_stat_update( unsign
   1.149      ptwr_eip_stat_reset();
   1.150  }
   1.151  
   1.152 -void ptwr_eip_stat_reset()
   1.153 +void ptwr_eip_stat_reset(void)
   1.154  {
   1.155 -    memset( ptwr_eip_stats, 0, sizeof(ptwr_eip_stats));
   1.156 +    memset(ptwr_eip_stats, 0, sizeof(ptwr_eip_stats));
   1.157  }
   1.158  
   1.159 -void ptwr_eip_stat_print()
   1.160 +void ptwr_eip_stat_print(void)
   1.161  {
   1.162      struct domain *e;
   1.163      domid_t d;
   1.164 -
   1.165 -    for_each_domain(e)
   1.166 +    int i, j;
   1.167 +
   1.168 +    for_each_domain( e )
   1.169      {
   1.170 -	int i;
   1.171 -	d = e->domain_id;
   1.172 -
   1.173 -	for(i=0;i<ptwr_eip_buckets;i++)
   1.174 -	{
   1.175 -	    if ( ptwr_eip_stats[i].eip && ptwr_eip_stats[i].id == d )
   1.176 -	    {
   1.177 -		int j;
   1.178 -		printk("D %d  eip %08lx ",
   1.179 -		       ptwr_eip_stats[i].id, ptwr_eip_stats[i].eip );
   1.180 -
   1.181 -		for(j=0;j<ptwr_eip_stat_thresholdN;j++)
   1.182 -		    printk("<=%u %4u \t",
   1.183 -			   ptwr_eip_stat_threshold[j],
   1.184 -			   ptwr_eip_stats[i].val[j] );
   1.185 -		printk("\n");
   1.186 -	    }	
   1.187 -	}
   1.188 +        d = e->domain_id;
   1.189 +
   1.190 +        for ( i = 0; i < ptwr_eip_buckets; i++ )
   1.191 +        {
   1.192 +            if ( ptwr_eip_stats[i].eip && ptwr_eip_stats[i].id != d )
   1.193 +                continue;
   1.194 +
   1.195 +            printk("D %d  eip %08lx ",
   1.196 +                   ptwr_eip_stats[i].id, ptwr_eip_stats[i].eip);
   1.197 +
   1.198 +            for ( j = 0; j < ptwr_eip_stat_thresholdN; j++ )
   1.199 +                printk("<=%u %4u \t",
   1.200 +                       ptwr_eip_stat_threshold[j],
   1.201 +                       ptwr_eip_stats[i].val[j]);
   1.202 +            printk("\n");
   1.203 +        }
   1.204      }
   1.205  }
   1.206  
   1.207  #else /* PERF_ARRAYS */
   1.208  
   1.209 -#define ptwr_eip_stat_update( eip, id, modified ) ((void)0)
   1.210 +#define ptwr_eip_stat_update(eip, id, modified) ((void)0)
   1.211  
   1.212  #endif
   1.213  
   1.214 @@ -3025,8 +3018,8 @@ int revalidate_l1(
   1.215  /* Flush the given writable p.t. page and write-protect it again. */
   1.216  void ptwr_flush(struct domain *d, const int which)
   1.217  {
   1.218 -    unsigned long  pte, *ptep, l1va;
   1.219 -    l1_pgentry_t  *pl1e;
   1.220 +    unsigned long l1va;
   1.221 +    l1_pgentry_t  *pl1e, pte, *ptep;
   1.222      l2_pgentry_t  *pl2e;
   1.223      unsigned int   modified;
   1.224  
   1.225 @@ -3046,13 +3039,13 @@ void ptwr_flush(struct domain *d, const 
   1.226          TOGGLE_MODE();
   1.227  
   1.228      l1va = d->arch.ptwr[which].l1va;
   1.229 -    ptep = (unsigned long *)&linear_pg_table[l1_linear_offset(l1va)];
   1.230 +    ptep = (l1_pgentry_t *)&linear_pg_table[l1_linear_offset(l1va)];
   1.231  
   1.232      /*
   1.233       * STEP 1. Write-protect the p.t. page so no more updates can occur.
   1.234       */
   1.235  
   1.236 -    if ( unlikely(__get_user(pte, ptep)) )
   1.237 +    if ( unlikely(__get_user(pte.l1, &ptep->l1)) )
   1.238      {
   1.239          MEM_LOG("ptwr: Could not read pte at %p", ptep);
   1.240          /*
   1.241 @@ -3062,8 +3055,8 @@ void ptwr_flush(struct domain *d, const 
   1.242          BUG();
   1.243      }
   1.244      PTWR_PRINTK("[%c] disconnected_l1va at %p is %lx\n",
   1.245 -                PTWR_PRINT_WHICH, ptep, pte);
   1.246 -    pte &= ~_PAGE_RW;
   1.247 +                PTWR_PRINT_WHICH, ptep, pte.l1);
   1.248 +    l1e_remove_flags(pte, _PAGE_RW);
   1.249  
   1.250      /* Write-protect the p.t. page in the guest page table. */
   1.251      if ( unlikely(__put_user(pte, ptep)) )
   1.252 @@ -3080,7 +3073,7 @@ void ptwr_flush(struct domain *d, const 
   1.253      /* NB. INVLPG is a serialising instruction: flushes pending updates. */
   1.254      flush_tlb_one_mask(d->cpumask, l1va);
   1.255      PTWR_PRINTK("[%c] disconnected_l1va at %p now %lx\n",
   1.256 -                PTWR_PRINT_WHICH, ptep, pte);
   1.257 +                PTWR_PRINT_WHICH, ptep, pte.l1);
   1.258  
   1.259      /*
   1.260       * STEP 2. Validate any modified PTEs.
   1.261 @@ -3247,7 +3240,7 @@ static struct x86_mem_emulator ptwr_mem_
   1.262  
   1.263  /* Write page fault handler: check if guest is trying to modify a PTE. */
   1.264  int ptwr_do_page_fault(struct domain *d, unsigned long addr, 
   1.265 -		       struct cpu_user_regs *regs)
   1.266 +                       struct cpu_user_regs *regs)
   1.267  {
   1.268      unsigned long    pfn;
   1.269      struct pfn_info *page;