mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
Merge tag 'v6.1.8' into odroid-6.1.y
This is the 6.1.8 stable release Change-Id: I0040dbd7ee29d9637182a3122340ccf77b106447
This commit is contained in:
6
Documentation/ABI/testing/sysfs-kernel-oops_count
Normal file
6
Documentation/ABI/testing/sysfs-kernel-oops_count
Normal file
@@ -0,0 +1,6 @@
|
||||
What: /sys/kernel/oops_count
|
||||
Date: November 2022
|
||||
KernelVersion: 6.2.0
|
||||
Contact: Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
|
||||
Description:
|
||||
Shows how many times the system has Oopsed since last boot.
|
||||
6
Documentation/ABI/testing/sysfs-kernel-warn_count
Normal file
6
Documentation/ABI/testing/sysfs-kernel-warn_count
Normal file
@@ -0,0 +1,6 @@
|
||||
What: /sys/kernel/warn_count
|
||||
Date: November 2022
|
||||
KernelVersion: 6.2.0
|
||||
Contact: Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
|
||||
Description:
|
||||
Shows how many times the system has Warned since last boot.
|
||||
@@ -667,6 +667,15 @@ This is the default behavior.
|
||||
an oops event is detected.
|
||||
|
||||
|
||||
oops_limit
|
||||
==========
|
||||
|
||||
Number of kernel oopses after which the kernel should panic when
|
||||
``panic_on_oops`` is not set. Setting this to 0 disables checking
|
||||
the count. Setting this to 1 has the same effect as setting
|
||||
``panic_on_oops=1``. The default value is 10000.
|
||||
|
||||
|
||||
osrelease, ostype & version
|
||||
===========================
|
||||
|
||||
@@ -1523,6 +1532,16 @@ entry will default to 2 instead of 0.
|
||||
2 Unprivileged calls to ``bpf()`` are disabled
|
||||
= =============================================================
|
||||
|
||||
|
||||
warn_limit
|
||||
==========
|
||||
|
||||
Number of kernel warnings after which the kernel should panic when
|
||||
``panic_on_warn`` is not set. Setting this to 0 disables checking
|
||||
the warning count. Setting this to 1 has the same effect as setting
|
||||
``panic_on_warn=1``. The default value is 0.
|
||||
|
||||
|
||||
watchdog
|
||||
========
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ properties:
|
||||
- description: Display byte clock
|
||||
- description: Display byte interface clock
|
||||
- description: Display pixel clock
|
||||
- description: Display escape clock
|
||||
- description: Display core clock
|
||||
- description: Display AHB clock
|
||||
- description: Display AXI clock
|
||||
|
||||
@@ -134,8 +134,6 @@ required:
|
||||
- phy-names
|
||||
- assigned-clocks
|
||||
- assigned-clock-parents
|
||||
- power-domains
|
||||
- operating-points-v2
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@@ -69,7 +69,6 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- vdds-supply
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- vcca-supply
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -34,6 +34,10 @@ properties:
|
||||
vddio-supply:
|
||||
description: Phandle to vdd-io regulator device node.
|
||||
|
||||
qcom,dsi-phy-regulator-ldo-mode:
|
||||
type: boolean
|
||||
description: Indicates if the LDO mode PHY regulator is wanted.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright 2019 BayLibre, SAS
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/phy/amlogic,meson-g12a-usb2-phy.yaml#"
|
||||
$id: "http://devicetree.org/schemas/phy/amlogic,g12a-usb2-phy.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Amlogic G12A USB2 PHY
|
||||
@@ -13,8 +13,8 @@ maintainers:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,meson-g12a-usb2-phy
|
||||
- amlogic,meson-a1-usb2-phy
|
||||
- amlogic,g12a-usb2-phy
|
||||
- amlogic,a1-usb2-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -68,7 +68,7 @@ additionalProperties: false
|
||||
examples:
|
||||
- |
|
||||
phy@36000 {
|
||||
compatible = "amlogic,meson-g12a-usb2-phy";
|
||||
compatible = "amlogic,g12a-usb2-phy";
|
||||
reg = <0x36000 0x2000>;
|
||||
clocks = <&xtal>;
|
||||
clock-names = "xtal";
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright 2019 BayLibre, SAS
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml#"
|
||||
$id: "http://devicetree.org/schemas/phy/amlogic,g12a-usb3-pcie-phy.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Amlogic G12A USB3 + PCIE Combo PHY
|
||||
@@ -13,7 +13,7 @@ maintainers:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,meson-g12a-usb3-pcie-phy
|
||||
- amlogic,g12a-usb3-pcie-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -49,7 +49,7 @@ additionalProperties: false
|
||||
examples:
|
||||
- |
|
||||
phy@46000 {
|
||||
compatible = "amlogic,meson-g12a-usb3-pcie-phy";
|
||||
compatible = "amlogic,g12a-usb3-pcie-phy";
|
||||
reg = <0x46000 0x2000>;
|
||||
clocks = <&ref_clk>;
|
||||
clock-names = "ref_clk";
|
||||
@@ -651,17 +651,6 @@ See drivers/gpu/drm/amd/display/TODO for tasks.
|
||||
|
||||
Contact: Harry Wentland, Alex Deucher
|
||||
|
||||
vmwgfx: Replace hashtable with Linux' implementation
|
||||
----------------------------------------------------
|
||||
|
||||
The vmwgfx driver uses its own hashtable implementation. Replace the
|
||||
code with Linux' implementation and update the callers. It's mostly a
|
||||
refactoring task, but the interfaces are different.
|
||||
|
||||
Contact: Zack Rusin, Thomas Zimmermann <tzimmermann@suse.de>
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Bootsplash
|
||||
==========
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
from sphinx.util.pycompat import execfile_
|
||||
from sphinx.util.osutil import fs_encoding
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def loadConfig(namespace):
|
||||
@@ -48,7 +48,9 @@ def loadConfig(namespace):
|
||||
sys.stdout.write("load additional sphinx-config: %s\n" % config_file)
|
||||
config = namespace.copy()
|
||||
config['__file__'] = config_file
|
||||
execfile_(config_file, config)
|
||||
with open(config_file, 'rb') as f:
|
||||
code = compile(f.read(), fs_encoding, 'exec')
|
||||
exec(code, config)
|
||||
del config['__file__']
|
||||
namespace.update(config)
|
||||
else:
|
||||
|
||||
@@ -8248,6 +8248,20 @@ CPU[EAX=1]:ECX[24] (TSC_DEADLINE) is not reported by ``KVM_GET_SUPPORTED_CPUID``
|
||||
It can be enabled if ``KVM_CAP_TSC_DEADLINE_TIMER`` is present and the kernel
|
||||
has enabled in-kernel emulation of the local APIC.
|
||||
|
||||
CPU topology
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Several CPUID values include topology information for the host CPU:
|
||||
0x0b and 0x1f for Intel systems, 0x8000001e for AMD systems. Different
|
||||
versions of KVM return different values for this information and userspace
|
||||
should not rely on it. Currently they return all zeroes.
|
||||
|
||||
If userspace wishes to set up a guest topology, it should be careful that
|
||||
the values of these three leaves differ for each CPU. In particular,
|
||||
the APIC ID is found in EDX for all subleaves of 0x0b and 0x1f, and in EAX
|
||||
for 0x8000001e; the latter also encodes the core id and node id in bits
|
||||
7:0 of EBX and ECX respectively.
|
||||
|
||||
Obsolete ioctls and capabilities
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -11117,6 +11117,8 @@ M: Kees Cook <keescook@chromium.org>
|
||||
L: linux-hardening@vger.kernel.org
|
||||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
|
||||
F: Documentation/ABI/testing/sysfs-kernel-oops_count
|
||||
F: Documentation/ABI/testing/sysfs-kernel-warn_count
|
||||
F: include/linux/overflow.h
|
||||
F: include/linux/randomize_kstack.h
|
||||
F: mm/usercopy.c
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 4
|
||||
SUBLEVEL = 8
|
||||
EXTRAVERSION =
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
|
||||
@@ -19,16 +19,16 @@
|
||||
serial@f995e000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
sdhci@f9824900 {
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
sdhci@f98a4900 {
|
||||
cd-gpios = <&tlmm 122 GPIO_ACTIVE_LOW>;
|
||||
bus-width = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&sdhc_1 {
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&sdhc_2 {
|
||||
cd-gpios = <&tlmm 122 GPIO_ACTIVE_LOW>;
|
||||
bus-width = <4>;
|
||||
};
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mmc@f9824900 {
|
||||
sdhc_1: mmc@f9824900 {
|
||||
compatible = "qcom,apq8084-sdhci", "qcom,sdhci-msm-v4";
|
||||
reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
|
||||
reg-names = "hc", "core";
|
||||
@@ -432,7 +432,7 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mmc@f98a4900 {
|
||||
sdhc_2: mmc@f98a4900 {
|
||||
compatible = "qcom,apq8084-sdhci", "qcom,sdhci-msm-v4";
|
||||
reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
|
||||
reg-names = "hc", "core";
|
||||
|
||||
@@ -128,15 +128,16 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
|
||||
#define TIF_NEED_RESCHED 1 /* rescheduling necessary */
|
||||
#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
|
||||
#define TIF_UPROBE 3 /* breakpointed or singlestepping */
|
||||
#define TIF_SYSCALL_TRACE 4 /* syscall trace active */
|
||||
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
|
||||
#define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
|
||||
#define TIF_SECCOMP 7 /* seccomp syscall filtering active */
|
||||
#define TIF_NOTIFY_SIGNAL 8 /* signal notifications exist */
|
||||
#define TIF_NOTIFY_SIGNAL 4 /* signal notifications exist */
|
||||
|
||||
#define TIF_USING_IWMMXT 17
|
||||
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
|
||||
#define TIF_RESTORE_SIGMASK 20
|
||||
#define TIF_RESTORE_SIGMASK 19
|
||||
#define TIF_SYSCALL_TRACE 20 /* syscall trace active */
|
||||
#define TIF_SYSCALL_AUDIT 21 /* syscall auditing active */
|
||||
#define TIF_SYSCALL_TRACEPOINT 22 /* syscall tracepoint instrumentation */
|
||||
#define TIF_SECCOMP 23 /* seccomp syscall filtering active */
|
||||
|
||||
|
||||
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
||||
|
||||
@@ -4,6 +4,7 @@ menuconfig ARCH_OMAP1
|
||||
depends on ARCH_MULTI_V4T || ARCH_MULTI_V5
|
||||
depends on CPU_LITTLE_ENDIAN
|
||||
depends on ATAGS
|
||||
select ARCH_OMAP
|
||||
select ARCH_HAS_HOLES_MEMORYMODEL
|
||||
select ARCH_OMAP
|
||||
select CLKSRC_MMIO
|
||||
@@ -45,10 +46,6 @@ config ARCH_OMAP16XX
|
||||
select CPU_ARM926T
|
||||
select OMAP_DM_TIMER
|
||||
|
||||
config ARCH_OMAP1_ANY
|
||||
select ARCH_OMAP
|
||||
def_bool ARCH_OMAP730 || ARCH_OMAP850 || ARCH_OMAP15XX || ARCH_OMAP16XX
|
||||
|
||||
config ARCH_OMAP
|
||||
bool
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
ifdef CONFIG_ARCH_OMAP1_ANY
|
||||
|
||||
# Common support
|
||||
obj-y := io.o id.o sram-init.o sram.o time.o irq.o mux.o flash.o \
|
||||
serial.o devices.o dma.o omap-dma.o fb.o
|
||||
@@ -59,5 +57,3 @@ obj-$(CONFIG_ARCH_OMAP730) += gpio7xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP850) += gpio7xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP15XX) += gpio15xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP16XX) += gpio16xx.o
|
||||
|
||||
endif
|
||||
|
||||
@@ -22,17 +22,14 @@
|
||||
* The machine specific code may provide the extra mapping besides the
|
||||
* default mapping provided here.
|
||||
*/
|
||||
static struct map_desc omap_io_desc[] __initdata = {
|
||||
#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
|
||||
static struct map_desc omap7xx_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = OMAP1_IO_VIRT,
|
||||
.pfn = __phys_to_pfn(OMAP1_IO_PHYS),
|
||||
.length = OMAP1_IO_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
|
||||
#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
|
||||
static struct map_desc omap7xx_io_desc[] __initdata = {
|
||||
},
|
||||
{
|
||||
.virtual = OMAP7XX_DSP_BASE,
|
||||
.pfn = __phys_to_pfn(OMAP7XX_DSP_START),
|
||||
@@ -49,6 +46,12 @@ static struct map_desc omap7xx_io_desc[] __initdata = {
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
static struct map_desc omap1510_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = OMAP1_IO_VIRT,
|
||||
.pfn = __phys_to_pfn(OMAP1_IO_PHYS),
|
||||
.length = OMAP1_IO_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
{
|
||||
.virtual = OMAP1510_DSP_BASE,
|
||||
.pfn = __phys_to_pfn(OMAP1510_DSP_START),
|
||||
@@ -65,6 +68,12 @@ static struct map_desc omap1510_io_desc[] __initdata = {
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
static struct map_desc omap16xx_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = OMAP1_IO_VIRT,
|
||||
.pfn = __phys_to_pfn(OMAP1_IO_PHYS),
|
||||
.length = OMAP1_IO_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
{
|
||||
.virtual = OMAP16XX_DSP_BASE,
|
||||
.pfn = __phys_to_pfn(OMAP16XX_DSP_START),
|
||||
@@ -79,18 +88,9 @@ static struct map_desc omap16xx_io_desc[] __initdata = {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Maps common IO regions for omap1
|
||||
*/
|
||||
static void __init omap1_map_common_io(void)
|
||||
{
|
||||
iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
|
||||
}
|
||||
|
||||
#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
|
||||
void __init omap7xx_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
iotable_init(omap7xx_io_desc, ARRAY_SIZE(omap7xx_io_desc));
|
||||
}
|
||||
#endif
|
||||
@@ -98,7 +98,6 @@ void __init omap7xx_map_io(void)
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
void __init omap15xx_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
|
||||
}
|
||||
#endif
|
||||
@@ -106,7 +105,6 @@ void __init omap15xx_map_io(void)
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
void __init omap16xx_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -89,7 +89,6 @@ static struct omap_mcbsp_ops omap1_mcbsp_ops = {
|
||||
#define OMAP1610_MCBSP2_BASE 0xfffb1000
|
||||
#define OMAP1610_MCBSP3_BASE 0xe1017000
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
|
||||
struct resource omap7xx_mcbsp_res[][6] = {
|
||||
{
|
||||
{
|
||||
@@ -159,14 +158,7 @@ static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
|
||||
};
|
||||
#define OMAP7XX_MCBSP_RES_SZ ARRAY_SIZE(omap7xx_mcbsp_res[1])
|
||||
#define OMAP7XX_MCBSP_COUNT ARRAY_SIZE(omap7xx_mcbsp_res)
|
||||
#else
|
||||
#define omap7xx_mcbsp_res_0 NULL
|
||||
#define omap7xx_mcbsp_pdata NULL
|
||||
#define OMAP7XX_MCBSP_RES_SZ 0
|
||||
#define OMAP7XX_MCBSP_COUNT 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
struct resource omap15xx_mcbsp_res[][6] = {
|
||||
{
|
||||
{
|
||||
@@ -266,14 +258,7 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
|
||||
};
|
||||
#define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1])
|
||||
#define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res)
|
||||
#else
|
||||
#define omap15xx_mcbsp_res_0 NULL
|
||||
#define omap15xx_mcbsp_pdata NULL
|
||||
#define OMAP15XX_MCBSP_RES_SZ 0
|
||||
#define OMAP15XX_MCBSP_COUNT 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
struct resource omap16xx_mcbsp_res[][6] = {
|
||||
{
|
||||
{
|
||||
@@ -373,12 +358,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
|
||||
};
|
||||
#define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1])
|
||||
#define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res)
|
||||
#else
|
||||
#define omap16xx_mcbsp_res_0 NULL
|
||||
#define omap16xx_mcbsp_pdata NULL
|
||||
#define OMAP16XX_MCBSP_RES_SZ 0
|
||||
#define OMAP16XX_MCBSP_COUNT 0
|
||||
#endif
|
||||
|
||||
static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
|
||||
struct omap_mcbsp_platform_data *config, int size)
|
||||
|
||||
@@ -106,13 +106,6 @@
|
||||
#define OMAP7XX_IDLECT3 0xfffece24
|
||||
#define OMAP7XX_IDLE_LOOP_REQUEST 0x0C00
|
||||
|
||||
#if !defined(CONFIG_ARCH_OMAP730) && \
|
||||
!defined(CONFIG_ARCH_OMAP850) && \
|
||||
!defined(CONFIG_ARCH_OMAP15XX) && \
|
||||
!defined(CONFIG_ARCH_OMAP16XX)
|
||||
#warning "Power management for this processor not implemented yet"
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <linux/clk.h>
|
||||
|
||||
@@ -1279,7 +1279,7 @@
|
||||
reg = <0x32f10100 0x8>,
|
||||
<0x381f0000 0x20>;
|
||||
clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
|
||||
<&clk IMX8MP_CLK_USB_ROOT>;
|
||||
<&clk IMX8MP_CLK_USB_SUSP>;
|
||||
clock-names = "hsio", "suspend";
|
||||
interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
||||
power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB>;
|
||||
@@ -1292,9 +1292,9 @@
|
||||
usb_dwc3_0: usb@38100000 {
|
||||
compatible = "snps,dwc3";
|
||||
reg = <0x38100000 0x10000>;
|
||||
clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
|
||||
clocks = <&clk IMX8MP_CLK_USB_ROOT>,
|
||||
<&clk IMX8MP_CLK_USB_CORE_REF>,
|
||||
<&clk IMX8MP_CLK_USB_ROOT>;
|
||||
<&clk IMX8MP_CLK_USB_SUSP>;
|
||||
clock-names = "bus_early", "ref", "suspend";
|
||||
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
|
||||
phys = <&usb3_phy0>, <&usb3_phy0>;
|
||||
@@ -1321,7 +1321,7 @@
|
||||
reg = <0x32f10108 0x8>,
|
||||
<0x382f0000 0x20>;
|
||||
clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
|
||||
<&clk IMX8MP_CLK_USB_ROOT>;
|
||||
<&clk IMX8MP_CLK_USB_SUSP>;
|
||||
clock-names = "hsio", "suspend";
|
||||
interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
|
||||
power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB>;
|
||||
@@ -1334,9 +1334,9 @@
|
||||
usb_dwc3_1: usb@38200000 {
|
||||
compatible = "snps,dwc3";
|
||||
reg = <0x38200000 0x10000>;
|
||||
clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
|
||||
clocks = <&clk IMX8MP_CLK_USB_ROOT>,
|
||||
<&clk IMX8MP_CLK_USB_CORE_REF>,
|
||||
<&clk IMX8MP_CLK_USB_ROOT>;
|
||||
<&clk IMX8MP_CLK_USB_SUSP>;
|
||||
clock-names = "bus_early", "ref", "suspend";
|
||||
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
|
||||
phys = <&usb3_phy1>, <&usb3_phy1>;
|
||||
|
||||
@@ -315,7 +315,7 @@ __ll_sc__cmpxchg_double##name(unsigned long old1, \
|
||||
" cbnz %w0, 1b\n" \
|
||||
" " #mb "\n" \
|
||||
"2:" \
|
||||
: "=&r" (tmp), "=&r" (ret), "+Q" (*(unsigned long *)ptr) \
|
||||
: "=&r" (tmp), "=&r" (ret), "+Q" (*(__uint128_t *)ptr) \
|
||||
: "r" (old1), "r" (old2), "r" (new1), "r" (new2) \
|
||||
: cl); \
|
||||
\
|
||||
|
||||
@@ -311,7 +311,7 @@ __lse__cmpxchg_double##name(unsigned long old1, \
|
||||
" eor %[old2], %[old2], %[oldval2]\n" \
|
||||
" orr %[old1], %[old1], %[old2]" \
|
||||
: [old1] "+&r" (x0), [old2] "+&r" (x1), \
|
||||
[v] "+Q" (*(unsigned long *)ptr) \
|
||||
[v] "+Q" (*(__uint128_t *)ptr) \
|
||||
: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \
|
||||
[oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \
|
||||
: cl); \
|
||||
|
||||
@@ -25,6 +25,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
|
||||
({ \
|
||||
efi_virtmap_load(); \
|
||||
__efi_fpsimd_begin(); \
|
||||
spin_lock(&efi_rt_lock); \
|
||||
})
|
||||
|
||||
#undef arch_efi_call_virt
|
||||
@@ -33,10 +34,12 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
|
||||
|
||||
#define arch_efi_call_virt_teardown() \
|
||||
({ \
|
||||
spin_unlock(&efi_rt_lock); \
|
||||
__efi_fpsimd_end(); \
|
||||
efi_virtmap_unload(); \
|
||||
})
|
||||
|
||||
extern spinlock_t efi_rt_lock;
|
||||
efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
|
||||
|
||||
#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
|
||||
|
||||
@@ -373,8 +373,26 @@ static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
|
||||
|
||||
static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (kvm_vcpu_abt_iss1tw(vcpu))
|
||||
return true;
|
||||
if (kvm_vcpu_abt_iss1tw(vcpu)) {
|
||||
/*
|
||||
* Only a permission fault on a S1PTW should be
|
||||
* considered as a write. Otherwise, page tables baked
|
||||
* in a read-only memslot will result in an exception
|
||||
* being delivered in the guest.
|
||||
*
|
||||
* The drawback is that we end-up faulting twice if the
|
||||
* guest is using any of HW AF/DB: a translation fault
|
||||
* to map the page containing the PT (read only at
|
||||
* first), then a permission fault to allow the flags
|
||||
* to be set.
|
||||
*/
|
||||
switch (kvm_vcpu_trap_get_fault_type(vcpu)) {
|
||||
case ESR_ELx_FSC_PERM:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (kvm_vcpu_trap_is_iabt(vcpu))
|
||||
return false;
|
||||
|
||||
@@ -682,7 +682,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
|
||||
#define pud_leaf(pud) (pud_present(pud) && !pud_table(pud))
|
||||
#define pud_valid(pud) pte_valid(pud_pte(pud))
|
||||
#define pud_user(pud) pte_user(pud_pte(pud))
|
||||
|
||||
#define pud_user_exec(pud) pte_user_exec(pud_pte(pud))
|
||||
|
||||
static inline void set_pud(pud_t *pudp, pud_t pud)
|
||||
{
|
||||
@@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
|
||||
|
||||
static inline bool pmd_user_accessible_page(pmd_t pmd)
|
||||
{
|
||||
return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
|
||||
return pmd_leaf(pmd) && !pmd_present_invalid(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
|
||||
}
|
||||
|
||||
static inline bool pud_user_accessible_page(pud_t pud)
|
||||
{
|
||||
return pud_leaf(pud) && pud_user(pud);
|
||||
return pud_leaf(pud) && (pud_user(pud) || pud_user_exec(pud));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
SYM_FUNC_START(__efi_rt_asm_wrapper)
|
||||
stp x29, x30, [sp, #-32]!
|
||||
@@ -16,6 +17,12 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
|
||||
*/
|
||||
stp x1, x18, [sp, #16]
|
||||
|
||||
ldr_l x16, efi_rt_stack_top
|
||||
mov sp, x16
|
||||
#ifdef CONFIG_SHADOW_CALL_STACK
|
||||
str x18, [sp, #-16]!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are lucky enough that no EFI runtime services take more than
|
||||
* 5 arguments, so all are passed in registers rather than via the
|
||||
@@ -29,6 +36,7 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
|
||||
mov x4, x6
|
||||
blr x8
|
||||
|
||||
mov sp, x29
|
||||
ldp x1, x2, [sp, #16]
|
||||
cmp x2, x18
|
||||
ldp x29, x30, [sp], #32
|
||||
@@ -42,6 +50,10 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
|
||||
* called with preemption disabled and a separate shadow stack is used
|
||||
* for interrupts.
|
||||
*/
|
||||
mov x18, x2
|
||||
#ifdef CONFIG_SHADOW_CALL_STACK
|
||||
ldr_l x18, efi_rt_stack_top
|
||||
ldr x18, [x18, #-16]
|
||||
#endif
|
||||
|
||||
b efi_handle_corrupted_x18 // tail call
|
||||
SYM_FUNC_END(__efi_rt_asm_wrapper)
|
||||
|
||||
@@ -144,3 +144,30 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
|
||||
pr_err_ratelimited(FW_BUG "register x18 corrupted by EFI %s\n", f);
|
||||
return s;
|
||||
}
|
||||
|
||||
DEFINE_SPINLOCK(efi_rt_lock);
|
||||
|
||||
asmlinkage u64 *efi_rt_stack_top __ro_after_init;
|
||||
|
||||
/* EFI requires 8 KiB of stack space for runtime services */
|
||||
static_assert(THREAD_SIZE >= SZ_8K);
|
||||
|
||||
static int __init arm64_efi_rt_init(void)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!efi_enabled(EFI_RUNTIME_SERVICES))
|
||||
return 0;
|
||||
|
||||
p = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN, GFP_KERNEL,
|
||||
NUMA_NO_NODE, &&l);
|
||||
l: if (!p) {
|
||||
pr_warn("Failed to allocate EFI runtime stack\n");
|
||||
clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
efi_rt_stack_top = p + THREAD_SIZE;
|
||||
return 0;
|
||||
}
|
||||
core_initcall(arm64_efi_rt_init);
|
||||
|
||||
@@ -8,28 +8,27 @@
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/mte.h>
|
||||
|
||||
#define for_each_mte_vma(vmi, vma) \
|
||||
#define for_each_mte_vma(cprm, i, m) \
|
||||
if (system_supports_mte()) \
|
||||
for_each_vma(vmi, vma) \
|
||||
if (vma->vm_flags & VM_MTE)
|
||||
for (i = 0, m = cprm->vma_meta; \
|
||||
i < cprm->vma_count; \
|
||||
i++, m = cprm->vma_meta + i) \
|
||||
if (m->flags & VM_MTE)
|
||||
|
||||
static unsigned long mte_vma_tag_dump_size(struct vm_area_struct *vma)
|
||||
static unsigned long mte_vma_tag_dump_size(struct core_vma_metadata *m)
|
||||
{
|
||||
if (vma->vm_flags & VM_DONTDUMP)
|
||||
return 0;
|
||||
|
||||
return vma_pages(vma) * MTE_PAGE_TAG_STORAGE;
|
||||
return (m->dump_size >> PAGE_SHIFT) * MTE_PAGE_TAG_STORAGE;
|
||||
}
|
||||
|
||||
/* Derived from dump_user_range(); start/end must be page-aligned */
|
||||
static int mte_dump_tag_range(struct coredump_params *cprm,
|
||||
unsigned long start, unsigned long end)
|
||||
unsigned long start, unsigned long len)
|
||||
{
|
||||
int ret = 1;
|
||||
unsigned long addr;
|
||||
void *tags = NULL;
|
||||
|
||||
for (addr = start; addr < end; addr += PAGE_SIZE) {
|
||||
for (addr = start; addr < start + len; addr += PAGE_SIZE) {
|
||||
struct page *page = get_dump_page(addr);
|
||||
|
||||
/*
|
||||
@@ -65,7 +64,6 @@ static int mte_dump_tag_range(struct coredump_params *cprm,
|
||||
mte_save_page_tags(page_address(page), tags);
|
||||
put_page(page);
|
||||
if (!dump_emit(cprm, tags, MTE_PAGE_TAG_STORAGE)) {
|
||||
mte_free_tag_storage(tags);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
@@ -77,13 +75,13 @@ static int mte_dump_tag_range(struct coredump_params *cprm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
Elf_Half elf_core_extra_phdrs(void)
|
||||
Elf_Half elf_core_extra_phdrs(struct coredump_params *cprm)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
int i;
|
||||
struct core_vma_metadata *m;
|
||||
int vma_count = 0;
|
||||
VMA_ITERATOR(vmi, current->mm, 0);
|
||||
|
||||
for_each_mte_vma(vmi, vma)
|
||||
for_each_mte_vma(cprm, i, m)
|
||||
vma_count++;
|
||||
|
||||
return vma_count;
|
||||
@@ -91,18 +89,18 @@ Elf_Half elf_core_extra_phdrs(void)
|
||||
|
||||
int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
VMA_ITERATOR(vmi, current->mm, 0);
|
||||
int i;
|
||||
struct core_vma_metadata *m;
|
||||
|
||||
for_each_mte_vma(vmi, vma) {
|
||||
for_each_mte_vma(cprm, i, m) {
|
||||
struct elf_phdr phdr;
|
||||
|
||||
phdr.p_type = PT_AARCH64_MEMTAG_MTE;
|
||||
phdr.p_offset = offset;
|
||||
phdr.p_vaddr = vma->vm_start;
|
||||
phdr.p_vaddr = m->start;
|
||||
phdr.p_paddr = 0;
|
||||
phdr.p_filesz = mte_vma_tag_dump_size(vma);
|
||||
phdr.p_memsz = vma->vm_end - vma->vm_start;
|
||||
phdr.p_filesz = mte_vma_tag_dump_size(m);
|
||||
phdr.p_memsz = m->end - m->start;
|
||||
offset += phdr.p_filesz;
|
||||
phdr.p_flags = 0;
|
||||
phdr.p_align = 0;
|
||||
@@ -114,28 +112,25 @@ int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t elf_core_extra_data_size(void)
|
||||
size_t elf_core_extra_data_size(struct coredump_params *cprm)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
int i;
|
||||
struct core_vma_metadata *m;
|
||||
size_t data_size = 0;
|
||||
VMA_ITERATOR(vmi, current->mm, 0);
|
||||
|
||||
for_each_mte_vma(vmi, vma)
|
||||
data_size += mte_vma_tag_dump_size(vma);
|
||||
for_each_mte_vma(cprm, i, m)
|
||||
data_size += mte_vma_tag_dump_size(m);
|
||||
|
||||
return data_size;
|
||||
}
|
||||
|
||||
int elf_core_write_extra_data(struct coredump_params *cprm)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
VMA_ITERATOR(vmi, current->mm, 0);
|
||||
int i;
|
||||
struct core_vma_metadata *m;
|
||||
|
||||
for_each_mte_vma(vmi, vma) {
|
||||
if (vma->vm_flags & VM_DONTDUMP)
|
||||
continue;
|
||||
|
||||
if (!mte_dump_tag_range(cprm, vma->vm_start, vma->vm_end))
|
||||
for_each_mte_vma(cprm, i, m) {
|
||||
if (!mte_dump_tag_range(cprm, m->start, m->dump_size))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1364,7 +1364,7 @@ enum aarch64_regset {
|
||||
#ifdef CONFIG_ARM64_SVE
|
||||
REGSET_SVE,
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_SVE
|
||||
#ifdef CONFIG_ARM64_SME
|
||||
REGSET_SSVE,
|
||||
REGSET_ZA,
|
||||
#endif
|
||||
|
||||
@@ -280,7 +280,12 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
|
||||
|
||||
vl = task_get_sme_vl(current);
|
||||
} else {
|
||||
if (!system_supports_sve())
|
||||
/*
|
||||
* A SME only system use SVE for streaming mode so can
|
||||
* have a SVE formatted context with a zero VL and no
|
||||
* payload data.
|
||||
*/
|
||||
if (!system_supports_sve() && !system_supports_sme())
|
||||
return -EINVAL;
|
||||
|
||||
vl = task_get_sve_vl(current);
|
||||
@@ -729,7 +734,7 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (system_supports_sve()) {
|
||||
if (system_supports_sve() || system_supports_sme()) {
|
||||
unsigned int vq = 0;
|
||||
|
||||
if (add_all || test_thread_flag(TIF_SVE) ||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <asm/elf.h>
|
||||
|
||||
|
||||
Elf64_Half elf_core_extra_phdrs(void)
|
||||
Elf64_Half elf_core_extra_phdrs(struct coredump_params *cprm)
|
||||
{
|
||||
return GATE_EHDR->e_phnum;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ int elf_core_write_extra_data(struct coredump_params *cprm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t elf_core_extra_data_size(void)
|
||||
size_t elf_core_extra_data_size(struct coredump_params *cprm)
|
||||
{
|
||||
const struct elf_phdr *const gate_phdrs =
|
||||
(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
|
||||
|
||||
@@ -94,7 +94,7 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
|
||||
c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
|
||||
LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
|
||||
|
||||
elf_hwcap |= HWCAP_LOONGARCH_CRC32;
|
||||
elf_hwcap = HWCAP_LOONGARCH_CPUCFG | HWCAP_LOONGARCH_CRC32;
|
||||
|
||||
config = read_cpucfg(LOONGARCH_CPUCFG1);
|
||||
if (config & CPUCFG1_UAL) {
|
||||
|
||||
@@ -64,7 +64,7 @@ void __init plat_mem_setup(void)
|
||||
dtb = get_fdt();
|
||||
__dt_setup_arch(dtb);
|
||||
|
||||
if (!early_init_dt_scan_memory())
|
||||
if (early_init_dt_scan_memory())
|
||||
return;
|
||||
|
||||
if (soc_info.mem_detect)
|
||||
|
||||
@@ -49,6 +49,19 @@
|
||||
#define MADV_DONTFORK 10 /* don't inherit across fork */
|
||||
#define MADV_DOFORK 11 /* do inherit across fork */
|
||||
|
||||
#define MADV_MERGEABLE 12 /* KSM may merge identical pages */
|
||||
#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */
|
||||
|
||||
#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
|
||||
#define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */
|
||||
|
||||
#define MADV_DONTDUMP 16 /* Explicity exclude from the core dump,
|
||||
overrides the coredump filter bits */
|
||||
#define MADV_DODUMP 17 /* Clear the MADV_NODUMP flag */
|
||||
|
||||
#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */
|
||||
#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */
|
||||
|
||||
#define MADV_COLD 20 /* deactivate these pages */
|
||||
#define MADV_PAGEOUT 21 /* reclaim these pages */
|
||||
|
||||
@@ -57,27 +70,13 @@
|
||||
|
||||
#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */
|
||||
|
||||
#define MADV_MERGEABLE 65 /* KSM may merge identical pages */
|
||||
#define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */
|
||||
|
||||
#define MADV_HUGEPAGE 67 /* Worth backing with hugepages */
|
||||
#define MADV_NOHUGEPAGE 68 /* Not worth backing with hugepages */
|
||||
|
||||
#define MADV_DONTDUMP 69 /* Explicity exclude from the core dump,
|
||||
overrides the coredump filter bits */
|
||||
#define MADV_DODUMP 70 /* Clear the MADV_NODUMP flag */
|
||||
|
||||
#define MADV_WIPEONFORK 71 /* Zero memory on fork, child only */
|
||||
#define MADV_KEEPONFORK 72 /* Undo MADV_WIPEONFORK */
|
||||
|
||||
#define MADV_COLLAPSE 73 /* Synchronous hugepage collapse */
|
||||
#define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */
|
||||
|
||||
#define MADV_HWPOISON 100 /* poison a page for testing */
|
||||
#define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */
|
||||
|
||||
/* compatibility flags */
|
||||
#define MAP_FILE 0
|
||||
#define MAP_VARIABLE 0
|
||||
|
||||
#define PKEY_DISABLE_ACCESS 0x1
|
||||
#define PKEY_DISABLE_WRITE 0x2
|
||||
|
||||
@@ -465,3 +465,31 @@ asmlinkage long parisc_inotify_init1(int flags)
|
||||
flags = FIX_O_NONBLOCK(flags);
|
||||
return sys_inotify_init1(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* madvise() wrapper
|
||||
*
|
||||
* Up to kernel v6.1 parisc has different values than all other
|
||||
* platforms for the MADV_xxx flags listed below.
|
||||
* To keep binary compatibility with existing userspace programs
|
||||
* translate the former values to the new values.
|
||||
*
|
||||
* XXX: Remove this wrapper in year 2025 (or later)
|
||||
*/
|
||||
|
||||
asmlinkage notrace long parisc_madvise(unsigned long start, size_t len_in, int behavior)
|
||||
{
|
||||
switch (behavior) {
|
||||
case 65: behavior = MADV_MERGEABLE; break;
|
||||
case 66: behavior = MADV_UNMERGEABLE; break;
|
||||
case 67: behavior = MADV_HUGEPAGE; break;
|
||||
case 68: behavior = MADV_NOHUGEPAGE; break;
|
||||
case 69: behavior = MADV_DONTDUMP; break;
|
||||
case 70: behavior = MADV_DODUMP; break;
|
||||
case 71: behavior = MADV_WIPEONFORK; break;
|
||||
case 72: behavior = MADV_KEEPONFORK; break;
|
||||
case 73: behavior = MADV_COLLAPSE; break;
|
||||
}
|
||||
|
||||
return sys_madvise(start, len_in, behavior);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
116 common sysinfo sys_sysinfo compat_sys_sysinfo
|
||||
117 common shutdown sys_shutdown
|
||||
118 common fsync sys_fsync
|
||||
119 common madvise sys_madvise
|
||||
119 common madvise parisc_madvise
|
||||
120 common clone sys_clone_wrapper
|
||||
121 common setdomainname sys_setdomainname
|
||||
122 common sendfile sys_sendfile compat_sys_sendfile
|
||||
|
||||
@@ -137,7 +137,7 @@ struct imc_pmu {
|
||||
* are inited.
|
||||
*/
|
||||
struct imc_pmu_ref {
|
||||
struct mutex lock;
|
||||
spinlock_t lock;
|
||||
unsigned int id;
|
||||
int refc;
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <asm/cputhreads.h>
|
||||
#include <asm/smp.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
/* Nest IMC data structures and variables */
|
||||
|
||||
@@ -21,7 +22,7 @@
|
||||
* Used to avoid races in counting the nest-pmu units during hotplug
|
||||
* register and unregister
|
||||
*/
|
||||
static DEFINE_MUTEX(nest_init_lock);
|
||||
static DEFINE_SPINLOCK(nest_init_lock);
|
||||
static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc);
|
||||
static struct imc_pmu **per_nest_pmu_arr;
|
||||
static cpumask_t nest_imc_cpumask;
|
||||
@@ -50,7 +51,7 @@ static int trace_imc_mem_size;
|
||||
* core and trace-imc
|
||||
*/
|
||||
static struct imc_pmu_ref imc_global_refc = {
|
||||
.lock = __MUTEX_INITIALIZER(imc_global_refc.lock),
|
||||
.lock = __SPIN_LOCK_INITIALIZER(imc_global_refc.lock),
|
||||
.id = 0,
|
||||
.refc = 0,
|
||||
};
|
||||
@@ -400,7 +401,7 @@ static int ppc_nest_imc_cpu_offline(unsigned int cpu)
|
||||
get_hard_smp_processor_id(cpu));
|
||||
/*
|
||||
* If this is the last cpu in this chip then, skip the reference
|
||||
* count mutex lock and make the reference count on this chip zero.
|
||||
* count lock and make the reference count on this chip zero.
|
||||
*/
|
||||
ref = get_nest_pmu_ref(cpu);
|
||||
if (!ref)
|
||||
@@ -462,15 +463,15 @@ static void nest_imc_counters_release(struct perf_event *event)
|
||||
/*
|
||||
* See if we need to disable the nest PMU.
|
||||
* If no events are currently in use, then we have to take a
|
||||
* mutex to ensure that we don't race with another task doing
|
||||
* lock to ensure that we don't race with another task doing
|
||||
* enable or disable the nest counters.
|
||||
*/
|
||||
ref = get_nest_pmu_ref(event->cpu);
|
||||
if (!ref)
|
||||
return;
|
||||
|
||||
/* Take the mutex lock for this node and then decrement the reference count */
|
||||
mutex_lock(&ref->lock);
|
||||
/* Take the lock for this node and then decrement the reference count */
|
||||
spin_lock(&ref->lock);
|
||||
if (ref->refc == 0) {
|
||||
/*
|
||||
* The scenario where this is true is, when perf session is
|
||||
@@ -482,7 +483,7 @@ static void nest_imc_counters_release(struct perf_event *event)
|
||||
* an OPAL call to disable the engine in that node.
|
||||
*
|
||||
*/
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
return;
|
||||
}
|
||||
ref->refc--;
|
||||
@@ -490,7 +491,7 @@ static void nest_imc_counters_release(struct perf_event *event)
|
||||
rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST,
|
||||
get_hard_smp_processor_id(event->cpu));
|
||||
if (rc) {
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
pr_err("nest-imc: Unable to stop the counters for core %d\n", node_id);
|
||||
return;
|
||||
}
|
||||
@@ -498,7 +499,7 @@ static void nest_imc_counters_release(struct perf_event *event)
|
||||
WARN(1, "nest-imc: Invalid event reference count\n");
|
||||
ref->refc = 0;
|
||||
}
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
}
|
||||
|
||||
static int nest_imc_event_init(struct perf_event *event)
|
||||
@@ -557,26 +558,25 @@ static int nest_imc_event_init(struct perf_event *event)
|
||||
|
||||
/*
|
||||
* Get the imc_pmu_ref struct for this node.
|
||||
* Take the mutex lock and then increment the count of nest pmu events
|
||||
* inited.
|
||||
* Take the lock and then increment the count of nest pmu events inited.
|
||||
*/
|
||||
ref = get_nest_pmu_ref(event->cpu);
|
||||
if (!ref)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ref->lock);
|
||||
spin_lock(&ref->lock);
|
||||
if (ref->refc == 0) {
|
||||
rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_NEST,
|
||||
get_hard_smp_processor_id(event->cpu));
|
||||
if (rc) {
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
pr_err("nest-imc: Unable to start the counters for node %d\n",
|
||||
node_id);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
++ref->refc;
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
|
||||
event->destroy = nest_imc_counters_release;
|
||||
return 0;
|
||||
@@ -612,9 +612,8 @@ static int core_imc_mem_init(int cpu, int size)
|
||||
return -ENOMEM;
|
||||
mem_info->vbase = page_address(page);
|
||||
|
||||
/* Init the mutex */
|
||||
core_imc_refc[core_id].id = core_id;
|
||||
mutex_init(&core_imc_refc[core_id].lock);
|
||||
spin_lock_init(&core_imc_refc[core_id].lock);
|
||||
|
||||
rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_CORE,
|
||||
__pa((void *)mem_info->vbase),
|
||||
@@ -703,9 +702,8 @@ static int ppc_core_imc_cpu_offline(unsigned int cpu)
|
||||
perf_pmu_migrate_context(&core_imc_pmu->pmu, cpu, ncpu);
|
||||
} else {
|
||||
/*
|
||||
* If this is the last cpu in this core then, skip taking refernce
|
||||
* count mutex lock for this core and directly zero "refc" for
|
||||
* this core.
|
||||
* If this is the last cpu in this core then skip taking reference
|
||||
* count lock for this core and directly zero "refc" for this core.
|
||||
*/
|
||||
opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
|
||||
get_hard_smp_processor_id(cpu));
|
||||
@@ -720,11 +718,11 @@ static int ppc_core_imc_cpu_offline(unsigned int cpu)
|
||||
* last cpu in this core and core-imc event running
|
||||
* in this cpu.
|
||||
*/
|
||||
mutex_lock(&imc_global_refc.lock);
|
||||
spin_lock(&imc_global_refc.lock);
|
||||
if (imc_global_refc.id == IMC_DOMAIN_CORE)
|
||||
imc_global_refc.refc--;
|
||||
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -739,7 +737,7 @@ static int core_imc_pmu_cpumask_init(void)
|
||||
|
||||
static void reset_global_refc(struct perf_event *event)
|
||||
{
|
||||
mutex_lock(&imc_global_refc.lock);
|
||||
spin_lock(&imc_global_refc.lock);
|
||||
imc_global_refc.refc--;
|
||||
|
||||
/*
|
||||
@@ -751,7 +749,7 @@ static void reset_global_refc(struct perf_event *event)
|
||||
imc_global_refc.refc = 0;
|
||||
imc_global_refc.id = 0;
|
||||
}
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
}
|
||||
|
||||
static void core_imc_counters_release(struct perf_event *event)
|
||||
@@ -764,17 +762,17 @@ static void core_imc_counters_release(struct perf_event *event)
|
||||
/*
|
||||
* See if we need to disable the IMC PMU.
|
||||
* If no events are currently in use, then we have to take a
|
||||
* mutex to ensure that we don't race with another task doing
|
||||
* lock to ensure that we don't race with another task doing
|
||||
* enable or disable the core counters.
|
||||
*/
|
||||
core_id = event->cpu / threads_per_core;
|
||||
|
||||
/* Take the mutex lock and decrement the refernce count for this core */
|
||||
/* Take the lock and decrement the refernce count for this core */
|
||||
ref = &core_imc_refc[core_id];
|
||||
if (!ref)
|
||||
return;
|
||||
|
||||
mutex_lock(&ref->lock);
|
||||
spin_lock(&ref->lock);
|
||||
if (ref->refc == 0) {
|
||||
/*
|
||||
* The scenario where this is true is, when perf session is
|
||||
@@ -786,7 +784,7 @@ static void core_imc_counters_release(struct perf_event *event)
|
||||
* an OPAL call to disable the engine in that core.
|
||||
*
|
||||
*/
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
return;
|
||||
}
|
||||
ref->refc--;
|
||||
@@ -794,7 +792,7 @@ static void core_imc_counters_release(struct perf_event *event)
|
||||
rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
|
||||
get_hard_smp_processor_id(event->cpu));
|
||||
if (rc) {
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
pr_err("IMC: Unable to stop the counters for core %d\n", core_id);
|
||||
return;
|
||||
}
|
||||
@@ -802,7 +800,7 @@ static void core_imc_counters_release(struct perf_event *event)
|
||||
WARN(1, "core-imc: Invalid event reference count\n");
|
||||
ref->refc = 0;
|
||||
}
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
|
||||
reset_global_refc(event);
|
||||
}
|
||||
@@ -840,7 +838,6 @@ static int core_imc_event_init(struct perf_event *event)
|
||||
if ((!pcmi->vbase))
|
||||
return -ENODEV;
|
||||
|
||||
/* Get the core_imc mutex for this core */
|
||||
ref = &core_imc_refc[core_id];
|
||||
if (!ref)
|
||||
return -EINVAL;
|
||||
@@ -848,22 +845,22 @@ static int core_imc_event_init(struct perf_event *event)
|
||||
/*
|
||||
* Core pmu units are enabled only when it is used.
|
||||
* See if this is triggered for the first time.
|
||||
* If yes, take the mutex lock and enable the core counters.
|
||||
* If yes, take the lock and enable the core counters.
|
||||
* If not, just increment the count in core_imc_refc struct.
|
||||
*/
|
||||
mutex_lock(&ref->lock);
|
||||
spin_lock(&ref->lock);
|
||||
if (ref->refc == 0) {
|
||||
rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE,
|
||||
get_hard_smp_processor_id(event->cpu));
|
||||
if (rc) {
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
pr_err("core-imc: Unable to start the counters for core %d\n",
|
||||
core_id);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
++ref->refc;
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
|
||||
/*
|
||||
* Since the system can run either in accumulation or trace-mode
|
||||
@@ -874,7 +871,7 @@ static int core_imc_event_init(struct perf_event *event)
|
||||
* to know whether any other trace/thread imc
|
||||
* events are running.
|
||||
*/
|
||||
mutex_lock(&imc_global_refc.lock);
|
||||
spin_lock(&imc_global_refc.lock);
|
||||
if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_CORE) {
|
||||
/*
|
||||
* No other trace/thread imc events are running in
|
||||
@@ -883,10 +880,10 @@ static int core_imc_event_init(struct perf_event *event)
|
||||
imc_global_refc.id = IMC_DOMAIN_CORE;
|
||||
imc_global_refc.refc++;
|
||||
} else {
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
|
||||
event->hw.event_base = (u64)pcmi->vbase + (config & IMC_EVENT_OFFSET_MASK);
|
||||
event->destroy = core_imc_counters_release;
|
||||
@@ -958,10 +955,10 @@ static int ppc_thread_imc_cpu_offline(unsigned int cpu)
|
||||
mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63))));
|
||||
|
||||
/* Reduce the refc if thread-imc event running on this cpu */
|
||||
mutex_lock(&imc_global_refc.lock);
|
||||
spin_lock(&imc_global_refc.lock);
|
||||
if (imc_global_refc.id == IMC_DOMAIN_THREAD)
|
||||
imc_global_refc.refc--;
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1001,7 +998,7 @@ static int thread_imc_event_init(struct perf_event *event)
|
||||
if (!target)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&imc_global_refc.lock);
|
||||
spin_lock(&imc_global_refc.lock);
|
||||
/*
|
||||
* Check if any other trace/core imc events are running in the
|
||||
* system, if not set the global id to thread-imc.
|
||||
@@ -1010,10 +1007,10 @@ static int thread_imc_event_init(struct perf_event *event)
|
||||
imc_global_refc.id = IMC_DOMAIN_THREAD;
|
||||
imc_global_refc.refc++;
|
||||
} else {
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
|
||||
event->pmu->task_ctx_nr = perf_sw_context;
|
||||
event->destroy = reset_global_refc;
|
||||
@@ -1135,25 +1132,25 @@ static int thread_imc_event_add(struct perf_event *event, int flags)
|
||||
/*
|
||||
* imc pmus are enabled only when it is used.
|
||||
* See if this is triggered for the first time.
|
||||
* If yes, take the mutex lock and enable the counters.
|
||||
* If yes, take the lock and enable the counters.
|
||||
* If not, just increment the count in ref count struct.
|
||||
*/
|
||||
ref = &core_imc_refc[core_id];
|
||||
if (!ref)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ref->lock);
|
||||
spin_lock(&ref->lock);
|
||||
if (ref->refc == 0) {
|
||||
if (opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE,
|
||||
get_hard_smp_processor_id(smp_processor_id()))) {
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
pr_err("thread-imc: Unable to start the counter\
|
||||
for core %d\n", core_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
++ref->refc;
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1170,12 +1167,12 @@ static void thread_imc_event_del(struct perf_event *event, int flags)
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&ref->lock);
|
||||
spin_lock(&ref->lock);
|
||||
ref->refc--;
|
||||
if (ref->refc == 0) {
|
||||
if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
|
||||
get_hard_smp_processor_id(smp_processor_id()))) {
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
pr_err("thread-imc: Unable to stop the counters\
|
||||
for core %d\n", core_id);
|
||||
return;
|
||||
@@ -1183,7 +1180,7 @@ static void thread_imc_event_del(struct perf_event *event, int flags)
|
||||
} else if (ref->refc < 0) {
|
||||
ref->refc = 0;
|
||||
}
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
|
||||
/* Set bit 0 of LDBAR to zero, to stop posting updates to memory */
|
||||
mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63))));
|
||||
@@ -1224,9 +1221,8 @@ static int trace_imc_mem_alloc(int cpu_id, int size)
|
||||
}
|
||||
}
|
||||
|
||||
/* Init the mutex, if not already */
|
||||
trace_imc_refc[core_id].id = core_id;
|
||||
mutex_init(&trace_imc_refc[core_id].lock);
|
||||
spin_lock_init(&trace_imc_refc[core_id].lock);
|
||||
|
||||
mtspr(SPRN_LDBAR, 0);
|
||||
return 0;
|
||||
@@ -1246,10 +1242,10 @@ static int ppc_trace_imc_cpu_offline(unsigned int cpu)
|
||||
* Reduce the refc if any trace-imc event running
|
||||
* on this cpu.
|
||||
*/
|
||||
mutex_lock(&imc_global_refc.lock);
|
||||
spin_lock(&imc_global_refc.lock);
|
||||
if (imc_global_refc.id == IMC_DOMAIN_TRACE)
|
||||
imc_global_refc.refc--;
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1371,17 +1367,17 @@ static int trace_imc_event_add(struct perf_event *event, int flags)
|
||||
}
|
||||
|
||||
mtspr(SPRN_LDBAR, ldbar_value);
|
||||
mutex_lock(&ref->lock);
|
||||
spin_lock(&ref->lock);
|
||||
if (ref->refc == 0) {
|
||||
if (opal_imc_counters_start(OPAL_IMC_COUNTERS_TRACE,
|
||||
get_hard_smp_processor_id(smp_processor_id()))) {
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
pr_err("trace-imc: Unable to start the counters for core %d\n", core_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
++ref->refc;
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1414,19 +1410,19 @@ static void trace_imc_event_del(struct perf_event *event, int flags)
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&ref->lock);
|
||||
spin_lock(&ref->lock);
|
||||
ref->refc--;
|
||||
if (ref->refc == 0) {
|
||||
if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_TRACE,
|
||||
get_hard_smp_processor_id(smp_processor_id()))) {
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
pr_err("trace-imc: Unable to stop the counters for core %d\n", core_id);
|
||||
return;
|
||||
}
|
||||
} else if (ref->refc < 0) {
|
||||
ref->refc = 0;
|
||||
}
|
||||
mutex_unlock(&ref->lock);
|
||||
spin_unlock(&ref->lock);
|
||||
|
||||
trace_imc_event_stop(event, flags);
|
||||
}
|
||||
@@ -1448,7 +1444,7 @@ static int trace_imc_event_init(struct perf_event *event)
|
||||
* no other thread is running any core/thread imc
|
||||
* events
|
||||
*/
|
||||
mutex_lock(&imc_global_refc.lock);
|
||||
spin_lock(&imc_global_refc.lock);
|
||||
if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_TRACE) {
|
||||
/*
|
||||
* No core/thread imc events are running in the
|
||||
@@ -1457,10 +1453,10 @@ static int trace_imc_event_init(struct perf_event *event)
|
||||
imc_global_refc.id = IMC_DOMAIN_TRACE;
|
||||
imc_global_refc.refc++;
|
||||
} else {
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
mutex_unlock(&imc_global_refc.lock);
|
||||
spin_unlock(&imc_global_refc.lock);
|
||||
|
||||
event->hw.idx = -1;
|
||||
|
||||
@@ -1533,10 +1529,10 @@ static int init_nest_pmu_ref(void)
|
||||
i = 0;
|
||||
for_each_node(nid) {
|
||||
/*
|
||||
* Mutex lock to avoid races while tracking the number of
|
||||
* Take the lock to avoid races while tracking the number of
|
||||
* sessions using the chip's nest pmu units.
|
||||
*/
|
||||
mutex_init(&nest_imc_refc[i].lock);
|
||||
spin_lock_init(&nest_imc_refc[i].lock);
|
||||
|
||||
/*
|
||||
* Loop to init the "id" with the node_id. Variable "i" initialized to
|
||||
@@ -1633,7 +1629,7 @@ static void imc_common_mem_free(struct imc_pmu *pmu_ptr)
|
||||
static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)
|
||||
{
|
||||
if (pmu_ptr->domain == IMC_DOMAIN_NEST) {
|
||||
mutex_lock(&nest_init_lock);
|
||||
spin_lock(&nest_init_lock);
|
||||
if (nest_pmus == 1) {
|
||||
cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE);
|
||||
kfree(nest_imc_refc);
|
||||
@@ -1643,7 +1639,7 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)
|
||||
|
||||
if (nest_pmus > 0)
|
||||
nest_pmus--;
|
||||
mutex_unlock(&nest_init_lock);
|
||||
spin_unlock(&nest_init_lock);
|
||||
}
|
||||
|
||||
/* Free core_imc memory */
|
||||
@@ -1800,11 +1796,11 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id
|
||||
* rest. To handle the cpuhotplug callback unregister, we track
|
||||
* the number of nest pmus in "nest_pmus".
|
||||
*/
|
||||
mutex_lock(&nest_init_lock);
|
||||
spin_lock(&nest_init_lock);
|
||||
if (nest_pmus == 0) {
|
||||
ret = init_nest_pmu_ref();
|
||||
if (ret) {
|
||||
mutex_unlock(&nest_init_lock);
|
||||
spin_unlock(&nest_init_lock);
|
||||
kfree(per_nest_pmu_arr);
|
||||
per_nest_pmu_arr = NULL;
|
||||
goto err_free_mem;
|
||||
@@ -1812,7 +1808,7 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id
|
||||
/* Register for cpu hotplug notification. */
|
||||
ret = nest_pmu_cpumask_init();
|
||||
if (ret) {
|
||||
mutex_unlock(&nest_init_lock);
|
||||
spin_unlock(&nest_init_lock);
|
||||
kfree(nest_imc_refc);
|
||||
kfree(per_nest_pmu_arr);
|
||||
per_nest_pmu_arr = NULL;
|
||||
@@ -1820,7 +1816,7 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id
|
||||
}
|
||||
}
|
||||
nest_pmus++;
|
||||
mutex_unlock(&nest_init_lock);
|
||||
spin_unlock(&nest_init_lock);
|
||||
break;
|
||||
case IMC_DOMAIN_CORE:
|
||||
ret = core_imc_pmu_cpumask_init();
|
||||
|
||||
@@ -328,7 +328,7 @@
|
||||
bus-range = <0x0 0xff>;
|
||||
ranges = <0x81000000 0x0 0x60080000 0x0 0x60080000 0x0 0x10000>, /* I/O */
|
||||
<0x82000000 0x0 0x60090000 0x0 0x60090000 0x0 0xff70000>, /* mem */
|
||||
<0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x1000000>, /* mem */
|
||||
<0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x10000000>, /* mem */
|
||||
<0xc3000000 0x20 0x00000000 0x20 0x00000000 0x20 0x00000000>; /* mem prefetchable */
|
||||
num-lanes = <0x8>;
|
||||
interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, <63>, <64>;
|
||||
|
||||
@@ -165,7 +165,7 @@ do { \
|
||||
might_fault(); \
|
||||
access_ok(__p, sizeof(*__p)) ? \
|
||||
__get_user((x), __p) : \
|
||||
((x) = 0, -EFAULT); \
|
||||
((x) = (__force __typeof__(x))0, -EFAULT); \
|
||||
})
|
||||
|
||||
#define __put_user_asm(insn, x, ptr, err) \
|
||||
|
||||
@@ -31,9 +31,9 @@ __RISCV_INSN_FUNCS(fence, 0x7f, 0x0f);
|
||||
} while (0)
|
||||
|
||||
__RISCV_INSN_FUNCS(c_j, 0xe003, 0xa001);
|
||||
__RISCV_INSN_FUNCS(c_jr, 0xf007, 0x8002);
|
||||
__RISCV_INSN_FUNCS(c_jr, 0xf07f, 0x8002);
|
||||
__RISCV_INSN_FUNCS(c_jal, 0xe003, 0x2001);
|
||||
__RISCV_INSN_FUNCS(c_jalr, 0xf007, 0x9002);
|
||||
__RISCV_INSN_FUNCS(c_jalr, 0xf07f, 0x9002);
|
||||
__RISCV_INSN_FUNCS(c_beqz, 0xe003, 0xc001);
|
||||
__RISCV_INSN_FUNCS(c_bnez, 0xe003, 0xe001);
|
||||
__RISCV_INSN_FUNCS(c_ebreak, 0xffff, 0x9002);
|
||||
|
||||
@@ -131,19 +131,21 @@ struct hws_combined_entry {
|
||||
struct hws_diag_entry diag; /* Diagnostic-sampling data entry */
|
||||
} __packed;
|
||||
|
||||
struct hws_trailer_entry {
|
||||
union {
|
||||
struct {
|
||||
unsigned int f:1; /* 0 - Block Full Indicator */
|
||||
unsigned int a:1; /* 1 - Alert request control */
|
||||
unsigned int t:1; /* 2 - Timestamp format */
|
||||
unsigned int :29; /* 3 - 31: Reserved */
|
||||
unsigned int bsdes:16; /* 32-47: size of basic SDE */
|
||||
unsigned int dsdes:16; /* 48-63: size of diagnostic SDE */
|
||||
};
|
||||
unsigned long long flags; /* 0 - 63: All indicators */
|
||||
union hws_trailer_header {
|
||||
struct {
|
||||
unsigned int f:1; /* 0 - Block Full Indicator */
|
||||
unsigned int a:1; /* 1 - Alert request control */
|
||||
unsigned int t:1; /* 2 - Timestamp format */
|
||||
unsigned int :29; /* 3 - 31: Reserved */
|
||||
unsigned int bsdes:16; /* 32-47: size of basic SDE */
|
||||
unsigned int dsdes:16; /* 48-63: size of diagnostic SDE */
|
||||
unsigned long long overflow; /* 64 - Overflow Count */
|
||||
};
|
||||
unsigned long long overflow; /* 64 - sample Overflow count */
|
||||
__uint128_t val;
|
||||
};
|
||||
|
||||
struct hws_trailer_entry {
|
||||
union hws_trailer_header header; /* 0 - 15 Flags + Overflow Count */
|
||||
unsigned char timestamp[16]; /* 16 - 31 timestamp */
|
||||
unsigned long long reserved1; /* 32 -Reserved */
|
||||
unsigned long long reserved2; /* */
|
||||
@@ -290,14 +292,11 @@ static inline unsigned long sample_rate_to_freq(struct hws_qsi_info_block *qsi,
|
||||
return USEC_PER_SEC * qsi->cpu_speed / rate;
|
||||
}
|
||||
|
||||
#define SDB_TE_ALERT_REQ_MASK 0x4000000000000000UL
|
||||
#define SDB_TE_BUFFER_FULL_MASK 0x8000000000000000UL
|
||||
|
||||
/* Return TOD timestamp contained in an trailer entry */
|
||||
static inline unsigned long long trailer_timestamp(struct hws_trailer_entry *te)
|
||||
{
|
||||
/* TOD in STCKE format */
|
||||
if (te->t)
|
||||
if (te->header.t)
|
||||
return *((unsigned long long *) &te->timestamp[1]);
|
||||
|
||||
/* TOD in STCK format */
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
pcp_op_T__ *ptr__; \
|
||||
preempt_disable_notrace(); \
|
||||
ptr__ = raw_cpu_ptr(&(pcp)); \
|
||||
prev__ = *ptr__; \
|
||||
prev__ = READ_ONCE(*ptr__); \
|
||||
do { \
|
||||
old__ = prev__; \
|
||||
new__ = old__ op (val); \
|
||||
|
||||
@@ -187,8 +187,6 @@ static int kexec_file_add_ipl_report(struct kimage *image,
|
||||
|
||||
data->memsz = ALIGN(data->memsz, PAGE_SIZE);
|
||||
buf.mem = data->memsz;
|
||||
if (image->type == KEXEC_TYPE_CRASH)
|
||||
buf.mem += crashk_res.start;
|
||||
|
||||
ptr = (void *)ipl_cert_list_addr;
|
||||
end = ptr + ipl_cert_list_size;
|
||||
@@ -225,6 +223,9 @@ static int kexec_file_add_ipl_report(struct kimage *image,
|
||||
data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr);
|
||||
*lc_ipl_parmblock_ptr = (__u32)buf.mem;
|
||||
|
||||
if (image->type == KEXEC_TYPE_CRASH)
|
||||
buf.mem += crashk_res.start;
|
||||
|
||||
ret = kexec_add_buffer(&buf);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
@@ -163,14 +163,15 @@ static void free_sampling_buffer(struct sf_buffer *sfb)
|
||||
|
||||
static int alloc_sample_data_block(unsigned long *sdbt, gfp_t gfp_flags)
|
||||
{
|
||||
unsigned long sdb, *trailer;
|
||||
struct hws_trailer_entry *te;
|
||||
unsigned long sdb;
|
||||
|
||||
/* Allocate and initialize sample-data-block */
|
||||
sdb = get_zeroed_page(gfp_flags);
|
||||
if (!sdb)
|
||||
return -ENOMEM;
|
||||
trailer = trailer_entry_ptr(sdb);
|
||||
*trailer = SDB_TE_ALERT_REQ_MASK;
|
||||
te = (struct hws_trailer_entry *)trailer_entry_ptr(sdb);
|
||||
te->header.a = 1;
|
||||
|
||||
/* Link SDB into the sample-data-block-table */
|
||||
*sdbt = sdb;
|
||||
@@ -1206,7 +1207,7 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
|
||||
"%s: Found unknown"
|
||||
" sampling data entry: te->f %i"
|
||||
" basic.def %#4x (%p)\n", __func__,
|
||||
te->f, sample->def, sample);
|
||||
te->header.f, sample->def, sample);
|
||||
/* Sample slot is not yet written or other record.
|
||||
*
|
||||
* This condition can occur if the buffer was reused
|
||||
@@ -1217,7 +1218,7 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
|
||||
* that are not full. Stop processing if the first
|
||||
* invalid format was detected.
|
||||
*/
|
||||
if (!te->f)
|
||||
if (!te->header.f)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1227,6 +1228,16 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
|
||||
}
|
||||
}
|
||||
|
||||
static inline __uint128_t __cdsg(__uint128_t *ptr, __uint128_t old, __uint128_t new)
|
||||
{
|
||||
asm volatile(
|
||||
" cdsg %[old],%[new],%[ptr]\n"
|
||||
: [old] "+d" (old), [ptr] "+QS" (*ptr)
|
||||
: [new] "d" (new)
|
||||
: "memory", "cc");
|
||||
return old;
|
||||
}
|
||||
|
||||
/* hw_perf_event_update() - Process sampling buffer
|
||||
* @event: The perf event
|
||||
* @flush_all: Flag to also flush partially filled sample-data-blocks
|
||||
@@ -1243,10 +1254,11 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
|
||||
*/
|
||||
static void hw_perf_event_update(struct perf_event *event, int flush_all)
|
||||
{
|
||||
unsigned long long event_overflow, sampl_overflow, num_sdb;
|
||||
union hws_trailer_header old, prev, new;
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
struct hws_trailer_entry *te;
|
||||
unsigned long *sdbt;
|
||||
unsigned long long event_overflow, sampl_overflow, num_sdb, te_flags;
|
||||
int done;
|
||||
|
||||
/*
|
||||
@@ -1266,25 +1278,25 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all)
|
||||
te = (struct hws_trailer_entry *) trailer_entry_ptr(*sdbt);
|
||||
|
||||
/* Leave loop if no more work to do (block full indicator) */
|
||||
if (!te->f) {
|
||||
if (!te->header.f) {
|
||||
done = 1;
|
||||
if (!flush_all)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check the sample overflow count */
|
||||
if (te->overflow)
|
||||
if (te->header.overflow)
|
||||
/* Account sample overflows and, if a particular limit
|
||||
* is reached, extend the sampling buffer.
|
||||
* For details, see sfb_account_overflows().
|
||||
*/
|
||||
sampl_overflow += te->overflow;
|
||||
sampl_overflow += te->header.overflow;
|
||||
|
||||
/* Timestamps are valid for full sample-data-blocks only */
|
||||
debug_sprintf_event(sfdbg, 6, "%s: sdbt %#lx "
|
||||
"overflow %llu timestamp %#llx\n",
|
||||
__func__, (unsigned long)sdbt, te->overflow,
|
||||
(te->f) ? trailer_timestamp(te) : 0ULL);
|
||||
__func__, (unsigned long)sdbt, te->header.overflow,
|
||||
(te->header.f) ? trailer_timestamp(te) : 0ULL);
|
||||
|
||||
/* Collect all samples from a single sample-data-block and
|
||||
* flag if an (perf) event overflow happened. If so, the PMU
|
||||
@@ -1294,12 +1306,16 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all)
|
||||
num_sdb++;
|
||||
|
||||
/* Reset trailer (using compare-double-and-swap) */
|
||||
/* READ_ONCE() 16 byte header */
|
||||
prev.val = __cdsg(&te->header.val, 0, 0);
|
||||
do {
|
||||
te_flags = te->flags & ~SDB_TE_BUFFER_FULL_MASK;
|
||||
te_flags |= SDB_TE_ALERT_REQ_MASK;
|
||||
} while (!cmpxchg_double(&te->flags, &te->overflow,
|
||||
te->flags, te->overflow,
|
||||
te_flags, 0ULL));
|
||||
old.val = prev.val;
|
||||
new.val = prev.val;
|
||||
new.f = 0;
|
||||
new.a = 1;
|
||||
new.overflow = 0;
|
||||
prev.val = __cdsg(&te->header.val, old.val, new.val);
|
||||
} while (prev.val != old.val);
|
||||
|
||||
/* Advance to next sample-data-block */
|
||||
sdbt++;
|
||||
@@ -1384,7 +1400,7 @@ static void aux_output_end(struct perf_output_handle *handle)
|
||||
range_scan = AUX_SDB_NUM_ALERT(aux);
|
||||
for (i = 0, idx = aux->head; i < range_scan; i++, idx++) {
|
||||
te = aux_sdb_trailer(aux, idx);
|
||||
if (!(te->flags & SDB_TE_BUFFER_FULL_MASK))
|
||||
if (!te->header.f)
|
||||
break;
|
||||
}
|
||||
/* i is num of SDBs which are full */
|
||||
@@ -1392,7 +1408,7 @@ static void aux_output_end(struct perf_output_handle *handle)
|
||||
|
||||
/* Remove alert indicators in the buffer */
|
||||
te = aux_sdb_trailer(aux, aux->alert_mark);
|
||||
te->flags &= ~SDB_TE_ALERT_REQ_MASK;
|
||||
te->header.a = 0;
|
||||
|
||||
debug_sprintf_event(sfdbg, 6, "%s: SDBs %ld range %ld head %ld\n",
|
||||
__func__, i, range_scan, aux->head);
|
||||
@@ -1437,9 +1453,9 @@ static int aux_output_begin(struct perf_output_handle *handle,
|
||||
idx = aux->empty_mark + 1;
|
||||
for (i = 0; i < range_scan; i++, idx++) {
|
||||
te = aux_sdb_trailer(aux, idx);
|
||||
te->flags &= ~(SDB_TE_BUFFER_FULL_MASK |
|
||||
SDB_TE_ALERT_REQ_MASK);
|
||||
te->overflow = 0;
|
||||
te->header.f = 0;
|
||||
te->header.a = 0;
|
||||
te->header.overflow = 0;
|
||||
}
|
||||
/* Save the position of empty SDBs */
|
||||
aux->empty_mark = aux->head + range - 1;
|
||||
@@ -1448,7 +1464,7 @@ static int aux_output_begin(struct perf_output_handle *handle,
|
||||
/* Set alert indicator */
|
||||
aux->alert_mark = aux->head + range/2 - 1;
|
||||
te = aux_sdb_trailer(aux, aux->alert_mark);
|
||||
te->flags = te->flags | SDB_TE_ALERT_REQ_MASK;
|
||||
te->header.a = 1;
|
||||
|
||||
/* Reset hardware buffer head */
|
||||
head = AUX_SDB_INDEX(aux, aux->head);
|
||||
@@ -1475,14 +1491,17 @@ static int aux_output_begin(struct perf_output_handle *handle,
|
||||
static bool aux_set_alert(struct aux_buffer *aux, unsigned long alert_index,
|
||||
unsigned long long *overflow)
|
||||
{
|
||||
unsigned long long orig_overflow, orig_flags, new_flags;
|
||||
union hws_trailer_header old, prev, new;
|
||||
struct hws_trailer_entry *te;
|
||||
|
||||
te = aux_sdb_trailer(aux, alert_index);
|
||||
/* READ_ONCE() 16 byte header */
|
||||
prev.val = __cdsg(&te->header.val, 0, 0);
|
||||
do {
|
||||
orig_flags = te->flags;
|
||||
*overflow = orig_overflow = te->overflow;
|
||||
if (orig_flags & SDB_TE_BUFFER_FULL_MASK) {
|
||||
old.val = prev.val;
|
||||
new.val = prev.val;
|
||||
*overflow = old.overflow;
|
||||
if (old.f) {
|
||||
/*
|
||||
* SDB is already set by hardware.
|
||||
* Abort and try to set somewhere
|
||||
@@ -1490,10 +1509,10 @@ static bool aux_set_alert(struct aux_buffer *aux, unsigned long alert_index,
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
new_flags = orig_flags | SDB_TE_ALERT_REQ_MASK;
|
||||
} while (!cmpxchg_double(&te->flags, &te->overflow,
|
||||
orig_flags, orig_overflow,
|
||||
new_flags, 0ULL));
|
||||
new.a = 1;
|
||||
new.overflow = 0;
|
||||
prev.val = __cdsg(&te->header.val, old.val, new.val);
|
||||
} while (prev.val != old.val);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1522,8 +1541,9 @@ static bool aux_set_alert(struct aux_buffer *aux, unsigned long alert_index,
|
||||
static bool aux_reset_buffer(struct aux_buffer *aux, unsigned long range,
|
||||
unsigned long long *overflow)
|
||||
{
|
||||
unsigned long long orig_overflow, orig_flags, new_flags;
|
||||
unsigned long i, range_scan, idx, idx_old;
|
||||
union hws_trailer_header old, prev, new;
|
||||
unsigned long long orig_overflow;
|
||||
struct hws_trailer_entry *te;
|
||||
|
||||
debug_sprintf_event(sfdbg, 6, "%s: range %ld head %ld alert %ld "
|
||||
@@ -1554,17 +1574,20 @@ static bool aux_reset_buffer(struct aux_buffer *aux, unsigned long range,
|
||||
idx_old = idx = aux->empty_mark + 1;
|
||||
for (i = 0; i < range_scan; i++, idx++) {
|
||||
te = aux_sdb_trailer(aux, idx);
|
||||
/* READ_ONCE() 16 byte header */
|
||||
prev.val = __cdsg(&te->header.val, 0, 0);
|
||||
do {
|
||||
orig_flags = te->flags;
|
||||
orig_overflow = te->overflow;
|
||||
new_flags = orig_flags & ~SDB_TE_BUFFER_FULL_MASK;
|
||||
old.val = prev.val;
|
||||
new.val = prev.val;
|
||||
orig_overflow = old.overflow;
|
||||
new.f = 0;
|
||||
new.overflow = 0;
|
||||
if (idx == aux->alert_mark)
|
||||
new_flags |= SDB_TE_ALERT_REQ_MASK;
|
||||
new.a = 1;
|
||||
else
|
||||
new_flags &= ~SDB_TE_ALERT_REQ_MASK;
|
||||
} while (!cmpxchg_double(&te->flags, &te->overflow,
|
||||
orig_flags, orig_overflow,
|
||||
new_flags, 0ULL));
|
||||
new.a = 0;
|
||||
prev.val = __cdsg(&te->header.val, old.val, new.val);
|
||||
} while (prev.val != old.val);
|
||||
*overflow += orig_overflow;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ intcall:
|
||||
movw %dx, %si
|
||||
movw %sp, %di
|
||||
movw $11, %cx
|
||||
rep; movsd
|
||||
rep; movsl
|
||||
|
||||
/* Pop full state from the stack */
|
||||
popal
|
||||
@@ -67,7 +67,7 @@ intcall:
|
||||
jz 4f
|
||||
movw %sp, %si
|
||||
movw $11, %cx
|
||||
rep; movsd
|
||||
rep; movsl
|
||||
4: addw $44, %sp
|
||||
|
||||
/* Restore state and return */
|
||||
|
||||
@@ -800,13 +800,18 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &model_hsx),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &model_spr),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &model_spr),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, &model_skl),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, &model_skl),
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, rapl_model_match);
|
||||
|
||||
@@ -1951,6 +1951,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
|
||||
if (ctrl == PR_SPEC_FORCE_DISABLE)
|
||||
task_set_spec_ib_force_disable(task);
|
||||
task_update_spec_tif(task);
|
||||
if (task == current)
|
||||
indirect_branch_prediction_barrier();
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
|
||||
@@ -146,6 +146,30 @@ static inline struct rmid_entry *__rmid_entry(u32 rmid)
|
||||
return entry;
|
||||
}
|
||||
|
||||
static int __rmid_read(u32 rmid, enum resctrl_event_id eventid, u64 *val)
|
||||
{
|
||||
u64 msr_val;
|
||||
|
||||
/*
|
||||
* As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured
|
||||
* with a valid event code for supported resource type and the bits
|
||||
* IA32_QM_EVTSEL.RMID (bits 41:32) are configured with valid RMID,
|
||||
* IA32_QM_CTR.data (bits 61:0) reports the monitored data.
|
||||
* IA32_QM_CTR.Error (bit 63) and IA32_QM_CTR.Unavailable (bit 62)
|
||||
* are error bits.
|
||||
*/
|
||||
wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid);
|
||||
rdmsrl(MSR_IA32_QM_CTR, msr_val);
|
||||
|
||||
if (msr_val & RMID_VAL_ERROR)
|
||||
return -EIO;
|
||||
if (msr_val & RMID_VAL_UNAVAIL)
|
||||
return -EINVAL;
|
||||
|
||||
*val = msr_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_domain *hw_dom,
|
||||
u32 rmid,
|
||||
enum resctrl_event_id eventid)
|
||||
@@ -172,8 +196,12 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d,
|
||||
struct arch_mbm_state *am;
|
||||
|
||||
am = get_arch_mbm_state(hw_dom, rmid, eventid);
|
||||
if (am)
|
||||
if (am) {
|
||||
memset(am, 0, sizeof(*am));
|
||||
|
||||
/* Record any initial, non-zero count value. */
|
||||
__rmid_read(rmid, eventid, &am->prev_msr);
|
||||
}
|
||||
}
|
||||
|
||||
static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width)
|
||||
@@ -191,25 +219,14 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d,
|
||||
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
|
||||
struct arch_mbm_state *am;
|
||||
u64 msr_val, chunks;
|
||||
int ret;
|
||||
|
||||
if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured
|
||||
* with a valid event code for supported resource type and the bits
|
||||
* IA32_QM_EVTSEL.RMID (bits 41:32) are configured with valid RMID,
|
||||
* IA32_QM_CTR.data (bits 61:0) reports the monitored data.
|
||||
* IA32_QM_CTR.Error (bit 63) and IA32_QM_CTR.Unavailable (bit 62)
|
||||
* are error bits.
|
||||
*/
|
||||
wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid);
|
||||
rdmsrl(MSR_IA32_QM_CTR, msr_val);
|
||||
|
||||
if (msr_val & RMID_VAL_ERROR)
|
||||
return -EIO;
|
||||
if (msr_val & RMID_VAL_UNAVAIL)
|
||||
return -EINVAL;
|
||||
ret = __rmid_read(rmid, eventid, &msr_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
am = get_arch_mbm_state(hw_dom, rmid, eventid);
|
||||
if (am) {
|
||||
|
||||
@@ -580,8 +580,10 @@ static int __rdtgroup_move_task(struct task_struct *tsk,
|
||||
/*
|
||||
* Ensure the task's closid and rmid are written before determining if
|
||||
* the task is current that will decide if it will be interrupted.
|
||||
* This pairs with the full barrier between the rq->curr update and
|
||||
* resctrl_sched_in() during context switch.
|
||||
*/
|
||||
barrier();
|
||||
smp_mb();
|
||||
|
||||
/*
|
||||
* By now, the task's closid and rmid are set. If the task is current
|
||||
@@ -2401,6 +2403,14 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to,
|
||||
WRITE_ONCE(t->closid, to->closid);
|
||||
WRITE_ONCE(t->rmid, to->mon.rmid);
|
||||
|
||||
/*
|
||||
* Order the closid/rmid stores above before the loads
|
||||
* in task_curr(). This pairs with the full barrier
|
||||
* between the rq->curr update and resctrl_sched_in()
|
||||
* during context switch.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
/*
|
||||
* If the task is on a CPU, set the CPU in the mask.
|
||||
* The detection is inaccurate as tasks might move or
|
||||
|
||||
@@ -401,10 +401,8 @@ int crash_load_segments(struct kimage *image)
|
||||
kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
|
||||
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
|
||||
ret = kexec_add_buffer(&kbuf);
|
||||
if (ret) {
|
||||
vfree((void *)image->elf_headers);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
image->elf_load_addr = kbuf.mem;
|
||||
pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
|
||||
image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
|
||||
|
||||
@@ -391,8 +391,6 @@ int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf,
|
||||
{
|
||||
struct fpstate *kstate = gfpu->fpstate;
|
||||
const union fpregs_state *ustate = buf;
|
||||
struct pkru_state *xpkru;
|
||||
int ret;
|
||||
|
||||
if (!cpu_feature_enabled(X86_FEATURE_XSAVE)) {
|
||||
if (ustate->xsave.header.xfeatures & ~XFEATURE_MASK_FPSSE)
|
||||
@@ -406,16 +404,15 @@ int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf,
|
||||
if (ustate->xsave.header.xfeatures & ~xcr0)
|
||||
return -EINVAL;
|
||||
|
||||
ret = copy_uabi_from_kernel_to_xstate(kstate, ustate);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* Nullify @vpkru to preserve its current value if PKRU's bit isn't set
|
||||
* in the header. KVM's odd ABI is to leave PKRU untouched in this
|
||||
* case (all other components are eventually re-initialized).
|
||||
*/
|
||||
if (!(ustate->xsave.header.xfeatures & XFEATURE_MASK_PKRU))
|
||||
vpkru = NULL;
|
||||
|
||||
/* Retrieve PKRU if not in init state */
|
||||
if (kstate->regs.xsave.header.xfeatures & XFEATURE_MASK_PKRU) {
|
||||
xpkru = get_xsave_addr(&kstate->regs.xsave, XFEATURE_PKRU);
|
||||
*vpkru = xpkru->pkru;
|
||||
}
|
||||
return 0;
|
||||
return copy_uabi_from_kernel_to_xstate(kstate, ustate, vpkru);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fpu_copy_uabi_to_guest_fpstate);
|
||||
#endif /* CONFIG_KVM */
|
||||
|
||||
@@ -133,9 +133,6 @@ static void __init fpu__init_system_generic(void)
|
||||
fpu__init_system_mxcsr();
|
||||
}
|
||||
|
||||
/* Get alignment of the TYPE. */
|
||||
#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)
|
||||
|
||||
/*
|
||||
* Enforce that 'MEMBER' is the last field of 'TYPE'.
|
||||
*
|
||||
@@ -143,8 +140,8 @@ static void __init fpu__init_system_generic(void)
|
||||
* because that's how C aligns structs.
|
||||
*/
|
||||
#define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
|
||||
BUILD_BUG_ON(sizeof(TYPE) != ALIGN(offsetofend(TYPE, MEMBER), \
|
||||
TYPE_ALIGN(TYPE)))
|
||||
BUILD_BUG_ON(sizeof(TYPE) != \
|
||||
ALIGN(offsetofend(TYPE, MEMBER), _Alignof(TYPE)))
|
||||
|
||||
/*
|
||||
* We append the 'struct fpu' to the task_struct:
|
||||
|
||||
@@ -167,7 +167,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
|
||||
}
|
||||
|
||||
fpu_force_restore(fpu);
|
||||
ret = copy_uabi_from_kernel_to_xstate(fpu->fpstate, kbuf ?: tmpbuf);
|
||||
ret = copy_uabi_from_kernel_to_xstate(fpu->fpstate, kbuf ?: tmpbuf, &target->thread.pkru);
|
||||
|
||||
out:
|
||||
vfree(tmpbuf);
|
||||
|
||||
@@ -396,7 +396,7 @@ static bool __fpu_restore_sig(void __user *buf, void __user *buf_fx,
|
||||
|
||||
fpregs = &fpu->fpstate->regs;
|
||||
if (use_xsave() && !fx_only) {
|
||||
if (copy_sigframe_from_user_to_xstate(fpu->fpstate, buf_fx))
|
||||
if (copy_sigframe_from_user_to_xstate(tsk, buf_fx))
|
||||
return false;
|
||||
} else {
|
||||
if (__copy_from_user(&fpregs->fxsave, buf_fx,
|
||||
|
||||
@@ -1200,8 +1200,36 @@ static int copy_from_buffer(void *dst, unsigned int offset, unsigned int size,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy_uabi_to_xstate - Copy a UABI format buffer to the kernel xstate
|
||||
* @fpstate: The fpstate buffer to copy to
|
||||
* @kbuf: The UABI format buffer, if it comes from the kernel
|
||||
* @ubuf: The UABI format buffer, if it comes from userspace
|
||||
* @pkru: The location to write the PKRU value to
|
||||
*
|
||||
* Converts from the UABI format into the kernel internal hardware
|
||||
* dependent format.
|
||||
*
|
||||
* This function ultimately has three different callers with distinct PKRU
|
||||
* behavior.
|
||||
* 1. When called from sigreturn the PKRU register will be restored from
|
||||
* @fpstate via an XRSTOR. Correctly copying the UABI format buffer to
|
||||
* @fpstate is sufficient to cover this case, but the caller will also
|
||||
* pass a pointer to the thread_struct's pkru field in @pkru and updating
|
||||
* it is harmless.
|
||||
* 2. When called from ptrace the PKRU register will be restored from the
|
||||
* thread_struct's pkru field. A pointer to that is passed in @pkru.
|
||||
* The kernel will restore it manually, so the XRSTOR behavior that resets
|
||||
* the PKRU register to the hardware init value (0) if the corresponding
|
||||
* xfeatures bit is not set is emulated here.
|
||||
* 3. When called from KVM the PKRU register will be restored from the vcpu's
|
||||
* pkru field. A pointer to that is passed in @pkru. KVM hasn't used
|
||||
* XRSTOR and hasn't had the PKRU resetting behavior described above. To
|
||||
* preserve that KVM behavior, it passes NULL for @pkru if the xfeatures
|
||||
* bit is not set.
|
||||
*/
|
||||
static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
|
||||
const void __user *ubuf)
|
||||
const void __user *ubuf, u32 *pkru)
|
||||
{
|
||||
struct xregs_state *xsave = &fpstate->regs.xsave;
|
||||
unsigned int offset, size;
|
||||
@@ -1250,6 +1278,20 @@ static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
|
||||
}
|
||||
}
|
||||
|
||||
if (hdr.xfeatures & XFEATURE_MASK_PKRU) {
|
||||
struct pkru_state *xpkru;
|
||||
|
||||
xpkru = __raw_xsave_addr(xsave, XFEATURE_PKRU);
|
||||
*pkru = xpkru->pkru;
|
||||
} else {
|
||||
/*
|
||||
* KVM may pass NULL here to indicate that it does not need
|
||||
* PKRU updated.
|
||||
*/
|
||||
if (pkru)
|
||||
*pkru = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The state that came in from userspace was user-state only.
|
||||
* Mask all the user states out of 'xfeatures':
|
||||
@@ -1268,9 +1310,9 @@ static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
|
||||
* Convert from a ptrace standard-format kernel buffer to kernel XSAVE[S]
|
||||
* format and copy to the target thread. Used by ptrace and KVM.
|
||||
*/
|
||||
int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf)
|
||||
int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf, u32 *pkru)
|
||||
{
|
||||
return copy_uabi_to_xstate(fpstate, kbuf, NULL);
|
||||
return copy_uabi_to_xstate(fpstate, kbuf, NULL, pkru);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1278,10 +1320,10 @@ int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf)
|
||||
* XSAVE[S] format and copy to the target thread. This is called from the
|
||||
* sigreturn() and rt_sigreturn() system calls.
|
||||
*/
|
||||
int copy_sigframe_from_user_to_xstate(struct fpstate *fpstate,
|
||||
int copy_sigframe_from_user_to_xstate(struct task_struct *tsk,
|
||||
const void __user *ubuf)
|
||||
{
|
||||
return copy_uabi_to_xstate(fpstate, NULL, ubuf);
|
||||
return copy_uabi_to_xstate(tsk->thread.fpu.fpstate, NULL, ubuf, &tsk->thread.pkru);
|
||||
}
|
||||
|
||||
static bool validate_independent_components(u64 mask)
|
||||
|
||||
@@ -46,8 +46,8 @@ extern void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
|
||||
u32 pkru_val, enum xstate_copy_mode copy_mode);
|
||||
extern void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,
|
||||
enum xstate_copy_mode mode);
|
||||
extern int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf);
|
||||
extern int copy_sigframe_from_user_to_xstate(struct fpstate *fpstate, const void __user *ubuf);
|
||||
extern int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf, u32 *pkru);
|
||||
extern int copy_sigframe_from_user_to_xstate(struct task_struct *tsk, const void __user *ubuf);
|
||||
|
||||
|
||||
extern void fpu__init_cpu_xstate(void);
|
||||
|
||||
@@ -759,15 +759,21 @@ struct kvm_cpuid_array {
|
||||
int nent;
|
||||
};
|
||||
|
||||
static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
|
||||
u32 function, u32 index)
|
||||
static struct kvm_cpuid_entry2 *get_next_cpuid(struct kvm_cpuid_array *array)
|
||||
{
|
||||
struct kvm_cpuid_entry2 *entry;
|
||||
|
||||
if (array->nent >= array->maxnent)
|
||||
return NULL;
|
||||
|
||||
entry = &array->entries[array->nent++];
|
||||
return &array->entries[array->nent++];
|
||||
}
|
||||
|
||||
static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
|
||||
u32 function, u32 index)
|
||||
{
|
||||
struct kvm_cpuid_entry2 *entry = get_next_cpuid(array);
|
||||
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
entry->function = function;
|
||||
@@ -945,22 +951,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
|
||||
entry->edx = edx.full;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Per Intel's SDM, the 0x1f is a superset of 0xb,
|
||||
* thus they can be handled by common code.
|
||||
*/
|
||||
case 0x1f:
|
||||
case 0xb:
|
||||
/*
|
||||
* Populate entries until the level type (ECX[15:8]) of the
|
||||
* previous entry is zero. Note, CPUID EAX.{0x1f,0xb}.0 is
|
||||
* the starting entry, filled by the primary do_host_cpuid().
|
||||
* No topology; a valid topology is indicated by the presence
|
||||
* of subleaf 1.
|
||||
*/
|
||||
for (i = 1; entry->ecx & 0xff00; ++i) {
|
||||
entry = do_host_cpuid(array, function, i);
|
||||
if (!entry)
|
||||
goto out;
|
||||
}
|
||||
entry->eax = entry->ebx = entry->ecx = 0;
|
||||
break;
|
||||
case 0xd: {
|
||||
u64 permitted_xcr0 = kvm_caps.supported_xcr0 & xstate_get_guest_group_perm();
|
||||
@@ -1193,6 +1190,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
|
||||
entry->ebx = entry->ecx = entry->edx = 0;
|
||||
break;
|
||||
case 0x8000001e:
|
||||
/* Do not return host topology information. */
|
||||
entry->eax = entry->ebx = entry->ecx = 0;
|
||||
entry->edx = 0; /* reserved */
|
||||
break;
|
||||
case 0x8000001F:
|
||||
if (!kvm_cpu_cap_has(X86_FEATURE_SEV)) {
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
*/
|
||||
SYM_FUNC_START(__iowrite32_copy)
|
||||
movl %edx,%ecx
|
||||
rep movsd
|
||||
rep movsl
|
||||
RET
|
||||
SYM_FUNC_END(__iowrite32_copy)
|
||||
|
||||
@@ -434,7 +434,8 @@ static unsigned long pat_x_mtrr_type(u64 start, u64 end,
|
||||
u8 mtrr_type, uniform;
|
||||
|
||||
mtrr_type = mtrr_type_lookup(start, end, &uniform);
|
||||
if (mtrr_type != MTRR_TYPE_WRBACK)
|
||||
if (mtrr_type != MTRR_TYPE_WRBACK &&
|
||||
mtrr_type != MTRR_TYPE_INVALID)
|
||||
return _PAGE_CACHE_MODE_UC_MINUS;
|
||||
|
||||
return _PAGE_CACHE_MODE_WB;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <asm/elf.h>
|
||||
|
||||
|
||||
Elf32_Half elf_core_extra_phdrs(void)
|
||||
Elf32_Half elf_core_extra_phdrs(struct coredump_params *cprm)
|
||||
{
|
||||
return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ int elf_core_write_extra_data(struct coredump_params *cprm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t elf_core_extra_data_size(void)
|
||||
size_t elf_core_extra_data_size(struct coredump_params *cprm)
|
||||
{
|
||||
if ( vsyscall_ehdr ) {
|
||||
const struct elfhdr *const ehdrp =
|
||||
|
||||
@@ -300,6 +300,16 @@ static struct bio *bio_split_rw(struct bio *bio, struct queue_limits *lim,
|
||||
*segs = nsegs;
|
||||
return NULL;
|
||||
split:
|
||||
/*
|
||||
* We can't sanely support splitting for a REQ_NOWAIT bio. End it
|
||||
* with EAGAIN if splitting is required and return an error pointer.
|
||||
*/
|
||||
if (bio->bi_opf & REQ_NOWAIT) {
|
||||
bio->bi_status = BLK_STS_AGAIN;
|
||||
bio_endio(bio);
|
||||
return ERR_PTR(-EAGAIN);
|
||||
}
|
||||
|
||||
*segs = nsegs;
|
||||
|
||||
/*
|
||||
@@ -348,11 +358,13 @@ struct bio *__bio_split_to_limits(struct bio *bio, struct queue_limits *lim,
|
||||
default:
|
||||
split = bio_split_rw(bio, lim, nr_segs, bs,
|
||||
get_max_io_size(bio, lim) << SECTOR_SHIFT);
|
||||
if (IS_ERR(split))
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (split) {
|
||||
/* there isn't chance to merge the splitted bio */
|
||||
/* there isn't chance to merge the split bio */
|
||||
split->bi_opf |= REQ_NOMERGE;
|
||||
|
||||
blkcg_bio_issue_init(split);
|
||||
|
||||
@@ -2919,8 +2919,11 @@ void blk_mq_submit_bio(struct bio *bio)
|
||||
blk_status_t ret;
|
||||
|
||||
bio = blk_queue_bounce(bio, q);
|
||||
if (bio_may_exceed_limits(bio, &q->limits))
|
||||
if (bio_may_exceed_limits(bio, &q->limits)) {
|
||||
bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
|
||||
if (!bio)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bio_integrity_prep(bio))
|
||||
return;
|
||||
|
||||
@@ -294,7 +294,7 @@ static inline int deadline_check_fifo(struct dd_per_prio *per_prio,
|
||||
/*
|
||||
* Check if rq has a sequential request preceding it.
|
||||
*/
|
||||
static bool deadline_is_seq_writes(struct deadline_data *dd, struct request *rq)
|
||||
static bool deadline_is_seq_write(struct deadline_data *dd, struct request *rq)
|
||||
{
|
||||
struct request *prev = deadline_earlier_request(rq);
|
||||
|
||||
@@ -353,7 +353,7 @@ deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
|
||||
list_for_each_entry(rq, &per_prio->fifo_list[DD_WRITE], queuelist) {
|
||||
if (blk_req_can_dispatch_to_zone(rq) &&
|
||||
(blk_queue_nonrot(rq->q) ||
|
||||
!deadline_is_seq_writes(dd, rq)))
|
||||
!deadline_is_seq_write(dd, rq)))
|
||||
goto out;
|
||||
}
|
||||
rq = NULL;
|
||||
|
||||
@@ -354,6 +354,9 @@ void spk_ttyio_release(struct spk_synth *in_synth)
|
||||
{
|
||||
struct tty_struct *tty = in_synth->dev;
|
||||
|
||||
if (tty == NULL)
|
||||
return;
|
||||
|
||||
tty_lock(tty);
|
||||
|
||||
if (tty->ops->close)
|
||||
|
||||
@@ -70,11 +70,7 @@ module_param(device_id_scheme, bool, 0444);
|
||||
static int only_lcd = -1;
|
||||
module_param(only_lcd, int, 0444);
|
||||
|
||||
/*
|
||||
* Display probing is known to take up to 5 seconds, so delay the fallback
|
||||
* backlight registration by 5 seconds + 3 seconds for some extra margin.
|
||||
*/
|
||||
static int register_backlight_delay = 8;
|
||||
static int register_backlight_delay;
|
||||
module_param(register_backlight_delay, int, 0444);
|
||||
MODULE_PARM_DESC(register_backlight_delay,
|
||||
"Delay in seconds before doing fallback (non GPU driver triggered) "
|
||||
@@ -2178,6 +2174,17 @@ static bool should_check_lcd_flag(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* At least one graphics driver has reported that no LCD is connected
|
||||
* via the native interface. cancel the registration for fallback acpi_video0.
|
||||
* If another driver still deems this necessary, it can explicitly register it.
|
||||
*/
|
||||
void acpi_video_report_nolcd(void)
|
||||
{
|
||||
cancel_delayed_work(&video_bus_register_backlight_work);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_report_nolcd);
|
||||
|
||||
int acpi_video_register(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -75,7 +75,8 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
|
||||
}
|
||||
|
||||
#define FIND_CHILD_MIN_SCORE 1
|
||||
#define FIND_CHILD_MAX_SCORE 2
|
||||
#define FIND_CHILD_MID_SCORE 2
|
||||
#define FIND_CHILD_MAX_SCORE 3
|
||||
|
||||
static int match_any(struct acpi_device *adev, void *not_used)
|
||||
{
|
||||
@@ -96,8 +97,17 @@ static int find_child_checks(struct acpi_device *adev, bool check_children)
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
|
||||
if (status == AE_NOT_FOUND)
|
||||
if (status == AE_NOT_FOUND) {
|
||||
/*
|
||||
* Special case: backlight device objects without _STA are
|
||||
* preferred to other objects with the same _ADR value, because
|
||||
* it is more likely that they are actually useful.
|
||||
*/
|
||||
if (adev->pnp.type.backlight)
|
||||
return FIND_CHILD_MID_SCORE;
|
||||
|
||||
return FIND_CHILD_MIN_SCORE;
|
||||
}
|
||||
|
||||
if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
|
||||
return -ENODEV;
|
||||
|
||||
@@ -236,6 +236,11 @@ static acpi_status acpi_platformrt_space_handler(u32 function,
|
||||
efi_status_t status;
|
||||
struct prm_context_buffer context;
|
||||
|
||||
if (!efi_enabled(EFI_RUNTIME_SERVICES)) {
|
||||
pr_err_ratelimited("PRM: EFI runtime services no longer available\n");
|
||||
return AE_NO_HANDLER;
|
||||
}
|
||||
|
||||
/*
|
||||
* The returned acpi_status will always be AE_OK. Error values will be
|
||||
* saved in the first byte of the PRM message buffer to be used by ASL.
|
||||
@@ -325,6 +330,11 @@ void __init init_prmt(void)
|
||||
|
||||
pr_info("PRM: found %u modules\n", mc);
|
||||
|
||||
if (!efi_enabled(EFI_RUNTIME_SERVICES)) {
|
||||
pr_err("PRM: EFI runtime services unavailable\n");
|
||||
return;
|
||||
}
|
||||
|
||||
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
|
||||
ACPI_ADR_SPACE_PLATFORM_RT,
|
||||
&acpi_platformrt_space_handler,
|
||||
|
||||
@@ -1370,9 +1370,12 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
|
||||
* Some devices don't reliably have _HIDs & _CIDs, so add
|
||||
* synthetic HIDs to make sure drivers can find them.
|
||||
*/
|
||||
if (acpi_is_video_device(handle))
|
||||
if (acpi_is_video_device(handle)) {
|
||||
acpi_add_id(pnp, ACPI_VIDEO_HID);
|
||||
else if (acpi_bay_match(handle))
|
||||
pnp->type.backlight = 1;
|
||||
break;
|
||||
}
|
||||
if (acpi_bay_match(handle))
|
||||
acpi_add_id(pnp, ACPI_BAY_HID);
|
||||
else if (acpi_dock_match(handle))
|
||||
acpi_add_id(pnp, ACPI_DOCK_HID);
|
||||
|
||||
@@ -50,6 +50,10 @@ static void acpi_video_parse_cmdline(void)
|
||||
acpi_backlight_cmdline = acpi_backlight_video;
|
||||
if (!strcmp("native", acpi_video_backlight_string))
|
||||
acpi_backlight_cmdline = acpi_backlight_native;
|
||||
if (!strcmp("nvidia_wmi_ec", acpi_video_backlight_string))
|
||||
acpi_backlight_cmdline = acpi_backlight_nvidia_wmi_ec;
|
||||
if (!strcmp("apple_gmux", acpi_video_backlight_string))
|
||||
acpi_backlight_cmdline = acpi_backlight_apple_gmux;
|
||||
if (!strcmp("none", acpi_video_backlight_string))
|
||||
acpi_backlight_cmdline = acpi_backlight_none;
|
||||
}
|
||||
|
||||
@@ -1607,6 +1607,8 @@ void drbd_submit_bio(struct bio *bio)
|
||||
struct drbd_device *device = bio->bi_bdev->bd_disk->private_data;
|
||||
|
||||
bio = bio_split_to_limits(bio);
|
||||
if (!bio)
|
||||
return;
|
||||
|
||||
/*
|
||||
* what we "blindly" assume:
|
||||
|
||||
@@ -2400,6 +2400,8 @@ static void pkt_submit_bio(struct bio *bio)
|
||||
struct bio *split;
|
||||
|
||||
bio = bio_split_to_limits(bio);
|
||||
if (!bio)
|
||||
return;
|
||||
|
||||
pkt_dbg(2, pd, "start = %6llx stop = %6llx\n",
|
||||
(unsigned long long)bio->bi_iter.bi_sector,
|
||||
|
||||
@@ -587,6 +587,8 @@ static void ps3vram_submit_bio(struct bio *bio)
|
||||
dev_dbg(&dev->core, "%s\n", __func__);
|
||||
|
||||
bio = bio_split_to_limits(bio);
|
||||
if (!bio)
|
||||
return;
|
||||
|
||||
spin_lock_irq(&priv->lock);
|
||||
busy = !bio_list_empty(&priv->list);
|
||||
|
||||
@@ -1992,6 +1992,9 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
|
||||
struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (issue_flags & IO_URING_F_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
ublk_ctrl_cmd_dump(cmd);
|
||||
|
||||
if (!(issue_flags & IO_URING_F_SQE128))
|
||||
|
||||
@@ -315,22 +315,35 @@ static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx)
|
||||
virtqueue_notify(vq->vq);
|
||||
}
|
||||
|
||||
static blk_status_t virtblk_fail_to_queue(struct request *req, int rc)
|
||||
{
|
||||
virtblk_cleanup_cmd(req);
|
||||
switch (rc) {
|
||||
case -ENOSPC:
|
||||
return BLK_STS_DEV_RESOURCE;
|
||||
case -ENOMEM:
|
||||
return BLK_STS_RESOURCE;
|
||||
default:
|
||||
return BLK_STS_IOERR;
|
||||
}
|
||||
}
|
||||
|
||||
static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
|
||||
struct virtio_blk *vblk,
|
||||
struct request *req,
|
||||
struct virtblk_req *vbr)
|
||||
{
|
||||
blk_status_t status;
|
||||
int num;
|
||||
|
||||
status = virtblk_setup_cmd(vblk->vdev, req, vbr);
|
||||
if (unlikely(status))
|
||||
return status;
|
||||
|
||||
vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr);
|
||||
if (unlikely(vbr->sg_table.nents < 0)) {
|
||||
virtblk_cleanup_cmd(req);
|
||||
return BLK_STS_RESOURCE;
|
||||
}
|
||||
num = virtblk_map_data(hctx, req, vbr);
|
||||
if (unlikely(num < 0))
|
||||
return virtblk_fail_to_queue(req, -ENOMEM);
|
||||
vbr->sg_table.nents = num;
|
||||
|
||||
blk_mq_start_request(req);
|
||||
|
||||
@@ -364,15 +377,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
blk_mq_stop_hw_queue(hctx);
|
||||
spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
|
||||
virtblk_unmap_data(req, vbr);
|
||||
virtblk_cleanup_cmd(req);
|
||||
switch (err) {
|
||||
case -ENOSPC:
|
||||
return BLK_STS_DEV_RESOURCE;
|
||||
case -ENOMEM:
|
||||
return BLK_STS_RESOURCE;
|
||||
default:
|
||||
return BLK_STS_IOERR;
|
||||
}
|
||||
return virtblk_fail_to_queue(req, err);
|
||||
}
|
||||
|
||||
if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq))
|
||||
|
||||
@@ -2157,10 +2157,17 @@ static void qca_serdev_shutdown(struct device *dev)
|
||||
int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
|
||||
struct serdev_device *serdev = to_serdev_device(dev);
|
||||
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
|
||||
struct hci_uart *hu = &qcadev->serdev_hu;
|
||||
struct hci_dev *hdev = hu->hdev;
|
||||
struct qca_data *qca = hu->priv;
|
||||
const u8 ibs_wake_cmd[] = { 0xFD };
|
||||
const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
|
||||
|
||||
if (qcadev->btsoc_type == QCA_QCA6390) {
|
||||
if (test_bit(QCA_BT_OFF, &qca->flags) ||
|
||||
!test_bit(HCI_RUNNING, &hdev->flags))
|
||||
return;
|
||||
|
||||
serdev_device_write_flush(serdev);
|
||||
ret = serdev_device_write_buf(serdev, ibs_wake_cmd,
|
||||
sizeof(ibs_wake_cmd));
|
||||
|
||||
@@ -412,7 +412,9 @@ int tpm_pm_suspend(struct device *dev)
|
||||
}
|
||||
|
||||
suspended:
|
||||
return rc;
|
||||
if (rc)
|
||||
dev_err(dev, "Ignoring error %d while suspending\n", rc);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_pm_suspend);
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
#define PCI1760_CMD_CLR_IMB2 0x00 /* Clears IMB2 */
|
||||
#define PCI1760_CMD_SET_DO 0x01 /* Set output state */
|
||||
#define PCI1760_CMD_GET_DO 0x02 /* Read output status */
|
||||
#define PCI1760_CMD_GET_STATUS 0x03 /* Read current status */
|
||||
#define PCI1760_CMD_GET_STATUS 0x07 /* Read current status */
|
||||
#define PCI1760_CMD_GET_FW_VER 0x0e /* Read firmware version */
|
||||
#define PCI1760_CMD_GET_HW_VER 0x0f /* Read hardware version */
|
||||
#define PCI1760_CMD_SET_PWM_HI(x) (0x10 + (x) * 2) /* Set "hi" period */
|
||||
|
||||
@@ -307,6 +307,7 @@ static void amd_pstate_adjust_perf(unsigned int cpu,
|
||||
max_perf = min_perf;
|
||||
|
||||
amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true);
|
||||
cpufreq_cpu_put(policy);
|
||||
}
|
||||
|
||||
static int amd_get_min_freq(struct amd_cpudata *cpudata)
|
||||
|
||||
@@ -239,7 +239,8 @@ static int virtio_crypto_alg_skcipher_close_session(
|
||||
pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n",
|
||||
ctrl_status->status, destroy_session->session_id);
|
||||
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
||||
@@ -168,14 +168,11 @@ void dma_buf_uninit_sysfs_statistics(void)
|
||||
kset_unregister(dma_buf_stats_kset);
|
||||
}
|
||||
|
||||
int dma_buf_stats_setup(struct dma_buf *dmabuf)
|
||||
int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file)
|
||||
{
|
||||
struct dma_buf_sysfs_entry *sysfs_entry;
|
||||
int ret;
|
||||
|
||||
if (!dmabuf || !dmabuf->file)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dmabuf->exp_name) {
|
||||
pr_err("exporter name must not be empty if stats needed\n");
|
||||
return -EINVAL;
|
||||
@@ -192,7 +189,7 @@ int dma_buf_stats_setup(struct dma_buf *dmabuf)
|
||||
|
||||
/* create the directory for buffer stats */
|
||||
ret = kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_ktype, NULL,
|
||||
"%lu", file_inode(dmabuf->file)->i_ino);
|
||||
"%lu", file_inode(file)->i_ino);
|
||||
if (ret)
|
||||
goto err_sysfs_dmabuf;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
int dma_buf_init_sysfs_statistics(void);
|
||||
void dma_buf_uninit_sysfs_statistics(void);
|
||||
|
||||
int dma_buf_stats_setup(struct dma_buf *dmabuf);
|
||||
int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file);
|
||||
|
||||
void dma_buf_stats_teardown(struct dma_buf *dmabuf);
|
||||
#else
|
||||
@@ -25,7 +25,7 @@ static inline int dma_buf_init_sysfs_statistics(void)
|
||||
|
||||
static inline void dma_buf_uninit_sysfs_statistics(void) {}
|
||||
|
||||
static inline int dma_buf_stats_setup(struct dma_buf *dmabuf)
|
||||
static inline int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,10 +95,11 @@ static int dma_buf_file_release(struct inode *inode, struct file *file)
|
||||
return -EINVAL;
|
||||
|
||||
dmabuf = file->private_data;
|
||||
|
||||
mutex_lock(&db_list.lock);
|
||||
list_del(&dmabuf->list_node);
|
||||
mutex_unlock(&db_list.lock);
|
||||
if (dmabuf) {
|
||||
mutex_lock(&db_list.lock);
|
||||
list_del(&dmabuf->list_node);
|
||||
mutex_unlock(&db_list.lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -523,17 +524,17 @@ static inline int is_dma_buf_file(struct file *file)
|
||||
return file->f_op == &dma_buf_fops;
|
||||
}
|
||||
|
||||
static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
|
||||
static struct file *dma_buf_getfile(size_t size, int flags)
|
||||
{
|
||||
static atomic64_t dmabuf_inode = ATOMIC64_INIT(0);
|
||||
struct file *file;
|
||||
struct inode *inode = alloc_anon_inode(dma_buf_mnt->mnt_sb);
|
||||
struct file *file;
|
||||
|
||||
if (IS_ERR(inode))
|
||||
return ERR_CAST(inode);
|
||||
|
||||
inode->i_size = dmabuf->size;
|
||||
inode_set_bytes(inode, dmabuf->size);
|
||||
inode->i_size = size;
|
||||
inode_set_bytes(inode, size);
|
||||
|
||||
/*
|
||||
* The ->i_ino acquired from get_next_ino() is not unique thus
|
||||
@@ -547,8 +548,6 @@ static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
|
||||
flags, &dma_buf_fops);
|
||||
if (IS_ERR(file))
|
||||
goto err_alloc_file;
|
||||
file->private_data = dmabuf;
|
||||
file->f_path.dentry->d_fsdata = dmabuf;
|
||||
|
||||
return file;
|
||||
|
||||
@@ -614,19 +613,11 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
size_t alloc_size = sizeof(struct dma_buf);
|
||||
int ret;
|
||||
|
||||
if (!exp_info->resv)
|
||||
alloc_size += sizeof(struct dma_resv);
|
||||
else
|
||||
/* prevent &dma_buf[1] == dma_buf->resv */
|
||||
alloc_size += 1;
|
||||
|
||||
if (WARN_ON(!exp_info->priv
|
||||
|| !exp_info->ops
|
||||
|| !exp_info->ops->map_dma_buf
|
||||
|| !exp_info->ops->unmap_dma_buf
|
||||
|| !exp_info->ops->release)) {
|
||||
if (WARN_ON(!exp_info->priv || !exp_info->ops
|
||||
|| !exp_info->ops->map_dma_buf
|
||||
|| !exp_info->ops->unmap_dma_buf
|
||||
|| !exp_info->ops->release))
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (WARN_ON(exp_info->ops->cache_sgt_mapping &&
|
||||
(exp_info->ops->pin || exp_info->ops->unpin)))
|
||||
@@ -638,10 +629,21 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
if (!try_module_get(exp_info->owner))
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
file = dma_buf_getfile(exp_info->size, exp_info->flags);
|
||||
if (IS_ERR(file)) {
|
||||
ret = PTR_ERR(file);
|
||||
goto err_module;
|
||||
}
|
||||
|
||||
if (!exp_info->resv)
|
||||
alloc_size += sizeof(struct dma_resv);
|
||||
else
|
||||
/* prevent &dma_buf[1] == dma_buf->resv */
|
||||
alloc_size += 1;
|
||||
dmabuf = kzalloc(alloc_size, GFP_KERNEL);
|
||||
if (!dmabuf) {
|
||||
ret = -ENOMEM;
|
||||
goto err_module;
|
||||
goto err_file;
|
||||
}
|
||||
|
||||
dmabuf->priv = exp_info->priv;
|
||||
@@ -653,44 +655,36 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
init_waitqueue_head(&dmabuf->poll);
|
||||
dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf->poll;
|
||||
dmabuf->cb_in.active = dmabuf->cb_out.active = 0;
|
||||
|
||||
if (!resv) {
|
||||
resv = (struct dma_resv *)&dmabuf[1];
|
||||
dma_resv_init(resv);
|
||||
}
|
||||
dmabuf->resv = resv;
|
||||
|
||||
file = dma_buf_getfile(dmabuf, exp_info->flags);
|
||||
if (IS_ERR(file)) {
|
||||
ret = PTR_ERR(file);
|
||||
goto err_dmabuf;
|
||||
}
|
||||
|
||||
dmabuf->file = file;
|
||||
|
||||
mutex_init(&dmabuf->lock);
|
||||
INIT_LIST_HEAD(&dmabuf->attachments);
|
||||
|
||||
if (!resv) {
|
||||
dmabuf->resv = (struct dma_resv *)&dmabuf[1];
|
||||
dma_resv_init(dmabuf->resv);
|
||||
} else {
|
||||
dmabuf->resv = resv;
|
||||
}
|
||||
|
||||
ret = dma_buf_stats_setup(dmabuf, file);
|
||||
if (ret)
|
||||
goto err_dmabuf;
|
||||
|
||||
file->private_data = dmabuf;
|
||||
file->f_path.dentry->d_fsdata = dmabuf;
|
||||
dmabuf->file = file;
|
||||
|
||||
mutex_lock(&db_list.lock);
|
||||
list_add(&dmabuf->list_node, &db_list.head);
|
||||
mutex_unlock(&db_list.lock);
|
||||
|
||||
ret = dma_buf_stats_setup(dmabuf);
|
||||
if (ret)
|
||||
goto err_sysfs;
|
||||
|
||||
return dmabuf;
|
||||
|
||||
err_sysfs:
|
||||
/*
|
||||
* Set file->f_path.dentry->d_fsdata to NULL so that when
|
||||
* dma_buf_release() gets invoked by dentry_ops, it exits
|
||||
* early before calling the release() dma_buf op.
|
||||
*/
|
||||
file->f_path.dentry->d_fsdata = NULL;
|
||||
fput(file);
|
||||
err_dmabuf:
|
||||
if (!resv)
|
||||
dma_resv_fini(dmabuf->resv);
|
||||
kfree(dmabuf);
|
||||
err_file:
|
||||
fput(file);
|
||||
err_module:
|
||||
module_put(exp_info->owner);
|
||||
return ERR_PTR(ret);
|
||||
|
||||
@@ -1018,6 +1018,11 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
|
||||
|
||||
/* The bad descriptor currently is in the head of vc list */
|
||||
vd = vchan_next_desc(&chan->vc);
|
||||
if (!vd) {
|
||||
dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n",
|
||||
axi_chan_name(chan));
|
||||
goto out;
|
||||
}
|
||||
/* Remove the completed descriptor from issued list */
|
||||
list_del(&vd->node);
|
||||
|
||||
@@ -1032,6 +1037,7 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
|
||||
/* Try to restart the controller */
|
||||
axi_chan_start_first_queued(chan);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&chan->vc.lock, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -1173,8 +1173,19 @@ static void idxd_flush_pending_descs(struct idxd_irq_entry *ie)
|
||||
spin_unlock(&ie->list_lock);
|
||||
|
||||
list_for_each_entry_safe(desc, itr, &flist, list) {
|
||||
struct dma_async_tx_descriptor *tx;
|
||||
|
||||
list_del(&desc->list);
|
||||
ctype = desc->completion->status ? IDXD_COMPLETE_NORMAL : IDXD_COMPLETE_ABORT;
|
||||
/*
|
||||
* wq is being disabled. Any remaining descriptors are
|
||||
* likely to be stuck and can be dropped. callback could
|
||||
* point to code that is no longer accessible, for example
|
||||
* if dmatest module has been unloaded.
|
||||
*/
|
||||
tx = &desc->txd;
|
||||
tx->callback = NULL;
|
||||
tx->callback_result = NULL;
|
||||
idxd_dma_complete_txd(desc, ctype, true);
|
||||
}
|
||||
}
|
||||
@@ -1391,8 +1402,7 @@ err_res_alloc:
|
||||
err_irq:
|
||||
idxd_wq_unmap_portal(wq);
|
||||
err_map_portal:
|
||||
rc = idxd_wq_disable(wq, false);
|
||||
if (rc < 0)
|
||||
if (idxd_wq_disable(wq, false))
|
||||
dev_dbg(dev, "wq %s disable failed\n", dev_name(wq_confdev(wq)));
|
||||
err:
|
||||
return rc;
|
||||
@@ -1409,11 +1419,11 @@ void drv_disable_wq(struct idxd_wq *wq)
|
||||
dev_warn(dev, "Clients has claim on wq %d: %d\n",
|
||||
wq->id, idxd_wq_refcount(wq));
|
||||
|
||||
idxd_wq_free_resources(wq);
|
||||
idxd_wq_unmap_portal(wq);
|
||||
idxd_wq_drain(wq);
|
||||
idxd_wq_free_irq(wq);
|
||||
idxd_wq_reset(wq);
|
||||
idxd_wq_free_resources(wq);
|
||||
percpu_ref_exit(&wq->wq_active);
|
||||
wq->type = IDXD_WQT_NONE;
|
||||
wq->client_count = 0;
|
||||
|
||||
@@ -914,7 +914,7 @@ static void ldma_dev_init(struct ldma_dev *d)
|
||||
}
|
||||
}
|
||||
|
||||
static int ldma_cfg_init(struct ldma_dev *d)
|
||||
static int ldma_parse_dt(struct ldma_dev *d)
|
||||
{
|
||||
struct fwnode_handle *fwnode = dev_fwnode(d->dev);
|
||||
struct ldma_port *p;
|
||||
@@ -1661,10 +1661,6 @@ static int intel_ldma_probe(struct platform_device *pdev)
|
||||
p->ldev = d;
|
||||
}
|
||||
|
||||
ret = ldma_cfg_init(d);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dma_dev->dev = &pdev->dev;
|
||||
|
||||
ch_mask = (unsigned long)d->channels_mask;
|
||||
@@ -1675,6 +1671,10 @@ static int intel_ldma_probe(struct platform_device *pdev)
|
||||
ldma_dma_init_v3X(j, d);
|
||||
}
|
||||
|
||||
ret = ldma_parse_dt(d);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dma_dev->device_alloc_chan_resources = ldma_alloc_chan_resources;
|
||||
dma_dev->device_free_chan_resources = ldma_free_chan_resources;
|
||||
dma_dev->device_terminate_all = ldma_terminate_all;
|
||||
|
||||
@@ -221,7 +221,7 @@ static int tegra_adma_init(struct tegra_adma *tdma)
|
||||
int ret;
|
||||
|
||||
/* Clear any interrupts */
|
||||
tdma_write(tdma, tdma->cdata->global_int_clear, 0x1);
|
||||
tdma_write(tdma, tdma->cdata->ch_base_offset + tdma->cdata->global_int_clear, 0x1);
|
||||
|
||||
/* Assert soft reset */
|
||||
tdma_write(tdma, ADMA_GLOBAL_SOFT_RESET, 0x1);
|
||||
|
||||
@@ -394,17 +394,16 @@ static void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev)
|
||||
* Then restart the workq on the new delay
|
||||
*/
|
||||
void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev,
|
||||
unsigned long value)
|
||||
unsigned long msec)
|
||||
{
|
||||
unsigned long jiffs = msecs_to_jiffies(value);
|
||||
edac_dev->poll_msec = msec;
|
||||
edac_dev->delay = msecs_to_jiffies(msec);
|
||||
|
||||
if (value == 1000)
|
||||
jiffs = round_jiffies_relative(value);
|
||||
|
||||
edac_dev->poll_msec = value;
|
||||
edac_dev->delay = jiffs;
|
||||
|
||||
edac_mod_work(&edac_dev->work, jiffs);
|
||||
/* See comment in edac_device_workq_setup() above */
|
||||
if (edac_dev->poll_msec == 1000)
|
||||
edac_mod_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
|
||||
else
|
||||
edac_mod_work(&edac_dev->work, edac_dev->delay);
|
||||
}
|
||||
|
||||
int edac_device_alloc_index(void)
|
||||
|
||||
@@ -52,7 +52,7 @@ bool edac_stop_work(struct delayed_work *work);
|
||||
bool edac_mod_work(struct delayed_work *work, unsigned long delay);
|
||||
|
||||
extern void edac_device_reset_delay_period(struct edac_device_ctl_info
|
||||
*edac_dev, unsigned long value);
|
||||
*edac_dev, unsigned long msec);
|
||||
extern void edac_mc_reset_delay_period(unsigned long value);
|
||||
|
||||
/*
|
||||
|
||||
@@ -374,8 +374,8 @@ static int __init efisubsys_init(void)
|
||||
efi_kobj = kobject_create_and_add("efi", firmware_kobj);
|
||||
if (!efi_kobj) {
|
||||
pr_err("efi: Firmware registration failed.\n");
|
||||
destroy_workqueue(efi_rts_wq);
|
||||
return -ENOMEM;
|
||||
error = -ENOMEM;
|
||||
goto err_destroy_wq;
|
||||
}
|
||||
|
||||
if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
|
||||
@@ -423,7 +423,10 @@ err_unregister:
|
||||
generic_ops_unregister();
|
||||
err_put:
|
||||
kobject_put(efi_kobj);
|
||||
destroy_workqueue(efi_rts_wq);
|
||||
err_destroy_wq:
|
||||
if (efi_rts_wq)
|
||||
destroy_workqueue(efi_rts_wq);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -611,7 +614,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
|
||||
|
||||
seed = early_memremap(efi_rng_seed, sizeof(*seed));
|
||||
if (seed != NULL) {
|
||||
size = min(seed->size, EFI_RANDOM_SEED_SIZE);
|
||||
size = min_t(u32, seed->size, SZ_1K); // sanity check
|
||||
early_memunmap(seed, sizeof(*seed));
|
||||
} else {
|
||||
pr_err("Could not map UEFI random seed!\n");
|
||||
@@ -620,8 +623,8 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
|
||||
seed = early_memremap(efi_rng_seed,
|
||||
sizeof(*seed) + size);
|
||||
if (seed != NULL) {
|
||||
pr_notice("seeding entropy pool\n");
|
||||
add_bootloader_randomness(seed->bits, size);
|
||||
memzero_explicit(seed->bits, size);
|
||||
early_memunmap(seed, sizeof(*seed) + size);
|
||||
} else {
|
||||
pr_err("Could not map UEFI random seed!\n");
|
||||
|
||||
@@ -882,6 +882,8 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);
|
||||
efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
|
||||
unsigned long *addr, unsigned long random_seed);
|
||||
|
||||
efi_status_t efi_random_get_seed(void);
|
||||
|
||||
efi_status_t check_platform_features(void);
|
||||
|
||||
void *get_efi_config_table(efi_guid_t guid);
|
||||
|
||||
@@ -67,27 +67,43 @@ efi_status_t efi_random_get_seed(void)
|
||||
efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
|
||||
efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
|
||||
efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
|
||||
struct linux_efi_random_seed *prev_seed, *seed = NULL;
|
||||
int prev_seed_size = 0, seed_size = EFI_RANDOM_SEED_SIZE;
|
||||
efi_rng_protocol_t *rng = NULL;
|
||||
struct linux_efi_random_seed *seed = NULL;
|
||||
efi_status_t status;
|
||||
|
||||
status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* Check whether a seed was provided by a prior boot stage. In that
|
||||
* case, instead of overwriting it, let's create a new buffer that can
|
||||
* hold both, and concatenate the existing and the new seeds.
|
||||
* Note that we should read the seed size with caution, in case the
|
||||
* table got corrupted in memory somehow.
|
||||
*/
|
||||
prev_seed = get_efi_config_table(LINUX_EFI_RANDOM_SEED_TABLE_GUID);
|
||||
if (prev_seed && prev_seed->size <= 512U) {
|
||||
prev_seed_size = prev_seed->size;
|
||||
seed_size += prev_seed_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the
|
||||
* allocation will survive a kexec reboot (although we refresh the seed
|
||||
* beforehand)
|
||||
*/
|
||||
status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
|
||||
sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
|
||||
struct_size(seed, bits, seed_size),
|
||||
(void **)&seed);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_warn("Failed to allocate memory for RNG seed.\n");
|
||||
goto err_warn;
|
||||
}
|
||||
|
||||
status = efi_call_proto(rng, get_rng, &rng_algo_raw,
|
||||
EFI_RANDOM_SEED_SIZE, seed->bits);
|
||||
EFI_RANDOM_SEED_SIZE, seed->bits);
|
||||
|
||||
if (status == EFI_UNSUPPORTED)
|
||||
/*
|
||||
@@ -100,14 +116,28 @@ efi_status_t efi_random_get_seed(void)
|
||||
if (status != EFI_SUCCESS)
|
||||
goto err_freepool;
|
||||
|
||||
seed->size = EFI_RANDOM_SEED_SIZE;
|
||||
seed->size = seed_size;
|
||||
if (prev_seed_size)
|
||||
memcpy(seed->bits + EFI_RANDOM_SEED_SIZE, prev_seed->bits,
|
||||
prev_seed_size);
|
||||
|
||||
status = efi_bs_call(install_configuration_table, &rng_table_guid, seed);
|
||||
if (status != EFI_SUCCESS)
|
||||
goto err_freepool;
|
||||
|
||||
if (prev_seed_size) {
|
||||
/* wipe and free the old seed if we managed to install the new one */
|
||||
memzero_explicit(prev_seed->bits, prev_seed_size);
|
||||
efi_bs_call(free_pool, prev_seed);
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
|
||||
err_freepool:
|
||||
memzero_explicit(seed, struct_size(seed, bits, seed_size));
|
||||
efi_bs_call(free_pool, seed);
|
||||
efi_warn("Failed to obtain seed from EFI_RNG_PROTOCOL\n");
|
||||
err_warn:
|
||||
if (prev_seed)
|
||||
efi_warn("Retaining bootloader-supplied seed only");
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ struct efi_runtime_work efi_rts_work;
|
||||
\
|
||||
if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \
|
||||
pr_warn_once("EFI Runtime Services are disabled!\n"); \
|
||||
efi_rts_work.status = EFI_DEVICE_ERROR; \
|
||||
goto exit; \
|
||||
} \
|
||||
\
|
||||
|
||||
@@ -361,9 +361,10 @@ static efi_status_t gsmi_get_variable(efi_char16_t *name,
|
||||
memcpy(data, gsmi_dev.data_buf->start, *data_size);
|
||||
|
||||
/* All variables are have the following attributes */
|
||||
*attr = EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
if (attr)
|
||||
*attr = EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&gsmi_dev.lock, flags);
|
||||
|
||||
@@ -440,6 +440,9 @@ static const struct file_operations psci_debugfs_ops = {
|
||||
|
||||
static int __init psci_debugfs_init(void)
|
||||
{
|
||||
if (!invoke_psci_fn || !psci_ops.get_version)
|
||||
return 0;
|
||||
|
||||
return PTR_ERR_OR_ZERO(debugfs_create_file("psci", 0444, NULL, NULL,
|
||||
&psci_debugfs_ops));
|
||||
}
|
||||
|
||||
@@ -473,6 +473,9 @@ static u8 pcal6534_recalc_addr(struct pca953x_chip *chip, int reg, int off)
|
||||
case PCAL6524_DEBOUNCE:
|
||||
pinctrl = ((reg & PCAL_PINCTRL_MASK) >> 1) + 0x1c;
|
||||
break;
|
||||
default:
|
||||
pinctrl = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return pinctrl + addr + (off / BANK_SZ);
|
||||
|
||||
@@ -215,6 +215,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
parent = irq_find_host(irq_parent);
|
||||
of_node_put(irq_parent);
|
||||
if (!parent) {
|
||||
dev_err(dev, "no IRQ parent domain\n");
|
||||
return -ENODEV;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user