Skip to content

Commit

Permalink
Merge branch 'release' of master.kernel.org:/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/aegl/linux-2.6

* 'release' of master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6:
  [IA64] Correct definition of handle_IPI
  [IA64] move SAL_CACHE_FLUSH check later in boot
  [IA64] MCA recovery: Montecito support
  [IA64] cpu-hotplug: Fixing confliction between CPU hot-add and IPI
  [IA64] don't double >> PAGE_SHIFT pointer for /dev/kmem access
  • Loading branch information
Linus Torvalds committed Nov 1, 2006
2 parents 16b7b2a + 024e4f2 commit d5b9b78
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 37 deletions.
95 changes: 68 additions & 27 deletions arch/ia64/kernel/mca_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,50 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci,
return MCA_IS_GLOBAL;
}

/**
* get_target_identifier - Get the valid Cache or Bus check target identifier.
* @peidx: pointer of index of processor error section
*
* Return value:
* target address on Success / 0 on Failue
*/
static u64
get_target_identifier(peidx_table_t *peidx)
{
u64 target_address = 0;
sal_log_mod_error_info_t *smei;
pal_cache_check_info_t *pcci;
int i, level = 9;

/*
* Look through the cache checks for a valid target identifier
* If more than one valid target identifier, return the one
* with the lowest cache level.
*/
for (i = 0; i < peidx_cache_check_num(peidx); i++) {
smei = (sal_log_mod_error_info_t *)peidx_cache_check(peidx, i);
if (smei->valid.target_identifier && smei->target_identifier) {
pcci = (pal_cache_check_info_t *)&(smei->check_info);
if (!target_address || (pcci->level < level)) {
target_address = smei->target_identifier;
level = pcci->level;
continue;
}
}
}
if (target_address)
return target_address;

/*
* Look at the bus check for a valid target identifier
*/
smei = peidx_bus_check(peidx, 0);
if (smei && smei->valid.target_identifier)
return smei->target_identifier;

return 0;
}

/**
* recover_from_read_error - Try to recover the errors which type are "read"s.
* @slidx: pointer of index of SAL error record
Expand All @@ -450,13 +494,14 @@ recover_from_read_error(slidx_table_t *slidx,
peidx_table_t *peidx, pal_bus_check_info_t *pbci,
struct ia64_sal_os_state *sos)
{
sal_log_mod_error_info_t *smei;
u64 target_identifier;
pal_min_state_area_t *pmsa;
struct ia64_psr *psr1, *psr2;
ia64_fptr_t *mca_hdlr_bh = (ia64_fptr_t*)mca_handler_bhhook;

/* Is target address valid? */
if (!pbci->tv)
target_identifier = get_target_identifier(peidx);
if (!target_identifier)
return fatal_mca("target address not valid");

/*
Expand Down Expand Up @@ -487,32 +532,28 @@ recover_from_read_error(slidx_table_t *slidx,
pmsa = sos->pal_min_state;
if (psr1->cpl != 0 ||
((psr2->cpl != 0) && mca_recover_range(pmsa->pmsa_iip))) {
smei = peidx_bus_check(peidx, 0);
if (smei->valid.target_identifier) {
/*
* setup for resume to bottom half of MCA,
* "mca_handler_bhhook"
*/
/* pass to bhhook as argument (gr8, ...) */
pmsa->pmsa_gr[8-1] = smei->target_identifier;
pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
/* set interrupted return address (but no use) */
pmsa->pmsa_br0 = pmsa->pmsa_iip;
/* change resume address to bottom half */
pmsa->pmsa_iip = mca_hdlr_bh->fp;
pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp;
/* set cpl with kernel mode */
psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
psr2->cpl = 0;
psr2->ri = 0;
psr2->bn = 1;
psr2->i = 0;

return mca_recovered("user memory corruption. "
/*
* setup for resume to bottom half of MCA,
* "mca_handler_bhhook"
*/
/* pass to bhhook as argument (gr8, ...) */
pmsa->pmsa_gr[8-1] = target_identifier;
pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
/* set interrupted return address (but no use) */
pmsa->pmsa_br0 = pmsa->pmsa_iip;
/* change resume address to bottom half */
pmsa->pmsa_iip = mca_hdlr_bh->fp;
pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp;
/* set cpl with kernel mode */
psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
psr2->cpl = 0;
psr2->ri = 0;
psr2->bn = 1;
psr2->i = 0;

return mca_recovered("user memory corruption. "
"kill affected process - recovered.");
}

}

return fatal_mca("kernel context not recovered, iip 0x%lx\n",
Expand Down
11 changes: 7 additions & 4 deletions arch/ia64/kernel/sal.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,13 @@ static void __init sal_desc_ap_wakeup(void *p) { }
*/
static int sal_cache_flush_drops_interrupts;

static void __init
void __init
check_sal_cache_flush (void)
{
unsigned long flags;
int cpu;
u64 vector;
u64 vector, cache_type = 3;
struct ia64_sal_retval isrv;

cpu = get_cpu();
local_irq_save(flags);
Expand All @@ -243,7 +244,10 @@ check_sal_cache_flush (void)
while (!ia64_get_irr(IA64_TIMER_VECTOR))
cpu_relax();

ia64_sal_cache_flush(3);
SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);

if (isrv.status)
printk(KERN_ERR "SAL_CAL_FLUSH failed with %ld\n", isrv.status);

if (ia64_get_irr(IA64_TIMER_VECTOR)) {
vector = ia64_get_ivr();
Expand Down Expand Up @@ -331,7 +335,6 @@ ia64_sal_init (struct ia64_sal_systab *systab)
p += SAL_DESC_SIZE(*p);
}

check_sal_cache_flush();
}

int
Expand Down
2 changes: 2 additions & 0 deletions arch/ia64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,8 @@ setup_arch (char **cmdline_p)
cpu_init(); /* initialize the bootstrap CPU */
mmu_context_init(); /* initialize context_id bitmap */

check_sal_cache_flush();

#ifdef CONFIG_ACPI
acpi_boot_init();
#endif
Expand Down
12 changes: 7 additions & 5 deletions arch/ia64/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ cpu_die(void)
}

irqreturn_t
handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
handle_IPI (int irq, void *dev_id)
{
int this_cpu = get_cpu();
unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
Expand Down Expand Up @@ -328,10 +328,14 @@ int
smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait)
{
struct call_data_struct data;
int cpus = num_online_cpus()-1;
int cpus;

if (!cpus)
spin_lock(&call_lock);
cpus = num_online_cpus() - 1;
if (!cpus) {
spin_unlock(&call_lock);
return 0;
}

/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
Expand All @@ -343,8 +347,6 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wai
if (wait)
atomic_set(&data.finished, 0);

spin_lock(&call_lock);

call_data = &data;
mb(); /* ensure store to call_data precedes setting of IPI_CALL_FUNC */
send_IPI_allbutself(IPI_CALL_FUNC);
Expand Down
1 change: 1 addition & 0 deletions include/asm-ia64/sal.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second,
}

extern s64 ia64_sal_cache_flush (u64 cache_type);
extern void __init check_sal_cache_flush (void);

/* Initialize all the processor and platform level instruction and data caches */
static inline s64
Expand Down
2 changes: 1 addition & 1 deletion include/asm-ia64/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ xlate_dev_kmem_ptr (char * p)
struct page *page;
char * ptr;

page = virt_to_page((unsigned long)p >> PAGE_SHIFT);
page = virt_to_page((unsigned long)p);
if (PageUncached(page))
ptr = (char *)__pa(p) + __IA64_UNCACHED_OFFSET;
else
Expand Down

0 comments on commit d5b9b78

Please sign in to comment.