Commit 0c961c55 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'parisc-4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc updates from Helge Deller:

 - add Kernel address space layout randomization support

 - re-enable interrupts earlier now that we have a working IRQ stack

 - optimize the timer interrupt function to better cope with missed
   timer irqs

 - fix error return code in parisc perf code (by Dan Carpenter)

 - fix PAT debug code

* 'parisc-4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Optimize timer interrupt function
  parisc: perf: return -EFAULT on error
  parisc: Enhance CPU detection code on PAT machines
  parisc: Re-enable interrupts early
  parisc: Enable KASLR
parents bc1ecd62 160494d3
...@@ -7,6 +7,7 @@ config PARISC ...@@ -7,6 +7,7 @@ config PARISC
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_SYSCALL_TRACEPOINTS select HAVE_SYSCALL_TRACEPOINTS
select ARCH_WANT_FRAME_POINTERS select ARCH_WANT_FRAME_POINTERS
select ARCH_HAS_ELF_RANDOMIZE
select RTC_CLASS select RTC_CLASS
select RTC_DRV_GENERIC select RTC_DRV_GENERIC
select INIT_ALL_POSSIBLE select INIT_ALL_POSSIBLE
......
...@@ -348,9 +348,10 @@ struct pt_regs; /* forward declaration... */ ...@@ -348,9 +348,10 @@ struct pt_regs; /* forward declaration... */
#define ELF_HWCAP 0 #define ELF_HWCAP 0
#define STACK_RND_MASK (is_32bit_task() ? \ /* Masks for stack and mmap randomization */
0x7ff >> (PAGE_SHIFT - 12) : \ #define BRK_RND_MASK (is_32bit_task() ? 0x07ffUL : 0x3ffffUL)
0x3ffff >> (PAGE_SHIFT - 12)) #define MMAP_RND_MASK (is_32bit_task() ? 0x1fffUL : 0x3ffffUL)
#define STACK_RND_MASK MMAP_RND_MASK
struct mm_struct; struct mm_struct;
extern unsigned long arch_randomize_brk(struct mm_struct *); extern unsigned long arch_randomize_brk(struct mm_struct *);
......
...@@ -289,7 +289,7 @@ extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info); ...@@ -289,7 +289,7 @@ extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info);
extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod, unsigned long view_type, void *mem_addr); extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod, unsigned long view_type, void *mem_addr);
extern int pdc_pat_cell_num_to_loc(void *, unsigned long); extern int pdc_pat_cell_num_to_loc(void *, unsigned long);
extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa); extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa);
extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset); extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset);
......
...@@ -93,9 +93,7 @@ struct system_cpuinfo_parisc { ...@@ -93,9 +93,7 @@ struct system_cpuinfo_parisc {
/* Per CPU data structure - ie varies per CPU. */ /* Per CPU data structure - ie varies per CPU. */
struct cpuinfo_parisc { struct cpuinfo_parisc {
unsigned long it_value; /* Interval Timer at last timer Intr */ unsigned long it_value; /* Interval Timer at last timer Intr */
unsigned long it_delta; /* Interval delta (tic_10ms / HZ * 100) */
unsigned long irq_count; /* number of IRQ's since boot */ unsigned long irq_count; /* number of IRQ's since boot */
unsigned long irq_max_cr16; /* longest time to handle a single IRQ */
unsigned long cpuid; /* aka slot_number or set to NO_PROC_ID */ unsigned long cpuid; /* aka slot_number or set to NO_PROC_ID */
unsigned long hpa; /* Host Physical address */ unsigned long hpa; /* Host Physical address */
unsigned long txn_addr; /* MMIO addr of EIR or id_eid */ unsigned long txn_addr; /* MMIO addr of EIR or id_eid */
...@@ -103,8 +101,6 @@ struct cpuinfo_parisc { ...@@ -103,8 +101,6 @@ struct cpuinfo_parisc {
unsigned long pending_ipi; /* bitmap of type ipi_message_type */ unsigned long pending_ipi; /* bitmap of type ipi_message_type */
#endif #endif
unsigned long bh_count; /* number of times bh was invoked */ unsigned long bh_count; /* number of times bh was invoked */
unsigned long prof_counter; /* per CPU profiling support */
unsigned long prof_multiplier; /* per CPU profiling support */
unsigned long fp_rev; unsigned long fp_rev;
unsigned long fp_model; unsigned long fp_model;
unsigned int state; unsigned int state;
......
...@@ -878,6 +878,9 @@ ENTRY_CFI(syscall_exit_rfi) ...@@ -878,6 +878,9 @@ ENTRY_CFI(syscall_exit_rfi)
STREG %r19,PT_SR7(%r16) STREG %r19,PT_SR7(%r16)
intr_return: intr_return:
/* NOTE: Need to enable interrupts incase we schedule. */
ssm PSW_SM_I, %r0
/* check for reschedule */ /* check for reschedule */
mfctl %cr30,%r1 mfctl %cr30,%r1
LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */ LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */
...@@ -904,11 +907,6 @@ intr_check_sig: ...@@ -904,11 +907,6 @@ intr_check_sig:
LDREG PT_IASQ1(%r16), %r20 LDREG PT_IASQ1(%r16), %r20
cmpib,COND(=),n 0,%r20,intr_restore /* backward */ cmpib,COND(=),n 0,%r20,intr_restore /* backward */
/* NOTE: We need to enable interrupts if we have to deliver
* signals. We used to do this earlier but it caused kernel
* stack overflows. */
ssm PSW_SM_I, %r0
copy %r0, %r25 /* long in_syscall = 0 */ copy %r0, %r25 /* long in_syscall = 0 */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */ ldo -16(%r30),%r29 /* Reference param save area */
...@@ -960,10 +958,6 @@ intr_do_resched: ...@@ -960,10 +958,6 @@ intr_do_resched:
cmpib,COND(=) 0, %r20, intr_do_preempt cmpib,COND(=) 0, %r20, intr_do_preempt
nop nop
/* NOTE: We need to enable interrupts if we schedule. We used
* to do this earlier but it caused kernel stack overflows. */
ssm PSW_SM_I, %r0
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */ ldo -16(%r30),%r29 /* Reference param save area */
#endif #endif
......
...@@ -1258,7 +1258,7 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long ...@@ -1258,7 +1258,7 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long
* *
* Retrieve the cpu number for the cpu at the specified HPA. * Retrieve the cpu number for the cpu at the specified HPA.
*/ */
int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa) int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa)
{ {
int retval; int retval;
unsigned long flags; unsigned long flags;
......
...@@ -216,9 +216,9 @@ pat_query_module(ulong pcell_loc, ulong mod_index) ...@@ -216,9 +216,9 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
register_parisc_device(dev); /* advertise device */ register_parisc_device(dev); /* advertise device */
#ifdef DEBUG_PAT #ifdef DEBUG_PAT
pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
/* dump what we see so far... */ /* dump what we see so far... */
switch (PAT_GET_ENTITY(dev->mod_info)) { switch (PAT_GET_ENTITY(dev->mod_info)) {
pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
unsigned long i; unsigned long i;
case PAT_ENTITY_PROC: case PAT_ENTITY_PROC:
...@@ -259,9 +259,9 @@ pat_query_module(ulong pcell_loc, ulong mod_index) ...@@ -259,9 +259,9 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
pa_pdc_cell->mod[4 + i * 3]); /* finish (ie end) */ pa_pdc_cell->mod[4 + i * 3]); /* finish (ie end) */
printk(KERN_DEBUG printk(KERN_DEBUG
" IO_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", " IO_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n",
i, io_pdc_cell->mod[2 + i * 3], /* type */ i, io_pdc_cell.mod[2 + i * 3], /* type */
io_pdc_cell->mod[3 + i * 3], /* start */ io_pdc_cell.mod[3 + i * 3], /* start */
io_pdc_cell->mod[4 + i * 3]); /* finish (ie end) */ io_pdc_cell.mod[4 + i * 3]); /* finish (ie end) */
} }
printk(KERN_DEBUG "\n"); printk(KERN_DEBUG "\n");
break; break;
......
...@@ -301,7 +301,6 @@ static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t ...@@ -301,7 +301,6 @@ static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t
static ssize_t perf_write(struct file *file, const char __user *buf, size_t count, static ssize_t perf_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos) loff_t *ppos)
{ {
int err;
size_t image_size; size_t image_size;
uint32_t image_type; uint32_t image_type;
uint32_t interface_type; uint32_t interface_type;
...@@ -320,8 +319,8 @@ static ssize_t perf_write(struct file *file, const char __user *buf, size_t coun ...@@ -320,8 +319,8 @@ static ssize_t perf_write(struct file *file, const char __user *buf, size_t coun
if (count != sizeof(uint32_t)) if (count != sizeof(uint32_t))
return -EIO; return -EIO;
if ((err = copy_from_user(&image_type, buf, sizeof(uint32_t))) != 0) if (copy_from_user(&image_type, buf, sizeof(uint32_t)))
return err; return -EFAULT;
/* Get the interface type and test type */ /* Get the interface type and test type */
interface_type = (image_type >> 16) & 0xffff; interface_type = (image_type >> 16) & 0xffff;
......
...@@ -276,11 +276,7 @@ void *dereference_function_descriptor(void *ptr) ...@@ -276,11 +276,7 @@ void *dereference_function_descriptor(void *ptr)
static inline unsigned long brk_rnd(void) static inline unsigned long brk_rnd(void)
{ {
/* 8MB for 32bit, 1GB for 64bit */ return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
if (is_32bit_task())
return (get_random_int() & 0x7ffUL) << PAGE_SHIFT;
else
return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT;
} }
unsigned long arch_randomize_brk(struct mm_struct *mm) unsigned long arch_randomize_brk(struct mm_struct *mm)
......
...@@ -78,11 +78,6 @@ DEFINE_PER_CPU(struct cpuinfo_parisc, cpu_data); ...@@ -78,11 +78,6 @@ DEFINE_PER_CPU(struct cpuinfo_parisc, cpu_data);
static void static void
init_percpu_prof(unsigned long cpunum) init_percpu_prof(unsigned long cpunum)
{ {
struct cpuinfo_parisc *p;
p = &per_cpu(cpu_data, cpunum);
p->prof_counter = 1;
p->prof_multiplier = 1;
} }
...@@ -99,6 +94,7 @@ static int processor_probe(struct parisc_device *dev) ...@@ -99,6 +94,7 @@ static int processor_probe(struct parisc_device *dev)
unsigned long txn_addr; unsigned long txn_addr;
unsigned long cpuid; unsigned long cpuid;
struct cpuinfo_parisc *p; struct cpuinfo_parisc *p;
struct pdc_pat_cpu_num cpu_info __maybe_unused;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
if (num_online_cpus() >= nr_cpu_ids) { if (num_online_cpus() >= nr_cpu_ids) {
...@@ -123,10 +119,6 @@ static int processor_probe(struct parisc_device *dev) ...@@ -123,10 +119,6 @@ static int processor_probe(struct parisc_device *dev)
ulong status; ulong status;
unsigned long bytecnt; unsigned long bytecnt;
pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell;
#undef USE_PAT_CPUID
#ifdef USE_PAT_CPUID
struct pdc_pat_cpu_num cpu_info;
#endif
pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL); pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL);
if (!pa_pdc_cell) if (!pa_pdc_cell)
...@@ -145,22 +137,27 @@ static int processor_probe(struct parisc_device *dev) ...@@ -145,22 +137,27 @@ static int processor_probe(struct parisc_device *dev)
kfree(pa_pdc_cell); kfree(pa_pdc_cell);
/* get the cpu number */
status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa.start);
BUG_ON(PDC_OK != status);
pr_info("Logical CPU #%lu is physical cpu #%lu at location "
"0x%lx with hpa %pa\n",
cpuid, cpu_info.cpu_num, cpu_info.cpu_loc,
&dev->hpa.start);
#undef USE_PAT_CPUID
#ifdef USE_PAT_CPUID #ifdef USE_PAT_CPUID
/* We need contiguous numbers for cpuid. Firmware's notion /* We need contiguous numbers for cpuid. Firmware's notion
* of cpuid is for physical CPUs and we just don't care yet. * of cpuid is for physical CPUs and we just don't care yet.
* We'll care when we need to query PAT PDC about a CPU *after* * We'll care when we need to query PAT PDC about a CPU *after*
* boot time (ie shutdown a CPU from an OS perspective). * boot time (ie shutdown a CPU from an OS perspective).
*/ */
/* get the cpu number */
status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa.start);
BUG_ON(PDC_OK != status);
if (cpu_info.cpu_num >= NR_CPUS) { if (cpu_info.cpu_num >= NR_CPUS) {
printk(KERN_WARNING "IGNORING CPU at 0x%x," printk(KERN_WARNING "IGNORING CPU at %pa,"
" cpu_slot_id > NR_CPUS" " cpu_slot_id > NR_CPUS"
" (%ld > %d)\n", " (%ld > %d)\n",
dev->hpa.start, cpu_info.cpu_num, NR_CPUS); &dev->hpa.start, cpu_info.cpu_num, NR_CPUS);
/* Ignore CPU since it will only crash */ /* Ignore CPU since it will only crash */
boot_cpu_data.cpu_count--; boot_cpu_data.cpu_count--;
return 1; return 1;
......
...@@ -225,19 +225,17 @@ static unsigned long mmap_rnd(void) ...@@ -225,19 +225,17 @@ static unsigned long mmap_rnd(void)
{ {
unsigned long rnd = 0; unsigned long rnd = 0;
/* if (current->flags & PF_RANDOMIZE)
* 8 bits of randomness in 32bit mmaps, 20 address space bits rnd = get_random_int() & MMAP_RND_MASK;
* 28 bits of randomness in 64bit mmaps, 40 address space bits
*/
if (current->flags & PF_RANDOMIZE) {
if (is_32bit_task())
rnd = get_random_int() % (1<<8);
else
rnd = get_random_int() % (1<<28);
}
return rnd << PAGE_SHIFT; return rnd << PAGE_SHIFT;
} }
unsigned long arch_mmap_rnd(void)
{
return (get_random_int() & MMAP_RND_MASK) << PAGE_SHIFT;
}
static unsigned long mmap_legacy_base(void) static unsigned long mmap_legacy_base(void)
{ {
return TASK_UNMAPPED_BASE + mmap_rnd(); return TASK_UNMAPPED_BASE + mmap_rnd();
......
...@@ -59,10 +59,9 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */ ...@@ -59,10 +59,9 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */
*/ */
irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
{ {
unsigned long now, now2; unsigned long now;
unsigned long next_tick; unsigned long next_tick;
unsigned long cycles_elapsed, ticks_elapsed = 1; unsigned long ticks_elapsed = 0;
unsigned long cycles_remainder;
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
...@@ -71,102 +70,49 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) ...@@ -71,102 +70,49 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
profile_tick(CPU_PROFILING); profile_tick(CPU_PROFILING);
/* Initialize next_tick to the expected tick time. */ /* Initialize next_tick to the old expected tick time. */
next_tick = cpuinfo->it_value; next_tick = cpuinfo->it_value;
/* Get current cycle counter (Control Register 16). */ /* Calculate how many ticks have elapsed. */
now = mfctl(16); do {
++ticks_elapsed;
cycles_elapsed = now - next_tick; next_tick += cpt;
now = mfctl(16);
if ((cycles_elapsed >> 6) < cpt) { } while (next_tick - now > cpt);
/* use "cheap" math (add/subtract) instead
* of the more expensive div/mul method
*/
cycles_remainder = cycles_elapsed;
while (cycles_remainder > cpt) {
cycles_remainder -= cpt;
ticks_elapsed++;
}
} else {
/* TODO: Reduce this to one fdiv op */
cycles_remainder = cycles_elapsed % cpt;
ticks_elapsed += cycles_elapsed / cpt;
}
/* convert from "division remainder" to "remainder of clock tick" */
cycles_remainder = cpt - cycles_remainder;
/* Determine when (in CR16 cycles) next IT interrupt will fire.
* We want IT to fire modulo clocktick even if we miss/skip some.
* But those interrupts don't in fact get delivered that regularly.
*/
next_tick = now + cycles_remainder;
/* Store (in CR16 cycles) up to when we are accounting right now. */
cpuinfo->it_value = next_tick; cpuinfo->it_value = next_tick;
/* Program the IT when to deliver the next interrupt. /* Go do system house keeping. */
* Only bottom 32-bits of next_tick are writable in CR16! if (cpu == 0)
*/ xtime_update(ticks_elapsed);
mtctl(next_tick, 16);
update_process_times(user_mode(get_irq_regs()));
/* Skip one clocktick on purpose if we missed next_tick. /* Skip clockticks on purpose if we know we would miss those.
* The new CR16 must be "later" than current CR16 otherwise * The new CR16 must be "later" than current CR16 otherwise
* itimer would not fire until CR16 wrapped - e.g 4 seconds * itimer would not fire until CR16 wrapped - e.g 4 seconds
* later on a 1Ghz processor. We'll account for the missed * later on a 1Ghz processor. We'll account for the missed
* tick on the next timer interrupt. * ticks on the next timer interrupt.
* We want IT to fire modulo clocktick even if we miss/skip some.
* But those interrupts don't in fact get delivered that regularly.
* *
* "next_tick - now" will always give the difference regardless * "next_tick - now" will always give the difference regardless
* if one or the other wrapped. If "now" is "bigger" we'll end up * if one or the other wrapped. If "now" is "bigger" we'll end up
* with a very large unsigned number. * with a very large unsigned number.
*/ */
now2 = mfctl(16); while (next_tick - mfctl(16) > cpt)
if (next_tick - now2 > cpt) next_tick += cpt;
mtctl(next_tick+cpt, 16);
#if 1 /* Program the IT when to deliver the next interrupt.
/* * Only bottom 32-bits of next_tick are writable in CR16!
* GGG: DEBUG code for how many cycles programming CR16 used. * Timer interrupt will be delivered at least a few hundred cycles
*/ * after the IT fires, so if we are too close (<= 500 cycles) to the
if (unlikely(now2 - now > 0x3000)) /* 12K cycles */ * next cycle, simply skip it.
printk (KERN_CRIT "timer_interrupt(CPU %d): SLOW! 0x%lx cycles!"
" cyc %lX rem %lX "
" next/now %lX/%lX\n",
cpu, now2 - now, cycles_elapsed, cycles_remainder,
next_tick, now );
#endif
/* Can we differentiate between "early CR16" (aka Scenario 1) and
* "long delay" (aka Scenario 3)? I don't think so.
*
* Timer_interrupt will be delivered at least a few hundred cycles
* after the IT fires. But it's arbitrary how much time passes
* before we call it "late". I've picked one second.
*
* It's important NO printk's are between reading CR16 and
* setting up the next value. May introduce huge variance.
*/
if (unlikely(ticks_elapsed > HZ)) {
/* Scenario 3: very long delay? bad in any case */
printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
" cycles %lX rem %lX "
" next/now %lX/%lX\n",
cpu,
cycles_elapsed, cycles_remainder,
next_tick, now );
}
/* Done mucking with unreliable delivery of interrupts.
* Go do system house keeping.
*/ */
if (next_tick - mfctl(16) <= 500)
if (!--cpuinfo->prof_counter) { next_tick += cpt;
cpuinfo->prof_counter = cpuinfo->prof_multiplier; mtctl(next_tick, 16);
update_process_times(user_mode(get_irq_regs()));
}
if (cpu == 0)
xtime_update(ticks_elapsed);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment