Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Peter Anvin: "This is a collection of miscellaneous fixes, the most important one is the fix for the Samsung laptop bricking issue (auto-blacklisting the samsung-laptop driver); the efi_enabled() changes you see below are prerequisites for that fix. The other issues fixed are booting on OLPC XO-1.5, an UV fix, NMI debugging, and requiring CAP_SYS_RAWIO for MSR references, just as with I/O port references." * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: samsung-laptop: Disable on EFI hardware efi: Make 'efi_enabled' a function to query EFI facilities smp: Fix SMP function call empty cpu mask race x86/msr: Add capabilities check x86/dma-debug: Bump PREALLOC_DMA_DEBUG_ENTRIES x86/olpc: Fix olpc-xo1-sci.c build errors arch/x86/platform/uv: Fix incorrect tlb flush all issue x86-64: Fix unwind annotations in recent NMI changes x86-32: Start out cr0 clean, disable paging before modifying cr3/4
This commit is contained in:
commit
bdb0ae6a76
|
@ -2138,6 +2138,7 @@ config OLPC_XO1_RTC
|
||||||
config OLPC_XO1_SCI
|
config OLPC_XO1_SCI
|
||||||
bool "OLPC XO-1 SCI extras"
|
bool "OLPC XO-1 SCI extras"
|
||||||
depends on OLPC && OLPC_XO1_PM
|
depends on OLPC && OLPC_XO1_PM
|
||||||
|
depends on INPUT=y
|
||||||
select POWER_SUPPLY
|
select POWER_SUPPLY
|
||||||
select GPIO_CS5535
|
select GPIO_CS5535
|
||||||
select MFD_CORE
|
select MFD_CORE
|
||||||
|
|
|
@ -94,6 +94,7 @@ extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
|
||||||
#endif /* CONFIG_X86_32 */
|
#endif /* CONFIG_X86_32 */
|
||||||
|
|
||||||
extern int add_efi_memmap;
|
extern int add_efi_memmap;
|
||||||
|
extern unsigned long x86_efi_facility;
|
||||||
extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
|
extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
|
||||||
extern int efi_memblock_x86_reserve_range(void);
|
extern int efi_memblock_x86_reserve_range(void);
|
||||||
extern void efi_call_phys_prelog(void);
|
extern void efi_call_phys_prelog(void);
|
||||||
|
|
|
@ -16,7 +16,7 @@ extern void uv_system_init(void);
|
||||||
extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
||||||
struct mm_struct *mm,
|
struct mm_struct *mm,
|
||||||
unsigned long start,
|
unsigned long start,
|
||||||
unsigned end,
|
unsigned long end,
|
||||||
unsigned int cpu);
|
unsigned int cpu);
|
||||||
|
|
||||||
#else /* X86_UV */
|
#else /* X86_UV */
|
||||||
|
|
|
@ -1781,6 +1781,7 @@ first_nmi:
|
||||||
* Leave room for the "copied" frame
|
* Leave room for the "copied" frame
|
||||||
*/
|
*/
|
||||||
subq $(5*8), %rsp
|
subq $(5*8), %rsp
|
||||||
|
CFI_ADJUST_CFA_OFFSET 5*8
|
||||||
|
|
||||||
/* Copy the stack frame to the Saved frame */
|
/* Copy the stack frame to the Saved frame */
|
||||||
.rept 5
|
.rept 5
|
||||||
|
@ -1863,10 +1864,8 @@ end_repeat_nmi:
|
||||||
nmi_swapgs:
|
nmi_swapgs:
|
||||||
SWAPGS_UNSAFE_STACK
|
SWAPGS_UNSAFE_STACK
|
||||||
nmi_restore:
|
nmi_restore:
|
||||||
RESTORE_ALL 8
|
/* Pop the extra iret frame at once */
|
||||||
|
RESTORE_ALL 6*8
|
||||||
/* Pop the extra iret frame */
|
|
||||||
addq $(5*8), %rsp
|
|
||||||
|
|
||||||
/* Clear the NMI executing stack variable */
|
/* Clear the NMI executing stack variable */
|
||||||
movq $0, 5*8(%rsp)
|
movq $0, 5*8(%rsp)
|
||||||
|
|
|
@ -300,6 +300,12 @@ ENTRY(startup_32_smp)
|
||||||
leal -__PAGE_OFFSET(%ecx),%esp
|
leal -__PAGE_OFFSET(%ecx),%esp
|
||||||
|
|
||||||
default_entry:
|
default_entry:
|
||||||
|
#define CR0_STATE (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | \
|
||||||
|
X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | \
|
||||||
|
X86_CR0_PG)
|
||||||
|
movl $(CR0_STATE & ~X86_CR0_PG),%eax
|
||||||
|
movl %eax,%cr0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* New page tables may be in 4Mbyte page mode and may
|
* New page tables may be in 4Mbyte page mode and may
|
||||||
* be using the global pages.
|
* be using the global pages.
|
||||||
|
@ -364,8 +370,7 @@ default_entry:
|
||||||
*/
|
*/
|
||||||
movl $pa(initial_page_table), %eax
|
movl $pa(initial_page_table), %eax
|
||||||
movl %eax,%cr3 /* set the page table pointer.. */
|
movl %eax,%cr3 /* set the page table pointer.. */
|
||||||
movl %cr0,%eax
|
movl $CR0_STATE,%eax
|
||||||
orl $X86_CR0_PG,%eax
|
|
||||||
movl %eax,%cr0 /* ..and set paging (PG) bit */
|
movl %eax,%cr0 /* ..and set paging (PG) bit */
|
||||||
ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */
|
ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */
|
||||||
1:
|
1:
|
||||||
|
|
|
@ -174,6 +174,9 @@ static int msr_open(struct inode *inode, struct file *file)
|
||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
struct cpuinfo_x86 *c;
|
struct cpuinfo_x86 *c;
|
||||||
|
|
||||||
|
if (!capable(CAP_SYS_RAWIO))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
cpu = iminor(file->f_path.dentry->d_inode);
|
cpu = iminor(file->f_path.dentry->d_inode);
|
||||||
if (cpu >= nr_cpu_ids || !cpu_online(cpu))
|
if (cpu >= nr_cpu_ids || !cpu_online(cpu))
|
||||||
return -ENXIO; /* No such CPU */
|
return -ENXIO; /* No such CPU */
|
||||||
|
|
|
@ -56,7 +56,7 @@ struct device x86_dma_fallback_dev = {
|
||||||
EXPORT_SYMBOL(x86_dma_fallback_dev);
|
EXPORT_SYMBOL(x86_dma_fallback_dev);
|
||||||
|
|
||||||
/* Number of entries preallocated for DMA-API debugging */
|
/* Number of entries preallocated for DMA-API debugging */
|
||||||
#define PREALLOC_DMA_DEBUG_ENTRIES 32768
|
#define PREALLOC_DMA_DEBUG_ENTRIES 65536
|
||||||
|
|
||||||
int dma_set_mask(struct device *dev, u64 mask)
|
int dma_set_mask(struct device *dev, u64 mask)
|
||||||
{
|
{
|
||||||
|
|
|
@ -584,7 +584,7 @@ static void native_machine_emergency_restart(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOT_EFI:
|
case BOOT_EFI:
|
||||||
if (efi_enabled)
|
if (efi_enabled(EFI_RUNTIME_SERVICES))
|
||||||
efi.reset_system(reboot_mode ?
|
efi.reset_system(reboot_mode ?
|
||||||
EFI_RESET_WARM :
|
EFI_RESET_WARM :
|
||||||
EFI_RESET_COLD,
|
EFI_RESET_COLD,
|
||||||
|
|
|
@ -807,15 +807,15 @@ void __init setup_arch(char **cmdline_p)
|
||||||
#ifdef CONFIG_EFI
|
#ifdef CONFIG_EFI
|
||||||
if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
|
if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
|
||||||
"EL32", 4)) {
|
"EL32", 4)) {
|
||||||
efi_enabled = 1;
|
set_bit(EFI_BOOT, &x86_efi_facility);
|
||||||
efi_64bit = false;
|
|
||||||
} else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
|
} else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
|
||||||
"EL64", 4)) {
|
"EL64", 4)) {
|
||||||
efi_enabled = 1;
|
set_bit(EFI_BOOT, &x86_efi_facility);
|
||||||
efi_64bit = true;
|
set_bit(EFI_64BIT, &x86_efi_facility);
|
||||||
}
|
}
|
||||||
if (efi_enabled && efi_memblock_x86_reserve_range())
|
|
||||||
efi_enabled = 0;
|
if (efi_enabled(EFI_BOOT))
|
||||||
|
efi_memblock_x86_reserve_range();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x86_init.oem.arch_setup();
|
x86_init.oem.arch_setup();
|
||||||
|
@ -888,7 +888,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
|
|
||||||
finish_e820_parsing();
|
finish_e820_parsing();
|
||||||
|
|
||||||
if (efi_enabled)
|
if (efi_enabled(EFI_BOOT))
|
||||||
efi_init();
|
efi_init();
|
||||||
|
|
||||||
dmi_scan_machine();
|
dmi_scan_machine();
|
||||||
|
@ -971,7 +971,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
* The EFI specification says that boot service code won't be called
|
* The EFI specification says that boot service code won't be called
|
||||||
* after ExitBootServices(). This is, in fact, a lie.
|
* after ExitBootServices(). This is, in fact, a lie.
|
||||||
*/
|
*/
|
||||||
if (efi_enabled)
|
if (efi_enabled(EFI_MEMMAP))
|
||||||
efi_reserve_boot_services();
|
efi_reserve_boot_services();
|
||||||
|
|
||||||
/* preallocate 4k for mptable mpc */
|
/* preallocate 4k for mptable mpc */
|
||||||
|
@ -1114,7 +1114,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
|
|
||||||
#ifdef CONFIG_VT
|
#ifdef CONFIG_VT
|
||||||
#if defined(CONFIG_VGA_CONSOLE)
|
#if defined(CONFIG_VGA_CONSOLE)
|
||||||
if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
|
if (!efi_enabled(EFI_BOOT) || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
|
||||||
conswitchp = &vga_con;
|
conswitchp = &vga_con;
|
||||||
#elif defined(CONFIG_DUMMY_CONSOLE)
|
#elif defined(CONFIG_DUMMY_CONSOLE)
|
||||||
conswitchp = &dummy_con;
|
conswitchp = &dummy_con;
|
||||||
|
@ -1131,14 +1131,14 @@ void __init setup_arch(char **cmdline_p)
|
||||||
register_refined_jiffies(CLOCK_TICK_RATE);
|
register_refined_jiffies(CLOCK_TICK_RATE);
|
||||||
|
|
||||||
#ifdef CONFIG_EFI
|
#ifdef CONFIG_EFI
|
||||||
/* Once setup is done above, disable efi_enabled on mismatched
|
/* Once setup is done above, unmap the EFI memory map on
|
||||||
* firmware/kernel archtectures since there is no support for
|
* mismatched firmware/kernel archtectures since there is no
|
||||||
* runtime services.
|
* support for runtime services.
|
||||||
*/
|
*/
|
||||||
if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) {
|
if (efi_enabled(EFI_BOOT) &&
|
||||||
|
IS_ENABLED(CONFIG_X86_64) != efi_enabled(EFI_64BIT)) {
|
||||||
pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
|
pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
|
||||||
efi_unmap_memmap();
|
efi_unmap_memmap();
|
||||||
efi_enabled = 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,6 @@
|
||||||
|
|
||||||
#define EFI_DEBUG 1
|
#define EFI_DEBUG 1
|
||||||
|
|
||||||
int efi_enabled;
|
|
||||||
EXPORT_SYMBOL(efi_enabled);
|
|
||||||
|
|
||||||
struct efi __read_mostly efi = {
|
struct efi __read_mostly efi = {
|
||||||
.mps = EFI_INVALID_TABLE_ADDR,
|
.mps = EFI_INVALID_TABLE_ADDR,
|
||||||
.acpi = EFI_INVALID_TABLE_ADDR,
|
.acpi = EFI_INVALID_TABLE_ADDR,
|
||||||
|
@ -69,19 +66,28 @@ EXPORT_SYMBOL(efi);
|
||||||
|
|
||||||
struct efi_memory_map memmap;
|
struct efi_memory_map memmap;
|
||||||
|
|
||||||
bool efi_64bit;
|
|
||||||
|
|
||||||
static struct efi efi_phys __initdata;
|
static struct efi efi_phys __initdata;
|
||||||
static efi_system_table_t efi_systab __initdata;
|
static efi_system_table_t efi_systab __initdata;
|
||||||
|
|
||||||
static inline bool efi_is_native(void)
|
static inline bool efi_is_native(void)
|
||||||
{
|
{
|
||||||
return IS_ENABLED(CONFIG_X86_64) == efi_64bit;
|
return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long x86_efi_facility;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if 'facility' is enabled, 0 otherwise.
|
||||||
|
*/
|
||||||
|
int efi_enabled(int facility)
|
||||||
|
{
|
||||||
|
return test_bit(facility, &x86_efi_facility) != 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(efi_enabled);
|
||||||
|
|
||||||
static int __init setup_noefi(char *arg)
|
static int __init setup_noefi(char *arg)
|
||||||
{
|
{
|
||||||
efi_enabled = 0;
|
clear_bit(EFI_BOOT, &x86_efi_facility);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
early_param("noefi", setup_noefi);
|
early_param("noefi", setup_noefi);
|
||||||
|
@ -426,6 +432,7 @@ void __init efi_reserve_boot_services(void)
|
||||||
|
|
||||||
void __init efi_unmap_memmap(void)
|
void __init efi_unmap_memmap(void)
|
||||||
{
|
{
|
||||||
|
clear_bit(EFI_MEMMAP, &x86_efi_facility);
|
||||||
if (memmap.map) {
|
if (memmap.map) {
|
||||||
early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
|
early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
|
||||||
memmap.map = NULL;
|
memmap.map = NULL;
|
||||||
|
@ -460,7 +467,7 @@ void __init efi_free_boot_services(void)
|
||||||
|
|
||||||
static int __init efi_systab_init(void *phys)
|
static int __init efi_systab_init(void *phys)
|
||||||
{
|
{
|
||||||
if (efi_64bit) {
|
if (efi_enabled(EFI_64BIT)) {
|
||||||
efi_system_table_64_t *systab64;
|
efi_system_table_64_t *systab64;
|
||||||
u64 tmp = 0;
|
u64 tmp = 0;
|
||||||
|
|
||||||
|
@ -552,7 +559,7 @@ static int __init efi_config_init(u64 tables, int nr_tables)
|
||||||
void *config_tables, *tablep;
|
void *config_tables, *tablep;
|
||||||
int i, sz;
|
int i, sz;
|
||||||
|
|
||||||
if (efi_64bit)
|
if (efi_enabled(EFI_64BIT))
|
||||||
sz = sizeof(efi_config_table_64_t);
|
sz = sizeof(efi_config_table_64_t);
|
||||||
else
|
else
|
||||||
sz = sizeof(efi_config_table_32_t);
|
sz = sizeof(efi_config_table_32_t);
|
||||||
|
@ -572,7 +579,7 @@ static int __init efi_config_init(u64 tables, int nr_tables)
|
||||||
efi_guid_t guid;
|
efi_guid_t guid;
|
||||||
unsigned long table;
|
unsigned long table;
|
||||||
|
|
||||||
if (efi_64bit) {
|
if (efi_enabled(EFI_64BIT)) {
|
||||||
u64 table64;
|
u64 table64;
|
||||||
guid = ((efi_config_table_64_t *)tablep)->guid;
|
guid = ((efi_config_table_64_t *)tablep)->guid;
|
||||||
table64 = ((efi_config_table_64_t *)tablep)->table;
|
table64 = ((efi_config_table_64_t *)tablep)->table;
|
||||||
|
@ -684,7 +691,6 @@ void __init efi_init(void)
|
||||||
if (boot_params.efi_info.efi_systab_hi ||
|
if (boot_params.efi_info.efi_systab_hi ||
|
||||||
boot_params.efi_info.efi_memmap_hi) {
|
boot_params.efi_info.efi_memmap_hi) {
|
||||||
pr_info("Table located above 4GB, disabling EFI.\n");
|
pr_info("Table located above 4GB, disabling EFI.\n");
|
||||||
efi_enabled = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab;
|
efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab;
|
||||||
|
@ -694,10 +700,10 @@ void __init efi_init(void)
|
||||||
((__u64)boot_params.efi_info.efi_systab_hi<<32));
|
((__u64)boot_params.efi_info.efi_systab_hi<<32));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (efi_systab_init(efi_phys.systab)) {
|
if (efi_systab_init(efi_phys.systab))
|
||||||
efi_enabled = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show what we know for posterity
|
* Show what we know for posterity
|
||||||
|
@ -715,10 +721,10 @@ void __init efi_init(void)
|
||||||
efi.systab->hdr.revision >> 16,
|
efi.systab->hdr.revision >> 16,
|
||||||
efi.systab->hdr.revision & 0xffff, vendor);
|
efi.systab->hdr.revision & 0xffff, vendor);
|
||||||
|
|
||||||
if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) {
|
if (efi_config_init(efi.systab->tables, efi.systab->nr_tables))
|
||||||
efi_enabled = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
set_bit(EFI_CONFIG_TABLES, &x86_efi_facility);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: We currently don't support runtime services on an EFI
|
* Note: We currently don't support runtime services on an EFI
|
||||||
|
@ -727,15 +733,17 @@ void __init efi_init(void)
|
||||||
|
|
||||||
if (!efi_is_native())
|
if (!efi_is_native())
|
||||||
pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
|
pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
|
||||||
else if (efi_runtime_init()) {
|
else {
|
||||||
efi_enabled = 0;
|
if (efi_runtime_init())
|
||||||
return;
|
return;
|
||||||
|
set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (efi_memmap_init()) {
|
if (efi_memmap_init())
|
||||||
efi_enabled = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
set_bit(EFI_MEMMAP, &x86_efi_facility);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
if (efi_is_native()) {
|
if (efi_is_native()) {
|
||||||
x86_platform.get_wallclock = efi_get_time;
|
x86_platform.get_wallclock = efi_get_time;
|
||||||
|
@ -969,6 +977,9 @@ u32 efi_mem_type(unsigned long phys_addr)
|
||||||
efi_memory_desc_t *md;
|
efi_memory_desc_t *md;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
if (!efi_enabled(EFI_MEMMAP))
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
||||||
md = p;
|
md = p;
|
||||||
if ((md->phys_addr <= phys_addr) &&
|
if ((md->phys_addr <= phys_addr) &&
|
||||||
|
|
|
@ -1034,7 +1034,8 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
|
||||||
* globally purge translation cache of a virtual address or all TLB's
|
* globally purge translation cache of a virtual address or all TLB's
|
||||||
* @cpumask: mask of all cpu's in which the address is to be removed
|
* @cpumask: mask of all cpu's in which the address is to be removed
|
||||||
* @mm: mm_struct containing virtual address range
|
* @mm: mm_struct containing virtual address range
|
||||||
* @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu)
|
* @start: start virtual address to be removed from TLB
|
||||||
|
* @end: end virtual address to be remove from TLB
|
||||||
* @cpu: the current cpu
|
* @cpu: the current cpu
|
||||||
*
|
*
|
||||||
* This is the entry point for initiating any UV global TLB shootdown.
|
* This is the entry point for initiating any UV global TLB shootdown.
|
||||||
|
@ -1056,7 +1057,7 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
|
||||||
*/
|
*/
|
||||||
const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
||||||
struct mm_struct *mm, unsigned long start,
|
struct mm_struct *mm, unsigned long start,
|
||||||
unsigned end, unsigned int cpu)
|
unsigned long end, unsigned int cpu)
|
||||||
{
|
{
|
||||||
int locals = 0;
|
int locals = 0;
|
||||||
int remotes = 0;
|
int remotes = 0;
|
||||||
|
@ -1113,7 +1114,10 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
||||||
|
|
||||||
record_send_statistics(stat, locals, hubs, remotes, bau_desc);
|
record_send_statistics(stat, locals, hubs, remotes, bau_desc);
|
||||||
|
|
||||||
bau_desc->payload.address = start;
|
if (!end || (end - start) <= PAGE_SIZE)
|
||||||
|
bau_desc->payload.address = start;
|
||||||
|
else
|
||||||
|
bau_desc->payload.address = TLB_FLUSH_ALL;
|
||||||
bau_desc->payload.sending_cpu = cpu;
|
bau_desc->payload.sending_cpu = cpu;
|
||||||
/*
|
/*
|
||||||
* uv_flush_send_and_wait returns 0 if all cpu's were messaged,
|
* uv_flush_send_and_wait returns 0 if all cpu's were messaged,
|
||||||
|
|
|
@ -250,7 +250,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
|
||||||
return acpi_rsdp;
|
return acpi_rsdp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (efi_enabled) {
|
if (efi_enabled(EFI_CONFIG_TABLES)) {
|
||||||
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
|
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
|
||||||
return efi.acpi20;
|
return efi.acpi20;
|
||||||
else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
|
else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
|
||||||
|
|
|
@ -471,7 +471,7 @@ void __init dmi_scan_machine(void)
|
||||||
char __iomem *p, *q;
|
char __iomem *p, *q;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (efi_enabled) {
|
if (efi_enabled(EFI_CONFIG_TABLES)) {
|
||||||
if (efi.smbios == EFI_INVALID_TABLE_ADDR)
|
if (efi.smbios == EFI_INVALID_TABLE_ADDR)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
|
@ -1782,7 +1782,7 @@ efivars_init(void)
|
||||||
printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
|
printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
|
||||||
EFIVARS_DATE);
|
EFIVARS_DATE);
|
||||||
|
|
||||||
if (!efi_enabled)
|
if (!efi_enabled(EFI_RUNTIME_SERVICES))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* For now we'll register the efi directory at /sys/firmware/efi */
|
/* For now we'll register the efi directory at /sys/firmware/efi */
|
||||||
|
@ -1822,7 +1822,7 @@ err_put:
|
||||||
static void __exit
|
static void __exit
|
||||||
efivars_exit(void)
|
efivars_exit(void)
|
||||||
{
|
{
|
||||||
if (efi_enabled) {
|
if (efi_enabled(EFI_RUNTIME_SERVICES)) {
|
||||||
unregister_efivars(&__efivars);
|
unregister_efivars(&__efivars);
|
||||||
kobject_put(efi_kobj);
|
kobject_put(efi_kobj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
|
||||||
/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
|
/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
|
||||||
* only use ACPI for this */
|
* only use ACPI for this */
|
||||||
|
|
||||||
if (!efi_enabled)
|
if (!efi_enabled(EFI_BOOT))
|
||||||
find_ibft_in_mem();
|
find_ibft_in_mem();
|
||||||
|
|
||||||
if (ibft_addr) {
|
if (ibft_addr) {
|
||||||
|
|
|
@ -429,7 +429,8 @@ bool radeon_card_posted(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
|
||||||
if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE)
|
if (efi_enabled(EFI_BOOT) &&
|
||||||
|
rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* first check CRTCs */
|
/* first check CRTCs */
|
||||||
|
|
|
@ -244,7 +244,7 @@ static int __init ibm_rtl_init(void) {
|
||||||
if (force)
|
if (force)
|
||||||
pr_warn("module loaded by force\n");
|
pr_warn("module loaded by force\n");
|
||||||
/* first ensure that we are running on IBM HW */
|
/* first ensure that we are running on IBM HW */
|
||||||
else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table))
|
else if (efi_enabled(EFI_BOOT) || !dmi_check_system(ibm_rtl_dmi_table))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* Get the address for the Extended BIOS Data Area */
|
/* Get the address for the Extended BIOS Data Area */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/efi.h>
|
||||||
#include <acpi/video.h>
|
#include <acpi/video.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1544,6 +1545,9 @@ static int __init samsung_init(void)
|
||||||
struct samsung_laptop *samsung;
|
struct samsung_laptop *samsung;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (efi_enabled(EFI_BOOT))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
quirks = &samsung_unknown;
|
quirks = &samsung_unknown;
|
||||||
if (!force && !dmi_check_system(samsung_dmi_table))
|
if (!force && !dmi_check_system(samsung_dmi_table))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
|
@ -633,7 +633,7 @@ static int isci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
pci_set_drvdata(pdev, pci_info);
|
pci_set_drvdata(pdev, pci_info);
|
||||||
|
|
||||||
if (efi_enabled)
|
if (efi_enabled(EFI_RUNTIME_SERVICES))
|
||||||
orom = isci_get_efi_var(pdev);
|
orom = isci_get_efi_var(pdev);
|
||||||
|
|
||||||
if (!orom)
|
if (!orom)
|
||||||
|
|
|
@ -618,18 +618,30 @@ extern int __init efi_setup_pcdp_console(char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We play games with efi_enabled so that the compiler will, if possible, remove
|
* We play games with efi_enabled so that the compiler will, if
|
||||||
* EFI-related code altogether.
|
* possible, remove EFI-related code altogether.
|
||||||
*/
|
*/
|
||||||
|
#define EFI_BOOT 0 /* Were we booted from EFI? */
|
||||||
|
#define EFI_SYSTEM_TABLES 1 /* Can we use EFI system tables? */
|
||||||
|
#define EFI_CONFIG_TABLES 2 /* Can we use EFI config tables? */
|
||||||
|
#define EFI_RUNTIME_SERVICES 3 /* Can we use runtime services? */
|
||||||
|
#define EFI_MEMMAP 4 /* Can we use EFI memory map? */
|
||||||
|
#define EFI_64BIT 5 /* Is the firmware 64-bit? */
|
||||||
|
|
||||||
#ifdef CONFIG_EFI
|
#ifdef CONFIG_EFI
|
||||||
# ifdef CONFIG_X86
|
# ifdef CONFIG_X86
|
||||||
extern int efi_enabled;
|
extern int efi_enabled(int facility);
|
||||||
extern bool efi_64bit;
|
|
||||||
# else
|
# else
|
||||||
# define efi_enabled 1
|
static inline int efi_enabled(int facility)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define efi_enabled 0
|
static inline int efi_enabled(int facility)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -604,7 +604,7 @@ asmlinkage void __init start_kernel(void)
|
||||||
pidmap_init();
|
pidmap_init();
|
||||||
anon_vma_init();
|
anon_vma_init();
|
||||||
#ifdef CONFIG_X86
|
#ifdef CONFIG_X86
|
||||||
if (efi_enabled)
|
if (efi_enabled(EFI_RUNTIME_SERVICES))
|
||||||
efi_enter_virtual_mode();
|
efi_enter_virtual_mode();
|
||||||
#endif
|
#endif
|
||||||
thread_info_cache_init();
|
thread_info_cache_init();
|
||||||
|
@ -632,7 +632,7 @@ asmlinkage void __init start_kernel(void)
|
||||||
acpi_early_init(); /* before LAPIC and SMP init */
|
acpi_early_init(); /* before LAPIC and SMP init */
|
||||||
sfi_init_late();
|
sfi_init_late();
|
||||||
|
|
||||||
if (efi_enabled) {
|
if (efi_enabled(EFI_RUNTIME_SERVICES)) {
|
||||||
efi_late_init();
|
efi_late_init();
|
||||||
efi_free_boot_services();
|
efi_free_boot_services();
|
||||||
}
|
}
|
||||||
|
|
13
kernel/smp.c
13
kernel/smp.c
|
@ -33,6 +33,7 @@ struct call_function_data {
|
||||||
struct call_single_data csd;
|
struct call_single_data csd;
|
||||||
atomic_t refs;
|
atomic_t refs;
|
||||||
cpumask_var_t cpumask;
|
cpumask_var_t cpumask;
|
||||||
|
cpumask_var_t cpumask_ipi;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data);
|
static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data);
|
||||||
|
@ -56,6 +57,9 @@ hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
|
||||||
if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL,
|
if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL,
|
||||||
cpu_to_node(cpu)))
|
cpu_to_node(cpu)))
|
||||||
return notifier_from_errno(-ENOMEM);
|
return notifier_from_errno(-ENOMEM);
|
||||||
|
if (!zalloc_cpumask_var_node(&cfd->cpumask_ipi, GFP_KERNEL,
|
||||||
|
cpu_to_node(cpu)))
|
||||||
|
return notifier_from_errno(-ENOMEM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
@ -65,6 +69,7 @@ hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
|
||||||
case CPU_DEAD:
|
case CPU_DEAD:
|
||||||
case CPU_DEAD_FROZEN:
|
case CPU_DEAD_FROZEN:
|
||||||
free_cpumask_var(cfd->cpumask);
|
free_cpumask_var(cfd->cpumask);
|
||||||
|
free_cpumask_var(cfd->cpumask_ipi);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -526,6 +531,12 @@ void smp_call_function_many(const struct cpumask *mask,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After we put an entry into the list, data->cpumask
|
||||||
|
* may be cleared again when another CPU sends another IPI for
|
||||||
|
* a SMP function call, so data->cpumask will be zero.
|
||||||
|
*/
|
||||||
|
cpumask_copy(data->cpumask_ipi, data->cpumask);
|
||||||
raw_spin_lock_irqsave(&call_function.lock, flags);
|
raw_spin_lock_irqsave(&call_function.lock, flags);
|
||||||
/*
|
/*
|
||||||
* Place entry at the _HEAD_ of the list, so that any cpu still
|
* Place entry at the _HEAD_ of the list, so that any cpu still
|
||||||
|
@ -549,7 +560,7 @@ void smp_call_function_many(const struct cpumask *mask,
|
||||||
smp_mb();
|
smp_mb();
|
||||||
|
|
||||||
/* Send a message to all CPUs in the map */
|
/* Send a message to all CPUs in the map */
|
||||||
arch_send_call_function_ipi_mask(data->cpumask);
|
arch_send_call_function_ipi_mask(data->cpumask_ipi);
|
||||||
|
|
||||||
/* Optionally wait for the CPUs to complete */
|
/* Optionally wait for the CPUs to complete */
|
||||||
if (wait)
|
if (wait)
|
||||||
|
|
Loading…
Reference in New Issue