]> nv-tegra.nvidia Code Review - linux-2.6.git/commitdiff
Merge branch 'release' of master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Wed, 1 Nov 2006 01:03:50 +0000 (17:03 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 1 Nov 2006 01:03:50 +0000 (17:03 -0800)
* '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

arch/ia64/kernel/mca_drv.c
arch/ia64/kernel/sal.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/smp.c
include/asm-ia64/sal.h
include/asm-ia64/uaccess.h

index a45009d2bc90149e5199a97c9eff86a8d552f5b0..afc1403799c9511505503d564c6bb30f18df0ea4 100644 (file)
@@ -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
@@ -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");
 
        /*
@@ -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",
index 642fdc7b969d5c4f6450f588e82e0f2a29064063..20bad78b5073d48ba454ee24131b01a81531861b 100644 (file)
@@ -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);
@@ -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();
@@ -331,7 +335,6 @@ ia64_sal_init (struct ia64_sal_systab *systab)
                p += SAL_DESC_SIZE(*p);
        }
 
-       check_sal_cache_flush();
 }
 
 int
index c4caa800349220d22b69dc25ac12e490d059c85d..d10404a4175630c6d18ccfe5aa5e265face6ec68 100644 (file)
@@ -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
index 657ac99a451cf8d550e10d5fa52af12f130b3588..6ab95ceaf9d4f34aa32a382a9e32cb68bb98b23b 100644 (file)
@@ -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);
@@ -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());
@@ -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);
index 0b210abbe0033ce06a1f7c1db28e8bcf0395ef6e..d000689d91421f6b0103660fe047146b166d50d0 100644 (file)
@@ -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
index 9adb51211c2270d7500dfb00d8ed3a59264651e6..449c8c0fa2bdc65165ff62248fdb4dbf8cba129e 100644 (file)
@@ -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