Re: [PATCH v12 3/3] ACPI: APEI: handle synchronous exceptions in task work

Shuai Xue
2024-09-05T03:09:58Z

在 2024/9/4 00:11, Jarkko Sakkinen 写道:
> On Mon Sep 2, 2024 at 6:00 AM EEST, Shuai Xue wrote:
>> The memory uncorrected error could be signaled by asynchronous interrupt
>> (specifically, SPI in arm64 platform), e.g. when an error is detected by
>> a background scrubber, or signaled by synchronous exception
>> (specifically, data abort excepction in arm64 platform), e.g. when a CPU
>> tries to access a poisoned cache line. Currently, both synchronous and
>> asynchronous error use memory_failure_queue() to schedule
>> memory_failure() exectute in kworker context.
>>
>> As a result, when a user-space process is accessing a poisoned data, a
>> data abort is taken and the memory_failure() is executed in the kworker
>> context:
>>
>> - will send wrong si_code by SIGBUS signal in early_kill mode, and
>> - can not kill the user-space in some cases resulting a synchronous
>> error infinite loop
>>
>> Issue 1: send wrong si_code in early_kill mode
>>
>> Since commit a70297d22132 ("ACPI: APEI: set memory failure flags as
>> MF_ACTION_REQUIRED on synchronous events")', the flag MF_ACTION_REQUIRED
>> could be used to determine whether a synchronous exception occurs on
>> ARM64 platform. When a synchronous exception is detected, the kernel is
>> expected to terminate the current process which has accessed poisoned
>> page. This is done by sending a SIGBUS signal with an error code
>> BUS_MCEERR_AR, indicating an action-required machine check error on
>> read.
>>
>> However, when kill_proc() is called to terminate the processes who have
>> the poisoned page mapped, it sends the incorrect SIGBUS error code
>> BUS_MCEERR_AO because the context in which it operates is not the one
>> where the error was triggered.
>>
>> To reproduce this problem:
>>
>> # STEP1: enable early kill mode
>> #sysctl -w vm.memory_failure_early_kill=1
>> vm.memory_failure_early_kill = 1
>>
>> # STEP2: inject an UCE error and consume it to trigger a synchronous error
>> #einj_mem_uc single
>> 0: single vaddr = 0xffffb0d75400 paddr = 4092d55b400
>> injecting ...
>> triggering ...
>> signal 7 code 5 addr 0xffffb0d75000
>> page not present
>> Test passed
>>
>> The si_code (code 5) from einj_mem_uc indicates that it is BUS_MCEERR_AO
>> error and it is not fact.
>>
>> To fix it, queue memory_failure() as a task_work so that it runs in
>> the context of the process that is actually consuming the poisoned data.
>>
>> After this patch set:
>
> s/patch set/patch/
>

Hi, Jarkko,

Will fix the typo in next version.

Thank you.

Best Regards,
Shuai