WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ia64-devel

[Xen-ia64-devel] [PATCH] fix I&D cache incoherency after vcpu migration

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] [PATCH] fix I&D cache incoherency after vcpu migration
From: Kouya SHIMURA <kouya@xxxxxxxxxxxxxx>
Date: Tue, 13 Feb 2007 21:15:30 +0900
Delivery-date: Tue, 13 Feb 2007 10:20:58 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
Windows on HVM ocasionally crashes with BSOD especially on boot time.
I finally found out the cause is PAL_CACHE_FLUSH(cache_type=4).
The cache_type means an argument of PAL_CACHE_FLUSH and cache_type=4
makes local instruction caches coherent with the data caches. 
See SDM vol2 11.10.3, PAL_CACHE_FLUSH. 
FYI, Linux never uses cache_type=4.

Currently PAL_CACHE_FLUSH is called on only local cpu and caches on the
other cpus are still incoherent.

Attached patch does:
- When cache_type=1,2,3 that means flushing caches on local cpus,
  caches on the other cpus becomes to be flushed also.
  It might be overkill and not efficient. But I think it's permissive 
  since these cache_type are seldom used. 

- When cache_type=4, the actual PAL call to the other cpus is deferred
  until the vcpu migration occurs or the cpu becomes idle. 
  Since Windows uses cache_type=4 quite often and many vcpus on SMP
  environment call PAL_CACHE_FLUSH simultaneously.

Thanks,
Kouya

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>

diff -r 8bdbe88e422f xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Mon Feb 12 10:10:37 2007 -0700
+++ b/xen/arch/ia64/xen/domain.c        Tue Feb 13 19:18:19 2007 +0900
@@ -138,6 +138,28 @@ static void flush_vtlb_for_context_switc
        }
 }
 
+static void flush_cache_for_context_switch(struct vcpu *next)
+{
+       extern cpumask_t cpu_cache_coherent_map;
+       int cpu = smp_processor_id();
+
+       if (is_idle_vcpu(next) ||
+           __test_and_clear_bit(cpu, &next->arch.cache_coherent_map)) {
+               if (cpu_test_and_clear(cpu, cpu_cache_coherent_map)) {
+                       unsigned long flags;
+                       u64 progress = 0;
+                       s64 status;
+
+                       local_irq_save(flags);
+                       status = ia64_pal_cache_flush(4, 0, &progress, NULL);
+                       local_irq_restore(flags);
+                       if (status != 0)
+                               panic_domain(NULL, "PAL_CACHE_FLUSH ERROR, "
+                                            "cache_type=4 status %lx", status);
+               }
+       }
+}
+
 static void lazy_fp_switch(struct vcpu *prev, struct vcpu *next)
 {
        /*
@@ -260,6 +282,7 @@ void context_switch(struct vcpu *prev, s
     }
    
     flush_vtlb_for_context_switch(prev, current);
+    flush_cache_for_context_switch(current);
     context_saved(prev);
 }
 
diff -r 8bdbe88e422f xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c       Mon Feb 12 10:10:37 2007 -0700
+++ b/xen/arch/ia64/xen/fw_emul.c       Tue Feb 13 19:19:56 2007 +0900
@@ -377,6 +377,28 @@ sal_emulator (long index, unsigned long 
                break;
        }
        return ((struct sal_ret_values) {status, r9, r10, r11});
+}
+
+cpumask_t cpu_cache_coherent_map;
+
+struct cache_flush_args {
+       u64 cache_type;
+       u64 operation;
+       u64 progress;
+       long status;
+};
+
+static void
+remote_pal_cache_flush(void *v)
+{
+       struct cache_flush_args *args = v;
+       long status;
+       u64 progress = args->progress;
+
+       status = ia64_pal_cache_flush(args->cache_type, args->operation,
+                                     &progress, NULL);
+       if (status != 0)
+               args->status = status;
 }
 
 struct ia64_pal_retval
@@ -542,8 +564,26 @@ xen_pal_emulator(unsigned long index, u6
                status = ia64_pal_register_info(in1, &r9, &r10);
                break;
            case PAL_CACHE_FLUSH:
+               if (in3 != 0) /* Initially progress_indicator must be 0 */
+                       panic_domain(NULL, "PAL_CACHE_FLUSH ERROR, "
+                                    "progress_indicator=%lx", in3);
+
                /* Always call Host Pal in int=0 */
                in2 &= ~PAL_CACHE_FLUSH_CHK_INTRS;
+
+               if (in1 != PAL_CACHE_TYPE_COHERENT) {
+                       struct cache_flush_args args = {
+                               .cache_type = in1,
+                               .operation = in2,
+                               .progress = 0,
+                               .status = 0
+                       };
+                       smp_call_function(remote_pal_cache_flush,
+                                         (void *)&args, 1, 1);
+                       if (args.status != 0)
+                               panic_domain(NULL, "PAL_CACHE_FLUSH ERROR, "
+                                            "remote status %lx", args.status);
+               }
 
                /*
                 * Call Host PAL cache flush
@@ -556,6 +596,13 @@ xen_pal_emulator(unsigned long index, u6
                        panic_domain(NULL, "PAL_CACHE_FLUSH ERROR, "
                                     "status %lx", status);
 
+               if (in1 == PAL_CACHE_TYPE_COHERENT) {
+                       int cpu = current->processor;
+                       cpus_setall(current->arch.cache_coherent_map);
+                       cpu_clear(cpu, current->arch.cache_coherent_map);
+                       cpus_setall(cpu_cache_coherent_map);
+                       cpu_clear(cpu, cpu_cache_coherent_map);
+               }
                break;
            case PAL_PERF_MON_INFO:
                {
diff -r 8bdbe88e422f xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Mon Feb 12 10:10:37 2007 -0700
+++ b/xen/include/asm-ia64/domain.h     Tue Feb 13 19:16:46 2007 +0900
@@ -201,6 +201,7 @@ struct arch_vcpu {
 #endif
 #define INVALID_PROCESSOR       INT_MAX
     int last_processor;
+    cpumask_t cache_coherent_map;
 };
 
 #include <asm/uaccess.h> /* for KERNEL_DS */
diff -r 8bdbe88e422f xen/include/asm-ia64/linux-xen/asm/pal.h
--- a/xen/include/asm-ia64/linux-xen/asm/pal.h  Mon Feb 12 10:10:37 2007 -0700
+++ b/xen/include/asm-ia64/linux-xen/asm/pal.h  Tue Feb 13 19:16:46 2007 +0900
@@ -112,6 +112,9 @@ typedef u64                         pal_cache_type_t;
 #define PAL_CACHE_TYPE_INSTRUCTION     1       /* Instruction cache */
 #define PAL_CACHE_TYPE_DATA            2       /* Data or unified cache */
 #define PAL_CACHE_TYPE_INSTRUCTION_DATA        3       /* Both Data & 
Instruction */
+#ifdef XEN
+#define PAL_CACHE_TYPE_COHERENT                4       /* Make I&D-cache 
coherent */
+#endif
 
 
 #define PAL_CACHE_FLUSH_INVALIDATE     1       /* Invalidate clean lines */
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
<Prev in Thread] Current Thread [Next in Thread>