From sbrabez@gmail.com  Sun May  5 22:43:56 2013
Return-Path: <sbrabez@gmail.com>
Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115])
	by hub.freebsd.org (Postfix) with ESMTP id 9AE70F30
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  5 May 2013 22:43:56 +0000 (UTC)
	(envelope-from sbrabez@gmail.com)
Received: from mail-we0-x230.google.com (mail-we0-x230.google.com [IPv6:2a00:1450:400c:c03::230])
	by mx1.freebsd.org (Postfix) with ESMTP id 36D7A99
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  5 May 2013 22:43:56 +0000 (UTC)
Received: by mail-we0-f176.google.com with SMTP id r6so2605963wey.35
        for <FreeBSD-gnats-submit@freebsd.org>; Sun, 05 May 2013 15:43:55 -0700 (PDT)
Received: from localhost ([2a01:e35:2ee4:8db0:a11:96ff:fe8c:77ec])
        by mx.google.com with ESMTPSA id g8sm11606019wiy.4.2013.05.05.15.43.54
        for <FreeBSD-gnats-submit@freebsd.org>
        (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Sun, 05 May 2013 15:43:54 -0700 (PDT)
Message-Id: <5186e0aa.4852b40a.6e3e.43a7@mx.google.com>
Date: Sun, 05 May 2013 15:43:54 -0700 (PDT)
From: Sofian Brabez <sbz@FreeBSD.org>
Sender: Sofian Brabez <sbrabez@gmail.com>
Reply-To: Sofian Brabez <sbz@FreeBSD.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] export CPU physical and virtual address sizes in sysctl oids using do_cpuid
X-Send-Pr-Version: 3.114
X-GNATS-Notify:

>Number:         178357
>Category:       amd64
>Synopsis:       [amd64] [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:  Sun Apr 20 03:04:18 UTC 2014
>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@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) {
+		sbuf_printf(sb,
+		    "address sizes\t: %u bits physical, %u bits virtual\n",
+		    cpu_pma_bits, cpu_vma_bits);
+	}
+
 	return (0);
 }
 #endif /* __i386__ || __amd64__ */
--- address_sizes.diff ends here ---


>Release-Note:
>Audit-Trail:

From: John Baldwin <jhb@freebsd.org>
To: freebsd-amd64@freebsd.org,
 Sofian Brabez <sbz@freebsd.org>
Cc: FreeBSD-gnats-submit@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

 > --- 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
>Unformatted:
