diff mbox series

[v2,for,4.13,1/2] x86/boot: allow early usage of cpu_has_hypervisor

Message ID 20191030145447.11122-1-sergey.dyasli@citrix.com (mailing list archive)
State New, archived
Headers show
Series [v2,for,4.13,1/2] x86/boot: allow early usage of cpu_has_hypervisor | expand

Commit Message

Sergey Dyasli Oct. 30, 2019, 2:54 p.m. UTC
Move early_cpu_init() to be near the top of __start_xen(). Since there
is no serial / vga output at that stage, introduce a new function
to print CPU information at the usual place during boot.

Finally, convert users of cpuid_ecx(1) & X86_FEATURE_HYPERVISOR.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
---
CC: Jan Beulich <jbeulich@suse.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
CC: Wei Liu <wl@xen.org>
CC: "Roger Pau Monné" <roger.pau@citrix.com>
CC: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/cpu/common.c   | 25 +++++++++++++++++--------
 xen/arch/x86/guest/xen.c    |  3 +--
 xen/arch/x86/mm.c           |  2 +-
 xen/arch/x86/setup.c        |  4 +++-
 xen/include/asm-x86/setup.h |  1 +
 5 files changed, 23 insertions(+), 12 deletions(-)

Comments

Jan Beulich Oct. 30, 2019, 3:32 p.m. UTC | #1
On 30.10.2019 15:54, Sergey Dyasli wrote:
> @@ -317,11 +316,6 @@ void __init early_cpu_init(void)
>  	c->x86_capability[cpufeat_word(X86_FEATURE_FPU)] = edx;
>  	c->x86_capability[cpufeat_word(X86_FEATURE_SSE3)] = ecx;
>  
> -	printk(XENLOG_INFO
> -	       "CPU Vendor: %s, Family %u (%#x), Model %u (%#x), Stepping %u (raw %08x)\n",
> -	       x86_cpuid_vendor_to_str(c->x86_vendor), c->x86, c->x86,
> -	       c->x86_model, c->x86_model, c->x86_mask, eax);

I'm slightly concerned of the code immediately ahead of this
printk() now running _much_ earlier. Did you inspect that there's
no change of the relevant cleared_caps[] entries between the new
and the old call position in setup.c?

> @@ -342,6 +336,21 @@ void __init early_cpu_init(void)
>  	initialize_cpu_data(0);
>  }
>  
> +void __init early_cpu_print_info(void)
> +{
> +	struct cpuinfo_x86 *c = &boot_cpu_data;

const

> +	if (unrecognised_cpu)
> +		printk(XENLOG_ERR
> +		       "Unrecognised or unsupported CPU vendor '%.12s'\n",
> +		       c->x86_vendor_id);
> +
> +	printk(XENLOG_INFO "CPU Vendor: %s, Family %u (%#x), Model %u (%#x), "
> +			   "Stepping %u (raw %08x)\n",
> +	       x86_cpuid_vendor_to_str(c->x86_vendor), c->x86, c->x86,
> +	       c->x86_model, c->x86_model, c->x86_mask, cpuid_eax(0x00000001));

May I suggest to use the shorter "1" here?

> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -723,6 +723,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      /* Enable NMIs.  Our loader (e.g. Tboot) may have left them disabled. */
>      enable_nmis();
>  
> +    early_cpu_init();
> +
>      if ( pvh_boot )
>      {
>          /*
> @@ -1519,7 +1521,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      softirq_init();
>      tasklet_subsys_init();
>  
> -    early_cpu_init();
> +    early_cpu_print_info();

I agree with splitting the function, but I guess this could still
be moved up by quite a bit, next to the printk()-s right after
console_init_preirq().

Jan
Sergey Dyasli Oct. 30, 2019, 5:13 p.m. UTC | #2
On 30/10/2019 15:32, Jan Beulich wrote:
> On 30.10.2019 15:54, Sergey Dyasli wrote:
>> @@ -317,11 +316,6 @@ void __init early_cpu_init(void)
>>  	c->x86_capability[cpufeat_word(X86_FEATURE_FPU)] = edx;
>>  	c->x86_capability[cpufeat_word(X86_FEATURE_SSE3)] = ecx;
>>  
>> -	printk(XENLOG_INFO
>> -	       "CPU Vendor: %s, Family %u (%#x), Model %u (%#x), Stepping %u (raw %08x)\n",
>> -	       x86_cpuid_vendor_to_str(c->x86_vendor), c->x86, c->x86,
>> -	       c->x86_model, c->x86_model, c->x86_mask, eax);
> 
> I'm slightly concerned of the code immediately ahead of this
> printk() now running _much_ earlier. Did you inspect that there's
> no change of the relevant cleared_caps[] entries between the new
> and the old call position in setup.c?

You are right, this idea requires a more sophisticated approach.
Please disregard this patch. For now I'll add something like
early_cpu_has_hypervisor(). Will send a v3 soon.

--
Thanks,
Sergey
diff mbox series

Patch

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 6c6bd63301..4f336f64d3 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -109,6 +109,7 @@  static const struct cpu_dev default_cpu = {
 	.c_init	= default_init,
 };
 static const struct cpu_dev *this_cpu = &default_cpu;
+static bool __initdata unrecognised_cpu;
 
 static DEFINE_PER_CPU(uint64_t, msr_misc_features);
 void (* __read_mostly ctxt_switch_masking)(const struct vcpu *next);
@@ -301,9 +302,7 @@  void __init early_cpu_init(void)
 	case X86_VENDOR_SHANGHAI: this_cpu = &shanghai_cpu_dev; break;
 	case X86_VENDOR_HYGON:    this_cpu = &hygon_cpu_dev;    break;
 	default:
-		printk(XENLOG_ERR
-		       "Unrecognised or unsupported CPU vendor '%.12s'\n",
-		       c->x86_vendor_id);
+		unrecognised_cpu = true;
 	}
 
 	cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
@@ -317,11 +316,6 @@  void __init early_cpu_init(void)
 	c->x86_capability[cpufeat_word(X86_FEATURE_FPU)] = edx;
 	c->x86_capability[cpufeat_word(X86_FEATURE_SSE3)] = ecx;
 
-	printk(XENLOG_INFO
-	       "CPU Vendor: %s, Family %u (%#x), Model %u (%#x), Stepping %u (raw %08x)\n",
-	       x86_cpuid_vendor_to_str(c->x86_vendor), c->x86, c->x86,
-	       c->x86_model, c->x86_model, c->x86_mask, eax);
-
 	eax = cpuid_eax(0x80000000);
 	if ((eax >> 16) == 0x8000 && eax >= 0x80000008) {
 		eax = cpuid_eax(0x80000008);
@@ -342,6 +336,21 @@  void __init early_cpu_init(void)
 	initialize_cpu_data(0);
 }
 
+void __init early_cpu_print_info(void)
+{
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
+	if (unrecognised_cpu)
+		printk(XENLOG_ERR
+		       "Unrecognised or unsupported CPU vendor '%.12s'\n",
+		       c->x86_vendor_id);
+
+	printk(XENLOG_INFO "CPU Vendor: %s, Family %u (%#x), Model %u (%#x), "
+			   "Stepping %u (raw %08x)\n",
+	       x86_cpuid_vendor_to_str(c->x86_vendor), c->x86, c->x86,
+	       c->x86_model, c->x86_model, c->x86_mask, cpuid_eax(0x00000001));
+}
+
 static void generic_identify(struct cpuinfo_x86 *c)
 {
 	u32 eax, ebx, ecx, edx, tmp;
diff --git a/xen/arch/x86/guest/xen.c b/xen/arch/x86/guest/xen.c
index 7b7a5badab..9b776afed9 100644
--- a/xen/arch/x86/guest/xen.c
+++ b/xen/arch/x86/guest/xen.c
@@ -72,8 +72,7 @@  void __init probe_hypervisor(void)
     if ( xen_guest )
         return;
 
-    /* Too early to use cpu_has_hypervisor */
-    if ( !(cpuid_ecx(1) & cpufeat_mask(X86_FEATURE_HYPERVISOR)) )
+    if ( !cpu_has_hypervisor )
         return;
 
     find_xen_leaves();
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 99816fc67c..4cdccab8c8 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5943,7 +5943,7 @@  const struct platform_bad_page *__init get_platform_badpages(unsigned int *array
     case 0x000806e0: /* erratum KBL??? */
     case 0x000906e0: /* errata KBL??? / KBW114 / CFW103 */
         *array_size = (cpuid_eax(0) >= 7 &&
-                       !(cpuid_ecx(1) & cpufeat_mask(X86_FEATURE_HYPERVISOR)) &&
+                       !cpu_has_hypervisor &&
                        (cpuid_count_ebx(7, 0) & cpufeat_mask(X86_FEATURE_HLE)));
         return &hle_bad_page;
     }
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index dec60d0301..07adfed566 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -723,6 +723,8 @@  void __init noreturn __start_xen(unsigned long mbi_p)
     /* Enable NMIs.  Our loader (e.g. Tboot) may have left them disabled. */
     enable_nmis();
 
+    early_cpu_init();
+
     if ( pvh_boot )
     {
         /*
@@ -1519,7 +1521,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
     softirq_init();
     tasklet_subsys_init();
 
-    early_cpu_init();
+    early_cpu_print_info();
 
     paging_init();
 
diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h
index 861d46d6ac..251151508d 100644
--- a/xen/include/asm-x86/setup.h
+++ b/xen/include/asm-x86/setup.h
@@ -15,6 +15,7 @@  extern char __2M_rwdata_start[], __2M_rwdata_end[];
 extern unsigned long xenheap_initial_phys_start;
 
 void early_cpu_init(void);
+void early_cpu_print_info(void);
 void early_time_init(void);
 
 void set_nr_cpu_ids(unsigned int max_cpus);