Skip to content

Commit

Permalink
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/tip/tip

Pull x86 fixes from Peter Anvin:
 "Three groups of fixes:

   1. Make sure we don't execute the early microcode patching if family
      < 6, since it would touch MSRs which don't exist on those
      families, causing crashes.

   2. The Xen partial emulation of HyperV can be dealt with more
      gracefully than just disabling the driver.

   3. More EFI variable space magic.  In particular, variables hidden
      from runtime code need to be taken into account too."

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, microcode: Verify the family before dispatching microcode patching
  x86, hyperv: Handle Xen emulation of Hyper-V more gracefully
  x86,efi: Implement efi_no_storage_paranoia parameter
  efi: Export efi_query_variable_store() for efivars.ko
  x86/Kconfig: Make EFI select UCS2_STRING
  efi: Distinguish between "remaining space" and actually used space
  efi: Pass boot services variable info to runtime code
  Move utf16 functions to kernel core and rename
  x86,efi: Check max_size only if it is non-zero.
  x86, efivars: firmware bug workarounds should be in platform code
  • Loading branch information
torvalds committed Apr 21, 2013
2 parents 8c3a13c + c0a9f45 commit db93f8b
Show file tree
Hide file tree
Showing 15 changed files with 361 additions and 103 deletions.
6 changes: 6 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
edd= [EDD]
Format: {"off" | "on" | "skip[mbr]"}

efi_no_storage_paranoia [EFI; X86]
Using this parameter you can use more than 50% of
your efi variable storage. Use this parameter only if
you are really sure that your UEFI does sane gc and
fulfills the spec otherwise your board may brick.

eisa_irq_edge= [PARISC,HW]
See header of drivers/parisc/eisa.c.

Expand Down
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1549,6 +1549,7 @@ config X86_SMAP
config EFI
bool "EFI runtime service support"
depends on ACPI
select UCS2_STRING
---help---
This enables the kernel to use EFI runtime services that are
available (such as the EFI variable services).
Expand Down
47 changes: 47 additions & 0 deletions arch/x86/boot/compressed/eboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,51 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
*size = len;
}

static efi_status_t setup_efi_vars(struct boot_params *params)
{
struct setup_data *data;
struct efi_var_bootdata *efidata;
u64 store_size, remaining_size, var_size;
efi_status_t status;

if (!sys_table->runtime->query_variable_info)
return EFI_UNSUPPORTED;

data = (struct setup_data *)(unsigned long)params->hdr.setup_data;

while (data && data->next)
data = (struct setup_data *)(unsigned long)data->next;

status = efi_call_phys4(sys_table->runtime->query_variable_info,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS, &store_size,
&remaining_size, &var_size);

if (status != EFI_SUCCESS)
return status;

status = efi_call_phys3(sys_table->boottime->allocate_pool,
EFI_LOADER_DATA, sizeof(*efidata), &efidata);

if (status != EFI_SUCCESS)
return status;

efidata->data.type = SETUP_EFI_VARS;
efidata->data.len = sizeof(struct efi_var_bootdata) -
sizeof(struct setup_data);
efidata->data.next = 0;
efidata->store_size = store_size;
efidata->remaining_size = remaining_size;
efidata->max_var_size = var_size;

if (data)
data->next = (unsigned long)efidata;
else
params->hdr.setup_data = (unsigned long)efidata;

}

static efi_status_t setup_efi_pci(struct boot_params *params)
{
efi_pci_io_protocol *pci;
Expand Down Expand Up @@ -1157,6 +1202,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,

setup_graphics(boot_params);

setup_efi_vars(boot_params);

setup_efi_pci(boot_params);

status = efi_call_phys3(sys_table->boottime->allocate_pool,
Expand Down
7 changes: 7 additions & 0 deletions arch/x86/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ extern void efi_call_phys_epilog(void);
extern void efi_unmap_memmap(void);
extern void efi_memory_uc(u64 addr, unsigned long size);

struct efi_var_bootdata {
struct setup_data data;
u64 store_size;
u64 remaining_size;
u64 max_var_size;
};

#ifdef CONFIG_EFI

static inline bool efi_is_native(void)
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/uapi/asm/bootparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define SETUP_E820_EXT 1
#define SETUP_DTB 2
#define SETUP_PCI 3
#define SETUP_EFI_VARS 4

/* ram_size flags */
#define RAMDISK_IMAGE_START_MASK 0x07FF
Expand Down
18 changes: 5 additions & 13 deletions arch/x86/kernel/cpu/mshyperv.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ static bool __init ms_hyperv_platform(void)
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
return false;

/*
* Xen emulates Hyper-V to support enlightened Windows.
* Check to see first if we are on a Xen Hypervisor.
*/
if (xen_cpuid_base())
return false;

cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
&eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);

Expand Down Expand Up @@ -82,12 +75,6 @@ static void __init ms_hyperv_init_platform(void)

if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100);
#if IS_ENABLED(CONFIG_HYPERV)
/*
* Setup the IDT for hypervisor callback.
*/
alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
#endif
}

const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
Expand All @@ -103,6 +90,11 @@ static irq_handler_t vmbus_isr;

void hv_register_vmbus_handler(int irq, irq_handler_t handler)
{
/*
* Setup the IDT for hypervisor callback.
*/
alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);

vmbus_irq = irq;
vmbus_isr = handler;
}
Expand Down
38 changes: 31 additions & 7 deletions arch/x86/kernel/microcode_core_early.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ static int __cpuinit x86_vendor(void)
u32 eax = 0x00000000;
u32 ebx, ecx = 0, edx;

if (!have_cpuid_p())
return X86_VENDOR_UNKNOWN;

native_cpuid(&eax, &ebx, &ecx, &edx);

if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx))
Expand All @@ -59,18 +56,45 @@ static int __cpuinit x86_vendor(void)
return X86_VENDOR_UNKNOWN;
}

static int __cpuinit x86_family(void)
{
u32 eax = 0x00000001;
u32 ebx, ecx = 0, edx;
int x86;

native_cpuid(&eax, &ebx, &ecx, &edx);

x86 = (eax >> 8) & 0xf;
if (x86 == 15)
x86 += (eax >> 20) & 0xff;

return x86;
}

void __init load_ucode_bsp(void)
{
int vendor = x86_vendor();
int vendor, x86;

if (!have_cpuid_p())
return;

if (vendor == X86_VENDOR_INTEL)
vendor = x86_vendor();
x86 = x86_family();

if (vendor == X86_VENDOR_INTEL && x86 >= 6)
load_ucode_intel_bsp();
}

void __cpuinit load_ucode_ap(void)
{
int vendor = x86_vendor();
int vendor, x86;

if (!have_cpuid_p())
return;

vendor = x86_vendor();
x86 = x86_family();

if (vendor == X86_VENDOR_INTEL)
if (vendor == X86_VENDOR_INTEL && x86 >= 6)
load_ucode_intel_ap();
}
Loading

0 comments on commit db93f8b

Please sign in to comment.