static int dtl_start(struct dtl *dtl) { unsigned long addr; int ret, hwcpu; /* Register our dtl buffer with the hypervisor. The HV expects the * buffer size to be passed in the second word of the buffer */ ((u32 *)dtl->buf)[1] = dtl->buf_entries * sizeof(struct dtl_entry); hwcpu = get_hard_smp_processor_id(dtl->cpu); addr = __pa(dtl->buf); ret = register_dtl(hwcpu, addr); if (ret) { printk(KERN_WARNING "%s: DTL registration for cpu %d (hw %d) " "failed with %d\n", __func__, dtl->cpu, hwcpu, ret); return -EIO; } /* set our initial buffer indices */ lppaca[dtl->cpu].dtl_idx = 0; /* ensure that our updates to the lppaca fields have occurred before * we actually enable the logging */ smp_wmb(); /* enable event logging */ lppaca[dtl->cpu].dtl_enable_mask = dtl_event_mask; return 0; }
void vpa_init(int cpu) { int hwcpu = get_hard_smp_processor_id(cpu); unsigned long addr; long ret; struct paca_struct *pp; struct dtl_entry *dtl; if (cpu_has_feature(CPU_FTR_ALTIVEC)) lppaca_of(cpu).vmxregs_in_use = 1; if (cpu_has_feature(CPU_FTR_ARCH_207S)) lppaca_of(cpu).ebb_regs_in_use = 1; addr = __pa(&lppaca_of(cpu)); ret = register_vpa(hwcpu, addr); if (ret) { pr_err("WARNING: VPA registration for cpu %d (hw %d) of area " "%lx failed with %ld\n", cpu, hwcpu, addr, ret); return; } /* * PAPR says this feature is SLB-Buffer but firmware never * reports that. All SPLPAR support SLB shadow buffer. */ addr = __pa(&slb_shadow[cpu]); if (firmware_has_feature(FW_FEATURE_SPLPAR)) { ret = register_slb_shadow(hwcpu, addr); if (ret) pr_err("WARNING: SLB shadow buffer registration for " "cpu %d (hw %d) of area %lx failed with %ld\n", cpu, hwcpu, addr, ret); } /* * Register dispatch trace log, if one has been allocated. */ pp = &paca[cpu]; dtl = pp->dispatch_log; if (dtl) { pp->dtl_ridx = 0; pp->dtl_curr = dtl; lppaca_of(cpu).dtl_idx = 0; /* hypervisor reads buffer length from this field */ dtl->enqueue_to_dispatch_time = DISPATCH_LOG_BYTES; ret = register_dtl(hwcpu, __pa(dtl)); if (ret) pr_err("WARNING: DTL registration of cpu %d (hw %d) " "failed with %ld\n", smp_processor_id(), hwcpu, ret); lppaca_of(cpu).dtl_enable_mask = 2; } }
static int dtl_enable(struct dtl *dtl) { unsigned long addr; int ret, hwcpu; /* only allow one reader */ if (dtl->buf) return -EBUSY; /* we need to store the original allocation size for use during read */ dtl->buf_entries = dtl_buf_entries; dtl->buf = kmalloc_node(dtl->buf_entries * sizeof(struct dtl_entry), GFP_KERNEL, cpu_to_node(dtl->cpu)); if (!dtl->buf) { printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n", __func__, dtl->cpu); return -ENOMEM; } /* Register our dtl buffer with the hypervisor. The HV expects the * buffer size to be passed in the second word of the buffer */ ((u32 *)dtl->buf)[1] = dtl->buf_entries * sizeof(struct dtl_entry); hwcpu = get_hard_smp_processor_id(dtl->cpu); addr = __pa(dtl->buf); ret = register_dtl(hwcpu, addr); if (ret) { printk(KERN_WARNING "%s: DTL registration for cpu %d (hw %d) " "failed with %d\n", __func__, dtl->cpu, hwcpu, ret); kfree(dtl->buf); return -EIO; } /* set our initial buffer indices */ dtl->last_idx = lppaca[dtl->cpu].dtl_idx = 0; /* ensure that our updates to the lppaca fields have occurred before * we actually enable the logging */ smp_wmb(); /* enable event logging */ lppaca[dtl->cpu].dtl_enable_mask = dtl_event_mask; return 0; }
void vpa_init(int cpu) { int hwcpu = get_hard_smp_processor_id(cpu); unsigned long addr; long ret; struct paca_struct *pp; struct dtl_entry *dtl; /* * The spec says it "may be problematic" if CPU x registers the VPA of * CPU y. We should never do that, but wail if we ever do. */ WARN_ON(cpu != smp_processor_id()); if (cpu_has_feature(CPU_FTR_ALTIVEC)) lppaca_of(cpu).vmxregs_in_use = 1; if (cpu_has_feature(CPU_FTR_ARCH_207S)) lppaca_of(cpu).ebb_regs_in_use = 1; addr = __pa(&lppaca_of(cpu)); ret = register_vpa(hwcpu, addr); if (ret) { pr_err("WARNING: VPA registration for cpu %d (hw %d) of area " "%lx failed with %ld\n", cpu, hwcpu, addr, ret); return; } #ifdef CONFIG_PPC_BOOK3S_64 /* * PAPR says this feature is SLB-Buffer but firmware never * reports that. All SPLPAR support SLB shadow buffer. */ if (!radix_enabled() && firmware_has_feature(FW_FEATURE_SPLPAR)) { addr = __pa(paca_ptrs[cpu]->slb_shadow_ptr); ret = register_slb_shadow(hwcpu, addr); if (ret) pr_err("WARNING: SLB shadow buffer registration for " "cpu %d (hw %d) of area %lx failed with %ld\n", cpu, hwcpu, addr, ret); } #endif /* CONFIG_PPC_BOOK3S_64 */ /* * Register dispatch trace log, if one has been allocated. */ pp = paca_ptrs[cpu]; dtl = pp->dispatch_log; if (dtl) { pp->dtl_ridx = 0; pp->dtl_curr = dtl; lppaca_of(cpu).dtl_idx = 0; /* hypervisor reads buffer length from this field */ dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES); ret = register_dtl(hwcpu, __pa(dtl)); if (ret) pr_err("WARNING: DTL registration of cpu %d (hw %d) " "failed with %ld\n", smp_processor_id(), hwcpu, ret); lppaca_of(cpu).dtl_enable_mask = 2; } }