Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Sep 2016 00:24:26 +0300
From:      Slawa Olhovchenkov <slw@zxy.spb.ru>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        Andriy Gapon <avg@FreeBSD.org>, stable@FreeBSD.org
Subject:   Re: X2APIC support
Message-ID:  <20160914212426.GI2840@zxy.spb.ru>
In-Reply-To: <20160914160802.GH38409@kib.kiev.ua>
References:  <37f5cebc-3fa1-9e95-5123-f3d8daa3130a@FreeBSD.org> <20160913152240.GE38409@kib.kiev.ua> <cb35f671-95e7-820f-6a78-ee60612cc1ad@FreeBSD.org> <20160914113634.GF38409@kib.kiev.ua> <763df55a-4b69-9f7a-1042-0f631a729881@FreeBSD.org> <20160914123313.GC2840@zxy.spb.ru> <966c58d6-db64-2879-6709-0aa596bec24b@FreeBSD.org> <20160914124950.GE2840@zxy.spb.ru> <50cf91d9-072d-76fe-768c-8a6a9515bd93@FreeBSD.org> <20160914160802.GH38409@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Sep 14, 2016 at 07:08:02PM +0300, Konstantin Belousov wrote:

> On Wed, Sep 14, 2016 at 05:02:21PM +0300, Andriy Gapon wrote:
> > On 14/09/2016 15:49, Slawa Olhovchenkov wrote:
> > > MSR_APICBASE = 0x        fee00d00
> > > x2APIC is prohibited but turned on by BIOS
> > 
> > Kostik, ^^^^^
> 
> Well, the following might work, but I have no good idea what to do
> when BIOS does handoff with x2APIC enabled and directs us to not
> enable it.  Switching to xAPIC mode is not an option, I suspect.

CPU: Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz (2200.05-MHz K8-class CPU)
  Origin="GenuineIntel"  Id=0x406f1  Family=0x6  Model=0x4f  Stepping=1
  Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
  Features2=0x7ffefbff<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,SMX,EST,TM2,SSSE3,SDBG,FMA,CX16,xTPR,PDCM,PCID,DCA,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,TSCDLT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND>
  AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM>
  AMD Features2=0x121<LAHF,ABM,Prefetch>
  Structured Extended Features=0x21cbfbb<FSGSBASE,TSCADJ,BMI1,HLE,AVX2,SMEP,BMI2,ERMS,INVPCID,RTM,PQM,NFPUSG,PQE,RDSEED,ADX,SMAP,PROCTRACE>
  XSAVE Features=0x1<XSAVEOPT>
  VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID,VID,PostIntr
  TSC: P-state invariant, performance statistics
real memory  = 137438953472 (131072 MB)
avail memory = 133407973376 (127227 MB)
Event timer "LAPIC" quality 600
ACPI APIC Table: <ALASKA A M I >
boot_cpu_id = 0
FreeBSD/SMP: Multiprocessor System Detected: 24 CPUs
FreeBSD/SMP: 2 package(s) x 12 core(s)
random: unblocking device.
ioapic0 <Version 2.0> irqs 0-23 on motherboard
ioapic1 <Version 2.0> irqs 24-47 on motherboard
ioapic2 <Version 2.0> irqs 48-71 on motherboard
random: entropy device external interface
module_register_init: MOD_LOAD (vesa, 0xffffffff807bf2f0, 0) error 19
random: registering fast source Intel Secure Key RNG
random: fast provider: "Intel Secure Key RNG"
kbd1 at kbdmux0
netmap: loaded module
vtvga0: <VT VGA driver> on motherboard
cryptosoft0: <software crypto> on motherboard
acpi0: <ALASKA A M I > on motherboard
acpi0: Power Button (fixed)
[...]

boot OK, w/o any APIC-related messages

> diff --git a/sys/x86/acpica/madt.c b/sys/x86/acpica/madt.c
> index 241a769..3a93fd6 100644
> --- a/sys/x86/acpica/madt.c
> +++ b/sys/x86/acpica/madt.c
> @@ -138,7 +138,6 @@ madt_setup_local(void)
>  
>  	madt = pmap_mapbios(madt_physaddr, madt_length);
>  	if ((cpu_feature2 & CPUID2_X2APIC) != 0) {
> -		x2apic_mode = 1;
>  		reason = NULL;
>  
>  		/*
> @@ -150,21 +149,17 @@ madt_setup_local(void)
>  		if (dmartbl_physaddr != 0) {
>  			dmartbl = acpi_map_table(dmartbl_physaddr,
>  			    ACPI_SIG_DMAR);
> -			if ((dmartbl->Flags & ACPI_DMAR_X2APIC_OPT_OUT) != 0) {
> -				x2apic_mode = 0;
> +			if ((dmartbl->Flags & ACPI_DMAR_X2APIC_OPT_OUT) != 0)
>  				reason = "by DMAR table";
> -			}
>  			acpi_unmap_table(dmartbl);
>  		}
>  		if (vm_guest == VM_GUEST_VMWARE) {
>  			vmware_hvcall(VMW_HVCMD_GETVCPU_INFO, p);
>  			if ((p[0] & VMW_VCPUINFO_VCPU_RESERVED) != 0 ||
> -			    (p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0) {
> -				x2apic_mode = 0;
> -		reason = "inside VMWare without intr redirection";
> -			}
> +			    (p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0)
> +				reason =
> +				    "inside VMWare without intr redirection";
>  		} else if (vm_guest == VM_GUEST_XEN) {
> -			x2apic_mode = 0;
>  			reason = "due to running under XEN";
>  		} else if (vm_guest == VM_GUEST_NO &&
>  		    CPUID_TO_FAMILY(cpu_id) == 0x6 &&
> @@ -184,13 +179,21 @@ madt_setup_local(void)
>  				if (!strcmp(hw_vendor, "LENOVO") ||
>  				    !strcmp(hw_vendor,
>  				    "ASUSTeK Computer Inc.")) {
> -					x2apic_mode = 0;
>  					reason =
>  				    "for a suspected SandyBridge BIOS bug";
>  				}
>  				freeenv(hw_vendor);
>  			}
>  		}
> +		if (reason != NULL && lapic_is_x2apic()) {
> +			if (bootverbose)
> +				printf("x2APIC should be disabled %s but "
> +				    "already enabled by BIOS; enabling.\n",
> +				     reason);
> +			reason = NULL;
> +		}
> +		if (reason == NULL)
> +			x2apic_mode = 1;
>  		TUNABLE_INT_FETCH("hw.x2apic_enable", &x2apic_mode);
>  		if (!x2apic_mode && reason != NULL && bootverbose)
>  			printf("x2APIC available but disabled %s\n", reason);
> diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h
> index 1ddb69e..09c3a63 100644
> --- a/sys/x86/include/apicvar.h
> +++ b/sys/x86/include/apicvar.h
> @@ -206,6 +206,7 @@ struct apic_ops {
>  	void	(*create)(u_int, int);
>  	void	(*init)(vm_paddr_t);
>  	void	(*xapic_mode)(void);
> +	bool	(*is_x2apic)(void);
>  	void	(*setup)(int);
>  	void	(*dump)(const char *);
>  	void	(*disable)(void);
> @@ -268,6 +269,13 @@ lapic_xapic_mode(void)
>  	apic_ops.xapic_mode();
>  }
>  
> +static inline bool
> +lapic_is_x2apic(void)
> +{
> +
> +	return (apic_ops.is_x2apic());
> +}
> +
>  static inline void
>  lapic_setup(int boot)
>  {
> diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
> index cd774df..d9a3453 100644
> --- a/sys/x86/x86/local_apic.c
> +++ b/sys/x86/x86/local_apic.c
> @@ -269,6 +269,16 @@ native_lapic_enable_x2apic(void)
>  	wrmsr(MSR_APICBASE, apic_base);
>  }
>  
> +static bool
> +native_lapic_is_x2apic(void)
> +{
> +	uint64_t apic_base;
> +
> +	apic_base = rdmsr(MSR_APICBASE);
> +	return ((apic_base & (APICBASE_X2APIC | APICBASE_ENABLED)) ==
> +	    (APICBASE_X2APIC | APICBASE_ENABLED));
> +}
> +
>  static void	lapic_enable(void);
>  static void	lapic_resume(struct pic *pic, bool suspend_cancelled);
>  static void	lapic_timer_oneshot(struct lapic *);
> @@ -329,6 +339,7 @@ struct apic_ops apic_ops = {
>  	.create			= native_lapic_create,
>  	.init			= native_lapic_init,
>  	.xapic_mode		= native_lapic_xapic_mode,
> +	.is_x2apic		= native_lapic_is_x2apic,
>  	.setup			= native_lapic_setup,
>  	.dump			= native_lapic_dump,
>  	.disable		= native_lapic_disable,
> diff --git a/sys/x86/xen/xen_apic.c b/sys/x86/xen/xen_apic.c
> index 4d7a39b..45c3c18 100644
> --- a/sys/x86/xen/xen_apic.c
> +++ b/sys/x86/xen/xen_apic.c
> @@ -139,6 +139,13 @@ xen_pv_lapic_disable(void)
>  
>  }
>  
> +static bool
> +xen_pv_lapic_is_x2apic(void)
> +{
> +
> +	return (false);
> +}
> +
>  static void
>  xen_pv_lapic_eoi(void)
>  {
> @@ -351,6 +358,7 @@ struct apic_ops xen_apic_ops = {
>  	.create			= xen_pv_lapic_create,
>  	.init			= xen_pv_lapic_init,
>  	.xapic_mode		= xen_pv_lapic_disable,
> +	.is_x2apic		= xen_pv_lapic_is_x2apic,
>  	.setup			= xen_pv_lapic_setup,
>  	.dump			= xen_pv_lapic_dump,
>  	.disable		= xen_pv_lapic_disable,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160914212426.GI2840>