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

Pull x86 fixes from Ingo Molnar:
 "Misc fixes:

   - fix hotplug bugs
   - fix irq live lock
   - fix various topology handling bugs
   - fix APIC ACK ordering
   - fix PV iopl handling
   - fix speling
   - fix/tweak memcpy_mcsafe() return value
   - fix fbcon bug
   - remove stray prototypes"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/msr: Remove unused native_read_tscp()
  x86/apic: Remove declaration of unused hw_nmi_is_cpu_stuck
  x86/oprofile/nmi: Add missing hotplug FROZEN handling
  x86/hpet: Use proper mask to modify hotplug action
  x86/apic/uv: Fix the hotplug notifier
  x86/apb/timer: Use proper mask to modify hotplug action
  x86/topology: Use total_cpus not nr_cpu_ids for logical packages
  x86/topology: Fix Intel HT disable
  x86/topology: Fix logical package mapping
  x86/irq: Cure live lock in fixup_irqs()
  x86/tsc: Prevent NULL pointer deref in calibrate_delay_is_known()
  x86/apic: Fix suspicious RCU usage in smp_trace_call_function_interrupt()
  x86/iopl: Fix iopl capability check on Xen PV
  x86/iopl/64: Properly context-switch IOPL on Xen PV
  selftests/x86: Add an iopl test
  x86/mm, x86/mce: Fix return type/value for memcpy_mcsafe()
  x86/video: Don't assume all FB devices are PCI devices
  arch/x86/irq: Purge useless handler declarations from hw_irq.h
  x86: Fix misspellings in comments
This commit is contained in:
Linus Torvalds 2016-03-24 09:47:32 -07:00
commit d88f48e128
61 changed files with 331 additions and 128 deletions

View File

@ -178,7 +178,7 @@ notrace static cycle_t vread_tsc(void)
/* /*
* GCC likes to generate cmov here, but this branch is extremely * GCC likes to generate cmov here, but this branch is extremely
* predictable (it's just a funciton of time and the likely is * predictable (it's just a function of time and the likely is
* very likely) and there's a data dependence, so force GCC * very likely) and there's a data dependence, so force GCC
* to generate a branch instead. I don't barrier() because * to generate a branch instead. I don't barrier() because
* we don't actually need a barrier, and if this function * we don't actually need a barrier, and if this function

View File

@ -649,7 +649,7 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event)
/* /*
* return the type of control flow change at address "from" * return the type of control flow change at address "from"
* intruction is not necessarily a branch (in case of interrupt). * instruction is not necessarily a branch (in case of interrupt).
* *
* The branch type returned also includes the priv level of the * The branch type returned also includes the priv level of the
* target of the control flow change (X86_BR_USER, X86_BR_KERNEL). * target of the control flow change (X86_BR_USER, X86_BR_KERNEL).

View File

@ -272,7 +272,7 @@ struct cpu_hw_events {
* events to select for counter rescheduling. * events to select for counter rescheduling.
* *
* Care must be taken as the rescheduling algorithm is O(n!) which * Care must be taken as the rescheduling algorithm is O(n!) which
* will increase scheduling cycles for an over-commited system * will increase scheduling cycles for an over-committed system
* dramatically. The number of such EVENT_CONSTRAINT_OVERLAP() macros * dramatically. The number of such EVENT_CONSTRAINT_OVERLAP() macros
* and its counter masks must be kept at a minimum. * and its counter masks must be kept at a minimum.
*/ */

View File

@ -643,8 +643,8 @@ static inline void entering_irq(void)
static inline void entering_ack_irq(void) static inline void entering_ack_irq(void)
{ {
ack_APIC_irq();
entering_irq(); entering_irq();
ack_APIC_irq();
} }
static inline void ipi_entering_ack_irq(void) static inline void ipi_entering_ack_irq(void)

View File

@ -52,7 +52,7 @@ int ftrace_int3_handler(struct pt_regs *regs);
* this screws up the trace output when tracing a ia32 task. * this screws up the trace output when tracing a ia32 task.
* Instead of reporting bogus syscalls, just do not trace them. * Instead of reporting bogus syscalls, just do not trace them.
* *
* If the user realy wants these, then they should use the * If the user really wants these, then they should use the
* raw syscall tracepoints with filtering. * raw syscall tracepoints with filtering.
*/ */
#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS 1 #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS 1

View File

@ -141,6 +141,7 @@ struct irq_alloc_info {
struct irq_cfg { struct irq_cfg {
unsigned int dest_apicid; unsigned int dest_apicid;
u8 vector; u8 vector;
u8 old_vector;
}; };
extern struct irq_cfg *irq_cfg(unsigned int irq); extern struct irq_cfg *irq_cfg(unsigned int irq);
@ -168,20 +169,6 @@ extern atomic_t irq_mis_count;
extern void elcr_set_level_irq(unsigned int irq); extern void elcr_set_level_irq(unsigned int irq);
/* SMP */
extern __visible void smp_apic_timer_interrupt(struct pt_regs *);
extern __visible void smp_spurious_interrupt(struct pt_regs *);
extern __visible void smp_x86_platform_ipi(struct pt_regs *);
extern __visible void smp_error_interrupt(struct pt_regs *);
#ifdef CONFIG_X86_IO_APIC
extern asmlinkage void smp_irq_move_cleanup_interrupt(void);
#endif
#ifdef CONFIG_SMP
extern __visible void smp_reschedule_interrupt(struct pt_regs *);
extern __visible void smp_call_function_interrupt(struct pt_regs *);
extern __visible void smp_call_function_single_interrupt(struct pt_regs *);
#endif
extern char irq_entries_start[]; extern char irq_entries_start[];
#ifdef CONFIG_TRACING #ifdef CONFIG_TRACING
#define trace_irq_entries_start irq_entries_start #define trace_irq_entries_start irq_entries_start

View File

@ -42,14 +42,6 @@ struct saved_msrs {
struct saved_msr *array; struct saved_msr *array;
}; };
static inline unsigned long long native_read_tscp(unsigned int *aux)
{
unsigned long low, high;
asm volatile(".byte 0x0f,0x01,0xf9"
: "=a" (low), "=d" (high), "=c" (*aux));
return low | ((u64)high << 32);
}
/* /*
* both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A" * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
* constraint has different meanings. For i386, "A" means exactly * constraint has different meanings. For i386, "A" means exactly

View File

@ -25,7 +25,7 @@
* This should be totally fair - if anything is waiting, a process that wants a * This should be totally fair - if anything is waiting, a process that wants a
* lock will go to the back of the queue. When the currently active lock is * lock will go to the back of the queue. When the currently active lock is
* released, if there's a writer at the front of the queue, then that and only * released, if there's a writer at the front of the queue, then that and only
* that will be woken up; if there's a bunch of consequtive readers at the * that will be woken up; if there's a bunch of consecutive readers at the
* front, then they'll all be woken up, but no other readers will be. * front, then they'll all be woken up, but no other readers will be.
*/ */

View File

@ -87,9 +87,9 @@ int strcmp(const char *cs, const char *ct);
* *
* Low level memory copy function that catches machine checks * Low level memory copy function that catches machine checks
* *
* Return true for success, false for fail * Return 0 for success, -EFAULT for fail
*/ */
bool memcpy_mcsafe(void *dst, const void *src, size_t cnt); int memcpy_mcsafe(void *dst, const void *src, size_t cnt);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */

View File

@ -62,4 +62,6 @@ void xen_arch_register_cpu(int num);
void xen_arch_unregister_cpu(int num); void xen_arch_unregister_cpu(int num);
#endif #endif
extern void xen_set_iopl_mask(unsigned mask);
#endif /* _ASM_X86_XEN_HYPERVISOR_H */ #endif /* _ASM_X86_XEN_HYPERVISOR_H */

View File

@ -956,7 +956,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
/* /*
* Note that the LAPIC address is obtained from the MADT (32-bit value) * Note that the LAPIC address is obtained from the MADT (32-bit value)
* and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). * and (optionally) overridden by a LAPIC_ADDR_OVR entry (64-bit value).
*/ */
count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
@ -984,7 +984,7 @@ static int __init acpi_parse_madt_lapic_entries(void)
/* /*
* Note that the LAPIC address is obtained from the MADT (32-bit value) * Note that the LAPIC address is obtained from the MADT (32-bit value)
* and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). * and (optionally) overridden by a LAPIC_ADDR_OVR entry (64-bit value).
*/ */
count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,

View File

@ -221,7 +221,7 @@ static int apbt_cpuhp_notify(struct notifier_block *n,
unsigned long cpu = (unsigned long)hcpu; unsigned long cpu = (unsigned long)hcpu;
struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu); struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu);
switch (action & 0xf) { switch (action & ~CPU_TASKS_FROZEN) {
case CPU_DEAD: case CPU_DEAD:
dw_apb_clockevent_pause(adev->timer); dw_apb_clockevent_pause(adev->timer);
if (system_state == SYSTEM_RUNNING) { if (system_state == SYSTEM_RUNNING) {

View File

@ -1611,7 +1611,7 @@ void __init enable_IR_x2apic(void)
legacy_pic->mask_all(); legacy_pic->mask_all();
mask_ioapic_entries(); mask_ioapic_entries();
/* If irq_remapping_prepare() succeded, try to enable it */ /* If irq_remapping_prepare() succeeded, try to enable it */
if (ir_stat >= 0) if (ir_stat >= 0)
ir_stat = try_to_enable_IR(); ir_stat = try_to_enable_IR();
/* ir_stat contains the remap mode or an error code */ /* ir_stat contains the remap mode or an error code */

View File

@ -213,6 +213,7 @@ update:
*/ */
cpumask_and(d->old_domain, d->old_domain, cpu_online_mask); cpumask_and(d->old_domain, d->old_domain, cpu_online_mask);
d->move_in_progress = !cpumask_empty(d->old_domain); d->move_in_progress = !cpumask_empty(d->old_domain);
d->cfg.old_vector = d->move_in_progress ? d->cfg.vector : 0;
d->cfg.vector = vector; d->cfg.vector = vector;
cpumask_copy(d->domain, vector_cpumask); cpumask_copy(d->domain, vector_cpumask);
success: success:
@ -655,46 +656,97 @@ void irq_complete_move(struct irq_cfg *cfg)
} }
/* /*
* Called with @desc->lock held and interrupts disabled. * Called from fixup_irqs() with @desc->lock held and interrupts disabled.
*/ */
void irq_force_complete_move(struct irq_desc *desc) void irq_force_complete_move(struct irq_desc *desc)
{ {
struct irq_data *irqdata = irq_desc_get_irq_data(desc); struct irq_data *irqdata = irq_desc_get_irq_data(desc);
struct apic_chip_data *data = apic_chip_data(irqdata); struct apic_chip_data *data = apic_chip_data(irqdata);
struct irq_cfg *cfg = data ? &data->cfg : NULL; struct irq_cfg *cfg = data ? &data->cfg : NULL;
unsigned int cpu;
if (!cfg) if (!cfg)
return; return;
__irq_complete_move(cfg, cfg->vector);
/* /*
* This is tricky. If the cleanup of @data->old_domain has not been * This is tricky. If the cleanup of @data->old_domain has not been
* done yet, then the following setaffinity call will fail with * done yet, then the following setaffinity call will fail with
* -EBUSY. This can leave the interrupt in a stale state. * -EBUSY. This can leave the interrupt in a stale state.
* *
* The cleanup cannot make progress because we hold @desc->lock. So in * All CPUs are stuck in stop machine with interrupts disabled so
* case @data->old_domain is not yet cleaned up, we need to drop the * calling __irq_complete_move() would be completely pointless.
* lock and acquire it again. @desc cannot go away, because the
* hotplug code holds the sparse irq lock.
*/ */
raw_spin_lock(&vector_lock); raw_spin_lock(&vector_lock);
/* Clean out all offline cpus (including ourself) first. */ /*
* Clean out all offline cpus (including the outgoing one) from the
* old_domain mask.
*/
cpumask_and(data->old_domain, data->old_domain, cpu_online_mask); cpumask_and(data->old_domain, data->old_domain, cpu_online_mask);
while (!cpumask_empty(data->old_domain)) {
/*
* If move_in_progress is cleared and the old_domain mask is empty,
* then there is nothing to cleanup. fixup_irqs() will take care of
* the stale vectors on the outgoing cpu.
*/
if (!data->move_in_progress && cpumask_empty(data->old_domain)) {
raw_spin_unlock(&vector_lock); raw_spin_unlock(&vector_lock);
raw_spin_unlock(&desc->lock); return;
cpu_relax();
raw_spin_lock(&desc->lock);
/*
* Reevaluate apic_chip_data. It might have been cleared after
* we dropped @desc->lock.
*/
data = apic_chip_data(irqdata);
if (!data)
return;
raw_spin_lock(&vector_lock);
} }
/*
* 1) The interrupt is in move_in_progress state. That means that we
* have not seen an interrupt since the io_apic was reprogrammed to
* the new vector.
*
* 2) The interrupt has fired on the new vector, but the cleanup IPIs
* have not been processed yet.
*/
if (data->move_in_progress) {
/*
* In theory there is a race:
*
* set_ioapic(new_vector) <-- Interrupt is raised before update
* is effective, i.e. it's raised on
* the old vector.
*
* So if the target cpu cannot handle that interrupt before
* the old vector is cleaned up, we get a spurious interrupt
* and in the worst case the ioapic irq line becomes stale.
*
* But in case of cpu hotplug this should be a non issue
* because if the affinity update happens right before all
* cpus rendevouz in stop machine, there is no way that the
* interrupt can be blocked on the target cpu because all cpus
* loops first with interrupts enabled in stop machine, so the
* old vector is not yet cleaned up when the interrupt fires.
*
* So the only way to run into this issue is if the delivery
* of the interrupt on the apic/system bus would be delayed
* beyond the point where the target cpu disables interrupts
* in stop machine. I doubt that it can happen, but at least
* there is a theroretical chance. Virtualization might be
* able to expose this, but AFAICT the IOAPIC emulation is not
* as stupid as the real hardware.
*
* Anyway, there is nothing we can do about that at this point
* w/o refactoring the whole fixup_irq() business completely.
* We print at least the irq number and the old vector number,
* so we have the necessary information when a problem in that
* area arises.
*/
pr_warn("IRQ fixup: irq %d move in progress, old vector %d\n",
irqdata->irq, cfg->old_vector);
}
/*
* If old_domain is not empty, then other cpus still have the irq
* descriptor set in their vector array. Clean it up.
*/
for_each_cpu(cpu, data->old_domain)
per_cpu(vector_irq, cpu)[cfg->old_vector] = VECTOR_UNUSED;
/* Cleanup the left overs of the (half finished) move */
cpumask_clear(data->old_domain);
data->move_in_progress = 0;
raw_spin_unlock(&vector_lock); raw_spin_unlock(&vector_lock);
} }
#endif #endif

View File

@ -792,7 +792,8 @@ static int uv_scir_cpu_notify(struct notifier_block *self, unsigned long action,
{ {
long cpu = (long)hcpu; long cpu = (long)hcpu;
switch (action) { switch (action & ~CPU_TASKS_FROZEN) {
case CPU_DOWN_FAILED:
case CPU_ONLINE: case CPU_ONLINE:
uv_heartbeat_enable(cpu); uv_heartbeat_enable(cpu);
break; break;
@ -860,7 +861,7 @@ int uv_set_vga_state(struct pci_dev *pdev, bool decode,
*/ */
void uv_cpu_init(void) void uv_cpu_init(void)
{ {
/* CPU 0 initilization will be done via uv_system_init. */ /* CPU 0 initialization will be done via uv_system_init. */
if (!uv_blade_info) if (!uv_blade_info)
return; return;

View File

@ -1088,7 +1088,7 @@ static int apm_get_battery_status(u_short which, u_short *status,
* @device: identity of device * @device: identity of device
* @enable: on/off * @enable: on/off
* *
* Activate or deactive power management on either a specific device * Activate or deactivate power management on either a specific device
* or the entire system (%APM_DEVICE_ALL). * or the entire system (%APM_DEVICE_ALL).
*/ */

View File

@ -85,7 +85,7 @@ static void init_amd_k5(struct cpuinfo_x86 *c)
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
/* /*
* General Systems BIOSen alias the cpu frequency registers * General Systems BIOSen alias the cpu frequency registers
* of the Elan at 0x000df000. Unfortuantly, one of the Linux * of the Elan at 0x000df000. Unfortunately, one of the Linux
* drivers subsequently pokes it, and changes the CPU speed. * drivers subsequently pokes it, and changes the CPU speed.
* Workaround : Remove the unneeded alias. * Workaround : Remove the unneeded alias.
*/ */

View File

@ -968,7 +968,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
if (this_cpu->c_identify) if (this_cpu->c_identify)
this_cpu->c_identify(c); this_cpu->c_identify(c);
/* Clear/Set all flags overriden by options, after probe */ /* Clear/Set all flags overridden by options, after probe */
for (i = 0; i < NCAPINTS; i++) { for (i = 0; i < NCAPINTS; i++) {
c->x86_capability[i] &= ~cpu_caps_cleared[i]; c->x86_capability[i] &= ~cpu_caps_cleared[i];
c->x86_capability[i] |= cpu_caps_set[i]; c->x86_capability[i] |= cpu_caps_set[i];
@ -1028,7 +1028,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
setup_pku(c); setup_pku(c);
/* /*
* Clear/Set all flags overriden by options, need do it * Clear/Set all flags overridden by options, need do it
* before following smp all cpus cap AND. * before following smp all cpus cap AND.
*/ */
for (i = 0; i < NCAPINTS; i++) { for (i = 0; i < NCAPINTS; i++) {

View File

@ -42,7 +42,7 @@ EXPORT_SYMBOL_GPL(mtrr_state);
* "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
* Opteron Processors" (26094 Rev. 3.30 February 2006), section * Opteron Processors" (26094 Rev. 3.30 February 2006), section
* "13.2.1.2 SYSCFG Register": "The MtrrFixDramModEn bit should be set * "13.2.1.2 SYSCFG Register": "The MtrrFixDramModEn bit should be set
* to 1 during BIOS initalization of the fixed MTRRs, then cleared to * to 1 during BIOS initialization of the fixed MTRRs, then cleared to
* 0 for operation." * 0 for operation."
*/ */
static inline void k8_check_syscfg_dram_mod_en(void) static inline void k8_check_syscfg_dram_mod_en(void)

View File

@ -287,7 +287,7 @@ static __init void early_pci_serial_init(char *s)
} }
/* /*
* Lastly, initalize the hardware * Lastly, initialize the hardware
*/ */
if (*s) { if (*s) {
if (strcmp(s, "nocfg") == 0) if (strcmp(s, "nocfg") == 0)

View File

@ -8,7 +8,7 @@
/* /*
* The xstateregs_active() routine is the same as the regset_fpregs_active() routine, * The xstateregs_active() routine is the same as the regset_fpregs_active() routine,
* as the "regset->n" for the xstate regset will be updated based on the feature * as the "regset->n" for the xstate regset will be updated based on the feature
* capabilites supported by the xsave. * capabilities supported by the xsave.
*/ */
int regset_fpregs_active(struct task_struct *target, const struct user_regset *regset) int regset_fpregs_active(struct task_struct *target, const struct user_regset *regset)
{ {

View File

@ -717,7 +717,7 @@ static int hpet_cpuhp_notify(struct notifier_block *n,
struct hpet_work_struct work; struct hpet_work_struct work;
struct hpet_dev *hdev = per_cpu(cpu_hpet_dev, cpu); struct hpet_dev *hdev = per_cpu(cpu_hpet_dev, cpu);
switch (action & 0xf) { switch (action & ~CPU_TASKS_FROZEN) {
case CPU_ONLINE: case CPU_ONLINE:
INIT_DELAYED_WORK_ONSTACK(&work.work, hpet_work); INIT_DELAYED_WORK_ONSTACK(&work.work, hpet_work);
init_completion(&work.complete); init_completion(&work.complete);

View File

@ -96,9 +96,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
SYSCALL_DEFINE1(iopl, unsigned int, level) SYSCALL_DEFINE1(iopl, unsigned int, level)
{ {
struct pt_regs *regs = current_pt_regs(); struct pt_regs *regs = current_pt_regs();
unsigned int old = (regs->flags >> 12) & 3;
struct thread_struct *t = &current->thread; struct thread_struct *t = &current->thread;
/*
* Careful: the IOPL bits in regs->flags are undefined under Xen PV
* and changing them has no effect.
*/
unsigned int old = t->iopl >> X86_EFLAGS_IOPL_BIT;
if (level > 3) if (level > 3)
return -EINVAL; return -EINVAL;
/* Trying to gain more privileges? */ /* Trying to gain more privileges? */
@ -106,8 +111,9 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
if (!capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_RAWIO))
return -EPERM; return -EPERM;
} }
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
t->iopl = level << 12; (level << X86_EFLAGS_IOPL_BIT);
t->iopl = level << X86_EFLAGS_IOPL_BIT;
set_iopl_mask(t->iopl); set_iopl_mask(t->iopl);
return 0; return 0;

View File

@ -271,7 +271,7 @@ static int bzImage64_probe(const char *buf, unsigned long len)
int ret = -ENOEXEC; int ret = -ENOEXEC;
struct setup_header *header; struct setup_header *header;
/* kernel should be atleast two sectors long */ /* kernel should be at least two sectors long */
if (len < 2 * 512) { if (len < 2 * 512) {
pr_err("File is too short to be a bzImage\n"); pr_err("File is too short to be a bzImage\n");
return ret; return ret;

View File

@ -609,9 +609,9 @@ static struct notifier_block kgdb_notifier = {
}; };
/** /**
* kgdb_arch_init - Perform any architecture specific initalization. * kgdb_arch_init - Perform any architecture specific initialization.
* *
* This function will handle the initalization of any architecture * This function will handle the initialization of any architecture
* specific callbacks. * specific callbacks.
*/ */
int kgdb_arch_init(void) int kgdb_arch_init(void)

View File

@ -226,7 +226,7 @@ static void kvm_setup_secondary_clock(void)
* registered memory location. If the guest happens to shutdown, this memory * registered memory location. If the guest happens to shutdown, this memory
* won't be valid. In cases like kexec, in which you install a new kernel, this * won't be valid. In cases like kexec, in which you install a new kernel, this
* means a random memory location will be kept being written. So before any * means a random memory location will be kept being written. So before any
* kind of shutdown from our side, we unregister the clock by writting anything * kind of shutdown from our side, we unregister the clock by writing anything
* that does not have the 'enable' bit set in the msr * that does not have the 'enable' bit set in the msr
*/ */
#ifdef CONFIG_KEXEC_CORE #ifdef CONFIG_KEXEC_CORE

View File

@ -48,6 +48,7 @@
#include <asm/syscalls.h> #include <asm/syscalls.h>
#include <asm/debugreg.h> #include <asm/debugreg.h>
#include <asm/switch_to.h> #include <asm/switch_to.h>
#include <asm/xen/hypervisor.h>
asmlinkage extern void ret_from_fork(void); asmlinkage extern void ret_from_fork(void);
@ -413,6 +414,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV)) task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
__switch_to_xtra(prev_p, next_p, tss); __switch_to_xtra(prev_p, next_p, tss);
#ifdef CONFIG_XEN
/*
* On Xen PV, IOPL bits in pt_regs->flags have no effect, and
* current_pt_regs()->flags may not match the current task's
* intended IOPL. We need to switch it manually.
*/
if (unlikely(static_cpu_has(X86_FEATURE_XENPV) &&
prev->iopl != next->iopl))
xen_set_iopl_mask(next->iopl);
#endif
if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) { if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) {
/* /*
* AMD CPUs have a misfeature: SYSRET sets the SS selector but * AMD CPUs have a misfeature: SYSRET sets the SS selector but

View File

@ -274,11 +274,6 @@ int topology_update_package_map(unsigned int apicid, unsigned int cpu)
if (test_and_set_bit(pkg, physical_package_map)) if (test_and_set_bit(pkg, physical_package_map))
goto found; goto found;
if (pkg < __max_logical_packages) {
set_bit(pkg, logical_package_map);
physical_to_logical_pkg[pkg] = pkg;
goto found;
}
new = find_first_zero_bit(logical_package_map, __max_logical_packages); new = find_first_zero_bit(logical_package_map, __max_logical_packages);
if (new >= __max_logical_packages) { if (new >= __max_logical_packages) {
physical_to_logical_pkg[pkg] = -1; physical_to_logical_pkg[pkg] = -1;
@ -317,9 +312,27 @@ static void __init smp_init_package_map(void)
/* /*
* Today neither Intel nor AMD support heterogenous systems. That * Today neither Intel nor AMD support heterogenous systems. That
* might change in the future.... * might change in the future....
*
* While ideally we'd want '* smp_num_siblings' in the below @ncpus
* computation, this won't actually work since some Intel BIOSes
* report inconsistent HT data when they disable HT.
*
* In particular, they reduce the APIC-IDs to only include the cores,
* but leave the CPUID topology to say there are (2) siblings.
* This means we don't know how many threads there will be until
* after the APIC enumeration.
*
* By not including this we'll sometimes over-estimate the number of
* logical packages by the amount of !present siblings, but this is
* still better than MAX_LOCAL_APIC.
*
* We use total_cpus not nr_cpu_ids because nr_cpu_ids can be limited
* on the command line leading to a similar issue as the HT disable
* problem because the hyperthreads are usually enumerated after the
* primary cores.
*/ */
ncpus = boot_cpu_data.x86_max_cores * smp_num_siblings; ncpus = boot_cpu_data.x86_max_cores;
__max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus); __max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus);
/* /*
* Possibly larger than what we need as the number of apic ids per * Possibly larger than what we need as the number of apic ids per

View File

@ -881,7 +881,7 @@ void tsc_restore_sched_clock_state(void)
local_irq_save(flags); local_irq_save(flags);
/* /*
* We're comming out of suspend, there's no concurrency yet; don't * We're coming out of suspend, there's no concurrency yet; don't
* bother being nice about the RCU stuff, just write to both * bother being nice about the RCU stuff, just write to both
* data fields. * data fields.
*/ */
@ -1306,11 +1306,15 @@ void __init tsc_init(void)
unsigned long calibrate_delay_is_known(void) unsigned long calibrate_delay_is_known(void)
{ {
int sibling, cpu = smp_processor_id(); int sibling, cpu = smp_processor_id();
struct cpumask *mask = topology_core_cpumask(cpu);
if (!tsc_disabled && !cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC)) if (!tsc_disabled && !cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC))
return 0; return 0;
sibling = cpumask_any_but(topology_core_cpumask(cpu), cpu); if (!mask)
return 0;
sibling = cpumask_any_but(mask, cpu);
if (sibling < nr_cpu_ids) if (sibling < nr_cpu_ids)
return cpu_data(sibling).loops_per_jiffy; return cpu_data(sibling).loops_per_jiffy;
return 0; return 0;

View File

@ -479,7 +479,7 @@ static bool spte_is_locklessly_modifiable(u64 spte)
static bool spte_has_volatile_bits(u64 spte) static bool spte_has_volatile_bits(u64 spte)
{ {
/* /*
* Always atomicly update spte if it can be updated * Always atomically update spte if it can be updated
* out of mmu-lock, it can ensure dirty bit is not lost, * out of mmu-lock, it can ensure dirty bit is not lost,
* also, it can help us to get a stable is_writable_pte() * also, it can help us to get a stable is_writable_pte()
* to ensure tlb flush is not missed. * to ensure tlb flush is not missed.
@ -550,7 +550,7 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte)
/* /*
* For the spte updated out of mmu-lock is safe, since * For the spte updated out of mmu-lock is safe, since
* we always atomicly update it, see the comments in * we always atomically update it, see the comments in
* spte_has_volatile_bits(). * spte_has_volatile_bits().
*/ */
if (spte_is_locklessly_modifiable(old_spte) && if (spte_is_locklessly_modifiable(old_spte) &&

View File

@ -5528,7 +5528,7 @@ static int handle_set_cr4(struct kvm_vcpu *vcpu, unsigned long val)
return kvm_set_cr4(vcpu, val); return kvm_set_cr4(vcpu, val);
} }
/* called to set cr0 as approriate for clts instruction exit. */ /* called to set cr0 as appropriate for clts instruction exit. */
static void handle_clts(struct kvm_vcpu *vcpu) static void handle_clts(struct kvm_vcpu *vcpu)
{ {
if (is_guest_mode(vcpu)) { if (is_guest_mode(vcpu)) {
@ -7267,7 +7267,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu)
/* The value to write might be 32 or 64 bits, depending on L1's long /* The value to write might be 32 or 64 bits, depending on L1's long
* mode, and eventually we need to write that into a field of several * mode, and eventually we need to write that into a field of several
* possible lengths. The code below first zero-extends the value to 64 * possible lengths. The code below first zero-extends the value to 64
* bit (field_value), and then copies only the approriate number of * bit (field_value), and then copies only the appropriate number of
* bits into the vmcs12 field. * bits into the vmcs12 field.
*/ */
u64 field_value = 0; u64 field_value = 0;

View File

@ -1562,7 +1562,7 @@ static cycle_t read_tsc(void)
/* /*
* GCC likes to generate cmov here, but this branch is extremely * GCC likes to generate cmov here, but this branch is extremely
* predictable (it's just a funciton of time and the likely is * predictable (it's just a function of time and the likely is
* very likely) and there's a data dependence, so force GCC * very likely) and there's a data dependence, so force GCC
* to generate a branch instead. I don't barrier() because * to generate a branch instead. I don't barrier() because
* we don't actually need a barrier, and if this function * we don't actually need a barrier, and if this function

View File

@ -1,6 +1,7 @@
/* Copyright 2002 Andi Kleen */ /* Copyright 2002 Andi Kleen */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/errno.h>
#include <asm/cpufeatures.h> #include <asm/cpufeatures.h>
#include <asm/alternative-asm.h> #include <asm/alternative-asm.h>
@ -268,16 +269,16 @@ ENTRY(memcpy_mcsafe)
decl %ecx decl %ecx
jnz .L_copy_trailing_bytes jnz .L_copy_trailing_bytes
/* Copy successful. Return true */ /* Copy successful. Return zero */
.L_done_memcpy_trap: .L_done_memcpy_trap:
xorq %rax, %rax xorq %rax, %rax
ret ret
ENDPROC(memcpy_mcsafe) ENDPROC(memcpy_mcsafe)
.section .fixup, "ax" .section .fixup, "ax"
/* Return false for any failure */ /* Return -EFAULT for any failure */
.L_memcpy_mcsafe_fail: .L_memcpy_mcsafe_fail:
mov $1, %rax mov $-EFAULT, %rax
ret ret
.previous .previous

View File

@ -9,7 +9,7 @@
/* /*
* ISO C memset - set a memory block to a byte value. This function uses fast * ISO C memset - set a memory block to a byte value. This function uses fast
* string to get better performance than the original function. The code is * string to get better performance than the original function. The code is
* simpler and shorter than the orignal function as well. * simpler and shorter than the original function as well.
* *
* rdi destination * rdi destination
* rsi value (char) * rsi value (char)

View File

@ -728,14 +728,14 @@ static inline unsigned long bd_entry_virt_space(struct mm_struct *mm)
/* /*
* This covers 32-bit emulation as well as 32-bit kernels * This covers 32-bit emulation as well as 32-bit kernels
* running on 64-bit harware. * running on 64-bit hardware.
*/ */
if (!is_64bit_mm(mm)) if (!is_64bit_mm(mm))
return (4ULL * GB) / MPX_BD_NR_ENTRIES_32; return (4ULL * GB) / MPX_BD_NR_ENTRIES_32;
/* /*
* 'x86_virt_bits' returns what the hardware is capable * 'x86_virt_bits' returns what the hardware is capable
* of, and returns the full >32-bit adddress space when * of, and returns the full >32-bit address space when
* running 32-bit kernels on 64-bit hardware. * running 32-bit kernels on 64-bit hardware.
*/ */
virt_space = (1ULL << boot_cpu_data.x86_virt_bits); virt_space = (1ULL << boot_cpu_data.x86_virt_bits);

View File

@ -149,7 +149,7 @@ enum {
PAT_WT = 4, /* Write Through */ PAT_WT = 4, /* Write Through */
PAT_WP = 5, /* Write Protected */ PAT_WP = 5, /* Write Protected */
PAT_WB = 6, /* Write Back (default) */ PAT_WB = 6, /* Write Back (default) */
PAT_UC_MINUS = 7, /* UC, but can be overriden by MTRR */ PAT_UC_MINUS = 7, /* UC, but can be overridden by MTRR */
}; };
#define CM(c) (_PAGE_CACHE_MODE_ ## c) #define CM(c) (_PAGE_CACHE_MODE_ ## c)

View File

@ -437,7 +437,8 @@ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
void *data) void *data)
{ {
int cpu = (unsigned long)data; int cpu = (unsigned long)data;
switch (action) {
switch (action & ~CPU_TASKS_FROZEN) {
case CPU_DOWN_FAILED: case CPU_DOWN_FAILED:
case CPU_ONLINE: case CPU_ONLINE:
smp_call_function_single(cpu, nmi_cpu_up, NULL, 0); smp_call_function_single(cpu, nmi_cpu_up, NULL, 0);

View File

@ -1,5 +1,5 @@
/* /*
* platform_bma023.c: bma023 platform data initilization file * platform_bma023.c: bma023 platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* *

View File

@ -1,5 +1,5 @@
/* /*
* platform_emc1403.c: emc1403 platform data initilization file * platform_emc1403.c: emc1403 platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_gpio_keys.c: gpio_keys platform data initilization file * platform_gpio_keys.c: gpio_keys platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_lis331.c: lis331 platform data initilization file * platform_lis331.c: lis331 platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_max7315.c: max7315 platform data initilization file * platform_max7315.c: max7315 platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_mpu3050.c: mpu3050 platform data initilization file * platform_mpu3050.c: mpu3050 platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_msic.c: MSIC platform data initilization file * platform_msic.c: MSIC platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_msic_audio.c: MSIC audio platform data initilization file * platform_msic_audio.c: MSIC audio platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_msic_battery.c: MSIC battery platform data initilization file * platform_msic_battery.c: MSIC battery platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_msic_gpio.c: MSIC GPIO platform data initilization file * platform_msic_gpio.c: MSIC GPIO platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_msic_ocd.c: MSIC OCD platform data initilization file * platform_msic_ocd.c: MSIC OCD platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_msic_power_btn.c: MSIC power btn platform data initilization file * platform_msic_power_btn.c: MSIC power btn platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_msic_thermal.c: msic_thermal platform data initilization file * platform_msic_thermal.c: msic_thermal platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_pmic_gpio.c: PMIC GPIO platform data initilization file * platform_pmic_gpio.c: PMIC GPIO platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_tc35876x.c: tc35876x platform data initilization file * platform_tc35876x.c: tc35876x platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -1,5 +1,5 @@
/* /*
* platform_tca6416.c: tca6416 platform data initilization file * platform_tca6416.c: tca6416 platform data initialization file
* *
* (C) Copyright 2013 Intel Corporation * (C) Copyright 2013 Intel Corporation
* Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com> * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>

View File

@ -8,7 +8,7 @@
*/ */
/* A stack for the loaded kernel. /* A stack for the loaded kernel.
* Seperate and in the data section so it can be prepopulated. * Separate and in the data section so it can be prepopulated.
*/ */
.data .data
.balign 4096 .balign 4096

View File

@ -14,26 +14,24 @@
int fb_is_primary_device(struct fb_info *info) int fb_is_primary_device(struct fb_info *info)
{ {
struct device *device = info->device; struct device *device = info->device;
struct pci_dev *pci_dev = NULL;
struct pci_dev *default_device = vga_default_device(); struct pci_dev *default_device = vga_default_device();
struct resource *res = NULL; struct pci_dev *pci_dev;
struct resource *res;
if (device) if (!device || !dev_is_pci(device))
pci_dev = to_pci_dev(device);
if (!pci_dev)
return 0; return 0;
pci_dev = to_pci_dev(device);
if (default_device) { if (default_device) {
if (pci_dev == default_device) if (pci_dev == default_device)
return 1; return 1;
else return 0;
return 0;
} }
res = &pci_dev->resource[PCI_ROM_RESOURCE]; res = pci_dev->resource + PCI_ROM_RESOURCE;
if (res && res->flags & IORESOURCE_ROM_SHADOW) if (res->flags & IORESOURCE_ROM_SHADOW)
return 1; return 1;
return 0; return 0;

View File

@ -962,7 +962,7 @@ static void xen_load_sp0(struct tss_struct *tss,
tss->x86_tss.sp0 = thread->sp0; tss->x86_tss.sp0 = thread->sp0;
} }
static void xen_set_iopl_mask(unsigned mask) void xen_set_iopl_mask(unsigned mask)
{ {
struct physdev_set_iopl set_iopl; struct physdev_set_iopl set_iopl;

View File

@ -1256,7 +1256,7 @@ static void __init xen_pagetable_cleanhighmap(void)
xen_cleanhighmap(addr, addr + size); xen_cleanhighmap(addr, addr + size);
xen_start_info->pt_base = (unsigned long)__va(__pa(xen_start_info->pt_base)); xen_start_info->pt_base = (unsigned long)__va(__pa(xen_start_info->pt_base));
#ifdef DEBUG #ifdef DEBUG
/* This is superflous and is not neccessary, but you know what /* This is superfluous and is not necessary, but you know what
* lets do it. The MODULES_VADDR -> MODULES_END should be clear of * lets do it. The MODULES_VADDR -> MODULES_END should be clear of
* anything at this stage. */ * anything at this stage. */
xen_cleanhighmap(MODULES_VADDR, roundup(MODULES_VADDR, PUD_SIZE) - 1); xen_cleanhighmap(MODULES_VADDR, roundup(MODULES_VADDR, PUD_SIZE) - 1);
@ -1474,7 +1474,7 @@ static void xen_write_cr3(unsigned long cr3)
/* /*
* At the start of the day - when Xen launches a guest, it has already * At the start of the day - when Xen launches a guest, it has already
* built pagetables for the guest. We diligently look over them * built pagetables for the guest. We diligently look over them
* in xen_setup_kernel_pagetable and graft as appropiate them in the * in xen_setup_kernel_pagetable and graft as appropriate them in the
* init_level4_pgt and its friends. Then when we are happy we load * init_level4_pgt and its friends. Then when we are happy we load
* the new init_level4_pgt - and continue on. * the new init_level4_pgt - and continue on.
* *
@ -2792,7 +2792,7 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
struct remap_data *rmd = data; struct remap_data *rmd = data;
pte_t pte = pte_mkspecial(mfn_pte(*rmd->mfn, rmd->prot)); pte_t pte = pte_mkspecial(mfn_pte(*rmd->mfn, rmd->prot));
/* If we have a contigious range, just update the mfn itself, /* If we have a contiguous range, just update the mfn itself,
else update pointer to be "next mfn". */ else update pointer to be "next mfn". */
if (rmd->contiguous) if (rmd->contiguous)
(*rmd->mfn)++; (*rmd->mfn)++;
@ -2833,7 +2833,7 @@ static int do_remap_gfn(struct vm_area_struct *vma,
rmd.mfn = gfn; rmd.mfn = gfn;
rmd.prot = prot; rmd.prot = prot;
/* We use the err_ptr to indicate if there we are doing a contigious /* We use the err_ptr to indicate if there we are doing a contiguous
* mapping or a discontigious mapping. */ * mapping or a discontigious mapping. */
rmd.contiguous = !err_ptr; rmd.contiguous = !err_ptr;

View File

@ -26,7 +26,7 @@
(1 << XENFEAT_auto_translated_physmap) | \ (1 << XENFEAT_auto_translated_physmap) | \
(1 << XENFEAT_supervisor_mode_kernel) | \ (1 << XENFEAT_supervisor_mode_kernel) | \
(1 << XENFEAT_hvm_callback_vector)) (1 << XENFEAT_hvm_callback_vector))
/* The XENFEAT_writable_page_tables is not stricly neccessary as we set that /* The XENFEAT_writable_page_tables is not stricly necessary as we set that
* up regardless whether this CONFIG option is enabled or not, but it * up regardless whether this CONFIG option is enabled or not, but it
* clarifies what the right flags need to be. * clarifies what the right flags need to be.
*/ */

View File

@ -65,7 +65,6 @@ static inline bool trigger_allbutself_cpu_backtrace(void)
#endif #endif
#ifdef CONFIG_LOCKUP_DETECTOR #ifdef CONFIG_LOCKUP_DETECTOR
int hw_nmi_is_cpu_stuck(struct pt_regs *);
u64 hw_nmi_get_sample_period(int watchdog_thresh); u64 hw_nmi_get_sample_period(int watchdog_thresh);
extern int nmi_watchdog_enabled; extern int nmi_watchdog_enabled;
extern int soft_watchdog_enabled; extern int soft_watchdog_enabled;

View File

@ -5,7 +5,7 @@ include ../lib.mk
.PHONY: all all_32 all_64 warn_32bit_failure clean .PHONY: all all_32 all_64 warn_32bit_failure clean
TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall \ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall \
check_initial_reg_state sigreturn ldt_gdt check_initial_reg_state sigreturn ldt_gdt iopl
TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
test_FCMOV test_FCOMI test_FISTTP \ test_FCMOV test_FCOMI test_FISTTP \
vdso_restorer vdso_restorer

View File

@ -0,0 +1,135 @@
/*
* iopl.c - Test case for a Linux on Xen 64-bit bug
* Copyright (c) 2015 Andrew Lutomirski
*/
#define _GNU_SOURCE
#include <err.h>
#include <stdio.h>
#include <stdint.h>
#include <signal.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdbool.h>
#include <sched.h>
#include <sys/io.h>
static int nerrs = 0;
static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}
static jmp_buf jmpbuf;
static void sigsegv(int sig, siginfo_t *si, void *ctx_void)
{
siglongjmp(jmpbuf, 1);
}
int main(void)
{
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset);
if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0)
err(1, "sched_setaffinity to CPU 0");
/* Probe for iopl support. Note that iopl(0) works even as nonroot. */
if (iopl(3) != 0) {
printf("[OK]\tiopl(3) failed (%d) -- try running as root\n",
errno);
return 0;
}
/* Restore our original state prior to starting the test. */
if (iopl(0) != 0)
err(1, "iopl(0)");
pid_t child = fork();
if (child == -1)
err(1, "fork");
if (child == 0) {
printf("\tchild: set IOPL to 3\n");
if (iopl(3) != 0)
err(1, "iopl");
printf("[RUN]\tchild: write to 0x80\n");
asm volatile ("outb %%al, $0x80" : : "a" (0));
return 0;
} else {
int status;
if (waitpid(child, &status, 0) != child ||
!WIFEXITED(status)) {
printf("[FAIL]\tChild died\n");
nerrs++;
} else if (WEXITSTATUS(status) != 0) {
printf("[FAIL]\tChild failed\n");
nerrs++;
} else {
printf("[OK]\tChild succeeded\n");
}
}
printf("[RUN]\tparent: write to 0x80 (should fail)\n");
sethandler(SIGSEGV, sigsegv, 0);
if (sigsetjmp(jmpbuf, 1) != 0) {
printf("[OK]\twrite was denied\n");
} else {
asm volatile ("outb %%al, $0x80" : : "a" (0));
printf("[FAIL]\twrite was allowed\n");
nerrs++;
}
/* Test the capability checks. */
printf("\tiopl(3)\n");
if (iopl(3) != 0)
err(1, "iopl(3)");
printf("\tDrop privileges\n");
if (setresuid(1, 1, 1) != 0) {
printf("[WARN]\tDropping privileges failed\n");
goto done;
}
printf("[RUN]\tiopl(3) unprivileged but with IOPL==3\n");
if (iopl(3) != 0) {
printf("[FAIL]\tiopl(3) should work if iopl is already 3 even if unprivileged\n");
nerrs++;
}
printf("[RUN]\tiopl(0) unprivileged\n");
if (iopl(0) != 0) {
printf("[FAIL]\tiopl(0) should work if iopl is already 3 even if unprivileged\n");
nerrs++;
}
printf("[RUN]\tiopl(3) unprivileged\n");
if (iopl(3) == 0) {
printf("[FAIL]\tiopl(3) should fail if when unprivileged if iopl==0\n");
nerrs++;
} else {
printf("[OK]\tFailed as expected\n");
}
done:
return nerrs ? 1 : 0;
}