Pull miscellaneous into release branch
Conflicts: arch/ia64/kernel/mca.c
This commit is contained in:
commit
71b264f85f
@ -622,6 +622,9 @@ config IRQ_PER_CPU
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config IOMMU_HELPER
|
||||||
|
def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC)
|
||||||
|
|
||||||
source "arch/ia64/hp/sim/Kconfig"
|
source "arch/ia64/hp/sim/Kconfig"
|
||||||
|
|
||||||
source "arch/ia64/Kconfig.debug"
|
source "arch/ia64/Kconfig.debug"
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <linux/nodemask.h>
|
#include <linux/nodemask.h>
|
||||||
#include <linux/bitops.h> /* hweight64() */
|
#include <linux/bitops.h> /* hweight64() */
|
||||||
#include <linux/crash_dump.h>
|
#include <linux/crash_dump.h>
|
||||||
|
#include <linux/iommu-helper.h>
|
||||||
|
|
||||||
#include <asm/delay.h> /* ia64_get_itc() */
|
#include <asm/delay.h> /* ia64_get_itc() */
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@ -460,6 +461,13 @@ get_iovp_order (unsigned long size)
|
|||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr,
|
||||||
|
unsigned int bitshiftcnt)
|
||||||
|
{
|
||||||
|
return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3)
|
||||||
|
+ bitshiftcnt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sba_search_bitmap - find free space in IO PDIR resource bitmap
|
* sba_search_bitmap - find free space in IO PDIR resource bitmap
|
||||||
* @ioc: IO MMU structure which owns the pdir we are interested in.
|
* @ioc: IO MMU structure which owns the pdir we are interested in.
|
||||||
@ -471,15 +479,25 @@ get_iovp_order (unsigned long size)
|
|||||||
* Cool perf optimization: search for log2(size) bits at a time.
|
* Cool perf optimization: search for log2(size) bits at a time.
|
||||||
*/
|
*/
|
||||||
static SBA_INLINE unsigned long
|
static SBA_INLINE unsigned long
|
||||||
sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
|
sba_search_bitmap(struct ioc *ioc, struct device *dev,
|
||||||
|
unsigned long bits_wanted, int use_hint)
|
||||||
{
|
{
|
||||||
unsigned long *res_ptr;
|
unsigned long *res_ptr;
|
||||||
unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
|
unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
|
||||||
unsigned long flags, pide = ~0UL;
|
unsigned long flags, pide = ~0UL, tpide;
|
||||||
|
unsigned long boundary_size;
|
||||||
|
unsigned long shift;
|
||||||
|
int ret;
|
||||||
|
|
||||||
ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
|
ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
|
||||||
ASSERT(res_ptr < res_end);
|
ASSERT(res_ptr < res_end);
|
||||||
|
|
||||||
|
boundary_size = (unsigned long long)dma_get_seg_boundary(dev) + 1;
|
||||||
|
boundary_size = ALIGN(boundary_size, 1ULL << iovp_shift) >> iovp_shift;
|
||||||
|
|
||||||
|
BUG_ON(ioc->ibase & ~iovp_mask);
|
||||||
|
shift = ioc->ibase >> iovp_shift;
|
||||||
|
|
||||||
spin_lock_irqsave(&ioc->res_lock, flags);
|
spin_lock_irqsave(&ioc->res_lock, flags);
|
||||||
|
|
||||||
/* Allow caller to force a search through the entire resource space */
|
/* Allow caller to force a search through the entire resource space */
|
||||||
@ -504,9 +522,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
|
|||||||
if (likely(*res_ptr != ~0UL)) {
|
if (likely(*res_ptr != ~0UL)) {
|
||||||
bitshiftcnt = ffz(*res_ptr);
|
bitshiftcnt = ffz(*res_ptr);
|
||||||
*res_ptr |= (1UL << bitshiftcnt);
|
*res_ptr |= (1UL << bitshiftcnt);
|
||||||
pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
|
pide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
|
||||||
pide <<= 3; /* convert to bit address */
|
|
||||||
pide += bitshiftcnt;
|
|
||||||
ioc->res_bitshift = bitshiftcnt + bits_wanted;
|
ioc->res_bitshift = bitshiftcnt + bits_wanted;
|
||||||
goto found_it;
|
goto found_it;
|
||||||
}
|
}
|
||||||
@ -535,11 +551,13 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
|
|||||||
DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr);
|
DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr);
|
||||||
ASSERT(0 != mask);
|
ASSERT(0 != mask);
|
||||||
for (; mask ; mask <<= o, bitshiftcnt += o) {
|
for (; mask ; mask <<= o, bitshiftcnt += o) {
|
||||||
if(0 == ((*res_ptr) & mask)) {
|
tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt);
|
||||||
|
ret = iommu_is_span_boundary(tpide, bits_wanted,
|
||||||
|
shift,
|
||||||
|
boundary_size);
|
||||||
|
if ((0 == ((*res_ptr) & mask)) && !ret) {
|
||||||
*res_ptr |= mask; /* mark resources busy! */
|
*res_ptr |= mask; /* mark resources busy! */
|
||||||
pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
|
pide = tpide;
|
||||||
pide <<= 3; /* convert to bit address */
|
|
||||||
pide += bitshiftcnt;
|
|
||||||
ioc->res_bitshift = bitshiftcnt + bits_wanted;
|
ioc->res_bitshift = bitshiftcnt + bits_wanted;
|
||||||
goto found_it;
|
goto found_it;
|
||||||
}
|
}
|
||||||
@ -560,6 +578,11 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
|
|||||||
end = res_end - qwords;
|
end = res_end - qwords;
|
||||||
|
|
||||||
for (; res_ptr < end; res_ptr++) {
|
for (; res_ptr < end; res_ptr++) {
|
||||||
|
tpide = ptr_to_pide(ioc, res_ptr, 0);
|
||||||
|
ret = iommu_is_span_boundary(tpide, bits_wanted,
|
||||||
|
shift, boundary_size);
|
||||||
|
if (ret)
|
||||||
|
goto next_ptr;
|
||||||
for (i = 0 ; i < qwords ; i++) {
|
for (i = 0 ; i < qwords ; i++) {
|
||||||
if (res_ptr[i] != 0)
|
if (res_ptr[i] != 0)
|
||||||
goto next_ptr;
|
goto next_ptr;
|
||||||
@ -572,8 +595,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint)
|
|||||||
res_ptr[i] = ~0UL;
|
res_ptr[i] = ~0UL;
|
||||||
res_ptr[i] |= RESMAP_MASK(bits);
|
res_ptr[i] |= RESMAP_MASK(bits);
|
||||||
|
|
||||||
pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
|
pide = tpide;
|
||||||
pide <<= 3; /* convert to bit address */
|
|
||||||
res_ptr += qwords;
|
res_ptr += qwords;
|
||||||
ioc->res_bitshift = bits;
|
ioc->res_bitshift = bits;
|
||||||
goto found_it;
|
goto found_it;
|
||||||
@ -605,7 +627,7 @@ found_it:
|
|||||||
* resource bit map.
|
* resource bit map.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
sba_alloc_range(struct ioc *ioc, size_t size)
|
sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
|
||||||
{
|
{
|
||||||
unsigned int pages_needed = size >> iovp_shift;
|
unsigned int pages_needed = size >> iovp_shift;
|
||||||
#ifdef PDIR_SEARCH_TIMING
|
#ifdef PDIR_SEARCH_TIMING
|
||||||
@ -622,9 +644,9 @@ sba_alloc_range(struct ioc *ioc, size_t size)
|
|||||||
/*
|
/*
|
||||||
** "seek and ye shall find"...praying never hurts either...
|
** "seek and ye shall find"...praying never hurts either...
|
||||||
*/
|
*/
|
||||||
pide = sba_search_bitmap(ioc, pages_needed, 1);
|
pide = sba_search_bitmap(ioc, dev, pages_needed, 1);
|
||||||
if (unlikely(pide >= (ioc->res_size << 3))) {
|
if (unlikely(pide >= (ioc->res_size << 3))) {
|
||||||
pide = sba_search_bitmap(ioc, pages_needed, 0);
|
pide = sba_search_bitmap(ioc, dev, pages_needed, 0);
|
||||||
if (unlikely(pide >= (ioc->res_size << 3))) {
|
if (unlikely(pide >= (ioc->res_size << 3))) {
|
||||||
#if DELAYED_RESOURCE_CNT > 0
|
#if DELAYED_RESOURCE_CNT > 0
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -653,7 +675,7 @@ sba_alloc_range(struct ioc *ioc, size_t size)
|
|||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&ioc->saved_lock, flags);
|
spin_unlock_irqrestore(&ioc->saved_lock, flags);
|
||||||
|
|
||||||
pide = sba_search_bitmap(ioc, pages_needed, 0);
|
pide = sba_search_bitmap(ioc, dev, pages_needed, 0);
|
||||||
if (unlikely(pide >= (ioc->res_size << 3)))
|
if (unlikely(pide >= (ioc->res_size << 3)))
|
||||||
panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n",
|
panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n",
|
||||||
ioc->ioc_hpa);
|
ioc->ioc_hpa);
|
||||||
@ -936,7 +958,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, int dir)
|
|||||||
spin_unlock_irqrestore(&ioc->res_lock, flags);
|
spin_unlock_irqrestore(&ioc->res_lock, flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pide = sba_alloc_range(ioc, size);
|
pide = sba_alloc_range(ioc, dev, size);
|
||||||
|
|
||||||
iovp = (dma_addr_t) pide << iovp_shift;
|
iovp = (dma_addr_t) pide << iovp_shift;
|
||||||
|
|
||||||
@ -1373,7 +1395,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev,
|
|||||||
dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask;
|
dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask;
|
||||||
ASSERT(dma_len <= DMA_CHUNK_SIZE);
|
ASSERT(dma_len <= DMA_CHUNK_SIZE);
|
||||||
dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG
|
dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG
|
||||||
| (sba_alloc_range(ioc, dma_len) << iovp_shift)
|
| (sba_alloc_range(ioc, dev, dma_len) << iovp_shift)
|
||||||
| dma_offset);
|
| dma_offset);
|
||||||
n_mappings++;
|
n_mappings++;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define ASM_OFFSETS_C 1
|
#define ASM_OFFSETS_C 1
|
||||||
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/pid.h>
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
|
|
||||||
#include <asm-ia64/processor.h>
|
#include <asm-ia64/processor.h>
|
||||||
@ -34,6 +35,9 @@ void foo(void)
|
|||||||
DEFINE(SIGFRAME_SIZE, sizeof (struct sigframe));
|
DEFINE(SIGFRAME_SIZE, sizeof (struct sigframe));
|
||||||
DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));
|
DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));
|
||||||
|
|
||||||
|
BUILD_BUG_ON(sizeof(struct upid) != 32);
|
||||||
|
DEFINE(IA64_UPID_SHIFT, 5);
|
||||||
|
|
||||||
BLANK();
|
BLANK();
|
||||||
|
|
||||||
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
||||||
@ -51,6 +55,9 @@ void foo(void)
|
|||||||
DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked));
|
DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked));
|
||||||
DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
|
DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
|
||||||
DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader));
|
DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader));
|
||||||
|
DEFINE(IA64_TASK_TGIDLINK_OFFSET, offsetof (struct task_struct, pids[PIDTYPE_PID].pid));
|
||||||
|
DEFINE(IA64_PID_LEVEL_OFFSET, offsetof (struct pid, level));
|
||||||
|
DEFINE(IA64_PID_UPID_OFFSET, offsetof (struct pid, numbers[0]));
|
||||||
DEFINE(IA64_TASK_PENDING_OFFSET,offsetof (struct task_struct, pending));
|
DEFINE(IA64_TASK_PENDING_OFFSET,offsetof (struct task_struct, pending));
|
||||||
DEFINE(IA64_TASK_PID_OFFSET, offsetof (struct task_struct, pid));
|
DEFINE(IA64_TASK_PID_OFFSET, offsetof (struct task_struct, pid));
|
||||||
DEFINE(IA64_TASK_REAL_PARENT_OFFSET, offsetof (struct task_struct, real_parent));
|
DEFINE(IA64_TASK_REAL_PARENT_OFFSET, offsetof (struct task_struct, real_parent));
|
||||||
|
@ -24,6 +24,7 @@ int kdump_status[NR_CPUS];
|
|||||||
static atomic_t kdump_cpu_frozen;
|
static atomic_t kdump_cpu_frozen;
|
||||||
atomic_t kdump_in_progress;
|
atomic_t kdump_in_progress;
|
||||||
static int kdump_on_init = 1;
|
static int kdump_on_init = 1;
|
||||||
|
static int kdump_on_fatal_mca = 1;
|
||||||
|
|
||||||
static inline Elf64_Word
|
static inline Elf64_Word
|
||||||
*append_elf_note(Elf64_Word *buf, char *name, unsigned type, void *data,
|
*append_elf_note(Elf64_Word *buf, char *name, unsigned type, void *data,
|
||||||
@ -118,6 +119,7 @@ machine_crash_shutdown(struct pt_regs *pt)
|
|||||||
static void
|
static void
|
||||||
machine_kdump_on_init(void)
|
machine_kdump_on_init(void)
|
||||||
{
|
{
|
||||||
|
crash_save_vmcoreinfo();
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
kexec_disable_iosapic();
|
kexec_disable_iosapic();
|
||||||
machine_kexec(ia64_kimage);
|
machine_kexec(ia64_kimage);
|
||||||
@ -148,7 +150,7 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
|
|||||||
struct ia64_mca_notify_die *nd;
|
struct ia64_mca_notify_die *nd;
|
||||||
struct die_args *args = data;
|
struct die_args *args = data;
|
||||||
|
|
||||||
if (!kdump_on_init)
|
if (!kdump_on_init && !kdump_on_fatal_mca)
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
if (!ia64_kimage) {
|
if (!ia64_kimage) {
|
||||||
@ -173,32 +175,38 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
|
|||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case DIE_INIT_MONARCH_PROCESS:
|
case DIE_INIT_MONARCH_PROCESS:
|
||||||
|
if (kdump_on_init) {
|
||||||
atomic_set(&kdump_in_progress, 1);
|
atomic_set(&kdump_in_progress, 1);
|
||||||
*(nd->monarch_cpu) = -1;
|
*(nd->monarch_cpu) = -1;
|
||||||
break;
|
}
|
||||||
case DIE_INIT_MONARCH_LEAVE:
|
break;
|
||||||
|
case DIE_INIT_MONARCH_LEAVE:
|
||||||
|
if (kdump_on_init)
|
||||||
machine_kdump_on_init();
|
machine_kdump_on_init();
|
||||||
break;
|
break;
|
||||||
case DIE_INIT_SLAVE_LEAVE:
|
case DIE_INIT_SLAVE_LEAVE:
|
||||||
if (atomic_read(&kdump_in_progress))
|
if (atomic_read(&kdump_in_progress))
|
||||||
unw_init_running(kdump_cpu_freeze, NULL);
|
unw_init_running(kdump_cpu_freeze, NULL);
|
||||||
break;
|
break;
|
||||||
case DIE_MCA_RENDZVOUS_LEAVE:
|
case DIE_MCA_RENDZVOUS_LEAVE:
|
||||||
if (atomic_read(&kdump_in_progress))
|
if (atomic_read(&kdump_in_progress))
|
||||||
unw_init_running(kdump_cpu_freeze, NULL);
|
unw_init_running(kdump_cpu_freeze, NULL);
|
||||||
break;
|
break;
|
||||||
case DIE_MCA_MONARCH_LEAVE:
|
case DIE_MCA_MONARCH_LEAVE:
|
||||||
/* die_register->signr indicate if MCA is recoverable */
|
/* die_register->signr indicate if MCA is recoverable */
|
||||||
if (!args->signr)
|
if (kdump_on_fatal_mca && !args->signr) {
|
||||||
machine_kdump_on_init();
|
atomic_set(&kdump_in_progress, 1);
|
||||||
break;
|
*(nd->monarch_cpu) = -1;
|
||||||
|
machine_kdump_on_init();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SYSCTL
|
#ifdef CONFIG_SYSCTL
|
||||||
static ctl_table kdump_on_init_table[] = {
|
static ctl_table kdump_ctl_table[] = {
|
||||||
{
|
{
|
||||||
.ctl_name = CTL_UNNUMBERED,
|
.ctl_name = CTL_UNNUMBERED,
|
||||||
.procname = "kdump_on_init",
|
.procname = "kdump_on_init",
|
||||||
@ -207,6 +215,14 @@ static ctl_table kdump_on_init_table[] = {
|
|||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_dointvec,
|
.proc_handler = &proc_dointvec,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.ctl_name = CTL_UNNUMBERED,
|
||||||
|
.procname = "kdump_on_fatal_mca",
|
||||||
|
.data = &kdump_on_fatal_mca,
|
||||||
|
.maxlen = sizeof(int),
|
||||||
|
.mode = 0644,
|
||||||
|
.proc_handler = &proc_dointvec,
|
||||||
|
},
|
||||||
{ .ctl_name = 0 }
|
{ .ctl_name = 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -215,7 +231,7 @@ static ctl_table sys_table[] = {
|
|||||||
.ctl_name = CTL_KERN,
|
.ctl_name = CTL_KERN,
|
||||||
.procname = "kernel",
|
.procname = "kernel",
|
||||||
.mode = 0555,
|
.mode = 0555,
|
||||||
.child = kdump_on_init_table,
|
.child = kdump_ctl_table,
|
||||||
},
|
},
|
||||||
{ .ctl_name = 0 }
|
{ .ctl_name = 0 }
|
||||||
};
|
};
|
||||||
|
@ -61,13 +61,29 @@ ENTRY(fsys_getpid)
|
|||||||
.prologue
|
.prologue
|
||||||
.altrp b6
|
.altrp b6
|
||||||
.body
|
.body
|
||||||
|
add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16
|
||||||
|
;;
|
||||||
|
ld8 r17=[r17] // r17 = current->group_leader
|
||||||
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
|
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
|
||||||
;;
|
;;
|
||||||
ld4 r9=[r9]
|
ld4 r9=[r9]
|
||||||
add r8=IA64_TASK_TGID_OFFSET,r16
|
add r17=IA64_TASK_TGIDLINK_OFFSET,r17
|
||||||
;;
|
;;
|
||||||
and r9=TIF_ALLWORK_MASK,r9
|
and r9=TIF_ALLWORK_MASK,r9
|
||||||
ld4 r8=[r8] // r8 = current->tgid
|
ld8 r17=[r17] // r17 = current->group_leader->pids[PIDTYPE_PID].pid
|
||||||
|
;;
|
||||||
|
add r8=IA64_PID_LEVEL_OFFSET,r17
|
||||||
|
;;
|
||||||
|
ld4 r8=[r8] // r8 = pid->level
|
||||||
|
add r17=IA64_PID_UPID_OFFSET,r17 // r17 = &pid->numbers[0]
|
||||||
|
;;
|
||||||
|
shl r8=r8,IA64_UPID_SHIFT
|
||||||
|
;;
|
||||||
|
add r17=r17,r8 // r17 = &pid->numbers[pid->level]
|
||||||
|
;;
|
||||||
|
ld4 r8=[r17] // r8 = pid->numbers[pid->level].nr
|
||||||
|
;;
|
||||||
|
mov r17=0
|
||||||
;;
|
;;
|
||||||
cmp.ne p8,p0=0,r9
|
cmp.ne p8,p0=0,r9
|
||||||
(p8) br.spnt.many fsys_fallback_syscall
|
(p8) br.spnt.many fsys_fallback_syscall
|
||||||
@ -126,15 +142,25 @@ ENTRY(fsys_set_tid_address)
|
|||||||
.altrp b6
|
.altrp b6
|
||||||
.body
|
.body
|
||||||
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
|
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
|
||||||
|
add r17=IA64_TASK_TGIDLINK_OFFSET,r16
|
||||||
;;
|
;;
|
||||||
ld4 r9=[r9]
|
ld4 r9=[r9]
|
||||||
tnat.z p6,p7=r32 // check argument register for being NaT
|
tnat.z p6,p7=r32 // check argument register for being NaT
|
||||||
|
ld8 r17=[r17] // r17 = current->pids[PIDTYPE_PID].pid
|
||||||
;;
|
;;
|
||||||
and r9=TIF_ALLWORK_MASK,r9
|
and r9=TIF_ALLWORK_MASK,r9
|
||||||
add r8=IA64_TASK_PID_OFFSET,r16
|
add r8=IA64_PID_LEVEL_OFFSET,r17
|
||||||
add r18=IA64_TASK_CLEAR_CHILD_TID_OFFSET,r16
|
add r18=IA64_TASK_CLEAR_CHILD_TID_OFFSET,r16
|
||||||
;;
|
;;
|
||||||
ld4 r8=[r8]
|
ld4 r8=[r8] // r8 = pid->level
|
||||||
|
add r17=IA64_PID_UPID_OFFSET,r17 // r17 = &pid->numbers[0]
|
||||||
|
;;
|
||||||
|
shl r8=r8,IA64_UPID_SHIFT
|
||||||
|
;;
|
||||||
|
add r17=r17,r8 // r17 = &pid->numbers[pid->level]
|
||||||
|
;;
|
||||||
|
ld4 r8=[r17] // r8 = pid->numbers[pid->level].nr
|
||||||
|
;;
|
||||||
cmp.ne p8,p0=0,r9
|
cmp.ne p8,p0=0,r9
|
||||||
mov r17=-1
|
mov r17=-1
|
||||||
;;
|
;;
|
||||||
|
@ -472,7 +472,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
|
|||||||
static unsigned char count;
|
static unsigned char count;
|
||||||
static long last_time;
|
static long last_time;
|
||||||
|
|
||||||
if (jiffies - last_time > 5*HZ)
|
if (time_after(jiffies, last_time + 5 * HZ))
|
||||||
count = 0;
|
count = 0;
|
||||||
if (++count < 5) {
|
if (++count < 5) {
|
||||||
last_time = jiffies;
|
last_time = jiffies;
|
||||||
|
@ -78,6 +78,20 @@ static enum instruction_type bundle_encoding[32][3] = {
|
|||||||
{ u, u, u }, /* 1F */
|
{ u, u, u }, /* 1F */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Insert a long branch code */
|
||||||
|
static void __kprobes set_brl_inst(void *from, void *to)
|
||||||
|
{
|
||||||
|
s64 rel = ((s64) to - (s64) from) >> 4;
|
||||||
|
bundle_t *brl;
|
||||||
|
brl = (bundle_t *) ((u64) from & ~0xf);
|
||||||
|
brl->quad0.template = 0x05; /* [MLX](stop) */
|
||||||
|
brl->quad0.slot0 = NOP_M_INST; /* nop.m 0x0 */
|
||||||
|
brl->quad0.slot1_p0 = ((rel >> 20) & 0x7fffffffff) << 2;
|
||||||
|
brl->quad1.slot1_p1 = (((rel >> 20) & 0x7fffffffff) << 2) >> (64 - 46);
|
||||||
|
/* brl.cond.sptk.many.clr rel<<4 (qp=0) */
|
||||||
|
brl->quad1.slot2 = BRL_INST(rel >> 59, rel & 0xfffff);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In this function we check to see if the instruction
|
* In this function we check to see if the instruction
|
||||||
* is IP relative instruction and update the kprobe
|
* is IP relative instruction and update the kprobe
|
||||||
@ -496,6 +510,77 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
|||||||
regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
|
regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check the instruction in the slot is break */
|
||||||
|
static int __kprobes __is_ia64_break_inst(bundle_t *bundle, uint slot)
|
||||||
|
{
|
||||||
|
unsigned int major_opcode;
|
||||||
|
unsigned int template = bundle->quad0.template;
|
||||||
|
unsigned long kprobe_inst;
|
||||||
|
|
||||||
|
/* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
|
||||||
|
if (slot == 1 && bundle_encoding[template][1] == L)
|
||||||
|
slot++;
|
||||||
|
|
||||||
|
/* Get Kprobe probe instruction at given slot*/
|
||||||
|
get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
|
||||||
|
|
||||||
|
/* For break instruction,
|
||||||
|
* Bits 37:40 Major opcode to be zero
|
||||||
|
* Bits 27:32 X6 to be zero
|
||||||
|
* Bits 32:35 X3 to be zero
|
||||||
|
*/
|
||||||
|
if (major_opcode || ((kprobe_inst >> 27) & 0x1FF)) {
|
||||||
|
/* Not a break instruction */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is a break instruction */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In this function, we check whether the target bundle modifies IP or
|
||||||
|
* it triggers an exception. If so, it cannot be boostable.
|
||||||
|
*/
|
||||||
|
static int __kprobes can_boost(bundle_t *bundle, uint slot,
|
||||||
|
unsigned long bundle_addr)
|
||||||
|
{
|
||||||
|
unsigned int template = bundle->quad0.template;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (search_exception_tables(bundle_addr + slot) ||
|
||||||
|
__is_ia64_break_inst(bundle, slot))
|
||||||
|
return 0; /* exception may occur in this bundle*/
|
||||||
|
} while ((++slot) < 3);
|
||||||
|
template &= 0x1e;
|
||||||
|
if (template >= 0x10 /* including B unit */ ||
|
||||||
|
template == 0x04 /* including X unit */ ||
|
||||||
|
template == 0x06) /* undefined */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare long jump bundle and disables other boosters if need */
|
||||||
|
static void __kprobes prepare_booster(struct kprobe *p)
|
||||||
|
{
|
||||||
|
unsigned long addr = (unsigned long)p->addr & ~0xFULL;
|
||||||
|
unsigned int slot = (unsigned long)p->addr & 0xf;
|
||||||
|
struct kprobe *other_kp;
|
||||||
|
|
||||||
|
if (can_boost(&p->ainsn.insn[0].bundle, slot, addr)) {
|
||||||
|
set_brl_inst(&p->ainsn.insn[1].bundle, (bundle_t *)addr + 1);
|
||||||
|
p->ainsn.inst_flag |= INST_FLAG_BOOSTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disables boosters in previous slots */
|
||||||
|
for (; addr < (unsigned long)p->addr; addr++) {
|
||||||
|
other_kp = get_kprobe((void *)addr);
|
||||||
|
if (other_kp)
|
||||||
|
other_kp->ainsn.inst_flag &= ~INST_FLAG_BOOSTABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
unsigned long addr = (unsigned long) p->addr;
|
unsigned long addr = (unsigned long) p->addr;
|
||||||
@ -530,6 +615,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
|||||||
|
|
||||||
prepare_break_inst(template, slot, major_opcode, kprobe_inst, p, qp);
|
prepare_break_inst(template, slot, major_opcode, kprobe_inst, p, qp);
|
||||||
|
|
||||||
|
prepare_booster(p);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,7 +630,9 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
|
|||||||
src = &p->opcode.bundle;
|
src = &p->opcode.bundle;
|
||||||
|
|
||||||
flush_icache_range((unsigned long)p->ainsn.insn,
|
flush_icache_range((unsigned long)p->ainsn.insn,
|
||||||
(unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t));
|
(unsigned long)p->ainsn.insn +
|
||||||
|
sizeof(kprobe_opcode_t) * MAX_INSN_SIZE);
|
||||||
|
|
||||||
switch (p->ainsn.slot) {
|
switch (p->ainsn.slot) {
|
||||||
case 0:
|
case 0:
|
||||||
dest->quad0.slot0 = src->quad0.slot0;
|
dest->quad0.slot0 = src->quad0.slot0;
|
||||||
@ -584,13 +673,13 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
|
|||||||
void __kprobes arch_remove_kprobe(struct kprobe *p)
|
void __kprobes arch_remove_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
mutex_lock(&kprobe_mutex);
|
mutex_lock(&kprobe_mutex);
|
||||||
free_insn_slot(p->ainsn.insn, 0);
|
free_insn_slot(p->ainsn.insn, p->ainsn.inst_flag & INST_FLAG_BOOSTABLE);
|
||||||
mutex_unlock(&kprobe_mutex);
|
mutex_unlock(&kprobe_mutex);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* We are resuming execution after a single step fault, so the pt_regs
|
* We are resuming execution after a single step fault, so the pt_regs
|
||||||
* structure reflects the register state after we executed the instruction
|
* structure reflects the register state after we executed the instruction
|
||||||
* located in the kprobe (p->ainsn.insn.bundle). We still need to adjust
|
* located in the kprobe (p->ainsn.insn->bundle). We still need to adjust
|
||||||
* the ip to point back to the original stack address. To set the IP address
|
* the ip to point back to the original stack address. To set the IP address
|
||||||
* to original stack address, handle the case where we need to fixup the
|
* to original stack address, handle the case where we need to fixup the
|
||||||
* relative IP address and/or fixup branch register.
|
* relative IP address and/or fixup branch register.
|
||||||
@ -607,7 +696,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
|
|||||||
if (slot == 1 && bundle_encoding[template][1] == L)
|
if (slot == 1 && bundle_encoding[template][1] == L)
|
||||||
slot = 2;
|
slot = 2;
|
||||||
|
|
||||||
if (p->ainsn.inst_flag) {
|
if (p->ainsn.inst_flag & ~INST_FLAG_BOOSTABLE) {
|
||||||
|
|
||||||
if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
|
if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
|
||||||
/* Fix relative IP address */
|
/* Fix relative IP address */
|
||||||
@ -686,33 +775,12 @@ static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
|
|||||||
static int __kprobes is_ia64_break_inst(struct pt_regs *regs)
|
static int __kprobes is_ia64_break_inst(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned int slot = ia64_psr(regs)->ri;
|
unsigned int slot = ia64_psr(regs)->ri;
|
||||||
unsigned int template, major_opcode;
|
|
||||||
unsigned long kprobe_inst;
|
|
||||||
unsigned long *kprobe_addr = (unsigned long *)regs->cr_iip;
|
unsigned long *kprobe_addr = (unsigned long *)regs->cr_iip;
|
||||||
bundle_t bundle;
|
bundle_t bundle;
|
||||||
|
|
||||||
memcpy(&bundle, kprobe_addr, sizeof(bundle_t));
|
memcpy(&bundle, kprobe_addr, sizeof(bundle_t));
|
||||||
template = bundle.quad0.template;
|
|
||||||
|
|
||||||
/* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
|
return __is_ia64_break_inst(&bundle, slot);
|
||||||
if (slot == 1 && bundle_encoding[template][1] == L)
|
|
||||||
slot++;
|
|
||||||
|
|
||||||
/* Get Kprobe probe instruction at given slot*/
|
|
||||||
get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode);
|
|
||||||
|
|
||||||
/* For break instruction,
|
|
||||||
* Bits 37:40 Major opcode to be zero
|
|
||||||
* Bits 27:32 X6 to be zero
|
|
||||||
* Bits 32:35 X3 to be zero
|
|
||||||
*/
|
|
||||||
if (major_opcode || ((kprobe_inst >> 27) & 0x1FF) ) {
|
|
||||||
/* Not a break instruction */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is a break instruction */
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __kprobes pre_kprobes_handler(struct die_args *args)
|
static int __kprobes pre_kprobes_handler(struct die_args *args)
|
||||||
@ -802,6 +870,19 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ss_probe:
|
ss_probe:
|
||||||
|
#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM)
|
||||||
|
if (p->ainsn.inst_flag == INST_FLAG_BOOSTABLE && !p->post_handler) {
|
||||||
|
/* Boost up -- we can execute copied instructions directly */
|
||||||
|
ia64_psr(regs)->ri = p->ainsn.slot;
|
||||||
|
regs->cr_iip = (unsigned long)&p->ainsn.insn->bundle & ~0xFULL;
|
||||||
|
/* turn single stepping off */
|
||||||
|
ia64_psr(regs)->ss = 0;
|
||||||
|
|
||||||
|
reset_current_kprobe();
|
||||||
|
preempt_enable_no_resched();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
prepare_ss(p, regs);
|
prepare_ss(p, regs);
|
||||||
kcb->kprobe_status = KPROBE_HIT_SS;
|
kcb->kprobe_status = KPROBE_HIT_SS;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
* 2007-04-27 Russ Anderson <rja@sgi.com>
|
* 2007-04-27 Russ Anderson <rja@sgi.com>
|
||||||
* Support multiple cpus going through OS_MCA in the same event.
|
* Support multiple cpus going through OS_MCA in the same event.
|
||||||
*/
|
*/
|
||||||
|
#include <linux/jiffies.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
@ -295,7 +296,8 @@ static void ia64_mlogbuf_dump_from_init(void)
|
|||||||
if (mlogbuf_finished)
|
if (mlogbuf_finished)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mlogbuf_timestamp && (mlogbuf_timestamp + 30*HZ > jiffies)) {
|
if (mlogbuf_timestamp &&
|
||||||
|
time_before(jiffies, mlogbuf_timestamp + 30 * HZ)) {
|
||||||
printk(KERN_ERR "INIT: mlogbuf_dump is interrupted by INIT "
|
printk(KERN_ERR "INIT: mlogbuf_dump is interrupted by INIT "
|
||||||
" and the system seems to be messed up.\n");
|
" and the system seems to be messed up.\n");
|
||||||
ia64_mlogbuf_finish(0);
|
ia64_mlogbuf_finish(0);
|
||||||
@ -1311,20 +1313,17 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
|
|||||||
} else {
|
} else {
|
||||||
/* Dump buffered message to console */
|
/* Dump buffered message to console */
|
||||||
ia64_mlogbuf_finish(1);
|
ia64_mlogbuf_finish(1);
|
||||||
#ifdef CONFIG_KEXEC
|
|
||||||
atomic_set(&kdump_in_progress, 1);
|
|
||||||
monarch_cpu = -1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__get_cpu_var(ia64_mca_tr_reload)) {
|
if (__get_cpu_var(ia64_mca_tr_reload)) {
|
||||||
mca_insert_tr(0x1); /*Reload dynamic itrs*/
|
mca_insert_tr(0x1); /*Reload dynamic itrs*/
|
||||||
mca_insert_tr(0x2); /*Reload dynamic itrs*/
|
mca_insert_tr(0x2); /*Reload dynamic itrs*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
|
if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
|
||||||
== NOTIFY_STOP)
|
== NOTIFY_STOP)
|
||||||
ia64_mca_spin(__func__);
|
ia64_mca_spin(__func__);
|
||||||
|
|
||||||
|
|
||||||
if (atomic_dec_return(&mca_count) > 0) {
|
if (atomic_dec_return(&mca_count) > 0) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -4204,10 +4204,10 @@ pfm_check_task_exist(pfm_context_t *ctx)
|
|||||||
do_each_thread (g, t) {
|
do_each_thread (g, t) {
|
||||||
if (t->thread.pfm_context == ctx) {
|
if (t->thread.pfm_context == ctx) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
} while_each_thread (g, t);
|
} while_each_thread (g, t);
|
||||||
|
out:
|
||||||
read_unlock(&tasklist_lock);
|
read_unlock(&tasklist_lock);
|
||||||
|
|
||||||
DPRINT(("pfm_check_task_exist: ret=%d ctx=%p\n", ret, ctx));
|
DPRINT(("pfm_check_task_exist: ret=%d ctx=%p\n", ret, ctx));
|
||||||
|
@ -177,6 +177,29 @@ filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Similar to "filter_rsvd_memory()", but the reserved memory ranges
|
||||||
|
* are not filtered out.
|
||||||
|
*/
|
||||||
|
int __init
|
||||||
|
filter_memory(unsigned long start, unsigned long end, void *arg)
|
||||||
|
{
|
||||||
|
void (*func)(unsigned long, unsigned long, int);
|
||||||
|
|
||||||
|
#if IGNORE_PFN0
|
||||||
|
if (start == PAGE_OFFSET) {
|
||||||
|
printk(KERN_WARNING "warning: skipping physical page 0\n");
|
||||||
|
start += PAGE_SIZE;
|
||||||
|
if (start >= end)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
func = arg;
|
||||||
|
if (start < end)
|
||||||
|
call_pernode_memory(__pa(start), end - start, func);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void __init
|
static void __init
|
||||||
sort_regions (struct rsvd_region *rsvd_region, int max)
|
sort_regions (struct rsvd_region *rsvd_region, int max)
|
||||||
{
|
{
|
||||||
|
@ -400,9 +400,9 @@ smp_callin (void)
|
|||||||
/* Setup the per cpu irq handling data structures */
|
/* Setup the per cpu irq handling data structures */
|
||||||
__setup_vector_irq(cpuid);
|
__setup_vector_irq(cpuid);
|
||||||
cpu_set(cpuid, cpu_online_map);
|
cpu_set(cpuid, cpu_online_map);
|
||||||
unlock_ipi_calllock();
|
|
||||||
per_cpu(cpu_state, cpuid) = CPU_ONLINE;
|
per_cpu(cpu_state, cpuid) = CPU_ONLINE;
|
||||||
spin_unlock(&vector_lock);
|
spin_unlock(&vector_lock);
|
||||||
|
unlock_ipi_calllock();
|
||||||
|
|
||||||
smp_setup_percpu_timer();
|
smp_setup_percpu_timer();
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* 2001/08/13 Correct size of extended floats (float_fsz) from 16 to 10 bytes.
|
* 2001/08/13 Correct size of extended floats (float_fsz) from 16 to 10 bytes.
|
||||||
* 2001/01/17 Add support emulation of unaligned kernel accesses.
|
* 2001/01/17 Add support emulation of unaligned kernel accesses.
|
||||||
*/
|
*/
|
||||||
|
#include <linux/jiffies.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
@ -1290,7 +1291,7 @@ within_logging_rate_limit (void)
|
|||||||
{
|
{
|
||||||
static unsigned long count, last_time;
|
static unsigned long count, last_time;
|
||||||
|
|
||||||
if (jiffies - last_time > 5*HZ)
|
if (time_after(jiffies, last_time + 5 * HZ))
|
||||||
count = 0;
|
count = 0;
|
||||||
if (count < 5) {
|
if (count < 5) {
|
||||||
last_time = jiffies;
|
last_time = jiffies;
|
||||||
|
@ -45,8 +45,6 @@ void show_mem(void)
|
|||||||
|
|
||||||
printk(KERN_INFO "Mem-info:\n");
|
printk(KERN_INFO "Mem-info:\n");
|
||||||
show_free_areas();
|
show_free_areas();
|
||||||
printk(KERN_INFO "Free swap: %6ldkB\n",
|
|
||||||
nr_swap_pages<<(PAGE_SHIFT-10));
|
|
||||||
printk(KERN_INFO "Node memory in pages:\n");
|
printk(KERN_INFO "Node memory in pages:\n");
|
||||||
for_each_online_pgdat(pgdat) {
|
for_each_online_pgdat(pgdat) {
|
||||||
unsigned long present;
|
unsigned long present;
|
||||||
@ -255,7 +253,7 @@ paging_init (void)
|
|||||||
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
|
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
|
||||||
|
|
||||||
#ifdef CONFIG_VIRTUAL_MEM_MAP
|
#ifdef CONFIG_VIRTUAL_MEM_MAP
|
||||||
efi_memmap_walk(register_active_ranges, NULL);
|
efi_memmap_walk(filter_memory, register_active_ranges);
|
||||||
efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
|
efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
|
||||||
if (max_gap < LARGE_GAP) {
|
if (max_gap < LARGE_GAP) {
|
||||||
vmem_map = (struct page *) 0;
|
vmem_map = (struct page *) 0;
|
||||||
|
@ -445,7 +445,7 @@ void __init find_memory(void)
|
|||||||
mem_data[node].min_pfn = ~0UL;
|
mem_data[node].min_pfn = ~0UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
efi_memmap_walk(register_active_ranges, NULL);
|
efi_memmap_walk(filter_memory, register_active_ranges);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the boot memory maps in reverse order since that's
|
* Initialize the boot memory maps in reverse order since that's
|
||||||
@ -519,8 +519,6 @@ void show_mem(void)
|
|||||||
|
|
||||||
printk(KERN_INFO "Mem-info:\n");
|
printk(KERN_INFO "Mem-info:\n");
|
||||||
show_free_areas();
|
show_free_areas();
|
||||||
printk(KERN_INFO "Free swap: %6ldkB\n",
|
|
||||||
nr_swap_pages<<(PAGE_SHIFT-10));
|
|
||||||
printk(KERN_INFO "Node memory in pages:\n");
|
printk(KERN_INFO "Node memory in pages:\n");
|
||||||
for_each_online_pgdat(pgdat) {
|
for_each_online_pgdat(pgdat) {
|
||||||
unsigned long present;
|
unsigned long present;
|
||||||
|
@ -58,7 +58,6 @@ __ia64_sync_icache_dcache (pte_t pte)
|
|||||||
{
|
{
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
unsigned long order;
|
|
||||||
|
|
||||||
page = pte_page(pte);
|
page = pte_page(pte);
|
||||||
addr = (unsigned long) page_address(page);
|
addr = (unsigned long) page_address(page);
|
||||||
@ -66,12 +65,7 @@ __ia64_sync_icache_dcache (pte_t pte)
|
|||||||
if (test_bit(PG_arch_1, &page->flags))
|
if (test_bit(PG_arch_1, &page->flags))
|
||||||
return; /* i-cache is already coherent with d-cache */
|
return; /* i-cache is already coherent with d-cache */
|
||||||
|
|
||||||
if (PageCompound(page)) {
|
flush_icache_range(addr, addr + (PAGE_SIZE << compound_order(page)));
|
||||||
order = compound_order(page);
|
|
||||||
flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
flush_icache_range(addr, addr + PAGE_SIZE);
|
|
||||||
set_bit(PG_arch_1, &page->flags); /* mark page as clean */
|
set_bit(PG_arch_1, &page->flags); /* mark page as clean */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,12 +547,10 @@ find_largest_hole (u64 start, u64 end, void *arg)
|
|||||||
#endif /* CONFIG_VIRTUAL_MEM_MAP */
|
#endif /* CONFIG_VIRTUAL_MEM_MAP */
|
||||||
|
|
||||||
int __init
|
int __init
|
||||||
register_active_ranges(u64 start, u64 end, void *arg)
|
register_active_ranges(u64 start, u64 len, int nid)
|
||||||
{
|
{
|
||||||
int nid = paddr_to_nid(__pa(start));
|
u64 end = start + len;
|
||||||
|
|
||||||
if (nid < 0)
|
|
||||||
nid = 0;
|
|
||||||
#ifdef CONFIG_KEXEC
|
#ifdef CONFIG_KEXEC
|
||||||
if (start > crashk_res.start && start < crashk_res.end)
|
if (start > crashk_res.start && start < crashk_res.end)
|
||||||
start = crashk_res.end;
|
start = crashk_res.end;
|
||||||
|
@ -199,7 +199,7 @@ xpc_timeout_partition_disengage_request(unsigned long data)
|
|||||||
struct xpc_partition *part = (struct xpc_partition *) data;
|
struct xpc_partition *part = (struct xpc_partition *) data;
|
||||||
|
|
||||||
|
|
||||||
DBUG_ON(jiffies < part->disengage_request_timeout);
|
DBUG_ON(time_before(jiffies, part->disengage_request_timeout));
|
||||||
|
|
||||||
(void) xpc_partition_disengaged(part);
|
(void) xpc_partition_disengaged(part);
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ xpc_hb_beater(unsigned long dummy)
|
|||||||
{
|
{
|
||||||
xpc_vars->heartbeat++;
|
xpc_vars->heartbeat++;
|
||||||
|
|
||||||
if (jiffies >= xpc_hb_check_timeout) {
|
if (time_after_eq(jiffies, xpc_hb_check_timeout)) {
|
||||||
wake_up_interruptible(&xpc_act_IRQ_wq);
|
wake_up_interruptible(&xpc_act_IRQ_wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +270,7 @@ xpc_hb_checker(void *ignore)
|
|||||||
|
|
||||||
|
|
||||||
/* checking of remote heartbeats is skewed by IRQ handling */
|
/* checking of remote heartbeats is skewed by IRQ handling */
|
||||||
if (jiffies >= xpc_hb_check_timeout) {
|
if (time_after_eq(jiffies, xpc_hb_check_timeout)) {
|
||||||
dev_dbg(xpc_part, "checking remote heartbeats\n");
|
dev_dbg(xpc_part, "checking remote heartbeats\n");
|
||||||
xpc_check_remote_hb();
|
xpc_check_remote_hb();
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ xpc_hb_checker(void *ignore)
|
|||||||
/* wait for IRQ or timeout */
|
/* wait for IRQ or timeout */
|
||||||
(void) wait_event_interruptible(xpc_act_IRQ_wq,
|
(void) wait_event_interruptible(xpc_act_IRQ_wq,
|
||||||
(last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) ||
|
(last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) ||
|
||||||
jiffies >= xpc_hb_check_timeout ||
|
time_after_eq(jiffies, xpc_hb_check_timeout) ||
|
||||||
(volatile int) xpc_exiting));
|
(volatile int) xpc_exiting));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,7 +877,7 @@ xpc_partition_disengaged(struct xpc_partition *part)
|
|||||||
disengaged = (xpc_partition_engaged(1UL << partid) == 0);
|
disengaged = (xpc_partition_engaged(1UL << partid) == 0);
|
||||||
if (part->disengage_request_timeout) {
|
if (part->disengage_request_timeout) {
|
||||||
if (!disengaged) {
|
if (!disengaged) {
|
||||||
if (jiffies < part->disengage_request_timeout) {
|
if (time_before(jiffies, part->disengage_request_timeout)) {
|
||||||
/* timelimit hasn't been reached yet */
|
/* timelimit hasn't been reached yet */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,12 @@
|
|||||||
#include <asm/break.h>
|
#include <asm/break.h>
|
||||||
|
|
||||||
#define __ARCH_WANT_KPROBES_INSN_SLOT
|
#define __ARCH_WANT_KPROBES_INSN_SLOT
|
||||||
#define MAX_INSN_SIZE 1
|
#define MAX_INSN_SIZE 2 /* last half is for kprobe-booster */
|
||||||
#define BREAK_INST (long)(__IA64_BREAK_KPROBE << 6)
|
#define BREAK_INST (long)(__IA64_BREAK_KPROBE << 6)
|
||||||
|
#define NOP_M_INST (long)(1<<27)
|
||||||
|
#define BRL_INST(i1, i2) ((long)((0xcL << 37) | /* brl */ \
|
||||||
|
(0x1L << 12) | /* many */ \
|
||||||
|
(((i1) & 1) << 36) | ((i2) << 13))) /* imm */
|
||||||
|
|
||||||
typedef union cmp_inst {
|
typedef union cmp_inst {
|
||||||
struct {
|
struct {
|
||||||
@ -112,6 +116,7 @@ struct arch_specific_insn {
|
|||||||
#define INST_FLAG_FIX_RELATIVE_IP_ADDR 1
|
#define INST_FLAG_FIX_RELATIVE_IP_ADDR 1
|
||||||
#define INST_FLAG_FIX_BRANCH_REG 2
|
#define INST_FLAG_FIX_BRANCH_REG 2
|
||||||
#define INST_FLAG_BREAK_INST 4
|
#define INST_FLAG_BREAK_INST 4
|
||||||
|
#define INST_FLAG_BOOSTABLE 8
|
||||||
unsigned long inst_flag;
|
unsigned long inst_flag;
|
||||||
unsigned short target_br_reg;
|
unsigned short target_br_reg;
|
||||||
unsigned short slot;
|
unsigned short slot;
|
||||||
|
@ -35,6 +35,7 @@ extern void find_memory (void);
|
|||||||
extern void reserve_memory (void);
|
extern void reserve_memory (void);
|
||||||
extern void find_initrd (void);
|
extern void find_initrd (void);
|
||||||
extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
|
extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
|
||||||
|
extern int filter_memory (unsigned long start, unsigned long end, void *arg);
|
||||||
extern unsigned long efi_memmap_init(unsigned long *s, unsigned long *e);
|
extern unsigned long efi_memmap_init(unsigned long *s, unsigned long *e);
|
||||||
extern int find_max_min_low_pfn (unsigned long , unsigned long, void *);
|
extern int find_max_min_low_pfn (unsigned long , unsigned long, void *);
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ extern int reserve_elfcorehdr(unsigned long *start, unsigned long *end);
|
|||||||
|
|
||||||
#define IGNORE_PFN0 1 /* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
|
#define IGNORE_PFN0 1 /* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
|
||||||
|
|
||||||
extern int register_active_ranges(u64 start, u64 end, void *arg);
|
extern int register_active_ranges(u64 start, u64 len, int nid);
|
||||||
|
|
||||||
#ifdef CONFIG_VIRTUAL_MEM_MAP
|
#ifdef CONFIG_VIRTUAL_MEM_MAP
|
||||||
# define LARGE_GAP 0x40000000 /* Use virtual mem map if hole is > than this */
|
# define LARGE_GAP 0x40000000 /* Use virtual mem map if hole is > than this */
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* Copyright (C) 1999 VA Linux Systems
|
* Copyright (C) 1999 VA Linux Systems
|
||||||
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
|
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
|
||||||
* Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com>
|
* Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com>
|
||||||
|
* Copyright (C) 2008 Silicon Graphics, Inc. (SGI)
|
||||||
*
|
*
|
||||||
* 99/10/01 davidm Make sure we pass zero for reserved parameters.
|
* 99/10/01 davidm Make sure we pass zero for reserved parameters.
|
||||||
* 00/03/07 davidm Updated pal_cache_flush() to be in sync with PAL v2.6.
|
* 00/03/07 davidm Updated pal_cache_flush() to be in sync with PAL v2.6.
|
||||||
@ -73,6 +74,8 @@
|
|||||||
#define PAL_CACHE_SHARED_INFO 43 /* returns information on caches shared by logical processor */
|
#define PAL_CACHE_SHARED_INFO 43 /* returns information on caches shared by logical processor */
|
||||||
#define PAL_GET_HW_POLICY 48 /* Get current hardware resource sharing policy */
|
#define PAL_GET_HW_POLICY 48 /* Get current hardware resource sharing policy */
|
||||||
#define PAL_SET_HW_POLICY 49 /* Set current hardware resource sharing policy */
|
#define PAL_SET_HW_POLICY 49 /* Set current hardware resource sharing policy */
|
||||||
|
#define PAL_VP_INFO 50 /* Information about virtual processor features */
|
||||||
|
#define PAL_MC_HW_TRACKING 51 /* Hardware tracking status */
|
||||||
|
|
||||||
#define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */
|
#define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */
|
||||||
#define PAL_HALT_INFO 257 /* return the low power capabilities of processor */
|
#define PAL_HALT_INFO 257 /* return the low power capabilities of processor */
|
||||||
@ -504,7 +507,8 @@ typedef struct pal_cache_check_info_s {
|
|||||||
wiv : 1, /* Way field valid */
|
wiv : 1, /* Way field valid */
|
||||||
reserved2 : 1,
|
reserved2 : 1,
|
||||||
dp : 1, /* Data poisoned on MBE */
|
dp : 1, /* Data poisoned on MBE */
|
||||||
reserved3 : 8,
|
reserved3 : 6,
|
||||||
|
hlth : 2, /* Health indicator */
|
||||||
|
|
||||||
index : 20, /* Cache line index */
|
index : 20, /* Cache line index */
|
||||||
reserved4 : 2,
|
reserved4 : 2,
|
||||||
@ -542,7 +546,9 @@ typedef struct pal_tlb_check_info_s {
|
|||||||
dtc : 1, /* Fail in data TC */
|
dtc : 1, /* Fail in data TC */
|
||||||
itc : 1, /* Fail in inst. TC */
|
itc : 1, /* Fail in inst. TC */
|
||||||
op : 4, /* Cache operation */
|
op : 4, /* Cache operation */
|
||||||
reserved3 : 30,
|
reserved3 : 6,
|
||||||
|
hlth : 2, /* Health indicator */
|
||||||
|
reserved4 : 22,
|
||||||
|
|
||||||
is : 1, /* instruction set (1 == ia32) */
|
is : 1, /* instruction set (1 == ia32) */
|
||||||
iv : 1, /* instruction set field valid */
|
iv : 1, /* instruction set field valid */
|
||||||
@ -633,7 +639,8 @@ typedef struct pal_uarch_check_info_s {
|
|||||||
way : 6, /* Way of structure */
|
way : 6, /* Way of structure */
|
||||||
wv : 1, /* way valid */
|
wv : 1, /* way valid */
|
||||||
xv : 1, /* index valid */
|
xv : 1, /* index valid */
|
||||||
reserved1 : 8,
|
reserved1 : 6,
|
||||||
|
hlth : 2, /* Health indicator */
|
||||||
index : 8, /* Index or set of the uarch
|
index : 8, /* Index or set of the uarch
|
||||||
* structure that failed.
|
* structure that failed.
|
||||||
*/
|
*/
|
||||||
@ -1213,14 +1220,12 @@ ia64_pal_mc_drain (void)
|
|||||||
|
|
||||||
/* Return the machine check dynamic processor state */
|
/* Return the machine check dynamic processor state */
|
||||||
static inline s64
|
static inline s64
|
||||||
ia64_pal_mc_dynamic_state (u64 offset, u64 *size, u64 *pds)
|
ia64_pal_mc_dynamic_state (u64 info_type, u64 dy_buffer, u64 *size)
|
||||||
{
|
{
|
||||||
struct ia64_pal_retval iprv;
|
struct ia64_pal_retval iprv;
|
||||||
PAL_CALL(iprv, PAL_MC_DYNAMIC_STATE, offset, 0, 0);
|
PAL_CALL(iprv, PAL_MC_DYNAMIC_STATE, info_type, dy_buffer, 0);
|
||||||
if (size)
|
if (size)
|
||||||
*size = iprv.v0;
|
*size = iprv.v0;
|
||||||
if (pds)
|
|
||||||
*pds = iprv.v1;
|
|
||||||
return iprv.status;
|
return iprv.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1281,15 +1286,41 @@ ia64_pal_mc_expected (u64 expected, u64 *previous)
|
|||||||
return iprv.status;
|
return iprv.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef union pal_hw_tracking_u {
|
||||||
|
u64 pht_data;
|
||||||
|
struct {
|
||||||
|
u64 itc :4, /* Instruction cache tracking */
|
||||||
|
dct :4, /* Date cache tracking */
|
||||||
|
itt :4, /* Instruction TLB tracking */
|
||||||
|
ddt :4, /* Data TLB tracking */
|
||||||
|
reserved:48;
|
||||||
|
} pal_hw_tracking_s;
|
||||||
|
} pal_hw_tracking_u_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardware tracking status.
|
||||||
|
*/
|
||||||
|
static inline s64
|
||||||
|
ia64_pal_mc_hw_tracking (u64 *status)
|
||||||
|
{
|
||||||
|
struct ia64_pal_retval iprv;
|
||||||
|
PAL_CALL(iprv, PAL_MC_HW_TRACKING, 0, 0, 0);
|
||||||
|
if (status)
|
||||||
|
*status = iprv.v0;
|
||||||
|
return iprv.status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Register a platform dependent location with PAL to which it can save
|
/* Register a platform dependent location with PAL to which it can save
|
||||||
* minimal processor state in the event of a machine check or initialization
|
* minimal processor state in the event of a machine check or initialization
|
||||||
* event.
|
* event.
|
||||||
*/
|
*/
|
||||||
static inline s64
|
static inline s64
|
||||||
ia64_pal_mc_register_mem (u64 physical_addr)
|
ia64_pal_mc_register_mem (u64 physical_addr, u64 size, u64 *req_size)
|
||||||
{
|
{
|
||||||
struct ia64_pal_retval iprv;
|
struct ia64_pal_retval iprv;
|
||||||
PAL_CALL(iprv, PAL_MC_REGISTER_MEM, physical_addr, 0, 0);
|
PAL_CALL(iprv, PAL_MC_REGISTER_MEM, physical_addr, size, 0);
|
||||||
|
if (req_size)
|
||||||
|
*req_size = iprv.v0;
|
||||||
return iprv.status;
|
return iprv.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1631,6 +1662,29 @@ ia64_pal_vm_summary (pal_vm_info_1_u_t *vm_info_1, pal_vm_info_2_u_t *vm_info_2)
|
|||||||
return iprv.status;
|
return iprv.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef union pal_vp_info_u {
|
||||||
|
u64 pvi_val;
|
||||||
|
struct {
|
||||||
|
u64 index: 48, /* virtual feature set info */
|
||||||
|
vmm_id: 16; /* feature set id */
|
||||||
|
} pal_vp_info_s;
|
||||||
|
} pal_vp_info_u_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns infomation about virtual processor features
|
||||||
|
*/
|
||||||
|
static inline s64
|
||||||
|
ia64_pal_vp_info (u64 feature_set, u64 vp_buffer, u64 *vp_info, u64 *vmm_id)
|
||||||
|
{
|
||||||
|
struct ia64_pal_retval iprv;
|
||||||
|
PAL_CALL(iprv, PAL_VP_INFO, feature_set, vp_buffer, 0);
|
||||||
|
if (vp_info)
|
||||||
|
*vp_info = iprv.v0;
|
||||||
|
if (vmm_id)
|
||||||
|
*vmm_id = iprv.v1;
|
||||||
|
return iprv.status;
|
||||||
|
}
|
||||||
|
|
||||||
typedef union pal_itr_valid_u {
|
typedef union pal_itr_valid_u {
|
||||||
u64 piv_val;
|
u64 piv_val;
|
||||||
struct {
|
struct {
|
||||||
|
@ -371,7 +371,7 @@ pgd_index (unsigned long address)
|
|||||||
/* The offset in the 1-level directory is given by the 3 region bits
|
/* The offset in the 1-level directory is given by the 3 region bits
|
||||||
(61..63) and the level-1 bits. */
|
(61..63) and the level-1 bits. */
|
||||||
static inline pgd_t*
|
static inline pgd_t*
|
||||||
pgd_offset (struct mm_struct *mm, unsigned long address)
|
pgd_offset (const struct mm_struct *mm, unsigned long address)
|
||||||
{
|
{
|
||||||
return mm->pgd + pgd_index(address);
|
return mm->pgd + pgd_index(address);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user