Re: [PATCH] parisc: Fix code/instruction patching on PA1.x machines

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dave,

On 11/3/21 21:12, John David Anglin wrote:
> I think the real problem is that neither flush_kernel_vmap_range() or
> invalidate_kernel_vmap_range() flush the icache.  They only operate
> on the data cache. flush_icache_range will flush both caches.
Yes.
But we write the new instructions to a congruently memory are (same
physical memory like the kernel code), then flush/invalidate the
D-Cache, and finally flush the I-cache of kernel code memory.
See last function call of __patch_text_multiple().

So, logically I think it should work (and it does on PA2.x).

Or do you mean to flush the I-Cache of both mappings?

Helge


>
> Dave
>
> On 2021-10-31 5:14 p.m., Helge Deller wrote:
>> On PA1.x machines it's not sufficient to just flush the data and
>> instruction caches when we have written new instruction codes into the
>> parallel mapped memory segment, but we really need to invalidate (purge)
>> the cache too. Otherwise the processor will still execute the old
>> instructions which are still in the data/instruction cache.
>>
>> Signed-off-by: Helge Deller <deller@xxxxxx>
>> Fixes: 4e87ace902cf ("parisc: add support for patching multiple words")
>> Cc: stable@xxxxxxxxxxxxxxx # v5.3+
>>
>> diff --git a/arch/parisc/kernel/patch.c b/arch/parisc/kernel/patch.c
>> index 80a0ab372802..8cbb7e1d5a2b 100644
>> --- a/arch/parisc/kernel/patch.c
>> +++ b/arch/parisc/kernel/patch.c
>> @@ -81,7 +81,7 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
>>                * We're crossing a page boundary, so
>>                * need to remap
>>                */
>> -            flush_kernel_vmap_range((void *)fixmap,
>> +            invalidate_kernel_vmap_range((void *)fixmap,
>>                           (p-fixmap) * sizeof(*p));
>>               if (mapped)
>>                   patch_unmap(FIX_TEXT_POKE0, &flags);
>> @@ -90,9 +90,10 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
>>           }
>>       }
>>
>> -    flush_kernel_vmap_range((void *)fixmap, (p-fixmap) * sizeof(*p));
>> +    invalidate_kernel_vmap_range((void *)fixmap, (p-fixmap) * sizeof(*p));
>>       if (mapped)
>>           patch_unmap(FIX_TEXT_POKE0, &flags);
>> +    invalidate_kernel_vmap_range((void *)start, end - start);
>>       flush_icache_range(start, end);

^^  HERE


>>   }
>>
>
>





[Index of Archives]     [Linux SoC]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux