mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-04 12:47:04 +07:00
powerpc: mpc85xx: flush the l1 cache before cpu down in kexec
We observe a "Zero PT_NOTE entries found" warning when vmcore_init() is running on the dump-capture kernel. Actually the PT_NOTE segments is not empty, but the entries generated by crash_save_cpu() are not flushed to the memory before we reset these cores. So we should flush the l1 cache as what we do in cpu hotplug. With this change, we can also kill the mpc85xx_smp_flush_dcache_kexec() since that becomes unnecessary. Please note: this only fix the issue on e500 core, we still need to implement the function to flush the l2 cache for the e500mc core. Fortunately we already had proposing patch for this support [1]. Hope we can fix this issue for e500mc after that merged. [1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-March/115830.html Signed-off-by: Kevin Hao <haokexin@gmail.com> Signed-off-by: Scott Wood <scottwood@freescale.com>
This commit is contained in:
parent
5b2753fc3e
commit
379caf6063
@ -345,6 +345,7 @@ void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
|
||||
local_irq_disable();
|
||||
|
||||
if (secondary) {
|
||||
__flush_disable_L1();
|
||||
atomic_inc(&kexec_down_cpus);
|
||||
/* loop forever */
|
||||
while (1);
|
||||
@ -357,61 +358,11 @@ static void mpc85xx_smp_kexec_down(void *arg)
|
||||
ppc_md.kexec_cpu_down(0,1);
|
||||
}
|
||||
|
||||
static void map_and_flush(unsigned long paddr)
|
||||
{
|
||||
struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
|
||||
unsigned long kaddr = (unsigned long)kmap_atomic(page);
|
||||
|
||||
flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
|
||||
kunmap_atomic((void *)kaddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Before we reset the other cores, we need to flush relevant cache
|
||||
* out to memory so we don't get anything corrupted, some of these flushes
|
||||
* are performed out of an overabundance of caution as interrupts are not
|
||||
* disabled yet and we can switch cores
|
||||
*/
|
||||
static void mpc85xx_smp_flush_dcache_kexec(struct kimage *image)
|
||||
{
|
||||
kimage_entry_t *ptr, entry;
|
||||
unsigned long paddr;
|
||||
int i;
|
||||
|
||||
if (image->type == KEXEC_TYPE_DEFAULT) {
|
||||
/* normal kexec images are stored in temporary pages */
|
||||
for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE);
|
||||
ptr = (entry & IND_INDIRECTION) ?
|
||||
phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
|
||||
if (!(entry & IND_DESTINATION)) {
|
||||
map_and_flush(entry);
|
||||
}
|
||||
}
|
||||
/* flush out last IND_DONE page */
|
||||
map_and_flush(entry);
|
||||
} else {
|
||||
/* crash type kexec images are copied to the crash region */
|
||||
for (i = 0; i < image->nr_segments; i++) {
|
||||
struct kexec_segment *seg = &image->segment[i];
|
||||
for (paddr = seg->mem; paddr < seg->mem + seg->memsz;
|
||||
paddr += PAGE_SIZE) {
|
||||
map_and_flush(paddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* also flush the kimage struct to be passed in as well */
|
||||
flush_dcache_range((unsigned long)image,
|
||||
(unsigned long)image + sizeof(*image));
|
||||
}
|
||||
|
||||
static void mpc85xx_smp_machine_kexec(struct kimage *image)
|
||||
{
|
||||
int timeout = INT_MAX;
|
||||
int i, num_cpus = num_present_cpus();
|
||||
|
||||
mpc85xx_smp_flush_dcache_kexec(image);
|
||||
|
||||
if (image->type == KEXEC_TYPE_DEFAULT)
|
||||
smp_call_function(mpc85xx_smp_kexec_down, NULL, 0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user