Generic kernels feed many operation through the "machvec" logic to get the correct form of the operation for the current system. "mmiowb()" is one of those operations. Although machvec is initialized very early in boot, it isn't early enough for a recent upstream kernel change that added mmiowb to the spin_unlock() path. Statically initialize the mmiowb field of machvec so that we won't die with a call through a NULL pointer. This should be safe because we do the real initialization of machvec before bringing up any addtional CPUs or doing any I/O. Fixes: 49ca6462fc9e ("ia64/mmiowb: Add unconditional mmiowb() to arch_spin_unlock()") Signed-off-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
78 lines
1.5 KiB
C
78 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <linux/module.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <asm/machvec.h>
|
|
|
|
#ifdef CONFIG_IA64_GENERIC
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/string.h>
|
|
|
|
#include <asm/page.h>
|
|
|
|
struct ia64_machine_vector ia64_mv = {
|
|
.mmiowb = ___ia64_mmiowb
|
|
};
|
|
EXPORT_SYMBOL(ia64_mv);
|
|
|
|
static struct ia64_machine_vector * __init
|
|
lookup_machvec (const char *name)
|
|
{
|
|
extern struct ia64_machine_vector machvec_start[];
|
|
extern struct ia64_machine_vector machvec_end[];
|
|
struct ia64_machine_vector *mv;
|
|
|
|
for (mv = machvec_start; mv < machvec_end; ++mv)
|
|
if (strcmp (mv->name, name) == 0)
|
|
return mv;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void __init
|
|
machvec_init (const char *name)
|
|
{
|
|
struct ia64_machine_vector *mv;
|
|
|
|
if (!name)
|
|
name = acpi_get_sysname();
|
|
mv = lookup_machvec(name);
|
|
if (!mv)
|
|
panic("generic kernel failed to find machine vector for"
|
|
" platform %s!", name);
|
|
|
|
ia64_mv = *mv;
|
|
printk(KERN_INFO "booting generic kernel on platform %s\n", name);
|
|
}
|
|
|
|
void __init
|
|
machvec_init_from_cmdline(const char *cmdline)
|
|
{
|
|
char str[64];
|
|
const char *start;
|
|
char *end;
|
|
|
|
if (! (start = strstr(cmdline, "machvec=")) )
|
|
return machvec_init(NULL);
|
|
|
|
strlcpy(str, start + strlen("machvec="), sizeof(str));
|
|
if ( (end = strchr(str, ' ')) )
|
|
*end = '\0';
|
|
|
|
return machvec_init(str);
|
|
}
|
|
|
|
#endif /* CONFIG_IA64_GENERIC */
|
|
|
|
void
|
|
machvec_setup (char **arg)
|
|
{
|
|
}
|
|
EXPORT_SYMBOL(machvec_setup);
|
|
|
|
void
|
|
machvec_timer_interrupt (int irq, void *dev_id)
|
|
{
|
|
}
|
|
EXPORT_SYMBOL(machvec_timer_interrupt);
|