summaryrefslogtreecommitdiff
path: root/drivers/firmware/arm_sdei.c
AgeCommit message (Collapse)Author
2020-05-20firmware: arm_sdei: Document the motivation behind these set_fs() callsJames Morse
The SDEI handler save/restores the addr_limit using set_fs(). It isn't very clear why. The reason is to mirror the arch code's entry assembly. The arch code does this because perf may access user-space, and inheriting the addr_limit may be a problem. Add a comment explaining why this is here. Suggested-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Morse <james.morse@arm.com> Link: https://bugs.chromium.org/p/project-zero/issues/detail?id=822 Link: https://lore.kernel.org/r/20200519182108.13693-4-james.morse@arm.com Signed-off-by: Will Deacon <will@kernel.org>
2020-05-20firmware: arm_sdei: remove unused interfacesChristoph Hellwig
The export symbols to register/unregister and enable/disable events aren't used upstream, remove them. [ dropped the parts of Christoph's patch that made the API static too ] Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Morse <james.morse@arm.com> Link: https://lore.kernel.org/linux-arm-kernel/20200504164224.2842960-1-hch@lst.de/ Link: https://lore.kernel.org/r/20200519182108.13693-3-james.morse@arm.com Signed-off-by: Will Deacon <will@kernel.org>
2020-05-20firmware: arm_sdei: Put the SDEI table after using itHanjun Guo
The acpi_get_table() should be coupled with acpi_put_table() if the mapped table is not used for runtime after the initialization to release the table mapping, put the SDEI table after using it. Signed-off-by: Hanjun Guo <guohanjun@huawei.com> Signed-off-by: James Morse <james.morse@arm.com> Link: https://lore.kernel.org/linux-arm-kernel/1589021566-46373-1-git-send-email-guohanjun@huawei.com/ Link: https://lore.kernel.org/r/20200519182108.13693-2-james.morse@arm.com Signed-off-by: Will Deacon <will@kernel.org>
2020-05-04firmware: arm_sdei: Drop check for /firmware/ node and always register driverSudeep Holla
As with most of the drivers, let us register this driver unconditionally by dropping the checks for presence of firmware nodes(DT) or entries(ACPI). Further, as mentioned in the commit acafce48b07b ("firmware: arm_sdei: Fix DT platform device creation"), the core takes care of creation of platform device when the appropriate device node is found and probe is called accordingly. Let us check only for the presence of ACPI firmware entry before creating the platform device and flag warning if we fail. Signed-off-by: Sudeep Holla <sudeep.holla@arm.com> Reviewed-by: James Morse <james.morse@arm.com> Cc: James Morse <james.morse@arm.com> Link: https://lore.kernel.org/r/20200422122823.1390-1-sudeep.holla@arm.com Signed-off-by: Will Deacon <will@kernel.org>
2020-02-27firmware: arm_sdei: clean up sdei_event_create()Liguang Zhang
Function sdei_event_find() is always called in sdei_event_create(), but it is already called in sdei_event_register(). This code is trying to avoid a double-create of the same event, which can't happen as we still hold the sdei_events_lock. We can remove this needless sdei_event_find() call. Signed-off-by: Liguang Zhang <zhangliguang@linux.alibaba.com> [expanded commit message] Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2020-02-27firmware: arm_sdei: Use cpus_read_lock() to avoid races with cpuhpJames Morse
SDEI has private events that need registering and enabling on each CPU. CPUs can come and go while we are trying to do this. SDEI tries to avoid these problems by setting the reregister flag before the register call, so any CPUs that come online register the event too. Sticking plaster like this doesn't work, as if the register call fails, a CPU that subsequently comes online will register the event before reregister is cleared. Take cpus_read_lock() around the register and enable calls. We don't want surprise CPUs to do the wrong thing if they race with these calls failing. Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2020-02-27firmware: arm_sdei: fix possible double-lock on hibernate error pathLiguang Zhang
We call sdei_reregister_event() with sdei_list_lock held, if the register fails we call sdei_event_destroy() which also acquires sdei_list_lock thus creating A-A deadlock. Add '_llocked' to sdei_reregister_event(), to indicate the list lock is held, and add a _llocked variant of sdei_event_destroy(). Fixes: da351827240e ("firmware: arm_sdei: Add support for CPU and system power states") Signed-off-by: Liguang Zhang <zhangliguang@linux.alibaba.com> [expanded subject, added wrappers instead of duplicating contents] Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2020-02-27firmware: arm_sdei: fix double-lock on hibernate with shared eventsJames Morse
SDEI has private events that must be registered on each CPU. When CPUs come and go they must re-register and re-enable their private events. Each event has flags to indicate whether this should happen to protect against an event being registered on a CPU coming online, while all the others are unregistering the event. These flags are protected by the sdei_list_lock spinlock, because the cpuhp callbacks can't take the mutex. Hibernate needs to unregister all events, but keep the in-memory re-register and re-enable as they are. sdei_unregister_shared() takes the spinlock to walk the list, then calls _sdei_event_unregister() on each shared event. _sdei_event_unregister() tries to take the same spinlock to update re-register and re-enable. This doesn't go so well. Push the re-register and re-enable updates out to their callers. sdei_unregister_shared() doesn't want these values updated, so doesn't need to do anything. This also fixes shared events getting lost over hibernate as this path made them look unregistered. Fixes: da351827240e ("firmware: arm_sdei: Add support for CPU and system power states") Reported-by: Liguang Zhang <zhangliguang@linux.alibaba.com> Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2019-10-14firmware: arm_sdei: use common SMCCC_CONDUIT_*Mark Rutland
Now that we have common definitions for SMCCC conduits, move the SDEI code over to them, and remove the SDEI-specific definitions. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: James Morse <james.morse@arm.com> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2019-04-29firmware: arm_sdei: Prohibit probing in '_sdei_handler'Xiongfeng Wang
Functions called in '_sdei_handler' are needed to be marked as 'nokprobe'. Because these functions are called in NMI context and neither the arch-code's debug infrastructure nor kprobes core supports this. Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com> Reviewed-by: James Morse <james.morse@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
2019-02-11firmware: arm_sdei: Add ACPI GHES registration helperJames Morse
APEI's Generic Hardware Error Source structures do not describe whether the SDEI event is shared or private, as this information is discoverable via the API. GHES needs to know whether an event is normal or critical to avoid sharing locks or fixmap entries, but GHES shouldn't have to know about the SDEI API. Add a helper to register the GHES using the appropriate normal or critical callback. Signed-off-by: James Morse <james.morse@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-01-03firmware: arm_sdei: Fix DT platform device creationJames Morse
It turns out the dt-probing part of this wasn't tested properly after it was merged. commit 3aa0582fdb82 ("of: platform: populate /firmware/ node from of_platform_default_populate_init()") changed the core-code to generate the platform devices, meaning the driver's attempt fails, and it bails out. Fix this by removing the manual platform-device creation for DT systems, core code has always done this for us. CC: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
2019-01-03firmware: arm_sdei: fix wrong of_node_put() in init functionNicolas Saenz Julienne
After finding a "firmware" dt node arm_sdei tries to match it's compatible string with it. To do so it's calling of_find_matching_node() which already takes care of decreasing the refcount on the "firmware" node. We are then incorrectly decreasing the refcount on that node again. This patch removes the unwarranted call to of_node_put(). Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
2018-01-15firmware: arm_sdei: Fix return value check in sdei_present_dt()Wei Yongjun
In case of error, the function of_platform_device_create() returns NULL pointer not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test. Fixes: 677a60bd2003 ("firmware: arm_sdei: Discover SDEI support via ACPI") Acked-by: James Morse <james.morse@arm.com> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2018-01-14firmware: arm_sdei: Discover SDEI support via ACPIJames Morse
SDEI defines a new ACPI table to indicate the presence of the interface. The conduit is discovered in the same way as PSCI. For ACPI we need to create the platform device ourselves as SDEI doesn't have an entry in the DSDT. The SDEI platform device should be created after ACPI has been initialised so that we can parse the table, but before GHES devices are created, which may register SDE events if they use SDEI as their notification type. Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: James Morse <james.morse@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2018-01-14firmware: arm_sdei: add support for CPU private eventsJames Morse
Private SDE events are per-cpu, and need to be registered and enabled on each CPU. Hide this detail from the caller by adapting our {,un}register and {en,dis}able calls to send an IPI to each CPU if the event is private. CPU private events are unregistered when the CPU is powered-off, and re-registered when the CPU is brought back online. This saves bringing secondary cores back online to call private_reset() on shutdown, kexec and resume from hibernate. Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2018-01-13firmware: arm_sdei: Add support for CPU and system power statesJames Morse
When a CPU enters an idle lower-power state or is powering off, we need to mask SDE events so that no events can be delivered while we are messing with the MMU as the registered entry points won't be valid. If the system reboots, we want to unregister all events and mask the CPUs. For kexec this allows us to hand a clean slate to the next kernel instead of relying on it to call sdei_{private,system}_data_reset(). For hibernate we unregister all events and re-register them on restore, in case we restored with the SDE code loaded at a different address. (e.g. KASLR). Add all the notifiers necessary to do this. We only support shared events so all events are left registered and enabled over CPU hotplug. Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: James Morse <james.morse@arm.com> [catalin.marinas@arm.com: added CPU_PM_ENTER_FAILED case] Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2018-01-13firmware: arm_sdei: Add driver for Software Delegated ExceptionsJames Morse
The Software Delegated Exception Interface (SDEI) is an ARM standard for registering callbacks from the platform firmware into the OS. This is typically used to implement firmware notifications (such as firmware-first RAS) or promote an IRQ that has been promoted to a firmware-assisted NMI. Add the code for detecting the SDEI version and the framework for registering and unregistering events. Subsequent patches will add the arch-specific backend code and the necessary power management hooks. Only shared events are supported, power management, private events and discovery for ACPI systems will be added by later patches. Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>