Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:
 "A number of fixes and some late updates:

   - make in_compat_syscall() behavior on x86-32 similar to other
     platforms, this touches a number of generic files but is not
     intended to impact non-x86 platforms.

   - objtool fixes

   - PAT preemption fix

   - paravirt fixes/cleanups

   - cpufeatures updates for new instructions

   - earlyprintk quirk

   - make microcode version in sysfs world-readable (it is already
     world-readable in procfs)

   - minor cleanups and fixes"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  compat: Cleanup in_compat_syscall() callers
  x86/compat: Adjust in_compat_syscall() to generic code under !COMPAT
  objtool: Support GCC 9 cold subfunction naming scheme
  x86/numa_emulation: Fix uniform-split numa emulation
  x86/paravirt: Remove unused _paravirt_ident_32
  x86/mm/pat: Disable preemption around __flush_tlb_all()
  x86/paravirt: Remove GPL from pv_ops export
  x86/traps: Use format string with panic() call
  x86: Clean up 'sizeof x' => 'sizeof(x)'
  x86/cpufeatures: Enumerate MOVDIR64B instruction
  x86/cpufeatures: Enumerate MOVDIRI instruction
  x86/earlyprintk: Add a force option for pciserial device
  objtool: Support per-function rodata sections
  x86/microcode: Make revision and processor flags world-readable
This commit is contained in:
Linus Torvalds 2018-11-03 18:25:17 -07:00
commit 601a88077c
47 changed files with 198 additions and 171 deletions

View File

@ -1068,7 +1068,7 @@
earlyprintk=serial[,0x...[,baudrate]] earlyprintk=serial[,0x...[,baudrate]]
earlyprintk=ttySn[,baudrate] earlyprintk=ttySn[,baudrate]
earlyprintk=dbgp[debugController#] earlyprintk=dbgp[debugController#]
earlyprintk=pciserial,bus:device.function[,baudrate] earlyprintk=pciserial[,force],bus:device.function[,baudrate]
earlyprintk=xdbc[xhciController#] earlyprintk=xdbc[xhciController#]
earlyprintk is useful when the kernel crashes before earlyprintk is useful when the kernel crashes before
@ -1100,6 +1100,10 @@
The sclp output can only be used on s390. The sclp output can only be used on s390.
The optional "force" to "pciserial" enables use of a
PCI device even when its classcode is not of the
UART class.
edac_report= [HW,EDAC] Control how to report EDAC event edac_report= [HW,EDAC] Control how to report EDAC event
Format: {"on" | "off" | "force"} Format: {"on" | "off" | "force"}
on: enable EDAC to report H/W event. May be overridden on: enable EDAC to report H/W event. May be overridden

View File

@ -113,7 +113,7 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
{ {
int err; int err;
memset(&cpu.flags, 0, sizeof cpu.flags); memset(&cpu.flags, 0, sizeof(cpu.flags));
cpu.level = 3; cpu.level = 3;
if (has_eflag(X86_EFLAGS_AC)) if (has_eflag(X86_EFLAGS_AC))

View File

@ -50,7 +50,7 @@ static void parse_earlyprintk(void)
int pos = 0; int pos = 0;
int port = 0; int port = 0;
if (cmdline_find_option("earlyprintk", arg, sizeof arg) > 0) { if (cmdline_find_option("earlyprintk", arg, sizeof(arg)) > 0) {
char *e; char *e;
if (!strncmp(arg, "serial", 6)) { if (!strncmp(arg, "serial", 6)) {
@ -124,7 +124,7 @@ static void parse_console_uart8250(void)
* console=uart8250,io,0x3f8,115200n8 * console=uart8250,io,0x3f8,115200n8
* need to make sure it is last one console ! * need to make sure it is last one console !
*/ */
if (cmdline_find_option("console", optstr, sizeof optstr) <= 0) if (cmdline_find_option("console", optstr, sizeof(optstr)) <= 0)
return; return;
options = optstr; options = optstr;

View File

@ -76,7 +76,7 @@ static int get_edd_info(u8 devno, struct edd_info *ei)
{ {
struct biosregs ireg, oreg; struct biosregs ireg, oreg;
memset(ei, 0, sizeof *ei); memset(ei, 0, sizeof(*ei));
/* Check Extensions Present */ /* Check Extensions Present */
@ -133,7 +133,7 @@ void query_edd(void)
struct edd_info ei, *edp; struct edd_info ei, *edp;
u32 *mbrptr; u32 *mbrptr;
if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) { if (cmdline_find_option("edd", eddarg, sizeof(eddarg)) > 0) {
if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip")) { if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip")) {
do_edd = 1; do_edd = 1;
do_mbr = 0; do_mbr = 0;
@ -166,7 +166,7 @@ void query_edd(void)
*/ */
if (!get_edd_info(devno, &ei) if (!get_edd_info(devno, &ei)
&& boot_params.eddbuf_entries < EDDMAXNR) { && boot_params.eddbuf_entries < EDDMAXNR) {
memcpy(edp, &ei, sizeof ei); memcpy(edp, &ei, sizeof(ei));
edp++; edp++;
boot_params.eddbuf_entries++; boot_params.eddbuf_entries++;
} }

View File

@ -36,8 +36,8 @@ static void copy_boot_params(void)
const struct old_cmdline * const oldcmd = const struct old_cmdline * const oldcmd =
(const struct old_cmdline *)OLD_CL_ADDRESS; (const struct old_cmdline *)OLD_CL_ADDRESS;
BUILD_BUG_ON(sizeof boot_params != 4096); BUILD_BUG_ON(sizeof(boot_params) != 4096);
memcpy(&boot_params.hdr, &hdr, sizeof hdr); memcpy(&boot_params.hdr, &hdr, sizeof(hdr));
if (!boot_params.hdr.cmd_line_ptr && if (!boot_params.hdr.cmd_line_ptr &&
oldcmd->cl_magic == OLD_CL_MAGIC) { oldcmd->cl_magic == OLD_CL_MAGIC) {

View File

@ -26,7 +26,7 @@ static int detect_memory_e820(void)
initregs(&ireg); initregs(&ireg);
ireg.ax = 0xe820; ireg.ax = 0xe820;
ireg.cx = sizeof buf; ireg.cx = sizeof(buf);
ireg.edx = SMAP; ireg.edx = SMAP;
ireg.di = (size_t)&buf; ireg.di = (size_t)&buf;

View File

@ -21,7 +21,7 @@
void initregs(struct biosregs *reg) void initregs(struct biosregs *reg)
{ {
memset(reg, 0, sizeof *reg); memset(reg, 0, sizeof(*reg));
reg->eflags |= X86_EFLAGS_CF; reg->eflags |= X86_EFLAGS_CF;
reg->ds = ds(); reg->ds = ds();
reg->es = ds(); reg->es = ds();

View File

@ -62,7 +62,7 @@ static int vesa_probe(void)
if (mode & ~0x1ff) if (mode & ~0x1ff)
continue; continue;
memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ memset(&vminfo, 0, sizeof(vminfo)); /* Just in case... */
ireg.ax = 0x4f01; ireg.ax = 0x4f01;
ireg.cx = mode; ireg.cx = mode;
@ -109,7 +109,7 @@ static int vesa_set_mode(struct mode_info *mode)
int is_graphic; int is_graphic;
u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA; u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ memset(&vminfo, 0, sizeof(vminfo)); /* Just in case... */
initregs(&ireg); initregs(&ireg);
ireg.ax = 0x4f01; ireg.ax = 0x4f01;
@ -241,7 +241,7 @@ void vesa_store_edid(void)
struct biosregs ireg, oreg; struct biosregs ireg, oreg;
/* Apparently used as a nonsense token... */ /* Apparently used as a nonsense token... */
memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info); memset(&boot_params.edid_info, 0x13, sizeof(boot_params.edid_info));
if (vginfo.version < 0x0200) if (vginfo.version < 0x0200)
return; /* EDID requires VBE 2.0+ */ return; /* EDID requires VBE 2.0+ */

View File

@ -115,7 +115,7 @@ static unsigned int get_entry(void)
} else if ((key >= '0' && key <= '9') || } else if ((key >= '0' && key <= '9') ||
(key >= 'A' && key <= 'Z') || (key >= 'A' && key <= 'Z') ||
(key >= 'a' && key <= 'z')) { (key >= 'a' && key <= 'z')) {
if (len < sizeof entry_buf) { if (len < sizeof(entry_buf)) {
entry_buf[len++] = key; entry_buf[len++] = key;
putchar(key); putchar(key);
} }

View File

@ -4535,7 +4535,7 @@ __init int intel_pmu_init(void)
} }
} }
snprintf(pmu_name_str, sizeof pmu_name_str, "%s", name); snprintf(pmu_name_str, sizeof(pmu_name_str), "%s", name);
if (version >= 2 && extra_attr) { if (version >= 2 && extra_attr) {
x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr, x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr,

View File

@ -217,11 +217,18 @@ static inline bool in_x32_syscall(void)
return false; return false;
} }
static inline bool in_compat_syscall(void) static inline bool in_32bit_syscall(void)
{ {
return in_ia32_syscall() || in_x32_syscall(); return in_ia32_syscall() || in_x32_syscall();
} }
#ifdef CONFIG_COMPAT
static inline bool in_compat_syscall(void)
{
return in_32bit_syscall();
}
#define in_compat_syscall in_compat_syscall /* override the generic impl */ #define in_compat_syscall in_compat_syscall /* override the generic impl */
#endif
struct compat_siginfo; struct compat_siginfo;
int __copy_siginfo_to_user32(struct compat_siginfo __user *to, int __copy_siginfo_to_user32(struct compat_siginfo __user *to,

View File

@ -331,6 +331,8 @@
#define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */ #define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */
#define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */ #define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */
#define X86_FEATURE_CLDEMOTE (16*32+25) /* CLDEMOTE instruction */ #define X86_FEATURE_CLDEMOTE (16*32+25) /* CLDEMOTE instruction */
#define X86_FEATURE_MOVDIRI (16*32+27) /* MOVDIRI instruction */
#define X86_FEATURE_MOVDIR64B (16*32+28) /* MOVDIR64B instruction */
/* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */ /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */
#define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* MCA overflow recovery support */ #define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* MCA overflow recovery support */

View File

@ -76,9 +76,7 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name
#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS 1 #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS 1
static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs) static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
{ {
if (in_compat_syscall()) return in_32bit_syscall();
return true;
return false;
} }
#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_IA32_EMULATION */ #endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_IA32_EMULATION */
#endif /* !COMPILE_OFFSETS */ #endif /* !COMPILE_OFFSETS */

View File

@ -361,7 +361,6 @@ extern struct paravirt_patch_template pv_ops;
__visible extern const char start_##ops##_##name[], end_##ops##_##name[]; \ __visible extern const char start_##ops##_##name[], end_##ops##_##name[]; \
asm(NATIVE_LABEL("start_", ops, name) code NATIVE_LABEL("end_", ops, name)) asm(NATIVE_LABEL("start_", ops, name) code NATIVE_LABEL("end_", ops, name))
unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len); unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
unsigned paravirt_patch_default(u8 type, void *insnbuf, unsigned paravirt_patch_default(u8 type, void *insnbuf,
unsigned long addr, unsigned len); unsigned long addr, unsigned len);
@ -651,7 +650,6 @@ void paravirt_leave_lazy_mmu(void);
void paravirt_flush_lazy_mmu(void); void paravirt_flush_lazy_mmu(void);
void _paravirt_nop(void); void _paravirt_nop(void);
u32 _paravirt_ident_32(u32);
u64 _paravirt_ident_64(u64); u64 _paravirt_ident_64(u64);
#define paravirt_nop ((void *)_paravirt_nop) #define paravirt_nop ((void *)_paravirt_nop)

View File

@ -453,6 +453,12 @@ static inline void __native_flush_tlb_one_user(unsigned long addr)
*/ */
static inline void __flush_tlb_all(void) static inline void __flush_tlb_all(void)
{ {
/*
* This is to catch users with enabled preemption and the PGE feature
* and don't trigger the warning in __native_flush_tlb().
*/
VM_WARN_ON_ONCE(preemptible());
if (boot_cpu_has(X86_FEATURE_PGE)) { if (boot_cpu_has(X86_FEATURE_PGE)) {
__flush_tlb_global(); __flush_tlb_global();
} else { } else {

View File

@ -1074,7 +1074,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
#endif #endif
c->x86_cache_alignment = c->x86_clflush_size; c->x86_cache_alignment = c->x86_clflush_size;
memset(&c->x86_capability, 0, sizeof c->x86_capability); memset(&c->x86_capability, 0, sizeof(c->x86_capability));
c->extended_cpuid_level = 0; c->extended_cpuid_level = 0;
if (!have_cpuid_p()) if (!have_cpuid_p())
@ -1317,7 +1317,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
c->x86_virt_bits = 32; c->x86_virt_bits = 32;
#endif #endif
c->x86_cache_alignment = c->x86_clflush_size; c->x86_cache_alignment = c->x86_clflush_size;
memset(&c->x86_capability, 0, sizeof c->x86_capability); memset(&c->x86_capability, 0, sizeof(c->x86_capability));
generic_identify(c); generic_identify(c);

View File

@ -2215,7 +2215,7 @@ static int mce_device_create(unsigned int cpu)
if (dev) if (dev)
return 0; return 0;
dev = kzalloc(sizeof *dev, GFP_KERNEL); dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
dev->id = cpu; dev->id = cpu;

View File

@ -666,8 +666,8 @@ static ssize_t pf_show(struct device *dev,
} }
static DEVICE_ATTR_WO(reload); static DEVICE_ATTR_WO(reload);
static DEVICE_ATTR(version, 0400, version_show, NULL); static DEVICE_ATTR(version, 0444, version_show, NULL);
static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL); static DEVICE_ATTR(processor_flags, 0444, pf_show, NULL);
static struct attribute *mc_default_attrs[] = { static struct attribute *mc_default_attrs[] = {
&dev_attr_version.attr, &dev_attr_version.attr,

View File

@ -798,7 +798,7 @@ static void generic_set_all(void)
local_irq_restore(flags); local_irq_restore(flags);
/* Use the atomic bitops to update the global mask */ /* Use the atomic bitops to update the global mask */
for (count = 0; count < sizeof mask * 8; ++count) { for (count = 0; count < sizeof(mask) * 8; ++count) {
if (mask & 0x01) if (mask & 0x01)
set_bit(count, &smp_changes_mask); set_bit(count, &smp_changes_mask);
mask >>= 1; mask >>= 1;

View File

@ -174,12 +174,12 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
case MTRRIOC_SET_PAGE_ENTRY: case MTRRIOC_SET_PAGE_ENTRY:
case MTRRIOC_DEL_PAGE_ENTRY: case MTRRIOC_DEL_PAGE_ENTRY:
case MTRRIOC_KILL_PAGE_ENTRY: case MTRRIOC_KILL_PAGE_ENTRY:
if (copy_from_user(&sentry, arg, sizeof sentry)) if (copy_from_user(&sentry, arg, sizeof(sentry)))
return -EFAULT; return -EFAULT;
break; break;
case MTRRIOC_GET_ENTRY: case MTRRIOC_GET_ENTRY:
case MTRRIOC_GET_PAGE_ENTRY: case MTRRIOC_GET_PAGE_ENTRY:
if (copy_from_user(&gentry, arg, sizeof gentry)) if (copy_from_user(&gentry, arg, sizeof(gentry)))
return -EFAULT; return -EFAULT;
break; break;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
@ -332,7 +332,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
switch (cmd) { switch (cmd) {
case MTRRIOC_GET_ENTRY: case MTRRIOC_GET_ENTRY:
case MTRRIOC_GET_PAGE_ENTRY: case MTRRIOC_GET_PAGE_ENTRY:
if (copy_to_user(arg, &gentry, sizeof gentry)) if (copy_to_user(arg, &gentry, sizeof(gentry)))
err = -EFAULT; err = -EFAULT;
break; break;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT

View File

@ -213,8 +213,9 @@ static unsigned int mem32_serial_in(unsigned long addr, int offset)
* early_pci_serial_init() * early_pci_serial_init()
* *
* This function is invoked when the early_printk param starts with "pciserial" * This function is invoked when the early_printk param starts with "pciserial"
* The rest of the param should be ",B:D.F,baud" where B, D & F describe the * The rest of the param should be "[force],B:D.F,baud", where B, D & F describe
* location of a PCI device that must be a UART device. * the location of a PCI device that must be a UART device. "force" is optional
* and overrides the use of an UART device with a wrong PCI class code.
*/ */
static __init void early_pci_serial_init(char *s) static __init void early_pci_serial_init(char *s)
{ {
@ -224,17 +225,23 @@ static __init void early_pci_serial_init(char *s)
u32 classcode, bar0; u32 classcode, bar0;
u16 cmdreg; u16 cmdreg;
char *e; char *e;
int force = 0;
/*
* First, part the param to get the BDF values
*/
if (*s == ',') if (*s == ',')
++s; ++s;
if (*s == 0) if (*s == 0)
return; return;
/* Force the use of an UART device with wrong class code */
if (!strncmp(s, "force,", 6)) {
force = 1;
s += 6;
}
/*
* Part the param to get the BDF values
*/
bus = (u8)simple_strtoul(s, &e, 16); bus = (u8)simple_strtoul(s, &e, 16);
s = e; s = e;
if (*s != ':') if (*s != ':')
@ -253,7 +260,7 @@ static __init void early_pci_serial_init(char *s)
s++; s++;
/* /*
* Second, find the device from the BDF * Find the device from the BDF
*/ */
cmdreg = read_pci_config(bus, slot, func, PCI_COMMAND); cmdreg = read_pci_config(bus, slot, func, PCI_COMMAND);
classcode = read_pci_config(bus, slot, func, PCI_CLASS_REVISION); classcode = read_pci_config(bus, slot, func, PCI_CLASS_REVISION);
@ -264,8 +271,10 @@ static __init void early_pci_serial_init(char *s)
*/ */
if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) && if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) &&
(classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) || (classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) ||
(((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */ (((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */ {
return; if (!force)
return;
}
/* /*
* Determine if it is IO or memory mapped * Determine if it is IO or memory mapped
@ -289,7 +298,7 @@ static __init void early_pci_serial_init(char *s)
} }
/* /*
* Lastly, initialize the hardware * Initialize the hardware
*/ */
if (*s) { if (*s) {
if (strcmp(s, "nocfg") == 0) if (strcmp(s, "nocfg") == 0)

View File

@ -385,7 +385,7 @@ static void __init copy_bootdata(char *real_mode_data)
*/ */
sme_map_bootdata(real_mode_data); sme_map_bootdata(real_mode_data);
memcpy(&boot_params, real_mode_data, sizeof boot_params); memcpy(&boot_params, real_mode_data, sizeof(boot_params));
sanitize_boot_params(&boot_params); sanitize_boot_params(&boot_params);
cmd_line_ptr = get_cmd_line_ptr(); cmd_line_ptr = get_cmd_line_ptr();
if (cmd_line_ptr) { if (cmd_line_ptr) {

View File

@ -115,14 +115,14 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
err = -EBADF; err = -EBADF;
break; break;
} }
if (copy_from_user(&regs, uregs, sizeof regs)) { if (copy_from_user(&regs, uregs, sizeof(regs))) {
err = -EFAULT; err = -EFAULT;
break; break;
} }
err = rdmsr_safe_regs_on_cpu(cpu, regs); err = rdmsr_safe_regs_on_cpu(cpu, regs);
if (err) if (err)
break; break;
if (copy_to_user(uregs, &regs, sizeof regs)) if (copy_to_user(uregs, &regs, sizeof(regs)))
err = -EFAULT; err = -EFAULT;
break; break;
@ -131,14 +131,14 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
err = -EBADF; err = -EBADF;
break; break;
} }
if (copy_from_user(&regs, uregs, sizeof regs)) { if (copy_from_user(&regs, uregs, sizeof(regs))) {
err = -EFAULT; err = -EFAULT;
break; break;
} }
err = wrmsr_safe_regs_on_cpu(cpu, regs); err = wrmsr_safe_regs_on_cpu(cpu, regs);
if (err) if (err)
break; break;
if (copy_to_user(uregs, &regs, sizeof regs)) if (copy_to_user(uregs, &regs, sizeof(regs)))
err = -EFAULT; err = -EFAULT;
break; break;

View File

@ -56,17 +56,6 @@ asm (".pushsection .entry.text, \"ax\"\n"
".type _paravirt_nop, @function\n\t" ".type _paravirt_nop, @function\n\t"
".popsection"); ".popsection");
/* identity function, which can be inlined */
u32 notrace _paravirt_ident_32(u32 x)
{
return x;
}
u64 notrace _paravirt_ident_64(u64 x)
{
return x;
}
void __init default_banner(void) void __init default_banner(void)
{ {
printk(KERN_INFO "Booting paravirtualized kernel on %s\n", printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
@ -102,6 +91,12 @@ static unsigned paravirt_patch_call(void *insnbuf, const void *target,
} }
#ifdef CONFIG_PARAVIRT_XXL #ifdef CONFIG_PARAVIRT_XXL
/* identity function, which can be inlined */
u64 notrace _paravirt_ident_64(u64 x)
{
return x;
}
static unsigned paravirt_patch_jmp(void *insnbuf, const void *target, static unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
unsigned long addr, unsigned len) unsigned long addr, unsigned len)
{ {
@ -146,13 +141,11 @@ unsigned paravirt_patch_default(u8 type, void *insnbuf,
else if (opfunc == _paravirt_nop) else if (opfunc == _paravirt_nop)
ret = 0; ret = 0;
#ifdef CONFIG_PARAVIRT_XXL
/* identity functions just return their single argument */ /* identity functions just return their single argument */
else if (opfunc == _paravirt_ident_32)
ret = paravirt_patch_ident_32(insnbuf, len);
else if (opfunc == _paravirt_ident_64) else if (opfunc == _paravirt_ident_64)
ret = paravirt_patch_ident_64(insnbuf, len); ret = paravirt_patch_ident_64(insnbuf, len);
#ifdef CONFIG_PARAVIRT_XXL
else if (type == PARAVIRT_PATCH(cpu.iret) || else if (type == PARAVIRT_PATCH(cpu.iret) ||
type == PARAVIRT_PATCH(cpu.usergs_sysret64)) type == PARAVIRT_PATCH(cpu.usergs_sysret64))
/* If operation requires a jmp, then jmp */ /* If operation requires a jmp, then jmp */
@ -309,13 +302,8 @@ struct pv_info pv_info = {
#endif #endif
}; };
#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
/* 32-bit pagetable entries */
#define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_32)
#else
/* 64-bit pagetable entries */ /* 64-bit pagetable entries */
#define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64)
#endif
struct paravirt_patch_template pv_ops = { struct paravirt_patch_template pv_ops = {
/* Init ops. */ /* Init ops. */
@ -483,5 +471,5 @@ NOKPROBE_SYMBOL(native_set_debugreg);
NOKPROBE_SYMBOL(native_load_idt); NOKPROBE_SYMBOL(native_load_idt);
#endif #endif
EXPORT_SYMBOL_GPL(pv_ops); EXPORT_SYMBOL(pv_ops);
EXPORT_SYMBOL_GPL(pv_info); EXPORT_SYMBOL_GPL(pv_info);

View File

@ -10,24 +10,18 @@ DEF_NATIVE(cpu, iret, "iret");
DEF_NATIVE(mmu, read_cr2, "mov %cr2, %eax"); DEF_NATIVE(mmu, read_cr2, "mov %cr2, %eax");
DEF_NATIVE(mmu, write_cr3, "mov %eax, %cr3"); DEF_NATIVE(mmu, write_cr3, "mov %eax, %cr3");
DEF_NATIVE(mmu, read_cr3, "mov %cr3, %eax"); DEF_NATIVE(mmu, read_cr3, "mov %cr3, %eax");
#endif
#if defined(CONFIG_PARAVIRT_SPINLOCKS)
DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%eax)");
DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax");
#endif
unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len)
{
/* arg in %eax, return in %eax */
return 0;
}
unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len) unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len)
{ {
/* arg in %edx:%eax, return in %edx:%eax */ /* arg in %edx:%eax, return in %edx:%eax */
return 0; return 0;
} }
#endif
#if defined(CONFIG_PARAVIRT_SPINLOCKS)
DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%eax)");
DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax");
#endif
extern bool pv_is_native_spin_unlock(void); extern bool pv_is_native_spin_unlock(void);
extern bool pv_is_native_vcpu_is_preempted(void); extern bool pv_is_native_vcpu_is_preempted(void);

View File

@ -15,27 +15,19 @@ DEF_NATIVE(cpu, wbinvd, "wbinvd");
DEF_NATIVE(cpu, usergs_sysret64, "swapgs; sysretq"); DEF_NATIVE(cpu, usergs_sysret64, "swapgs; sysretq");
DEF_NATIVE(cpu, swapgs, "swapgs"); DEF_NATIVE(cpu, swapgs, "swapgs");
#endif
DEF_NATIVE(, mov32, "mov %edi, %eax");
DEF_NATIVE(, mov64, "mov %rdi, %rax"); DEF_NATIVE(, mov64, "mov %rdi, %rax");
#if defined(CONFIG_PARAVIRT_SPINLOCKS)
DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%rdi)");
DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax");
#endif
unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len)
{
return paravirt_patch_insns(insnbuf, len,
start__mov32, end__mov32);
}
unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len) unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len)
{ {
return paravirt_patch_insns(insnbuf, len, return paravirt_patch_insns(insnbuf, len,
start__mov64, end__mov64); start__mov64, end__mov64);
} }
#endif
#if defined(CONFIG_PARAVIRT_SPINLOCKS)
DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%rdi)");
DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax");
#endif
extern bool pv_is_native_spin_unlock(void); extern bool pv_is_native_spin_unlock(void);
extern bool pv_is_native_vcpu_is_preempted(void); extern bool pv_is_native_vcpu_is_preempted(void);

View File

@ -701,10 +701,10 @@ static void __set_personality_x32(void)
current->mm->context.ia32_compat = TIF_X32; current->mm->context.ia32_compat = TIF_X32;
current->personality &= ~READ_IMPLIES_EXEC; current->personality &= ~READ_IMPLIES_EXEC;
/* /*
* in_compat_syscall() uses the presence of the x32 syscall bit * in_32bit_syscall() uses the presence of the x32 syscall bit
* flag to determine compat status. The x86 mmap() code relies on * flag to determine compat status. The x86 mmap() code relies on
* the syscall bitness so set x32 syscall bit right here to make * the syscall bitness so set x32 syscall bit right here to make
* in_compat_syscall() work during exec(). * in_32bit_syscall() work during exec().
* *
* Pretend to come from a x32 execve. * Pretend to come from a x32 execve.
*/ */

View File

@ -105,7 +105,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
static void find_start_end(unsigned long addr, unsigned long flags, static void find_start_end(unsigned long addr, unsigned long flags,
unsigned long *begin, unsigned long *end) unsigned long *begin, unsigned long *end)
{ {
if (!in_compat_syscall() && (flags & MAP_32BIT)) { if (!in_32bit_syscall() && (flags & MAP_32BIT)) {
/* This is usually used needed to map code in small /* This is usually used needed to map code in small
model, so it needs to be in the first 31bit. Limit model, so it needs to be in the first 31bit. Limit
it to that. This means we need to move the it to that. This means we need to move the
@ -122,7 +122,7 @@ static void find_start_end(unsigned long addr, unsigned long flags,
} }
*begin = get_mmap_base(1); *begin = get_mmap_base(1);
if (in_compat_syscall()) if (in_32bit_syscall())
*end = task_size_32bit(); *end = task_size_32bit();
else else
*end = task_size_64bit(addr > DEFAULT_MAP_WINDOW); *end = task_size_64bit(addr > DEFAULT_MAP_WINDOW);
@ -193,7 +193,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr; return addr;
/* for MAP_32BIT mappings we force the legacy mmap base */ /* for MAP_32BIT mappings we force the legacy mmap base */
if (!in_compat_syscall() && (flags & MAP_32BIT)) if (!in_32bit_syscall() && (flags & MAP_32BIT))
goto bottomup; goto bottomup;
/* requesting a specific address */ /* requesting a specific address */
@ -217,9 +217,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
* If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area * If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
* in the full address space. * in the full address space.
* *
* !in_compat_syscall() check to avoid high addresses for x32. * !in_32bit_syscall() check to avoid high addresses for x32
* (and make it no op on native i386).
*/ */
if (addr > DEFAULT_MAP_WINDOW && !in_compat_syscall()) if (addr > DEFAULT_MAP_WINDOW && !in_32bit_syscall())
info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW; info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
info.align_mask = 0; info.align_mask = 0;

View File

@ -306,7 +306,7 @@ __visible void __noreturn handle_stack_overflow(const char *message,
die(message, regs, 0); die(message, regs, 0);
/* Be absolutely certain we don't return. */ /* Be absolutely certain we don't return. */
panic(message); panic("%s", message);
} }
#endif #endif

View File

@ -1509,7 +1509,7 @@ static int read_interrupt_descriptor(struct x86_emulate_ctxt *ctxt,
return emulate_gp(ctxt, index << 3 | 0x2); return emulate_gp(ctxt, index << 3 | 0x2);
addr = dt.address + index * 8; addr = dt.address + index * 8;
return linear_read_system(ctxt, addr, desc, sizeof *desc); return linear_read_system(ctxt, addr, desc, sizeof(*desc));
} }
static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt, static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt,
@ -1522,7 +1522,7 @@ static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt,
struct desc_struct desc; struct desc_struct desc;
u16 sel; u16 sel;
memset (dt, 0, sizeof *dt); memset(dt, 0, sizeof(*dt));
if (!ops->get_segment(ctxt, &sel, &desc, &base3, if (!ops->get_segment(ctxt, &sel, &desc, &base3,
VCPU_SREG_LDTR)) VCPU_SREG_LDTR))
return; return;
@ -1586,7 +1586,7 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
return rc; return rc;
return linear_write_system(ctxt, addr, desc, sizeof *desc); return linear_write_system(ctxt, addr, desc, sizeof(*desc));
} }
static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
@ -1604,7 +1604,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
u16 dummy; u16 dummy;
u32 base3 = 0; u32 base3 = 0;
memset(&seg_desc, 0, sizeof seg_desc); memset(&seg_desc, 0, sizeof(seg_desc));
if (ctxt->mode == X86EMUL_MODE_REAL) { if (ctxt->mode == X86EMUL_MODE_REAL) {
/* set real mode segment descriptor (keep limit etc. for /* set real mode segment descriptor (keep limit etc. for
@ -3075,17 +3075,17 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
int ret; int ret;
u32 new_tss_base = get_desc_base(new_desc); u32 new_tss_base = get_desc_base(new_desc);
ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof(tss_seg));
if (ret != X86EMUL_CONTINUE) if (ret != X86EMUL_CONTINUE)
return ret; return ret;
save_state_to_tss16(ctxt, &tss_seg); save_state_to_tss16(ctxt, &tss_seg);
ret = linear_write_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); ret = linear_write_system(ctxt, old_tss_base, &tss_seg, sizeof(tss_seg));
if (ret != X86EMUL_CONTINUE) if (ret != X86EMUL_CONTINUE)
return ret; return ret;
ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof(tss_seg));
if (ret != X86EMUL_CONTINUE) if (ret != X86EMUL_CONTINUE)
return ret; return ret;
@ -3094,7 +3094,7 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
ret = linear_write_system(ctxt, new_tss_base, ret = linear_write_system(ctxt, new_tss_base,
&tss_seg.prev_task_link, &tss_seg.prev_task_link,
sizeof tss_seg.prev_task_link); sizeof(tss_seg.prev_task_link));
if (ret != X86EMUL_CONTINUE) if (ret != X86EMUL_CONTINUE)
return ret; return ret;
} }
@ -3216,7 +3216,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
u32 eip_offset = offsetof(struct tss_segment_32, eip); u32 eip_offset = offsetof(struct tss_segment_32, eip);
u32 ldt_sel_offset = offsetof(struct tss_segment_32, ldt_selector); u32 ldt_sel_offset = offsetof(struct tss_segment_32, ldt_selector);
ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof(tss_seg));
if (ret != X86EMUL_CONTINUE) if (ret != X86EMUL_CONTINUE)
return ret; return ret;
@ -3228,7 +3228,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
if (ret != X86EMUL_CONTINUE) if (ret != X86EMUL_CONTINUE)
return ret; return ret;
ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof(tss_seg));
if (ret != X86EMUL_CONTINUE) if (ret != X86EMUL_CONTINUE)
return ret; return ret;
@ -3237,7 +3237,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
ret = linear_write_system(ctxt, new_tss_base, ret = linear_write_system(ctxt, new_tss_base,
&tss_seg.prev_task_link, &tss_seg.prev_task_link,
sizeof tss_seg.prev_task_link); sizeof(tss_seg.prev_task_link));
if (ret != X86EMUL_CONTINUE) if (ret != X86EMUL_CONTINUE)
return ret; return ret;
} }

View File

@ -2409,7 +2409,7 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
r = kvm_apic_state_fixup(vcpu, s, true); r = kvm_apic_state_fixup(vcpu, s, true);
if (r) if (r)
return r; return r;
memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s); memcpy(vcpu->arch.apic->regs, s->regs, sizeof(*s));
recalculate_apic_map(vcpu->kvm); recalculate_apic_map(vcpu->kvm);
kvm_apic_set_version(vcpu); kvm_apic_set_version(vcpu);

View File

@ -2924,7 +2924,7 @@ static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs,
unsigned size; unsigned size;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&msrs, user_msrs, sizeof msrs)) if (copy_from_user(&msrs, user_msrs, sizeof(msrs)))
goto out; goto out;
r = -E2BIG; r = -E2BIG;
@ -3091,11 +3091,11 @@ long kvm_arch_dev_ioctl(struct file *filp,
unsigned n; unsigned n;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) if (copy_from_user(&msr_list, user_msr_list, sizeof(msr_list)))
goto out; goto out;
n = msr_list.nmsrs; n = msr_list.nmsrs;
msr_list.nmsrs = num_msrs_to_save + num_emulated_msrs; msr_list.nmsrs = num_msrs_to_save + num_emulated_msrs;
if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) if (copy_to_user(user_msr_list, &msr_list, sizeof(msr_list)))
goto out; goto out;
r = -E2BIG; r = -E2BIG;
if (n < msr_list.nmsrs) if (n < msr_list.nmsrs)
@ -3117,7 +3117,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
struct kvm_cpuid2 cpuid; struct kvm_cpuid2 cpuid;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid)))
goto out; goto out;
r = kvm_dev_ioctl_get_cpuid(&cpuid, cpuid_arg->entries, r = kvm_dev_ioctl_get_cpuid(&cpuid, cpuid_arg->entries,
@ -3126,7 +3126,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
goto out; goto out;
r = -EFAULT; r = -EFAULT;
if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid)) if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid)))
goto out; goto out;
r = 0; r = 0;
break; break;
@ -3894,7 +3894,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_interrupt irq; struct kvm_interrupt irq;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&irq, argp, sizeof irq)) if (copy_from_user(&irq, argp, sizeof(irq)))
goto out; goto out;
r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); r = kvm_vcpu_ioctl_interrupt(vcpu, &irq);
break; break;
@ -3912,7 +3912,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_cpuid cpuid; struct kvm_cpuid cpuid;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid)))
goto out; goto out;
r = kvm_vcpu_ioctl_set_cpuid(vcpu, &cpuid, cpuid_arg->entries); r = kvm_vcpu_ioctl_set_cpuid(vcpu, &cpuid, cpuid_arg->entries);
break; break;
@ -3922,7 +3922,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_cpuid2 cpuid; struct kvm_cpuid2 cpuid;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid)))
goto out; goto out;
r = kvm_vcpu_ioctl_set_cpuid2(vcpu, &cpuid, r = kvm_vcpu_ioctl_set_cpuid2(vcpu, &cpuid,
cpuid_arg->entries); cpuid_arg->entries);
@ -3933,14 +3933,14 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_cpuid2 cpuid; struct kvm_cpuid2 cpuid;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) if (copy_from_user(&cpuid, cpuid_arg, sizeof(cpuid)))
goto out; goto out;
r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid, r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid,
cpuid_arg->entries); cpuid_arg->entries);
if (r) if (r)
goto out; goto out;
r = -EFAULT; r = -EFAULT;
if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid)) if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid)))
goto out; goto out;
r = 0; r = 0;
break; break;
@ -3961,13 +3961,13 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_tpr_access_ctl tac; struct kvm_tpr_access_ctl tac;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&tac, argp, sizeof tac)) if (copy_from_user(&tac, argp, sizeof(tac)))
goto out; goto out;
r = vcpu_ioctl_tpr_access_reporting(vcpu, &tac); r = vcpu_ioctl_tpr_access_reporting(vcpu, &tac);
if (r) if (r)
goto out; goto out;
r = -EFAULT; r = -EFAULT;
if (copy_to_user(argp, &tac, sizeof tac)) if (copy_to_user(argp, &tac, sizeof(tac)))
goto out; goto out;
r = 0; r = 0;
break; break;
@ -3980,7 +3980,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
if (!lapic_in_kernel(vcpu)) if (!lapic_in_kernel(vcpu))
goto out; goto out;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&va, argp, sizeof va)) if (copy_from_user(&va, argp, sizeof(va)))
goto out; goto out;
idx = srcu_read_lock(&vcpu->kvm->srcu); idx = srcu_read_lock(&vcpu->kvm->srcu);
r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
@ -3991,7 +3991,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
u64 mcg_cap; u64 mcg_cap;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&mcg_cap, argp, sizeof mcg_cap)) if (copy_from_user(&mcg_cap, argp, sizeof(mcg_cap)))
goto out; goto out;
r = kvm_vcpu_ioctl_x86_setup_mce(vcpu, mcg_cap); r = kvm_vcpu_ioctl_x86_setup_mce(vcpu, mcg_cap);
break; break;
@ -4000,7 +4000,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_x86_mce mce; struct kvm_x86_mce mce;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&mce, argp, sizeof mce)) if (copy_from_user(&mce, argp, sizeof(mce)))
goto out; goto out;
r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce); r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce);
break; break;
@ -4536,7 +4536,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (kvm->created_vcpus) if (kvm->created_vcpus)
goto set_identity_unlock; goto set_identity_unlock;
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&ident_addr, argp, sizeof ident_addr)) if (copy_from_user(&ident_addr, argp, sizeof(ident_addr)))
goto set_identity_unlock; goto set_identity_unlock;
r = kvm_vm_ioctl_set_identity_map_addr(kvm, ident_addr); r = kvm_vm_ioctl_set_identity_map_addr(kvm, ident_addr);
set_identity_unlock: set_identity_unlock:
@ -4620,7 +4620,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (r) if (r)
goto get_irqchip_out; goto get_irqchip_out;
r = -EFAULT; r = -EFAULT;
if (copy_to_user(argp, chip, sizeof *chip)) if (copy_to_user(argp, chip, sizeof(*chip)))
goto get_irqchip_out; goto get_irqchip_out;
r = 0; r = 0;
get_irqchip_out: get_irqchip_out:
@ -4666,7 +4666,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
} }
case KVM_SET_PIT: { case KVM_SET_PIT: {
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&u.ps, argp, sizeof u.ps)) if (copy_from_user(&u.ps, argp, sizeof(u.ps)))
goto out; goto out;
r = -ENXIO; r = -ENXIO;
if (!kvm->arch.vpit) if (!kvm->arch.vpit)
@ -8205,7 +8205,7 @@ static void __get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
sregs->efer = vcpu->arch.efer; sregs->efer = vcpu->arch.efer;
sregs->apic_base = kvm_get_apic_base(vcpu); sregs->apic_base = kvm_get_apic_base(vcpu);
memset(sregs->interrupt_bitmap, 0, sizeof sregs->interrupt_bitmap); memset(sregs->interrupt_bitmap, 0, sizeof(sregs->interrupt_bitmap));
if (vcpu->arch.interrupt.injected && !vcpu->arch.interrupt.soft) if (vcpu->arch.interrupt.injected && !vcpu->arch.interrupt.soft)
set_bit(vcpu->arch.interrupt.nr, set_bit(vcpu->arch.interrupt.nr,
@ -8509,7 +8509,7 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
fpu->last_opcode = fxsave->fop; fpu->last_opcode = fxsave->fop;
fpu->last_ip = fxsave->rip; fpu->last_ip = fxsave->rip;
fpu->last_dp = fxsave->rdp; fpu->last_dp = fxsave->rdp;
memcpy(fpu->xmm, fxsave->xmm_space, sizeof fxsave->xmm_space); memcpy(fpu->xmm, fxsave->xmm_space, sizeof(fxsave->xmm_space));
vcpu_put(vcpu); vcpu_put(vcpu);
return 0; return 0;
@ -8530,7 +8530,7 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
fxsave->fop = fpu->last_opcode; fxsave->fop = fpu->last_opcode;
fxsave->rip = fpu->last_ip; fxsave->rip = fpu->last_ip;
fxsave->rdp = fpu->last_dp; fxsave->rdp = fpu->last_dp;
memcpy(fxsave->xmm_space, fpu->xmm, sizeof fxsave->xmm_space); memcpy(fxsave->xmm_space, fpu->xmm, sizeof(fxsave->xmm_space));
vcpu_put(vcpu); vcpu_put(vcpu);
return 0; return 0;

View File

@ -92,7 +92,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
* If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area * If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
* in the full address space. * in the full address space.
*/ */
info.high_limit = in_compat_syscall() ? info.high_limit = in_32bit_syscall() ?
task_size_32bit() : task_size_64bit(addr > DEFAULT_MAP_WINDOW); task_size_32bit() : task_size_64bit(addr > DEFAULT_MAP_WINDOW);
info.align_mask = PAGE_MASK & ~huge_page_mask(h); info.align_mask = PAGE_MASK & ~huge_page_mask(h);
@ -116,7 +116,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
* If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area * If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
* in the full address space. * in the full address space.
*/ */
if (addr > DEFAULT_MAP_WINDOW && !in_compat_syscall()) if (addr > DEFAULT_MAP_WINDOW && !in_32bit_syscall())
info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW; info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
info.align_mask = PAGE_MASK & ~huge_page_mask(h); info.align_mask = PAGE_MASK & ~huge_page_mask(h);

View File

@ -166,7 +166,7 @@ unsigned long get_mmap_base(int is_legacy)
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES #ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
if (in_compat_syscall()) { if (in_32bit_syscall()) {
return is_legacy ? mm->mmap_compat_legacy_base return is_legacy ? mm->mmap_compat_legacy_base
: mm->mmap_compat_base; : mm->mmap_compat_base;
} }

View File

@ -399,9 +399,17 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
n = simple_strtoul(emu_cmdline, &emu_cmdline, 0); n = simple_strtoul(emu_cmdline, &emu_cmdline, 0);
ret = -1; ret = -1;
for_each_node_mask(i, physnode_mask) { for_each_node_mask(i, physnode_mask) {
/*
* The reason we pass in blk[0] is due to
* numa_remove_memblk_from() called by
* emu_setup_memblk() will delete entry 0
* and then move everything else up in the pi.blk
* array. Therefore we should always be looking
* at blk[0].
*/
ret = split_nodes_size_interleave_uniform(&ei, &pi, ret = split_nodes_size_interleave_uniform(&ei, &pi,
pi.blk[i].start, pi.blk[i].end, 0, pi.blk[0].start, pi.blk[0].end, 0,
n, &pi.blk[i], nid); n, &pi.blk[0], nid);
if (ret < 0) if (ret < 0)
break; break;
if (ret < n) { if (ret < n) {

View File

@ -2309,9 +2309,13 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
/* /*
* We should perform an IPI and flush all tlbs, * We should perform an IPI and flush all tlbs,
* but that can deadlock->flush only current cpu: * but that can deadlock->flush only current cpu.
* Preemption needs to be disabled around __flush_tlb_all() due to
* CR3 reload in __native_flush_tlb().
*/ */
preempt_disable();
__flush_tlb_all(); __flush_tlb_all();
preempt_enable();
arch_flush_lazy_mmu_mode(); arch_flush_lazy_mmu_mode();
} }

View File

@ -130,7 +130,7 @@ static void regex_init(int use_real_mode)
REG_EXTENDED|REG_NOSUB); REG_EXTENDED|REG_NOSUB);
if (err) { if (err) {
regerror(err, &sym_regex_c[i], errbuf, sizeof errbuf); regerror(err, &sym_regex_c[i], errbuf, sizeof(errbuf));
die("%s", errbuf); die("%s", errbuf);
} }
} }
@ -405,7 +405,7 @@ static void read_shdrs(FILE *fp)
} }
for (i = 0; i < ehdr.e_shnum; i++) { for (i = 0; i < ehdr.e_shnum; i++) {
struct section *sec = &secs[i]; struct section *sec = &secs[i];
if (fread(&shdr, sizeof shdr, 1, fp) != 1) if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
die("Cannot read ELF section headers %d/%d: %s\n", die("Cannot read ELF section headers %d/%d: %s\n",
i, ehdr.e_shnum, strerror(errno)); i, ehdr.e_shnum, strerror(errno));
sec->shdr.sh_name = elf_word_to_cpu(shdr.sh_name); sec->shdr.sh_name = elf_word_to_cpu(shdr.sh_name);

View File

@ -194,7 +194,7 @@ extern unsigned long um_vdso_addr;
typedef unsigned long elf_greg_t; typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) #define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG]; typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct user_i387_struct elf_fpregset_t; typedef struct user_i387_struct elf_fpregset_t;

View File

@ -229,14 +229,6 @@ sanity_check(struct efi_variable *var, efi_char16_t *name, efi_guid_t vendor,
return 0; return 0;
} }
static inline bool is_compat(void)
{
if (IS_ENABLED(CONFIG_COMPAT) && in_compat_syscall())
return true;
return false;
}
static void static void
copy_out_compat(struct efi_variable *dst, struct compat_efi_variable *src) copy_out_compat(struct efi_variable *dst, struct compat_efi_variable *src)
{ {
@ -263,7 +255,7 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
u8 *data; u8 *data;
int err; int err;
if (is_compat()) { if (in_compat_syscall()) {
struct compat_efi_variable *compat; struct compat_efi_variable *compat;
if (count != sizeof(*compat)) if (count != sizeof(*compat))
@ -324,7 +316,7 @@ efivar_show_raw(struct efivar_entry *entry, char *buf)
&entry->var.DataSize, entry->var.Data)) &entry->var.DataSize, entry->var.Data))
return -EIO; return -EIO;
if (is_compat()) { if (in_compat_syscall()) {
compat = (struct compat_efi_variable *)buf; compat = (struct compat_efi_variable *)buf;
size = sizeof(*compat); size = sizeof(*compat);
@ -418,7 +410,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
struct compat_efi_variable *compat = (struct compat_efi_variable *)buf; struct compat_efi_variable *compat = (struct compat_efi_variable *)buf;
struct efi_variable *new_var = (struct efi_variable *)buf; struct efi_variable *new_var = (struct efi_variable *)buf;
struct efivar_entry *new_entry; struct efivar_entry *new_entry;
bool need_compat = is_compat(); bool need_compat = in_compat_syscall();
efi_char16_t *name; efi_char16_t *name;
unsigned long size; unsigned long size;
u32 attributes; u32 attributes;
@ -495,7 +487,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EACCES; return -EACCES;
if (is_compat()) { if (in_compat_syscall()) {
if (count != sizeof(*compat)) if (count != sizeof(*compat))
return -EINVAL; return -EINVAL;

View File

@ -1032,9 +1032,9 @@ int kcompat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
#else /* !CONFIG_COMPAT */ #else /* !CONFIG_COMPAT */
#define is_compat_task() (0) #define is_compat_task() (0)
#ifndef in_compat_syscall /* Ensure no one redefines in_compat_syscall() under !CONFIG_COMPAT */
#define in_compat_syscall in_compat_syscall
static inline bool in_compat_syscall(void) { return false; } static inline bool in_compat_syscall(void) { return false; }
#endif
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */

View File

@ -842,7 +842,7 @@ int get_timespec64(struct timespec64 *ts,
ts->tv_sec = kts.tv_sec; ts->tv_sec = kts.tv_sec;
/* Zero out the padding for 32 bit systems or in compat mode */ /* Zero out the padding for 32 bit systems or in compat mode */
if (IS_ENABLED(CONFIG_64BIT_TIME) && (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall())) if (IS_ENABLED(CONFIG_64BIT_TIME) && in_compat_syscall())
kts.tv_nsec &= 0xFFFFFFFFUL; kts.tv_nsec &= 0xFFFFFFFFUL;
ts->tv_nsec = kts.tv_nsec; ts->tv_nsec = kts.tv_nsec;

View File

@ -2077,10 +2077,8 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
struct xfrm_mgr *km; struct xfrm_mgr *km;
struct xfrm_policy *pol = NULL; struct xfrm_policy *pol = NULL;
#ifdef CONFIG_COMPAT
if (in_compat_syscall()) if (in_compat_syscall())
return -EOPNOTSUPP; return -EOPNOTSUPP;
#endif
if (!optval && !optlen) { if (!optval && !optlen) {
xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL); xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);

View File

@ -2621,10 +2621,8 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
const struct xfrm_link *link; const struct xfrm_link *link;
int type, err; int type, err;
#ifdef CONFIG_COMPAT
if (in_compat_syscall()) if (in_compat_syscall())
return -EOPNOTSUPP; return -EOPNOTSUPP;
#endif
type = nlh->nlmsg_type; type = nlh->nlmsg_type;
if (type > XFRM_MSG_MAX) if (type > XFRM_MSG_MAX)

View File

@ -836,7 +836,7 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn,
struct symbol *pfunc = insn->func->pfunc; struct symbol *pfunc = insn->func->pfunc;
unsigned int prev_offset = 0; unsigned int prev_offset = 0;
list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) { list_for_each_entry_from(rela, &table->rela_sec->rela_list, list) {
if (rela == next_table) if (rela == next_table)
break; break;
@ -926,6 +926,7 @@ static struct rela *find_switch_table(struct objtool_file *file,
{ {
struct rela *text_rela, *rodata_rela; struct rela *text_rela, *rodata_rela;
struct instruction *orig_insn = insn; struct instruction *orig_insn = insn;
struct section *rodata_sec;
unsigned long table_offset; unsigned long table_offset;
/* /*
@ -953,10 +954,13 @@ static struct rela *find_switch_table(struct objtool_file *file,
/* look for a relocation which references .rodata */ /* look for a relocation which references .rodata */
text_rela = find_rela_by_dest_range(insn->sec, insn->offset, text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
insn->len); insn->len);
if (!text_rela || text_rela->sym != file->rodata->sym) if (!text_rela || text_rela->sym->type != STT_SECTION ||
!text_rela->sym->sec->rodata)
continue; continue;
table_offset = text_rela->addend; table_offset = text_rela->addend;
rodata_sec = text_rela->sym->sec;
if (text_rela->type == R_X86_64_PC32) if (text_rela->type == R_X86_64_PC32)
table_offset += 4; table_offset += 4;
@ -964,10 +968,10 @@ static struct rela *find_switch_table(struct objtool_file *file,
* Make sure the .rodata address isn't associated with a * Make sure the .rodata address isn't associated with a
* symbol. gcc jump tables are anonymous data. * symbol. gcc jump tables are anonymous data.
*/ */
if (find_symbol_containing(file->rodata, table_offset)) if (find_symbol_containing(rodata_sec, table_offset))
continue; continue;
rodata_rela = find_rela_by_dest(file->rodata, table_offset); rodata_rela = find_rela_by_dest(rodata_sec, table_offset);
if (rodata_rela) { if (rodata_rela) {
/* /*
* Use of RIP-relative switch jumps is quite rare, and * Use of RIP-relative switch jumps is quite rare, and
@ -1052,7 +1056,7 @@ static int add_switch_table_alts(struct objtool_file *file)
struct symbol *func; struct symbol *func;
int ret; int ret;
if (!file->rodata || !file->rodata->rela) if (!file->rodata)
return 0; return 0;
for_each_sec(file, sec) { for_each_sec(file, sec) {
@ -1198,10 +1202,33 @@ static int read_retpoline_hints(struct objtool_file *file)
return 0; return 0;
} }
static void mark_rodata(struct objtool_file *file)
{
struct section *sec;
bool found = false;
/*
* This searches for the .rodata section or multiple .rodata.func_name
* sections if -fdata-sections is being used. The .str.1.1 and .str.1.8
* rodata sections are ignored as they don't contain jump tables.
*/
for_each_sec(file, sec) {
if (!strncmp(sec->name, ".rodata", 7) &&
!strstr(sec->name, ".str1.")) {
sec->rodata = true;
found = true;
}
}
file->rodata = found;
}
static int decode_sections(struct objtool_file *file) static int decode_sections(struct objtool_file *file)
{ {
int ret; int ret;
mark_rodata(file);
ret = decode_instructions(file); ret = decode_instructions(file);
if (ret) if (ret)
return ret; return ret;
@ -2171,7 +2198,6 @@ int check(const char *_objname, bool orc)
INIT_LIST_HEAD(&file.insn_list); INIT_LIST_HEAD(&file.insn_list);
hash_init(file.insn_hash); hash_init(file.insn_hash);
file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard"); file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
file.rodata = find_section_by_name(file.elf, ".rodata");
file.c_file = find_section_by_name(file.elf, ".comment"); file.c_file = find_section_by_name(file.elf, ".comment");
file.ignore_unreachables = no_unreachable; file.ignore_unreachables = no_unreachable;
file.hints = false; file.hints = false;

View File

@ -60,8 +60,8 @@ struct objtool_file {
struct elf *elf; struct elf *elf;
struct list_head insn_list; struct list_head insn_list;
DECLARE_HASHTABLE(insn_hash, 16); DECLARE_HASHTABLE(insn_hash, 16);
struct section *rodata, *whitelist; struct section *whitelist;
bool ignore_unreachables, c_file, hints; bool ignore_unreachables, c_file, hints, rodata;
}; };
int check(const char *objname, bool orc); int check(const char *objname, bool orc);

View File

@ -301,7 +301,7 @@ static int read_symbols(struct elf *elf)
if (sym->type != STT_FUNC) if (sym->type != STT_FUNC)
continue; continue;
sym->pfunc = sym->cfunc = sym; sym->pfunc = sym->cfunc = sym;
coldstr = strstr(sym->name, ".cold."); coldstr = strstr(sym->name, ".cold");
if (!coldstr) if (!coldstr)
continue; continue;
@ -379,6 +379,7 @@ static int read_relas(struct elf *elf)
rela->offset = rela->rela.r_offset; rela->offset = rela->rela.r_offset;
symndx = GELF_R_SYM(rela->rela.r_info); symndx = GELF_R_SYM(rela->rela.r_info);
rela->sym = find_symbol_by_index(elf, symndx); rela->sym = find_symbol_by_index(elf, symndx);
rela->rela_sec = sec;
if (!rela->sym) { if (!rela->sym) {
WARN("can't find rela entry symbol %d for %s", WARN("can't find rela entry symbol %d for %s",
symndx, sec->name); symndx, sec->name);

View File

@ -48,7 +48,7 @@ struct section {
char *name; char *name;
int idx; int idx;
unsigned int len; unsigned int len;
bool changed, text; bool changed, text, rodata;
}; };
struct symbol { struct symbol {
@ -68,6 +68,7 @@ struct rela {
struct list_head list; struct list_head list;
struct hlist_node hash; struct hlist_node hash;
GElf_Rela rela; GElf_Rela rela;
struct section *rela_sec;
struct symbol *sym; struct symbol *sym;
unsigned int type; unsigned int type;
unsigned long offset; unsigned long offset;