amd64/178357: [patch] export CPU physical and virtual address sizes in sysctl oids using do_cpuid

John Baldwin jhb at freebsd.org
Mon May 20 20:50:03 UTC 2013


The following reply was made to PR amd64/178357; it has been noted by GNATS.

From: John Baldwin <jhb at freebsd.org>
To: freebsd-amd64 at freebsd.org,
 Sofian Brabez <sbz at freebsd.org>
Cc: FreeBSD-gnats-submit at freebsd.org
Subject: Re: amd64/178357: [patch] export CPU physical and virtual address sizes in sysctl oids using do_cpuid
Date: Mon, 20 May 2013 09:44:17 -0400

 On Sunday, May 05, 2013 6:43:54 pm Sofian Brabez wrote:
 > 
 > >Number:         178357
 > >Category:       amd64
 > >Synopsis:       [patch] export CPU physical and virtual address sizes in 
 sysctl oids using do_cpuid
 > >Confidential:   no
 > >Severity:       non-critical
 > >Priority:       low
 > >Responsible:    freebsd-amd64
 > >State:          open
 > >Quarter:        
 > >Keywords:       
 > >Date-Required:
 > >Class:          change-request
 > >Submitter-Id:   current-users
 > >Arrival-Date:   Sun May 05 22:50:00 UTC 2013
 > >Closed-Date:
 > >Last-Modified:
 > >Originator:     Sofian Brabez
 > >Release:        FreeBSD 10.0-CURRENT amd64
 > >Organization:
 > >Environment:
 > System: FreeBSD ogoshi.lan 10.0-CURRENT FreeBSD 10.0-CURRENT #3 r250287M: 
 Sun May 5 21:59:15 CEST 2013 
 root at ogoshi.lan:/usr/obj/usr/home/sbz/freebsd/svn/src/sys/GENERIC amd64
 > 
 > >Description:
 > This patch export CPU Physical and Virtual address sizes through the sysctl 
 interface
 > using do_cpuid function.
 > 
 > It also patch the sys/modules/linprocfs module add this information in the
 > /usr/compat/linux/proc/cpuinfo output like it's done in Linux /proc/cpuinfo.
 > 
 > More details can be found here: http://people.freebsd.org/~sbz/cpu/
 > >How-To-Repeat:
 > >Fix:
 > 
 > Apply the given patch.
 > 
 > --- address_sizes.diff begins here ---
 > Index: amd64/amd64/identcpu.c
 > ===================================================================
 > --- amd64/amd64/identcpu.c	(revision 250287)
 > +++ amd64/amd64/identcpu.c	(working copy)
 > @@ -109,6 +109,12 @@
 >  SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, 
 >      &hw_clockrate, 0, "CPU instruction clock rate");
 >  
 > +SYSCTL_UINT(_machdep, OID_AUTO, cpu_physical_address_bits, CTLFLAG_RD,
 > +    &cpu_pma_bits, 0, "CPU physical address bits");
 > +
 > +SYSCTL_UINT(_machdep, OID_AUTO, cpu_virtual_address_bits, CTLFLAG_RD,
 > +    &cpu_vma_bits, 0, "CPU virtual address bits");
 > +
 >  static eventhandler_tag tsc_post_tag;
 >  
 >  static char cpu_brand[48];
 > @@ -516,6 +522,16 @@
 >  	cpu_feature = regs[3];
 >  	cpu_feature2 = regs[2];
 >  
 > +	/* Intel CPUID Specification chapter 5.2.7 
 > +	 * eax=0x80000008
 > +	 * */
 > +	do_cpuid(0x80000008, regs);
 > +
 > +	/* upper bits are virtual size */
 > +	cpu_vma_bits = ((regs[0] >> 8) & 0xFF);
 > +	/* lower bits are physical size */
 > +	cpu_pma_bits = (regs[0] & 0xFF);
 > +
 >  	/*
 >  	 * Clear "Limit CPUID Maxval" bit and get the largest standard CPUID
 >  	 * function number again if it is set from BIOS.  It is necessary
 > Index: amd64/amd64/initcpu.c
 > ===================================================================
 > --- amd64/amd64/initcpu.c	(revision 250287)
 > +++ amd64/amd64/initcpu.c	(working copy)
 > @@ -66,10 +66,12 @@
 >  u_int	cpu_high;		/* Highest arg to CPUID */
 >  u_int	cpu_exthigh;		/* Highest arg to extended CPUID */
 >  u_int	cpu_id;			/* Stepping ID */
 > +u_int	cpu_pma_bits;		/* CPU physical address bits */
 >  u_int	cpu_procinfo;		/* HyperThreading Info / Brand Index / CLFUSH 
 */
 >  u_int	cpu_procinfo2;		/* Multicore info */
 >  char	cpu_vendor[20];		/* CPU Origin code */
 >  u_int	cpu_vendor_id;		/* CPU vendor ID */
 > +u_int	cpu_vma_bits;		/* CPU virtual address bits */
 >  u_int	cpu_fxsr;		/* SSE enabled */
 >  u_int	cpu_mxcsr_mask;		/* Valid bits in mxcsr */
 >  u_int	cpu_clflush_line_size = 32;
 > Index: amd64/include/md_var.h
 > ===================================================================
 > --- amd64/include/md_var.h	(revision 250287)
 > +++ amd64/include/md_var.h	(working copy)
 > @@ -54,10 +54,12 @@
 >  extern	u_int	cpu_id;
 >  extern	u_int	cpu_max_ext_state_size;
 >  extern	u_int	cpu_mxcsr_mask;
 > +extern u_int	cpu_pma_bits;
 >  extern	u_int	cpu_procinfo;
 >  extern	u_int	cpu_procinfo2;
 >  extern	char	cpu_vendor[];
 >  extern	u_int	cpu_vendor_id;
 > +extern u_int	cpu_vma_bits;
 >  extern	char	ctx_switch_xsave[];
 >  extern	char	kstack[];
 >  extern	char	sigcode[];
 > Index: compat/linprocfs/linprocfs.c
 > ===================================================================
 > --- compat/linprocfs/linprocfs.c	(revision 250287)
 > +++ compat/linprocfs/linprocfs.c	(working copy)
 > @@ -310,6 +310,12 @@
 >  		    fqmhz, fqkhz, fqmhz, fqkhz);
 >  	}
 >  
 > +	if (cpu_vma_bits != 0 && cpu_vma_bits != 0) {
 
 I think you want s/vma/pma/ here for the first check.
 
 > +		sbuf_printf(sb,
 > +		    "address sizes\t: %u bits physical, %u bits virtual\n",
 > +		    cpu_pma_bits, cpu_vma_bits);
 > +	}
 > +
 >  	return (0);
 >  }
 >  #endif /* __i386__ || __amd64__ */
 
 I don't know that we need to create new sysctls for this since userland 
 processes can just run cpuid directly.  I would be fine adding this to 
 linprocfs however.
 
 I think if we want to start exporting cpuid info via sysctl we should think 
 about designing a consistent interface for doing so rather than adding ad-hoc 
 sysctls for certain fields.
 
 -- 
 John Baldwin


More information about the freebsd-amd64 mailing list