static void remote_pal_cache_flush(void *data) { struct cache_flush_args *args = data; long status; u64 progress = args->progress; status = ia64_pal_cache_flush(args->cache_type, args->operation, &progress, NULL); if (status != 0) args->status = status; }
static struct ia64_pal_retval pal_cache_flush(struct kvm_vcpu *vcpu) { u64 gr28, gr29, gr30, gr31; struct ia64_pal_retval result = {0, 0, 0, 0}; struct cache_flush_args args = {0, 0, 0, 0}; long psr; gr28 = gr29 = gr30 = gr31 = 0; kvm_get_pal_call_data(vcpu, &gr28, &gr29, &gr30, &gr31); if (gr31 != 0) printk(KERN_ERR"vcpu:%p called cache_flush error!\n", vcpu); /* Always call Host Pal in int=1 */ gr30 &= ~PAL_CACHE_FLUSH_CHK_INTRS; args.cache_type = gr29; args.operation = gr30; smp_call_function(remote_pal_cache_flush, (void *)&args, 1); if (args.status != 0) printk(KERN_ERR"pal_cache_flush error!," "status:0x%lx\n", args.status); /* * Call Host PAL cache flush * Clear psr.ic when call PAL_CACHE_FLUSH */ local_irq_save(psr); result.status = ia64_pal_cache_flush(gr29, gr30, &result.v1, &result.v0); local_irq_restore(psr); if (result.status != 0) printk(KERN_ERR"vcpu:%p crashed due to cache_flush err:%ld" "in1:%lx,in2:%lx\n", vcpu, result.status, gr29, gr30); #if 0 if (gr29 == PAL_CACHE_TYPE_COHERENT) { cpus_setall(vcpu->arch.cache_coherent_map); cpu_clear(vcpu->cpu, vcpu->arch.cache_coherent_map); cpus_setall(cpu_cache_coherent_map); cpu_clear(vcpu->cpu, cpu_cache_coherent_map); } #endif return result; }
s64 ia64_sal_cache_flush (u64 cache_type) { struct ia64_sal_retval isrv; if (sal_cache_flush_drops_interrupts) { unsigned long flags; u64 progress; s64 rc; progress = 0; local_irq_save(flags); rc = ia64_pal_cache_flush(cache_type, PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL); local_irq_restore(flags); return rc; } SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); return isrv.status; }