patches for easier mirroring, to eliminate a special copy, to make www.freebsd.org/security a full copy of security.freebsd.org and be eventually be the same. For now files are just sitting there. The symlinks are missing. Discussed on: www (repository location) Discussed with: simon (so)
		
			
				
	
	
		
			184 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			184 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| Index: sys/i386/i386/mp_machdep.c
 | |
| ===================================================================
 | |
| RCS file: /home/ncvs/src/sys/i386/i386/mp_machdep.c,v
 | |
| retrieving revision 1.115.2.20
 | |
| diff -u -p -r1.115.2.20 mp_machdep.c
 | |
| --- sys/i386/i386/mp_machdep.c	16 Dec 2003 16:32:28 -0000	1.115.2.20
 | |
| +++ sys/i386/i386/mp_machdep.c	12 May 2005 19:02:40 -0000
 | |
| @@ -342,6 +342,9 @@ static int	apic_int_is_bus_type(int intr
 | |
|  
 | |
|  static int	hlt_cpus_mask;
 | |
|  static int	hlt_logical_cpus = 1;
 | |
| +static u_int	hyperthreading_cpus;
 | |
| +static u_int	hyperthreading_cpus_mask;
 | |
| +static int	hyperthreading_allowed;
 | |
|  static struct	sysctl_ctx_list logical_cpu_clist;
 | |
|  
 | |
|  /*
 | |
| @@ -982,6 +985,9 @@ mptable_pass2(void)
 | |
|  					proc.apic_id++;
 | |
|  					(void)processor_entry(&proc, cpu);
 | |
|  					logical_cpus_mask |= (1 << cpu);
 | |
| +					if (hyperthreading_cpus > 1 &&
 | |
| +					    proc.apic_id % hyperthreading_cpus != 0)
 | |
| +						hyperthreading_cpus_mask |= (1 << cpu);
 | |
|  					cpu++;
 | |
|  				}
 | |
|  			}
 | |
| @@ -1033,6 +1039,7 @@ static void
 | |
|  mptable_hyperthread_fixup(u_int id_mask)
 | |
|  {
 | |
|  	u_int i, id;
 | |
| +	u_int threads_per_cache, p[4];
 | |
|  
 | |
|  	/* Nothing to do if there is no HTT support. */
 | |
|  	if ((cpu_feature & CPUID_HTT) == 0)
 | |
| @@ -1042,6 +1049,48 @@ mptable_hyperthread_fixup(u_int id_mask)
 | |
|  		return;
 | |
|  
 | |
|  	/*
 | |
| +	 * Work out if hyperthreading is *really* enabled.  This
 | |
| +	 * is made really ugly by the fact that processors lie: Dual
 | |
| +	 * core processors claim to be hyperthreaded even when they're
 | |
| +	 * not, presumably because they want to be treated the same
 | |
| +	 * way as HTT with respect to per-cpu software licensing.
 | |
| +	 * At the time of writing (May 12, 2005) the only hyperthreaded
 | |
| +	 * cpus are from Intel, and Intel's dual-core processors can be
 | |
| +	 * identified via the "deterministic cache parameters" cpuid
 | |
| +	 * calls.
 | |
| +	 */
 | |
| +	/*
 | |
| +	 * First determine if this is an Intel processor which claims
 | |
| +	 * to have hyperthreading support.
 | |
| +	 */
 | |
| +	if ((cpu_feature & CPUID_HTT) &&
 | |
| +	    (strcmp(cpu_vendor, "GenuineIntel") == 0)) {
 | |
| +		/*
 | |
| +		 * If the "deterministic cache parameters" cpuid calls
 | |
| +		 * are available, use them.
 | |
| +		 */
 | |
| +		if (cpu_high >= 4) {
 | |
| +			/* Ask the processor about up to 32 caches. */
 | |
| +			for (i = 0; i < 32; i++) {
 | |
| +				cpuid_count(4, i, p);
 | |
| +				threads_per_cache = ((p[0] & 0x3ffc000) >> 14) + 1;
 | |
| +				if (hyperthreading_cpus < threads_per_cache)
 | |
| +					hyperthreading_cpus = threads_per_cache;
 | |
| +				if ((p[0] & 0x1f) == 0)
 | |
| +					break;
 | |
| +			}
 | |
| +		}
 | |
| +
 | |
| +		/*
 | |
| +		 * If the deterministic cache parameters are not
 | |
| +		 * available, or if no caches were reported to exist,
 | |
| +		 * just accept what the HTT flag indicated.
 | |
| +		 */
 | |
| +		if (hyperthreading_cpus == 0)
 | |
| +			hyperthreading_cpus = logical_cpus;
 | |
| +	}
 | |
| +
 | |
| +	/*
 | |
|  	 * For each APIC ID of a CPU that is set in the mask,
 | |
|  	 * scan the other candidate APIC ID's for this
 | |
|  	 * physical processor.  If any of those ID's are
 | |
| @@ -3035,6 +3084,9 @@ sysctl_htl_cpus(SYSCTL_HANDLER_ARGS)
 | |
|  	else
 | |
|  		hlt_logical_cpus = 0;
 | |
|  
 | |
| +	if (! hyperthreading_allowed)
 | |
| +		mask |= hyperthreading_cpus_mask;
 | |
| +
 | |
|  	if ((mask & all_cpus) == all_cpus)
 | |
|  		mask &= ~(1<<0);
 | |
|  	hlt_cpus_mask = mask;
 | |
| @@ -3058,6 +3110,9 @@ sysctl_hlt_logical_cpus(SYSCTL_HANDLER_A
 | |
|  	else
 | |
|  		hlt_cpus_mask &= ~logical_cpus_mask;
 | |
|  
 | |
| +	if (! hyperthreading_allowed)
 | |
| +		hlt_cpus_mask |= hyperthreading_cpus_mask;
 | |
| +
 | |
|  	if ((hlt_cpus_mask & all_cpus) == all_cpus)
 | |
|  		hlt_cpus_mask &= ~(1<<0);
 | |
|  
 | |
| @@ -3065,6 +3120,34 @@ sysctl_hlt_logical_cpus(SYSCTL_HANDLER_A
 | |
|  	return (error);
 | |
|  }
 | |
|  
 | |
| +static int
 | |
| +sysctl_hyperthreading_allowed(SYSCTL_HANDLER_ARGS)
 | |
| +{
 | |
| +	int allowed, error;
 | |
| +
 | |
| +	allowed = hyperthreading_allowed;
 | |
| +	error = sysctl_handle_int(oidp, &allowed, 0, req);
 | |
| +	if (error || !req->newptr)
 | |
| +		return (error);
 | |
| +
 | |
| +	if (allowed)
 | |
| +		hlt_cpus_mask &= ~hyperthreading_cpus_mask;
 | |
| +	else
 | |
| +		hlt_cpus_mask |= hyperthreading_cpus_mask;
 | |
| +
 | |
| +	if (logical_cpus_mask != 0 &&
 | |
| +	    (hlt_cpus_mask & logical_cpus_mask) == logical_cpus_mask)
 | |
| +		hlt_logical_cpus = 1;
 | |
| +	else
 | |
| +		hlt_logical_cpus = 0;
 | |
| +
 | |
| +	if ((hlt_cpus_mask & all_cpus) == all_cpus)
 | |
| +		hlt_cpus_mask &= ~(1<<0);
 | |
| +
 | |
| +	hyperthreading_allowed = allowed;
 | |
| +	return (error);
 | |
| +}
 | |
| +
 | |
|  static void
 | |
|  cpu_hlt_setup(void *dummy __unused)
 | |
|  {
 | |
| @@ -3084,6 +3167,22 @@ cpu_hlt_setup(void *dummy __unused)
 | |
|  
 | |
|  		if (hlt_logical_cpus)
 | |
|  			hlt_cpus_mask |= logical_cpus_mask;
 | |
| +
 | |
| +		/*
 | |
| +		 * If necessary for security purposes, force
 | |
| +		 * hyperthreading off, regardless of the value
 | |
| +		 * of hlt_logical_cpus.
 | |
| +		 */
 | |
| +		if (hyperthreading_cpus_mask) {
 | |
| +			TUNABLE_INT_FETCH("machdep.hyperthreading_allowed",
 | |
| +			    &hyperthreading_allowed);
 | |
| +			SYSCTL_ADD_PROC(&logical_cpu_clist,
 | |
| +			    SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO,
 | |
| +			    "hyperthreading_allowed", CTLTYPE_INT|CTLFLAG_RW,
 | |
| +			    0, 0, sysctl_hyperthreading_allowed, "IU", "");
 | |
| +			if (! hyperthreading_allowed)
 | |
| +				hlt_cpus_mask |= hyperthreading_cpus_mask;
 | |
| +		}
 | |
|  	}
 | |
|  }
 | |
|  SYSINIT(cpu_hlt, SI_SUB_SMP, SI_ORDER_ANY, cpu_hlt_setup, NULL);
 | |
| Index: sys/i386/include/cpufunc.h
 | |
| ===================================================================
 | |
| RCS file: /home/ncvs/src/sys/i386/include/cpufunc.h,v
 | |
| retrieving revision 1.96.2.3
 | |
| diff -u -p -r1.96.2.3 cpufunc.h
 | |
| --- sys/i386/include/cpufunc.h	28 Apr 2002 22:50:54 -0000	1.96.2.3
 | |
| +++ sys/i386/include/cpufunc.h	12 May 2005 19:02:40 -0000
 | |
| @@ -103,6 +103,14 @@ do_cpuid(u_int ax, u_int *p)
 | |
|  }
 | |
|  
 | |
|  static __inline void
 | |
| +cpuid_count(u_int ax, u_int cx, u_int *p)
 | |
| +{
 | |
| +	__asm __volatile("cpuid"
 | |
| +			 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
 | |
| +			 :  "0" (ax), "c" (cx));
 | |
| +}
 | |
| +
 | |
| +static __inline void
 | |
|  enable_intr(void)
 | |
|  {
 | |
|  #ifdef SMP
 |