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:42:08 UTC 2013
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