mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf before 7.0-rc2
Cross-merge BPF and other fixes after downstream PR. No conflicts. Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
commit
309d8808ee
9
.mailmap
9
.mailmap
|
|
@ -210,7 +210,12 @@ Daniel Borkmann <daniel@iogearbox.net> <daniel.borkmann@tik.ee.ethz.ch>
|
|||
Daniel Borkmann <daniel@iogearbox.net> <dborkmann@redhat.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <dborkman@redhat.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <dxchgb@gmail.com>
|
||||
Daniel Lezcano <daniel.lezcano@kernel.org> <daniel.lezcano@linaro.org>
|
||||
Daniel Lezcano <daniel.lezcano@kernel.org> <daniel.lezcano@free.fr>
|
||||
Daniel Lezcano <daniel.lezcano@kernel.org> <daniel.lezcano@linexp.org>
|
||||
Daniel Lezcano <daniel.lezcano@kernel.org> <dlezcano@fr.ibm.com>
|
||||
Daniel Thompson <danielt@kernel.org> <daniel.thompson@linaro.org>
|
||||
Daniele Alessandrelli <daniele.alessandrelli@gmail.com> <daniele.alessandrelli@intel.com>
|
||||
Danilo Krummrich <dakr@kernel.org> <dakr@redhat.com>
|
||||
David Brownell <david-b@pacbell.net>
|
||||
David Collins <quic_collinsd@quicinc.com> <collinsd@codeaurora.org>
|
||||
|
|
@ -876,6 +881,7 @@ Vivien Didelot <vivien.didelot@gmail.com> <vivien.didelot@savoirfairelinux.com>
|
|||
Vlad Dogaru <ddvlad@gmail.com> <vlad.dogaru@intel.com>
|
||||
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com>
|
||||
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
|
||||
Vlastimil Babka <vbabka@kernel.org> <vbabka@suse.cz>
|
||||
WangYuli <wangyuli@aosc.io> <wangyl5933@chinaunicom.cn>
|
||||
WangYuli <wangyuli@aosc.io> <wangyuli@deepin.org>
|
||||
Weiwen Hu <huweiwen@linux.alibaba.com> <sehuww@mail.scut.edu.cn>
|
||||
|
|
@ -890,7 +896,8 @@ Yanteng Si <si.yanteng@linux.dev> <siyanteng@loongson.cn>
|
|||
Ying Huang <huang.ying.caritas@gmail.com> <ying.huang@intel.com>
|
||||
Yixun Lan <dlan@kernel.org> <dlan@gentoo.org>
|
||||
Yixun Lan <dlan@kernel.org> <yixun.lan@amlogic.com>
|
||||
Yosry Ahmed <yosry.ahmed@linux.dev> <yosryahmed@google.com>
|
||||
Yosry Ahmed <yosry@kernel.org> <yosryahmed@google.com>
|
||||
Yosry Ahmed <yosry@kernel.org> <yosry.ahmed@linux.dev>
|
||||
Yu-Chun Lin <eleanor.lin@realtek.com> <eleanor15x@gmail.com>
|
||||
Yusuke Goda <goda.yusuke@renesas.com>
|
||||
Zack Rusin <zack.rusin@broadcom.com> <zackr@vmware.com>
|
||||
|
|
|
|||
|
|
@ -594,6 +594,9 @@ Values:
|
|||
their sockets will only be able to connect within their own
|
||||
namespace.
|
||||
|
||||
The first write to ``child_ns_mode`` locks its value. Subsequent writes of the
|
||||
same value succeed, but writing a different value returns ``-EBUSY``.
|
||||
|
||||
Changing ``child_ns_mode`` only affects namespaces created after the change;
|
||||
it does not modify the current namespace or any existing children.
|
||||
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ examples:
|
|||
regulator-max-microvolt = <1700000>;
|
||||
};
|
||||
mt6359_vrfck_1_ldo_reg: ldo_vrfck_1 {
|
||||
regulator-name = "vrfck";
|
||||
regulator-name = "vrfck_1";
|
||||
regulator-min-microvolt = <1240000>;
|
||||
regulator-max-microvolt = <1600000>;
|
||||
};
|
||||
|
|
@ -309,7 +309,7 @@ examples:
|
|||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
mt6359_vemc_1_ldo_reg: ldo_vemc_1 {
|
||||
regulator-name = "vemc";
|
||||
regulator-name = "vemc_1";
|
||||
regulator-min-microvolt = <2500000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,21 +22,6 @@ allOf:
|
|||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- baikal,bt1-sys-ssi
|
||||
then:
|
||||
properties:
|
||||
mux-controls:
|
||||
maxItems: 1
|
||||
required:
|
||||
- mux-controls
|
||||
else:
|
||||
required:
|
||||
- interrupts
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -75,10 +60,6 @@ properties:
|
|||
const: intel,mountevans-imc-ssi
|
||||
- description: AMD Pensando Elba SoC SPI Controller
|
||||
const: amd,pensando-elba-spi
|
||||
- description: Baikal-T1 SPI Controller
|
||||
const: baikal,bt1-ssi
|
||||
- description: Baikal-T1 System Boot SPI Controller
|
||||
const: baikal,bt1-sys-ssi
|
||||
- description: Canaan Kendryte K210 SoS SPI Controller
|
||||
const: canaan,k210-spi
|
||||
- description: Renesas RZ/N1 SPI Controller
|
||||
|
|
@ -170,6 +151,7 @@ required:
|
|||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- clocks
|
||||
- interrupts
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
@ -190,15 +172,4 @@ examples:
|
|||
rx-sample-delay-ns = <7>;
|
||||
};
|
||||
};
|
||||
- |
|
||||
spi@1f040100 {
|
||||
compatible = "baikal,bt1-sys-ssi";
|
||||
reg = <0x1f040100 0x900>,
|
||||
<0x1c000000 0x1000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
mux-controls = <&boot_mux>;
|
||||
clocks = <&ccu_sys>;
|
||||
clock-names = "ssi_clk";
|
||||
};
|
||||
...
|
||||
|
|
|
|||
44
MAINTAINERS
44
MAINTAINERS
|
|
@ -1292,7 +1292,6 @@ F: include/trace/events/amdxdna.h
|
|||
F: include/uapi/drm/amdxdna_accel.h
|
||||
|
||||
AMD XGBE DRIVER
|
||||
M: "Shyam Sundar S K" <Shyam-sundar.S-k@amd.com>
|
||||
M: Raju Rangoju <Raju.Rangoju@amd.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -6219,14 +6218,13 @@ S: Supported
|
|||
F: drivers/scsi/snic/
|
||||
|
||||
CISCO VIC ETHERNET NIC DRIVER
|
||||
M: Christian Benvenuti <benve@cisco.com>
|
||||
M: Satish Kharat <satishkh@cisco.com>
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/cisco/enic/
|
||||
|
||||
CISCO VIC LOW LATENCY NIC DRIVER
|
||||
M: Christian Benvenuti <benve@cisco.com>
|
||||
M: Nelson Escobar <neescoba@cisco.com>
|
||||
M: Satish Kharat <satishkh@cisco.com>
|
||||
S: Supported
|
||||
F: drivers/infiniband/hw/usnic/
|
||||
|
||||
|
|
@ -6280,7 +6278,7 @@ S: Maintained
|
|||
F: include/linux/clk.h
|
||||
|
||||
CLOCKSOURCE, CLOCKEVENT DRIVERS
|
||||
M: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@kernel.org>
|
||||
M: Thomas Gleixner <tglx@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
@ -6669,7 +6667,7 @@ F: rust/kernel/cpu.rs
|
|||
|
||||
CPU IDLE TIME MANAGEMENT FRAMEWORK
|
||||
M: "Rafael J. Wysocki" <rafael@kernel.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@kernel.org>
|
||||
R: Christian Loehle <christian.loehle@arm.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -6699,7 +6697,7 @@ F: arch/x86/kernel/msr.c
|
|||
|
||||
CPUIDLE DRIVER - ARM BIG LITTLE
|
||||
M: Lorenzo Pieralisi <lpieralisi@kernel.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
|
|
@ -6707,7 +6705,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
|
|||
F: drivers/cpuidle/cpuidle-big_little.c
|
||||
|
||||
CPUIDLE DRIVER - ARM EXYNOS
|
||||
M: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@kernel.org>
|
||||
M: Kukjin Kim <kgene@kernel.org>
|
||||
R: Krzysztof Kozlowski <krzk@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
|
|
@ -14412,9 +14410,9 @@ LANTIQ PEF2256 DRIVER
|
|||
M: Herve Codina <herve.codina@bootlin.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/lantiq,pef2256.yaml
|
||||
F: drivers/net/wan/framer/pef2256/
|
||||
F: drivers/net/wan/framer/
|
||||
F: drivers/pinctrl/pinctrl-pef2256.c
|
||||
F: include/linux/framer/pef2256.h
|
||||
F: include/linux/framer/
|
||||
|
||||
LASI 53c700 driver for PARISC
|
||||
M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
|
||||
|
|
@ -16656,7 +16654,7 @@ M: Andrew Morton <akpm@linux-foundation.org>
|
|||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Mike Rapoport <rppt@kernel.org>
|
||||
R: Suren Baghdasaryan <surenb@google.com>
|
||||
R: Michal Hocko <mhocko@suse.com>
|
||||
|
|
@ -16786,7 +16784,7 @@ M: Andrew Morton <akpm@linux-foundation.org>
|
|||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Mike Rapoport <rppt@kernel.org>
|
||||
R: Suren Baghdasaryan <surenb@google.com>
|
||||
R: Michal Hocko <mhocko@suse.com>
|
||||
|
|
@ -16841,7 +16839,7 @@ F: mm/oom_kill.c
|
|||
|
||||
MEMORY MANAGEMENT - PAGE ALLOCATOR
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Vlastimil Babka <vbabka@suse.cz>
|
||||
M: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Suren Baghdasaryan <surenb@google.com>
|
||||
R: Michal Hocko <mhocko@suse.com>
|
||||
R: Brendan Jackman <jackmanb@google.com>
|
||||
|
|
@ -16887,7 +16885,7 @@ M: David Hildenbrand <david@kernel.org>
|
|||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Rik van Riel <riel@surriel.com>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Harry Yoo <harry.yoo@oracle.com>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
L: linux-mm@kvack.org
|
||||
|
|
@ -16986,7 +16984,7 @@ MEMORY MAPPING
|
|||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
R: Pedro Falcato <pfalcato@suse.de>
|
||||
L: linux-mm@kvack.org
|
||||
|
|
@ -17016,7 +17014,7 @@ M: Andrew Morton <akpm@linux-foundation.org>
|
|||
M: Suren Baghdasaryan <surenb@google.com>
|
||||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Shakeel Butt <shakeel.butt@linux.dev>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
|
|
@ -17032,7 +17030,7 @@ M: Andrew Morton <akpm@linux-foundation.org>
|
|||
M: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
M: David Hildenbrand <david@kernel.org>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Jann Horn <jannh@google.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
|
|
@ -20509,7 +20507,7 @@ F: Documentation/devicetree/bindings/pci/hisilicon,kirin-pcie.yaml
|
|||
F: drivers/pci/controller/dwc/pcie-kirin.c
|
||||
|
||||
PCIE DRIVER FOR HISILICON STB
|
||||
M: Shawn Guo <shawn.guo@linaro.org>
|
||||
M: Shawn Guo <shawnguo@kernel.org>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/hisilicon-histb-pcie.txt
|
||||
|
|
@ -21695,7 +21693,7 @@ S: Maintained
|
|||
F: drivers/net/ethernet/qualcomm/emac/
|
||||
|
||||
QUALCOMM ETHQOS ETHERNET DRIVER
|
||||
M: Vinod Koul <vkoul@kernel.org>
|
||||
M: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -23174,7 +23172,7 @@ K: \b(?i:rust)\b
|
|||
RUST [ALLOC]
|
||||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
|
||||
R: Vlastimil Babka <vbabka@suse.cz>
|
||||
R: Vlastimil Babka <vbabka@kernel.org>
|
||||
R: Liam R. Howlett <Liam.Howlett@oracle.com>
|
||||
R: Uladzislau Rezki <urezki@gmail.com>
|
||||
L: rust-for-linux@vger.kernel.org
|
||||
|
|
@ -24350,7 +24348,7 @@ F: Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml
|
|||
F: drivers/nvmem/layouts/sl28vpd.c
|
||||
|
||||
SLAB ALLOCATOR
|
||||
M: Vlastimil Babka <vbabka@suse.cz>
|
||||
M: Vlastimil Babka <vbabka@kernel.org>
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
R: Christoph Lameter <cl@gentwo.org>
|
||||
R: David Rientjes <rientjes@google.com>
|
||||
|
|
@ -26217,7 +26215,7 @@ F: drivers/media/radio/radio-raremono.c
|
|||
|
||||
THERMAL
|
||||
M: Rafael J. Wysocki <rafael@kernel.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@kernel.org>
|
||||
R: Zhang Rui <rui.zhang@intel.com>
|
||||
R: Lukasz Luba <lukasz.luba@arm.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
|
|
@ -26247,7 +26245,7 @@ F: drivers/thermal/amlogic_thermal.c
|
|||
|
||||
THERMAL/CPU_COOLING
|
||||
M: Amit Daniel Kachhap <amit.kachhap@gmail.com>
|
||||
M: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
M: Daniel Lezcano <daniel.lezcano@kernel.org>
|
||||
M: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
R: Lukasz Luba <lukasz.luba@arm.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
|
|
@ -29186,7 +29184,7 @@ K: zstd
|
|||
|
||||
ZSWAP COMPRESSED SWAP CACHING
|
||||
M: Johannes Weiner <hannes@cmpxchg.org>
|
||||
M: Yosry Ahmed <yosry.ahmed@linux.dev>
|
||||
M: Yosry Ahmed <yosry@kernel.org>
|
||||
M: Nhat Pham <nphamcs@gmail.com>
|
||||
R: Chengming Zhou <chengming.zhou@linux.dev>
|
||||
L: linux-mm@kvack.org
|
||||
|
|
|
|||
|
|
@ -264,19 +264,33 @@ __iowrite64_copy(void __iomem *to, const void *from, size_t count)
|
|||
typedef int (*ioremap_prot_hook_t)(phys_addr_t phys_addr, size_t size,
|
||||
pgprot_t *prot);
|
||||
int arm64_ioremap_prot_hook_register(const ioremap_prot_hook_t hook);
|
||||
void __iomem *__ioremap_prot(phys_addr_t phys, size_t size, pgprot_t prot);
|
||||
|
||||
static inline void __iomem *ioremap_prot(phys_addr_t phys, size_t size,
|
||||
pgprot_t user_prot)
|
||||
{
|
||||
pgprot_t prot;
|
||||
ptdesc_t user_prot_val = pgprot_val(user_prot);
|
||||
|
||||
if (WARN_ON_ONCE(!(user_prot_val & PTE_USER)))
|
||||
return NULL;
|
||||
|
||||
prot = __pgprot_modify(PAGE_KERNEL, PTE_ATTRINDX_MASK,
|
||||
user_prot_val & PTE_ATTRINDX_MASK);
|
||||
return __ioremap_prot(phys, size, prot);
|
||||
}
|
||||
#define ioremap_prot ioremap_prot
|
||||
|
||||
#define _PAGE_IOREMAP PROT_DEVICE_nGnRE
|
||||
|
||||
#define ioremap(addr, size) \
|
||||
__ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
|
||||
#define ioremap_wc(addr, size) \
|
||||
ioremap_prot((addr), (size), __pgprot(PROT_NORMAL_NC))
|
||||
__ioremap_prot((addr), (size), __pgprot(PROT_NORMAL_NC))
|
||||
#define ioremap_np(addr, size) \
|
||||
ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRnE))
|
||||
__ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRnE))
|
||||
|
||||
|
||||
#define ioremap_encrypted(addr, size) \
|
||||
ioremap_prot((addr), (size), PAGE_KERNEL)
|
||||
__ioremap_prot((addr), (size), PAGE_KERNEL)
|
||||
|
||||
/*
|
||||
* io{read,write}{16,32,64}be() macros
|
||||
|
|
@ -297,7 +311,7 @@ static inline void __iomem *ioremap_cache(phys_addr_t addr, size_t size)
|
|||
if (pfn_is_map_memory(__phys_to_pfn(addr)))
|
||||
return (void __iomem *)__phys_to_virt(addr);
|
||||
|
||||
return ioremap_prot(addr, size, __pgprot(PROT_NORMAL));
|
||||
return __ioremap_prot(addr, size, __pgprot(PROT_NORMAL));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -164,9 +164,6 @@ static inline bool __pure lpa2_is_enabled(void)
|
|||
#define _PAGE_GCS (_PAGE_DEFAULT | PTE_NG | PTE_UXN | PTE_WRITE | PTE_USER)
|
||||
#define _PAGE_GCS_RO (_PAGE_DEFAULT | PTE_NG | PTE_UXN | PTE_USER)
|
||||
|
||||
#define PAGE_GCS __pgprot(_PAGE_GCS)
|
||||
#define PAGE_GCS_RO __pgprot(_PAGE_GCS_RO)
|
||||
|
||||
#define PIE_E0 ( \
|
||||
PIRx_ELx_PERM_PREP(pte_pi_index(_PAGE_GCS), PIE_GCS) | \
|
||||
PIRx_ELx_PERM_PREP(pte_pi_index(_PAGE_GCS_RO), PIE_R) | \
|
||||
|
|
|
|||
|
|
@ -31,19 +31,11 @@
|
|||
*/
|
||||
#define __TLBI_0(op, arg) asm (ARM64_ASM_PREAMBLE \
|
||||
"tlbi " #op "\n" \
|
||||
ALTERNATIVE("nop\n nop", \
|
||||
"dsb ish\n tlbi " #op, \
|
||||
ARM64_WORKAROUND_REPEAT_TLBI, \
|
||||
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \
|
||||
: : )
|
||||
|
||||
#define __TLBI_1(op, arg) asm (ARM64_ASM_PREAMBLE \
|
||||
"tlbi " #op ", %0\n" \
|
||||
ALTERNATIVE("nop\n nop", \
|
||||
"dsb ish\n tlbi " #op ", %0", \
|
||||
ARM64_WORKAROUND_REPEAT_TLBI, \
|
||||
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \
|
||||
: : "r" (arg))
|
||||
"tlbi " #op ", %x0\n" \
|
||||
: : "rZ" (arg))
|
||||
|
||||
#define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)
|
||||
|
||||
|
|
@ -181,6 +173,34 @@ static inline unsigned long get_trans_granule(void)
|
|||
(__pages >> (5 * (scale) + 1)) - 1; \
|
||||
})
|
||||
|
||||
#define __repeat_tlbi_sync(op, arg...) \
|
||||
do { \
|
||||
if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI)) \
|
||||
break; \
|
||||
__tlbi(op, ##arg); \
|
||||
dsb(ish); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Complete broadcast TLB maintenance issued by the host which invalidates
|
||||
* stage 1 information in the host's own translation regime.
|
||||
*/
|
||||
static inline void __tlbi_sync_s1ish(void)
|
||||
{
|
||||
dsb(ish);
|
||||
__repeat_tlbi_sync(vale1is, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Complete broadcast TLB maintenance issued by hyp code which invalidates
|
||||
* stage 1 translation information in any translation regime.
|
||||
*/
|
||||
static inline void __tlbi_sync_s1ish_hyp(void)
|
||||
{
|
||||
dsb(ish);
|
||||
__repeat_tlbi_sync(vale2is, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TLB Invalidation
|
||||
* ================
|
||||
|
|
@ -279,7 +299,7 @@ static inline void flush_tlb_all(void)
|
|||
{
|
||||
dsb(ishst);
|
||||
__tlbi(vmalle1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish();
|
||||
isb();
|
||||
}
|
||||
|
||||
|
|
@ -291,7 +311,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
|
|||
asid = __TLBI_VADDR(0, ASID(mm));
|
||||
__tlbi(aside1is, asid);
|
||||
__tlbi_user(aside1is, asid);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish();
|
||||
mmu_notifier_arch_invalidate_secondary_tlbs(mm, 0, -1UL);
|
||||
}
|
||||
|
||||
|
|
@ -345,20 +365,11 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
|
|||
unsigned long uaddr)
|
||||
{
|
||||
flush_tlb_page_nosync(vma, uaddr);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish();
|
||||
}
|
||||
|
||||
static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
|
||||
{
|
||||
/*
|
||||
* TLB flush deferral is not required on systems which are affected by
|
||||
* ARM64_WORKAROUND_REPEAT_TLBI, as __tlbi()/__tlbi_user() implementation
|
||||
* will have two consecutive TLBI instructions with a dsb(ish) in between
|
||||
* defeating the purpose (i.e save overall 'dsb ish' cost).
|
||||
*/
|
||||
if (alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +385,7 @@ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
|
|||
*/
|
||||
static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
|
||||
{
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -509,7 +520,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
|
|||
{
|
||||
__flush_tlb_range_nosync(vma->vm_mm, start, end, stride,
|
||||
last_level, tlb_level);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish();
|
||||
}
|
||||
|
||||
static inline void local_flush_tlb_contpte(struct vm_area_struct *vma,
|
||||
|
|
@ -557,7 +568,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
|
|||
dsb(ishst);
|
||||
__flush_tlb_range_op(vaale1is, start, pages, stride, 0,
|
||||
TLBI_TTL_UNKNOWN, false, lpa2_is_enabled());
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish();
|
||||
isb();
|
||||
}
|
||||
|
||||
|
|
@ -571,7 +582,7 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
|
|||
|
||||
dsb(ishst);
|
||||
__tlbi(vaae1is, addr);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish();
|
||||
isb();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
|
|||
prot = __acpi_get_writethrough_mem_attribute();
|
||||
}
|
||||
}
|
||||
return ioremap_prot(phys, size, prot);
|
||||
return __ioremap_prot(phys, size, prot);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ __do_compat_cache_op(unsigned long start, unsigned long end)
|
|||
* We pick the reserved-ASID to minimise the impact.
|
||||
*/
|
||||
__tlbi(aside1is, __TLBI_VADDR(0, 0));
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish();
|
||||
}
|
||||
|
||||
ret = caches_clean_inval_user_pou(start, start + chunk);
|
||||
|
|
|
|||
|
|
@ -400,16 +400,25 @@ static inline
|
|||
int counters_read_on_cpu(int cpu, smp_call_func_t func, u64 *val)
|
||||
{
|
||||
/*
|
||||
* Abort call on counterless CPU or when interrupts are
|
||||
* disabled - can lead to deadlock in smp sync call.
|
||||
* Abort call on counterless CPU.
|
||||
*/
|
||||
if (!cpu_has_amu_feat(cpu))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (WARN_ON_ONCE(irqs_disabled()))
|
||||
return -EPERM;
|
||||
|
||||
smp_call_function_single(cpu, func, val, 1);
|
||||
if (irqs_disabled()) {
|
||||
/*
|
||||
* When IRQs are disabled (tick path: sched_tick ->
|
||||
* topology_scale_freq_tick or cppc_scale_freq_tick), only local
|
||||
* CPU counter reads are allowed. Remote CPU counter read would
|
||||
* require smp_call_function_single() which is unsafe with IRQs
|
||||
* disabled.
|
||||
*/
|
||||
if (WARN_ON_ONCE(cpu != smp_processor_id()))
|
||||
return -EPERM;
|
||||
func(val);
|
||||
} else {
|
||||
smp_call_function_single(cpu, func, val, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ static void fixmap_clear_slot(struct hyp_fixmap_slot *slot)
|
|||
*/
|
||||
dsb(ishst);
|
||||
__tlbi_level(vale2is, __TLBI_VADDR(addr, 0), level);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
|
|||
*/
|
||||
dsb(ish);
|
||||
__tlbi(vmalle1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
|
||||
exit_vmid_context(&cxt);
|
||||
|
|
@ -226,7 +226,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
|
|||
|
||||
dsb(ish);
|
||||
__tlbi(vmalle1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
|
||||
exit_vmid_context(&cxt);
|
||||
|
|
@ -240,7 +240,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
|
|||
enter_vmid_context(mmu, &cxt, false);
|
||||
|
||||
__tlbi(vmalls12e1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
|
||||
exit_vmid_context(&cxt);
|
||||
|
|
@ -266,5 +266,5 @@ void __kvm_flush_vm_context(void)
|
|||
/* Same remark as in enter_vmid_context() */
|
||||
dsb(ish);
|
||||
__tlbi(alle1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ static int hyp_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,
|
|||
*unmapped += granule;
|
||||
}
|
||||
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
mm_ops->put_page(ctx->ptep);
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
|
|||
*/
|
||||
dsb(ish);
|
||||
__tlbi(vmalle1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
|
||||
exit_vmid_context(&cxt);
|
||||
|
|
@ -176,7 +176,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
|
|||
|
||||
dsb(ish);
|
||||
__tlbi(vmalle1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
|
||||
exit_vmid_context(&cxt);
|
||||
|
|
@ -192,7 +192,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
|
|||
enter_vmid_context(mmu, &cxt);
|
||||
|
||||
__tlbi(vmalls12e1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
|
||||
exit_vmid_context(&cxt);
|
||||
|
|
@ -217,7 +217,7 @@ void __kvm_flush_vm_context(void)
|
|||
{
|
||||
dsb(ishst);
|
||||
__tlbi(alle1is);
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -358,7 +358,7 @@ int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding)
|
|||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
dsb(ish);
|
||||
__tlbi_sync_s1ish_hyp();
|
||||
isb();
|
||||
|
||||
if (mmu)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,11 @@ static inline unsigned long xloops_to_cycles(unsigned long xloops)
|
|||
* Note that userspace cannot change the offset behind our back either,
|
||||
* as the vcpu mutex is held as long as KVM_RUN is in progress.
|
||||
*/
|
||||
#define __delay_cycles() __arch_counter_get_cntvct_stable()
|
||||
static cycles_t notrace __delay_cycles(void)
|
||||
{
|
||||
guard(preempt_notrace)();
|
||||
return __arch_counter_get_cntvct_stable();
|
||||
}
|
||||
|
||||
void __delay(unsigned long cycles)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ int arm64_ioremap_prot_hook_register(ioremap_prot_hook_t hook)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
|
||||
pgprot_t pgprot)
|
||||
void __iomem *__ioremap_prot(phys_addr_t phys_addr, size_t size,
|
||||
pgprot_t pgprot)
|
||||
{
|
||||
unsigned long last_addr = phys_addr + size - 1;
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
|
|||
|
||||
return generic_ioremap_prot(phys_addr, size, pgprot);
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap_prot);
|
||||
EXPORT_SYMBOL(__ioremap_prot);
|
||||
|
||||
/*
|
||||
* Must be called after early_fixmap_init
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ static pgprot_t protection_map[16] __ro_after_init = {
|
|||
[VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_SHARED_EXEC
|
||||
};
|
||||
|
||||
static ptdesc_t gcs_page_prot __ro_after_init = _PAGE_GCS_RO;
|
||||
|
||||
/*
|
||||
* You really shouldn't be using read() or write() on /dev/mem. This might go
|
||||
* away in the future.
|
||||
|
|
@ -73,9 +75,11 @@ static int __init adjust_protection_map(void)
|
|||
protection_map[VM_EXEC | VM_SHARED] = PAGE_EXECONLY;
|
||||
}
|
||||
|
||||
if (lpa2_is_enabled())
|
||||
if (lpa2_is_enabled()) {
|
||||
for (int i = 0; i < ARRAY_SIZE(protection_map); i++)
|
||||
pgprot_val(protection_map[i]) &= ~PTE_SHARED;
|
||||
gcs_page_prot &= ~PTE_SHARED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -87,7 +91,11 @@ pgprot_t vm_get_page_prot(vm_flags_t vm_flags)
|
|||
|
||||
/* Short circuit GCS to avoid bloating the table. */
|
||||
if (system_supports_gcs() && (vm_flags & VM_SHADOW_STACK)) {
|
||||
prot = _PAGE_GCS_RO;
|
||||
/* Honour mprotect(PROT_NONE) on shadow stack mappings */
|
||||
if (vm_flags & VM_ACCESS_FLAGS)
|
||||
prot = gcs_page_prot;
|
||||
else
|
||||
prot = pgprot_val(protection_map[VM_NONE]);
|
||||
} else {
|
||||
prot = pgprot_val(protection_map[vm_flags &
|
||||
(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]);
|
||||
|
|
|
|||
|
|
@ -2119,7 +2119,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
|||
extable_offset = round_up(prog_size + PLT_TARGET_SIZE, extable_align);
|
||||
image_size = extable_offset + extable_size;
|
||||
ro_header = bpf_jit_binary_pack_alloc(image_size, &ro_image_ptr,
|
||||
sizeof(u32), &header, &image_ptr,
|
||||
sizeof(u64), &header, &image_ptr,
|
||||
jit_fill_hole);
|
||||
if (!ro_header) {
|
||||
prog = orig_prog;
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ struct s390_idle_data {
|
|||
unsigned long mt_cycles_enter[8];
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
|
||||
|
||||
extern struct device_attribute dev_attr_idle_count;
|
||||
extern struct device_attribute dev_attr_idle_time_us;
|
||||
|
||||
void psw_idle(struct s390_idle_data *data, unsigned long psw_mask);
|
||||
|
||||
#endif /* _S390_IDLE_H */
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
#ifndef _S390_VTIME_H
|
||||
#define _S390_VTIME_H
|
||||
|
||||
#include <asm/lowcore.h>
|
||||
#include <asm/cpu_mf.h>
|
||||
#include <asm/idle.h>
|
||||
|
||||
DECLARE_PER_CPU(u64, mt_cycles[8]);
|
||||
|
||||
static inline void update_timer_sys(void)
|
||||
{
|
||||
struct lowcore *lc = get_lowcore();
|
||||
|
|
@ -20,4 +26,32 @@ static inline void update_timer_mcck(void)
|
|||
lc->last_update_timer = lc->mcck_enter_timer;
|
||||
}
|
||||
|
||||
static inline void update_timer_idle(void)
|
||||
{
|
||||
struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
|
||||
struct lowcore *lc = get_lowcore();
|
||||
u64 cycles_new[8];
|
||||
int i, mtid;
|
||||
|
||||
mtid = smp_cpu_mtid;
|
||||
if (mtid) {
|
||||
stcctm(MT_DIAG, mtid, cycles_new);
|
||||
for (i = 0; i < mtid; i++)
|
||||
__this_cpu_add(mt_cycles[i], cycles_new[i] - idle->mt_cycles_enter[i]);
|
||||
}
|
||||
/*
|
||||
* This is a bit subtle: Forward last_update_clock so it excludes idle
|
||||
* time. For correct steal time calculation in do_account_vtime() add
|
||||
* passed wall time before idle_enter to steal_timer:
|
||||
* During the passed wall time before idle_enter CPU time may have
|
||||
* been accounted to system, hardirq, softirq, etc. lowcore fields.
|
||||
* The accounted CPU times will be subtracted again from steal_timer
|
||||
* when accumulated steal time is calculated in do_account_vtime().
|
||||
*/
|
||||
lc->steal_timer += idle->clock_idle_enter - lc->last_update_clock;
|
||||
lc->last_update_clock = lc->int_clock;
|
||||
lc->system_timer += lc->last_update_timer - idle->timer_idle_enter;
|
||||
lc->last_update_timer = lc->sys_enter_timer;
|
||||
}
|
||||
|
||||
#endif /* _S390_VTIME_H */
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ long sys_s390_pci_mmio_write(unsigned long, const void __user *, size_t);
|
|||
long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t);
|
||||
long sys_s390_sthyi(unsigned long function_code, void __user *buffer, u64 __user *return_code, unsigned long flags);
|
||||
|
||||
DECLARE_PER_CPU(u64, mt_cycles[8]);
|
||||
|
||||
unsigned long stack_alloc(void);
|
||||
void stack_free(unsigned long stack);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,37 +15,22 @@
|
|||
#include <trace/events/power.h>
|
||||
#include <asm/cpu_mf.h>
|
||||
#include <asm/cputime.h>
|
||||
#include <asm/idle.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/smp.h>
|
||||
#include "entry.h"
|
||||
|
||||
static DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
|
||||
DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
|
||||
|
||||
void account_idle_time_irq(void)
|
||||
{
|
||||
struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
|
||||
struct lowcore *lc = get_lowcore();
|
||||
unsigned long idle_time;
|
||||
u64 cycles_new[8];
|
||||
int i;
|
||||
|
||||
if (smp_cpu_mtid) {
|
||||
stcctm(MT_DIAG, smp_cpu_mtid, cycles_new);
|
||||
for (i = 0; i < smp_cpu_mtid; i++)
|
||||
this_cpu_add(mt_cycles[i], cycles_new[i] - idle->mt_cycles_enter[i]);
|
||||
}
|
||||
|
||||
idle_time = lc->int_clock - idle->clock_idle_enter;
|
||||
|
||||
lc->steal_timer += idle->clock_idle_enter - lc->last_update_clock;
|
||||
lc->last_update_clock = lc->int_clock;
|
||||
|
||||
lc->system_timer += lc->last_update_timer - idle->timer_idle_enter;
|
||||
lc->last_update_timer = lc->sys_enter_timer;
|
||||
idle_time = get_lowcore()->int_clock - idle->clock_idle_enter;
|
||||
|
||||
/* Account time spent with enabled wait psw loaded as idle time. */
|
||||
WRITE_ONCE(idle->idle_time, READ_ONCE(idle->idle_time) + idle_time);
|
||||
WRITE_ONCE(idle->idle_count, READ_ONCE(idle->idle_count) + 1);
|
||||
__atomic64_add(idle_time, &idle->idle_time);
|
||||
__atomic64_add_const(1, &idle->idle_count);
|
||||
account_idle_time(cputime_to_nsecs(idle_time));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2377,7 +2377,7 @@ void __init setup_ipl(void)
|
|||
atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
|
||||
}
|
||||
|
||||
void s390_reset_system(void)
|
||||
void __no_stack_protector s390_reset_system(void)
|
||||
{
|
||||
/* Disable prefixing */
|
||||
set_prefix(0);
|
||||
|
|
|
|||
|
|
@ -146,6 +146,12 @@ void noinstr do_io_irq(struct pt_regs *regs)
|
|||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
bool from_idle;
|
||||
|
||||
from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
|
||||
if (from_idle) {
|
||||
update_timer_idle();
|
||||
regs->psw.mask &= ~(PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_WAIT);
|
||||
}
|
||||
|
||||
irq_enter_rcu();
|
||||
|
||||
if (user_mode(regs)) {
|
||||
|
|
@ -154,7 +160,6 @@ void noinstr do_io_irq(struct pt_regs *regs)
|
|||
current->thread.last_break = regs->last_break;
|
||||
}
|
||||
|
||||
from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
|
||||
if (from_idle)
|
||||
account_idle_time_irq();
|
||||
|
||||
|
|
@ -171,9 +176,6 @@ void noinstr do_io_irq(struct pt_regs *regs)
|
|||
|
||||
set_irq_regs(old_regs);
|
||||
irqentry_exit(regs, state);
|
||||
|
||||
if (from_idle)
|
||||
regs->psw.mask &= ~(PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_WAIT);
|
||||
}
|
||||
|
||||
void noinstr do_ext_irq(struct pt_regs *regs)
|
||||
|
|
@ -182,6 +184,12 @@ void noinstr do_ext_irq(struct pt_regs *regs)
|
|||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
bool from_idle;
|
||||
|
||||
from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
|
||||
if (from_idle) {
|
||||
update_timer_idle();
|
||||
regs->psw.mask &= ~(PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_WAIT);
|
||||
}
|
||||
|
||||
irq_enter_rcu();
|
||||
|
||||
if (user_mode(regs)) {
|
||||
|
|
@ -194,7 +202,6 @@ void noinstr do_ext_irq(struct pt_regs *regs)
|
|||
regs->int_parm = get_lowcore()->ext_params;
|
||||
regs->int_parm_long = get_lowcore()->ext_params2;
|
||||
|
||||
from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
|
||||
if (from_idle)
|
||||
account_idle_time_irq();
|
||||
|
||||
|
|
@ -203,9 +210,6 @@ void noinstr do_ext_irq(struct pt_regs *regs)
|
|||
irq_exit_rcu();
|
||||
set_irq_regs(old_regs);
|
||||
irqentry_exit(regs, state);
|
||||
|
||||
if (from_idle)
|
||||
regs->psw.mask &= ~(PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_WAIT);
|
||||
}
|
||||
|
||||
static void show_msi_interrupt(struct seq_file *p, int irq)
|
||||
|
|
|
|||
|
|
@ -48,8 +48,7 @@ static inline void set_vtimer(u64 expires)
|
|||
|
||||
static inline int virt_timer_forward(u64 elapsed)
|
||||
{
|
||||
BUG_ON(!irqs_disabled());
|
||||
|
||||
lockdep_assert_irqs_disabled();
|
||||
if (list_empty(&virt_timer_list))
|
||||
return 0;
|
||||
elapsed = atomic64_add_return(elapsed, &virt_timer_elapsed);
|
||||
|
|
@ -137,23 +136,16 @@ static int do_account_vtime(struct task_struct *tsk)
|
|||
lc->system_timer += timer;
|
||||
|
||||
/* Update MT utilization calculation */
|
||||
if (smp_cpu_mtid &&
|
||||
time_after64(jiffies_64, this_cpu_read(mt_scaling_jiffies)))
|
||||
if (smp_cpu_mtid && time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies)))
|
||||
update_mt_scaling();
|
||||
|
||||
/* Calculate cputime delta */
|
||||
user = update_tsk_timer(&tsk->thread.user_timer,
|
||||
READ_ONCE(lc->user_timer));
|
||||
guest = update_tsk_timer(&tsk->thread.guest_timer,
|
||||
READ_ONCE(lc->guest_timer));
|
||||
system = update_tsk_timer(&tsk->thread.system_timer,
|
||||
READ_ONCE(lc->system_timer));
|
||||
hardirq = update_tsk_timer(&tsk->thread.hardirq_timer,
|
||||
READ_ONCE(lc->hardirq_timer));
|
||||
softirq = update_tsk_timer(&tsk->thread.softirq_timer,
|
||||
READ_ONCE(lc->softirq_timer));
|
||||
lc->steal_timer +=
|
||||
clock - user - guest - system - hardirq - softirq;
|
||||
user = update_tsk_timer(&tsk->thread.user_timer, lc->user_timer);
|
||||
guest = update_tsk_timer(&tsk->thread.guest_timer, lc->guest_timer);
|
||||
system = update_tsk_timer(&tsk->thread.system_timer, lc->system_timer);
|
||||
hardirq = update_tsk_timer(&tsk->thread.hardirq_timer, lc->hardirq_timer);
|
||||
softirq = update_tsk_timer(&tsk->thread.softirq_timer, lc->softirq_timer);
|
||||
lc->steal_timer += clock - user - guest - system - hardirq - softirq;
|
||||
|
||||
/* Push account value */
|
||||
if (user) {
|
||||
|
|
@ -225,10 +217,6 @@ static u64 vtime_delta(void)
|
|||
return timer - lc->last_update_timer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update process times based on virtual cpu times stored by entry.S
|
||||
* to the lowcore fields user_timer, system_timer & steal_clock.
|
||||
*/
|
||||
void vtime_account_kernel(struct task_struct *tsk)
|
||||
{
|
||||
struct lowcore *lc = get_lowcore();
|
||||
|
|
@ -238,27 +226,17 @@ void vtime_account_kernel(struct task_struct *tsk)
|
|||
lc->guest_timer += delta;
|
||||
else
|
||||
lc->system_timer += delta;
|
||||
|
||||
virt_timer_forward(delta);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vtime_account_kernel);
|
||||
|
||||
void vtime_account_softirq(struct task_struct *tsk)
|
||||
{
|
||||
u64 delta = vtime_delta();
|
||||
|
||||
get_lowcore()->softirq_timer += delta;
|
||||
|
||||
virt_timer_forward(delta);
|
||||
get_lowcore()->softirq_timer += vtime_delta();
|
||||
}
|
||||
|
||||
void vtime_account_hardirq(struct task_struct *tsk)
|
||||
{
|
||||
u64 delta = vtime_delta();
|
||||
|
||||
get_lowcore()->hardirq_timer += delta;
|
||||
|
||||
virt_timer_forward(delta);
|
||||
get_lowcore()->hardirq_timer += vtime_delta();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ int __pfault_init(void)
|
|||
"0: nopr %%r7\n"
|
||||
EX_TABLE(0b, 0b)
|
||||
: [rc] "+d" (rc)
|
||||
: [refbk] "a" (&pfault_init_refbk), "m" (pfault_init_refbk)
|
||||
: [refbk] "a" (virt_to_phys(&pfault_init_refbk)), "m" (pfault_init_refbk)
|
||||
: "cc");
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ void __pfault_fini(void)
|
|||
"0: nopr %%r7\n"
|
||||
EX_TABLE(0b, 0b)
|
||||
:
|
||||
: [refbk] "a" (&pfault_fini_refbk), "m" (pfault_fini_refbk)
|
||||
: [refbk] "a" (virt_to_phys(&pfault_fini_refbk)), "m" (pfault_fini_refbk)
|
||||
: "cc");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -312,6 +312,8 @@ static dma_addr_t dma_4u_map_phys(struct device *dev, phys_addr_t phys,
|
|||
if (direction != DMA_TO_DEVICE)
|
||||
iopte_protection |= IOPTE_WRITE;
|
||||
|
||||
phys &= IO_PAGE_MASK;
|
||||
|
||||
for (i = 0; i < npages; i++, base++, phys += IO_PAGE_SIZE)
|
||||
iopte_val(*base) = iopte_protection | phys;
|
||||
|
||||
|
|
|
|||
|
|
@ -410,6 +410,8 @@ static dma_addr_t dma_4v_map_phys(struct device *dev, phys_addr_t phys,
|
|||
|
||||
iommu_batch_start(dev, prot, entry);
|
||||
|
||||
phys &= IO_PAGE_MASK;
|
||||
|
||||
for (i = 0; i < npages; i++, phys += IO_PAGE_SIZE) {
|
||||
long err = iommu_batch_add(phys, mask);
|
||||
if (unlikely(err < 0L))
|
||||
|
|
|
|||
|
|
@ -69,11 +69,11 @@ struct io_thread_req {
|
|||
};
|
||||
|
||||
|
||||
static struct io_thread_req * (*irq_req_buffer)[];
|
||||
static struct io_thread_req **irq_req_buffer;
|
||||
static struct io_thread_req *irq_remainder;
|
||||
static int irq_remainder_size;
|
||||
|
||||
static struct io_thread_req * (*io_req_buffer)[];
|
||||
static struct io_thread_req **io_req_buffer;
|
||||
static struct io_thread_req *io_remainder;
|
||||
static int io_remainder_size;
|
||||
|
||||
|
|
@ -398,7 +398,7 @@ static int thread_fd = -1;
|
|||
|
||||
static int bulk_req_safe_read(
|
||||
int fd,
|
||||
struct io_thread_req * (*request_buffer)[],
|
||||
struct io_thread_req **request_buffer,
|
||||
struct io_thread_req **remainder,
|
||||
int *remainder_size,
|
||||
int max_recs
|
||||
|
|
@ -465,7 +465,7 @@ static irqreturn_t ubd_intr(int irq, void *dev)
|
|||
&irq_remainder, &irq_remainder_size,
|
||||
UBD_REQ_BUFFER_SIZE)) >= 0) {
|
||||
for (i = 0; i < len / sizeof(struct io_thread_req *); i++)
|
||||
ubd_end_request((*irq_req_buffer)[i]);
|
||||
ubd_end_request(irq_req_buffer[i]);
|
||||
}
|
||||
|
||||
if (len < 0 && len != -EAGAIN)
|
||||
|
|
@ -1512,7 +1512,7 @@ void *io_thread(void *arg)
|
|||
}
|
||||
|
||||
for (count = 0; count < n/sizeof(struct io_thread_req *); count++) {
|
||||
struct io_thread_req *req = (*io_req_buffer)[count];
|
||||
struct io_thread_req *req = io_req_buffer[count];
|
||||
int i;
|
||||
|
||||
io_count++;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@
|
|||
#include "amdxdna_pci_drv.h"
|
||||
#include "amdxdna_pm.h"
|
||||
|
||||
static bool force_cmdlist;
|
||||
static bool force_cmdlist = true;
|
||||
module_param(force_cmdlist, bool, 0600);
|
||||
MODULE_PARM_DESC(force_cmdlist, "Force use command list (Default false)");
|
||||
MODULE_PARM_DESC(force_cmdlist, "Force use command list (Default true)");
|
||||
|
||||
#define HWCTX_MAX_TIMEOUT 60000 /* milliseconds */
|
||||
|
||||
|
|
@ -53,6 +53,7 @@ static void aie2_hwctx_stop(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hwct
|
|||
{
|
||||
drm_sched_stop(&hwctx->priv->sched, bad_job);
|
||||
aie2_destroy_context(xdna->dev_handle, hwctx);
|
||||
drm_sched_start(&hwctx->priv->sched, 0);
|
||||
}
|
||||
|
||||
static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hwctx)
|
||||
|
|
@ -80,7 +81,6 @@ static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hw
|
|||
}
|
||||
|
||||
out:
|
||||
drm_sched_start(&hwctx->priv->sched, 0);
|
||||
XDNA_DBG(xdna, "%s restarted, ret %d", hwctx->name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -297,19 +297,23 @@ aie2_sched_job_run(struct drm_sched_job *sched_job)
|
|||
struct dma_fence *fence;
|
||||
int ret;
|
||||
|
||||
if (!hwctx->priv->mbox_chann)
|
||||
ret = amdxdna_pm_resume_get(hwctx->client->xdna);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
if (!mmget_not_zero(job->mm))
|
||||
if (!hwctx->priv->mbox_chann) {
|
||||
amdxdna_pm_suspend_put(hwctx->client->xdna);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!mmget_not_zero(job->mm)) {
|
||||
amdxdna_pm_suspend_put(hwctx->client->xdna);
|
||||
return ERR_PTR(-ESRCH);
|
||||
}
|
||||
|
||||
kref_get(&job->refcnt);
|
||||
fence = dma_fence_get(job->fence);
|
||||
|
||||
ret = amdxdna_pm_resume_get(hwctx->client->xdna);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (job->drv_cmd) {
|
||||
switch (job->drv_cmd->opcode) {
|
||||
case SYNC_DEBUG_BO:
|
||||
|
|
@ -497,7 +501,7 @@ static void aie2_release_resource(struct amdxdna_hwctx *hwctx)
|
|||
|
||||
if (AIE2_FEATURE_ON(xdna->dev_handle, AIE2_TEMPORAL_ONLY)) {
|
||||
ret = aie2_destroy_context(xdna->dev_handle, hwctx);
|
||||
if (ret)
|
||||
if (ret && ret != -ENODEV)
|
||||
XDNA_ERR(xdna, "Destroy temporal only context failed, ret %d", ret);
|
||||
} else {
|
||||
ret = xrs_release_resource(xdna->xrs_hdl, (uintptr_t)hwctx);
|
||||
|
|
@ -629,7 +633,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
|
|||
goto free_entity;
|
||||
}
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto free_col_list;
|
||||
|
||||
|
|
@ -760,7 +764,7 @@ static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size
|
|||
if (!hwctx->cus)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto free_cus;
|
||||
|
||||
|
|
@ -1070,6 +1074,8 @@ void aie2_hmm_invalidate(struct amdxdna_gem_obj *abo,
|
|||
|
||||
ret = dma_resv_wait_timeout(gobj->resv, DMA_RESV_USAGE_BOOKKEEP,
|
||||
true, MAX_SCHEDULE_TIMEOUT);
|
||||
if (!ret || ret == -ERESTARTSYS)
|
||||
if (!ret)
|
||||
XDNA_ERR(xdna, "Failed to wait for bo, ret %ld", ret);
|
||||
else if (ret == -ERESTARTSYS)
|
||||
XDNA_DBG(xdna, "Wait for bo interrupted by signal");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,8 +216,10 @@ static int aie2_destroy_context_req(struct amdxdna_dev_hdl *ndev, u32 id)
|
|||
|
||||
req.context_id = id;
|
||||
ret = aie2_send_mgmt_msg_wait(ndev, &msg);
|
||||
if (ret)
|
||||
if (ret && ret != -ENODEV)
|
||||
XDNA_WARN(xdna, "Destroy context failed, ret %d", ret);
|
||||
else if (ret == -ENODEV)
|
||||
XDNA_DBG(xdna, "Destroy context: device already stopped");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -318,6 +320,9 @@ int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwc
|
|||
struct amdxdna_dev *xdna = ndev->xdna;
|
||||
int ret;
|
||||
|
||||
if (!hwctx->priv->mbox_chann)
|
||||
return 0;
|
||||
|
||||
xdna_mailbox_stop_channel(hwctx->priv->mbox_chann);
|
||||
ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
|
||||
xdna_mailbox_destroy_channel(hwctx->priv->mbox_chann);
|
||||
|
|
@ -694,11 +699,11 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz
|
|||
u32 cmd_len;
|
||||
void *cmd;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
if (*size < sizeof(*npu_slot) + cmd_len)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
|
@ -719,7 +724,6 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
|||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*sn);
|
||||
if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
|
|
@ -728,6 +732,7 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
|||
if (*size < sizeof(*npu_slot) + arg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
|
@ -751,7 +756,6 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t
|
|||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*pd);
|
||||
if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
|
|
@ -760,6 +764,7 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t
|
|||
if (*size < sizeof(*npu_slot) + arg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
|
||||
if (npu_slot->cu_idx == INVALID_CU_IDX)
|
||||
return -EINVAL;
|
||||
|
|
@ -787,7 +792,6 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
|||
u32 cmd_len;
|
||||
u32 arg_sz;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
|
||||
arg_sz = cmd_len - sizeof(*pd);
|
||||
if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
|
||||
|
|
@ -796,6 +800,7 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
|
|||
if (*size < sizeof(*npu_slot) + arg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
memset(npu_slot, 0, sizeof(*npu_slot));
|
||||
npu_slot->type = EXEC_NPU_TYPE_ELF;
|
||||
npu_slot->inst_buf_addr = pd->inst_buf;
|
||||
npu_slot->save_buf_addr = pd->save_buf;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ static int aie2_max_col = XRS_MAX_COL;
|
|||
module_param(aie2_max_col, uint, 0600);
|
||||
MODULE_PARM_DESC(aie2_max_col, "Maximum column could be used");
|
||||
|
||||
static char *npu_fw[] = {
|
||||
"npu_7.sbin",
|
||||
"npu.sbin"
|
||||
};
|
||||
|
||||
/*
|
||||
* The management mailbox channel is allocated by firmware.
|
||||
* The related register and ring buffer information is on SRAM BAR.
|
||||
|
|
@ -323,6 +328,7 @@ static void aie2_hw_stop(struct amdxdna_dev *xdna)
|
|||
return;
|
||||
}
|
||||
|
||||
aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, NULL);
|
||||
aie2_mgmt_fw_fini(ndev);
|
||||
xdna_mailbox_stop_channel(ndev->mgmt_chann);
|
||||
xdna_mailbox_destroy_channel(ndev->mgmt_chann);
|
||||
|
|
@ -406,18 +412,18 @@ static int aie2_hw_start(struct amdxdna_dev *xdna)
|
|||
goto stop_psp;
|
||||
}
|
||||
|
||||
ret = aie2_pm_init(ndev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "failed to init pm, ret %d", ret);
|
||||
goto destroy_mgmt_chann;
|
||||
}
|
||||
|
||||
ret = aie2_mgmt_fw_init(ndev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "initial mgmt firmware failed, ret %d", ret);
|
||||
goto destroy_mgmt_chann;
|
||||
}
|
||||
|
||||
ret = aie2_pm_init(ndev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "failed to init pm, ret %d", ret);
|
||||
goto destroy_mgmt_chann;
|
||||
}
|
||||
|
||||
ret = aie2_mgmt_fw_query(ndev);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "failed to query fw, ret %d", ret);
|
||||
|
|
@ -451,7 +457,6 @@ static int aie2_hw_suspend(struct amdxdna_dev *xdna)
|
|||
{
|
||||
struct amdxdna_client *client;
|
||||
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
list_for_each_entry(client, &xdna->client_list, node)
|
||||
aie2_hwctx_suspend(client);
|
||||
|
||||
|
|
@ -489,6 +494,7 @@ static int aie2_init(struct amdxdna_dev *xdna)
|
|||
struct psp_config psp_conf;
|
||||
const struct firmware *fw;
|
||||
unsigned long bars = 0;
|
||||
char *fw_full_path;
|
||||
int i, nvec, ret;
|
||||
|
||||
if (!hypervisor_is_type(X86_HYPER_NATIVE)) {
|
||||
|
|
@ -503,7 +509,19 @@ static int aie2_init(struct amdxdna_dev *xdna)
|
|||
ndev->priv = xdna->dev_info->dev_priv;
|
||||
ndev->xdna = xdna;
|
||||
|
||||
ret = request_firmware(&fw, ndev->priv->fw_path, &pdev->dev);
|
||||
for (i = 0; i < ARRAY_SIZE(npu_fw); i++) {
|
||||
fw_full_path = kasprintf(GFP_KERNEL, "%s%s", ndev->priv->fw_path, npu_fw[i]);
|
||||
if (!fw_full_path)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = firmware_request_nowarn(&fw, fw_full_path, &pdev->dev);
|
||||
kfree(fw_full_path);
|
||||
if (!ret) {
|
||||
XDNA_INFO(xdna, "Load firmware %s%s", ndev->priv->fw_path, npu_fw[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "failed to request_firmware %s, ret %d",
|
||||
ndev->priv->fw_path, ret);
|
||||
|
|
@ -951,7 +969,7 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i
|
|||
if (!drm_dev_enter(&xdna->ddev, &idx))
|
||||
return -ENODEV;
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto dev_exit;
|
||||
|
||||
|
|
@ -1044,7 +1062,7 @@ static int aie2_get_array(struct amdxdna_client *client,
|
|||
if (!drm_dev_enter(&xdna->ddev, &idx))
|
||||
return -ENODEV;
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto dev_exit;
|
||||
|
||||
|
|
@ -1134,7 +1152,7 @@ static int aie2_set_state(struct amdxdna_client *client,
|
|||
if (!drm_dev_enter(&xdna->ddev, &idx))
|
||||
return -ENODEV;
|
||||
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(xdna);
|
||||
if (ret)
|
||||
goto dev_exit;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = amdxdna_pm_resume_get(ndev->xdna);
|
||||
ret = amdxdna_pm_resume_get_locked(ndev->xdna);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,10 @@ void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size)
|
|||
|
||||
if (size) {
|
||||
count = FIELD_GET(AMDXDNA_CMD_COUNT, cmd->header);
|
||||
if (unlikely(count <= num_masks)) {
|
||||
if (unlikely(count <= num_masks ||
|
||||
count * sizeof(u32) +
|
||||
offsetof(struct amdxdna_cmd, data[0]) >
|
||||
abo->mem.size)) {
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -266,9 +269,9 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr
|
|||
struct amdxdna_drm_config_hwctx *args = data;
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(dev);
|
||||
struct amdxdna_hwctx *hwctx;
|
||||
int ret, idx;
|
||||
u32 buf_size;
|
||||
void *buf;
|
||||
int ret;
|
||||
u64 val;
|
||||
|
||||
if (XDNA_MBZ_DBG(xdna, &args->pad, sizeof(args->pad)))
|
||||
|
|
@ -310,20 +313,17 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&xdna->dev_lock);
|
||||
idx = srcu_read_lock(&client->hwctx_srcu);
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
hwctx = xa_load(&client->hwctx_xa, args->handle);
|
||||
if (!hwctx) {
|
||||
XDNA_DBG(xdna, "PID %d failed to get hwctx %d", client->pid, args->handle);
|
||||
ret = -EINVAL;
|
||||
goto unlock_srcu;
|
||||
goto free_buf;
|
||||
}
|
||||
|
||||
ret = xdna->dev_info->ops->hwctx_config(hwctx, args->param_type, val, buf, buf_size);
|
||||
|
||||
unlock_srcu:
|
||||
srcu_read_unlock(&client->hwctx_srcu, idx);
|
||||
mutex_unlock(&xdna->dev_lock);
|
||||
free_buf:
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -334,7 +334,7 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl)
|
|||
struct amdxdna_hwctx *hwctx;
|
||||
struct amdxdna_gem_obj *abo;
|
||||
struct drm_gem_object *gobj;
|
||||
int ret, idx;
|
||||
int ret;
|
||||
|
||||
if (!xdna->dev_info->ops->hwctx_sync_debug_bo)
|
||||
return -EOPNOTSUPP;
|
||||
|
|
@ -345,17 +345,15 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl)
|
|||
|
||||
abo = to_xdna_obj(gobj);
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
idx = srcu_read_lock(&client->hwctx_srcu);
|
||||
hwctx = xa_load(&client->hwctx_xa, abo->assigned_hwctx);
|
||||
if (!hwctx) {
|
||||
ret = -EINVAL;
|
||||
goto unlock_srcu;
|
||||
goto put_obj;
|
||||
}
|
||||
|
||||
ret = xdna->dev_info->ops->hwctx_sync_debug_bo(hwctx, debug_bo_hdl);
|
||||
|
||||
unlock_srcu:
|
||||
srcu_read_unlock(&client->hwctx_srcu, idx);
|
||||
put_obj:
|
||||
drm_gem_object_put(gobj);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@
|
|||
#include "amdxdna_pci_drv.h"
|
||||
#include "amdxdna_ubuf.h"
|
||||
|
||||
#define XDNA_MAX_CMD_BO_SIZE SZ_32K
|
||||
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
|
||||
static int
|
||||
|
|
@ -745,12 +743,6 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev,
|
|||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(dev);
|
||||
struct amdxdna_gem_obj *abo;
|
||||
int ret;
|
||||
|
||||
if (args->size > XDNA_MAX_CMD_BO_SIZE) {
|
||||
XDNA_ERR(xdna, "Command bo size 0x%llx too large", args->size);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (args->size < sizeof(struct amdxdna_cmd)) {
|
||||
XDNA_DBG(xdna, "Command BO size 0x%llx too small", args->size);
|
||||
|
|
@ -764,17 +756,7 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev,
|
|||
abo->type = AMDXDNA_BO_CMD;
|
||||
abo->client = filp->driver_priv;
|
||||
|
||||
ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret);
|
||||
goto release_obj;
|
||||
}
|
||||
|
||||
return abo;
|
||||
|
||||
release_obj:
|
||||
drm_gem_object_put(to_gobj(abo));
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
int amdxdna_drm_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
|
|
@ -871,6 +853,7 @@ struct amdxdna_gem_obj *amdxdna_gem_get_obj(struct amdxdna_client *client,
|
|||
struct amdxdna_dev *xdna = client->xdna;
|
||||
struct amdxdna_gem_obj *abo;
|
||||
struct drm_gem_object *gobj;
|
||||
int ret;
|
||||
|
||||
gobj = drm_gem_object_lookup(client->filp, bo_hdl);
|
||||
if (!gobj) {
|
||||
|
|
@ -879,9 +862,26 @@ struct amdxdna_gem_obj *amdxdna_gem_get_obj(struct amdxdna_client *client,
|
|||
}
|
||||
|
||||
abo = to_xdna_obj(gobj);
|
||||
if (bo_type == AMDXDNA_BO_INVALID || abo->type == bo_type)
|
||||
if (bo_type != AMDXDNA_BO_INVALID && abo->type != bo_type)
|
||||
goto put_obj;
|
||||
|
||||
if (bo_type != AMDXDNA_BO_CMD || abo->mem.kva)
|
||||
return abo;
|
||||
|
||||
if (abo->mem.size > SZ_32K) {
|
||||
XDNA_ERR(xdna, "Cmd bo is too big %ld", abo->mem.size);
|
||||
goto put_obj;
|
||||
}
|
||||
|
||||
ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret);
|
||||
goto put_obj;
|
||||
}
|
||||
|
||||
return abo;
|
||||
|
||||
put_obj:
|
||||
drm_gem_object_put(gobj);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ MODULE_FIRMWARE("amdnpu/1502_00/npu.sbin");
|
|||
MODULE_FIRMWARE("amdnpu/17f0_10/npu.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/17f0_11/npu.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/1502_00/npu_7.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/17f0_10/npu_7.sbin");
|
||||
MODULE_FIRMWARE("amdnpu/17f0_11/npu_7.sbin");
|
||||
|
||||
/*
|
||||
* 0.0: Initial version
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ int amdxdna_pm_suspend(struct device *dev)
|
|||
struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
if (xdna->dev_info->ops->suspend)
|
||||
ret = xdna->dev_info->ops->suspend(xdna);
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ int amdxdna_pm_resume(struct device *dev)
|
|||
struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
guard(mutex)(&xdna->dev_lock);
|
||||
if (xdna->dev_info->ops->resume)
|
||||
ret = xdna->dev_info->ops->resume(xdna);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,4 +15,15 @@ void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna);
|
|||
void amdxdna_pm_init(struct amdxdna_dev *xdna);
|
||||
void amdxdna_pm_fini(struct amdxdna_dev *xdna);
|
||||
|
||||
static inline int amdxdna_pm_resume_get_locked(struct amdxdna_dev *xdna)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_unlock(&xdna->dev_lock);
|
||||
ret = amdxdna_pm_resume_get(xdna);
|
||||
mutex_lock(&xdna->dev_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _AMDXDNA_PM_H_ */
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_print.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
|
|
@ -176,7 +177,10 @@ struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev,
|
|||
goto free_ent;
|
||||
}
|
||||
|
||||
exp_info.size += va_ent[i].len;
|
||||
if (check_add_overflow(exp_info.size, va_ent[i].len, &exp_info.size)) {
|
||||
ret = -EINVAL;
|
||||
goto free_ent;
|
||||
}
|
||||
}
|
||||
|
||||
ubuf->nr_pages = exp_info.size >> PAGE_SHIFT;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ static const struct aie2_fw_feature_tbl npu1_fw_feature_table[] = {
|
|||
};
|
||||
|
||||
static const struct amdxdna_dev_priv npu1_dev_priv = {
|
||||
.fw_path = "amdnpu/1502_00/npu.sbin",
|
||||
.fw_path = "amdnpu/1502_00/",
|
||||
.rt_config = npu1_default_rt_cfg,
|
||||
.dpm_clk_tbl = npu1_dpm_clk_table,
|
||||
.fw_feature_tbl = npu1_fw_feature_table,
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ const struct aie2_fw_feature_tbl npu4_fw_feature_table[] = {
|
|||
};
|
||||
|
||||
static const struct amdxdna_dev_priv npu4_dev_priv = {
|
||||
.fw_path = "amdnpu/17f0_10/npu.sbin",
|
||||
.fw_path = "amdnpu/17f0_10/",
|
||||
.rt_config = npu4_default_rt_cfg,
|
||||
.dpm_clk_tbl = npu4_dpm_clk_table,
|
||||
.fw_feature_tbl = npu4_fw_feature_table,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
#define NPU5_SRAM_BAR_BASE MMNPU_APERTURE1_BASE
|
||||
|
||||
static const struct amdxdna_dev_priv npu5_dev_priv = {
|
||||
.fw_path = "amdnpu/17f0_11/npu.sbin",
|
||||
.fw_path = "amdnpu/17f0_11/",
|
||||
.rt_config = npu4_default_rt_cfg,
|
||||
.dpm_clk_tbl = npu4_dpm_clk_table,
|
||||
.fw_feature_tbl = npu4_fw_feature_table,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
#define NPU6_SRAM_BAR_BASE MMNPU_APERTURE1_BASE
|
||||
|
||||
static const struct amdxdna_dev_priv npu6_dev_priv = {
|
||||
.fw_path = "amdnpu/17f0_10/npu.sbin",
|
||||
.fw_path = "amdnpu/17f0_10/",
|
||||
.rt_config = npu4_default_rt_cfg,
|
||||
.dpm_clk_tbl = npu4_dpm_clk_table,
|
||||
.fw_feature_tbl = npu4_fw_feature_table,
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ static void cmd_state_init(struct cmd_state *st)
|
|||
|
||||
static u64 cmd_to_addr(u32 *cmd)
|
||||
{
|
||||
return ((u64)((cmd[0] & 0xff0000) << 16)) | cmd[1];
|
||||
return (((u64)cmd[0] & 0xff0000) << 16) | cmd[1];
|
||||
}
|
||||
|
||||
static u64 dma_length(struct ethosu_validated_cmdstream_info *info,
|
||||
|
|
|
|||
|
|
@ -389,6 +389,19 @@ static const struct dmi_system_id acpi_osi_dmi_table[] __initconst = {
|
|||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* The screen backlight turns off during udev device creation
|
||||
* when returning true for _OSI("Windows 2009")
|
||||
*/
|
||||
{
|
||||
.callback = dmi_disable_osi_win7,
|
||||
.ident = "Acer Aspire One D255",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "AOD255"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* The wireless hotkey does not work on those machines when
|
||||
* returning true for _OSI("Windows 2012")
|
||||
|
|
|
|||
|
|
@ -386,6 +386,14 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "80E1"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = init_nvs_save_s3,
|
||||
.ident = "Lenovo G70-35",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "80Q5"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using
|
||||
* the Low Power S0 Idle firmware interface (see
|
||||
|
|
|
|||
|
|
@ -6269,10 +6269,6 @@ static void ata_port_detach(struct ata_port *ap)
|
|||
}
|
||||
}
|
||||
|
||||
/* Make sure the deferred qc work finished. */
|
||||
cancel_work_sync(&ap->deferred_qc_work);
|
||||
WARN_ON(ap->deferred_qc);
|
||||
|
||||
/* Tell EH to disable all devices */
|
||||
ap->pflags |= ATA_PFLAG_UNLOADING;
|
||||
ata_port_schedule_eh(ap);
|
||||
|
|
@ -6283,9 +6279,11 @@ static void ata_port_detach(struct ata_port *ap)
|
|||
/* wait till EH commits suicide */
|
||||
ata_port_wait_eh(ap);
|
||||
|
||||
/* it better be dead now */
|
||||
/* It better be dead now and not have any remaining deferred qc. */
|
||||
WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED));
|
||||
WARN_ON(ap->deferred_qc);
|
||||
|
||||
cancel_work_sync(&ap->deferred_qc_work);
|
||||
cancel_delayed_work_sync(&ap->hotplug_task);
|
||||
cancel_delayed_work_sync(&ap->scsi_rescan_task);
|
||||
|
||||
|
|
|
|||
|
|
@ -640,12 +640,28 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
|
|||
set_host_byte(scmd, DID_OK);
|
||||
|
||||
ata_qc_for_each_raw(ap, qc, i) {
|
||||
if (qc->flags & ATA_QCFLAG_ACTIVE &&
|
||||
qc->scsicmd == scmd)
|
||||
if (qc->scsicmd != scmd)
|
||||
continue;
|
||||
if ((qc->flags & ATA_QCFLAG_ACTIVE) ||
|
||||
qc == ap->deferred_qc)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < ATA_MAX_QUEUE) {
|
||||
if (qc == ap->deferred_qc) {
|
||||
/*
|
||||
* This is a deferred command that timed out while
|
||||
* waiting for the command queue to drain. Since the qc
|
||||
* is not active yet (deferred_qc is still set, so the
|
||||
* deferred qc work has not issued the command yet),
|
||||
* simply signal the timeout by finishing the SCSI
|
||||
* command and clear the deferred qc to prevent the
|
||||
* deferred qc work from issuing this qc.
|
||||
*/
|
||||
WARN_ON_ONCE(qc->flags & ATA_QCFLAG_ACTIVE);
|
||||
ap->deferred_qc = NULL;
|
||||
set_host_byte(scmd, DID_TIME_OUT);
|
||||
scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
|
||||
} else if (i < ATA_MAX_QUEUE) {
|
||||
/* the scmd has an associated qc */
|
||||
if (!(qc->flags & ATA_QCFLAG_EH)) {
|
||||
/* which hasn't failed yet, timeout */
|
||||
|
|
|
|||
|
|
@ -797,7 +797,18 @@ struct fwnode_handle *
|
|||
fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
|
||||
struct fwnode_handle *child)
|
||||
{
|
||||
return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
|
||||
struct fwnode_handle *next;
|
||||
|
||||
if (IS_ERR_OR_NULL(fwnode))
|
||||
return NULL;
|
||||
|
||||
/* Try to find a child in primary fwnode */
|
||||
next = fwnode_call_ptr_op(fwnode, get_next_child_node, child);
|
||||
if (next)
|
||||
return next;
|
||||
|
||||
/* When no more children in primary, continue with secondary */
|
||||
return fwnode_call_ptr_op(fwnode->secondary, get_next_child_node, child);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
|
||||
|
||||
|
|
@ -841,19 +852,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
|
|||
struct fwnode_handle *device_get_next_child_node(const struct device *dev,
|
||||
struct fwnode_handle *child)
|
||||
{
|
||||
const struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||
struct fwnode_handle *next;
|
||||
|
||||
if (IS_ERR_OR_NULL(fwnode))
|
||||
return NULL;
|
||||
|
||||
/* Try to find a child in primary fwnode */
|
||||
next = fwnode_get_next_child_node(fwnode, child);
|
||||
if (next)
|
||||
return next;
|
||||
|
||||
/* When no more children in primary, continue with secondary */
|
||||
return fwnode_get_next_child_node(fwnode->secondary, child);
|
||||
return fwnode_get_next_child_node(dev_fwnode(dev), child);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_get_next_child_node);
|
||||
|
||||
|
|
|
|||
|
|
@ -483,38 +483,20 @@ void drbd_al_begin_io(struct drbd_device *device, struct drbd_interval *i)
|
|||
|
||||
int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *i)
|
||||
{
|
||||
struct lru_cache *al = device->act_log;
|
||||
/* for bios crossing activity log extent boundaries,
|
||||
* we may need to activate two extents in one go */
|
||||
unsigned first = i->sector >> (AL_EXTENT_SHIFT-9);
|
||||
unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9);
|
||||
unsigned nr_al_extents;
|
||||
unsigned available_update_slots;
|
||||
unsigned enr;
|
||||
|
||||
D_ASSERT(device, first <= last);
|
||||
|
||||
nr_al_extents = 1 + last - first; /* worst case: all touched extends are cold. */
|
||||
available_update_slots = min(al->nr_elements - al->used,
|
||||
al->max_pending_changes - al->pending_changes);
|
||||
|
||||
/* We want all necessary updates for a given request within the same transaction
|
||||
* We could first check how many updates are *actually* needed,
|
||||
* and use that instead of the worst-case nr_al_extents */
|
||||
if (available_update_slots < nr_al_extents) {
|
||||
/* Too many activity log extents are currently "hot".
|
||||
*
|
||||
* If we have accumulated pending changes already,
|
||||
* we made progress.
|
||||
*
|
||||
* If we cannot get even a single pending change through,
|
||||
* stop the fast path until we made some progress,
|
||||
* or requests to "cold" extents could be starved. */
|
||||
if (!al->pending_changes)
|
||||
__set_bit(__LC_STARVING, &device->act_log->flags);
|
||||
return -ENOBUFS;
|
||||
if (i->partially_in_al_next_enr) {
|
||||
D_ASSERT(device, first < i->partially_in_al_next_enr);
|
||||
D_ASSERT(device, last >= i->partially_in_al_next_enr);
|
||||
first = i->partially_in_al_next_enr;
|
||||
}
|
||||
|
||||
D_ASSERT(device, first <= last);
|
||||
|
||||
/* Is resync active in this area? */
|
||||
for (enr = first; enr <= last; enr++) {
|
||||
struct lc_element *tmp;
|
||||
|
|
@ -529,14 +511,21 @@ int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *
|
|||
}
|
||||
}
|
||||
|
||||
/* Checkout the refcounts.
|
||||
* Given that we checked for available elements and update slots above,
|
||||
* this has to be successful. */
|
||||
/* Try to checkout the refcounts. */
|
||||
for (enr = first; enr <= last; enr++) {
|
||||
struct lc_element *al_ext;
|
||||
al_ext = lc_get_cumulative(device->act_log, enr);
|
||||
if (!al_ext)
|
||||
drbd_info(device, "LOGIC BUG for enr=%u\n", enr);
|
||||
|
||||
if (!al_ext) {
|
||||
/* Did not work. We may have exhausted the possible
|
||||
* changes per transaction. Or raced with someone
|
||||
* "locking" it against changes.
|
||||
* Remember where to continue from.
|
||||
*/
|
||||
if (enr > first)
|
||||
i->partially_in_al_next_enr = enr;
|
||||
return -ENOBUFS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -556,7 +545,11 @@ void drbd_al_complete_io(struct drbd_device *device, struct drbd_interval *i)
|
|||
|
||||
for (enr = first; enr <= last; enr++) {
|
||||
extent = lc_find(device->act_log, enr);
|
||||
if (!extent) {
|
||||
/* Yes, this masks a bug elsewhere. However, during normal
|
||||
* operation this is harmless, so no need to crash the kernel
|
||||
* by the BUG_ON(refcount == 0) in lc_put().
|
||||
*/
|
||||
if (!extent || extent->refcnt == 0) {
|
||||
drbd_err(device, "al_complete_io() called on inactive extent %u\n", enr);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,15 @@
|
|||
struct drbd_interval {
|
||||
struct rb_node rb;
|
||||
sector_t sector; /* start sector of the interval */
|
||||
unsigned int size; /* size in bytes */
|
||||
sector_t end; /* highest interval end in subtree */
|
||||
unsigned int size; /* size in bytes */
|
||||
unsigned int local:1 /* local or remote request? */;
|
||||
unsigned int waiting:1; /* someone is waiting for completion */
|
||||
unsigned int completed:1; /* this has been completed already;
|
||||
* ignore for conflict detection */
|
||||
|
||||
/* to resume a partially successful drbd_al_begin_io_nonblock(); */
|
||||
unsigned int partially_in_al_next_enr;
|
||||
};
|
||||
|
||||
static inline void drbd_clear_interval(struct drbd_interval *i)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/memcontrol.h>
|
||||
#include <linux/mm_inline.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/notifier.h>
|
||||
|
|
@ -732,9 +733,9 @@ int drbd_send_sync_param(struct drbd_peer_device *peer_device)
|
|||
}
|
||||
|
||||
if (apv >= 88)
|
||||
strcpy(p->verify_alg, nc->verify_alg);
|
||||
strscpy(p->verify_alg, nc->verify_alg);
|
||||
if (apv >= 89)
|
||||
strcpy(p->csums_alg, nc->csums_alg);
|
||||
strscpy(p->csums_alg, nc->csums_alg);
|
||||
rcu_read_unlock();
|
||||
|
||||
return drbd_send_command(peer_device, sock, cmd, size, NULL, 0);
|
||||
|
|
@ -745,6 +746,7 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm
|
|||
struct drbd_socket *sock;
|
||||
struct p_protocol *p;
|
||||
struct net_conf *nc;
|
||||
size_t integrity_alg_len;
|
||||
int size, cf;
|
||||
|
||||
sock = &connection->data;
|
||||
|
|
@ -762,8 +764,10 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm
|
|||
}
|
||||
|
||||
size = sizeof(*p);
|
||||
if (connection->agreed_pro_version >= 87)
|
||||
size += strlen(nc->integrity_alg) + 1;
|
||||
if (connection->agreed_pro_version >= 87) {
|
||||
integrity_alg_len = strlen(nc->integrity_alg) + 1;
|
||||
size += integrity_alg_len;
|
||||
}
|
||||
|
||||
p->protocol = cpu_to_be32(nc->wire_protocol);
|
||||
p->after_sb_0p = cpu_to_be32(nc->after_sb_0p);
|
||||
|
|
@ -778,7 +782,7 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm
|
|||
p->conn_flags = cpu_to_be32(cf);
|
||||
|
||||
if (connection->agreed_pro_version >= 87)
|
||||
strcpy(p->integrity_alg, nc->integrity_alg);
|
||||
strscpy(p->integrity_alg, nc->integrity_alg, integrity_alg_len);
|
||||
rcu_read_unlock();
|
||||
|
||||
return __conn_send_command(connection, sock, cmd, size, NULL, 0);
|
||||
|
|
|
|||
|
|
@ -3801,14 +3801,14 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i
|
|||
*new_net_conf = *old_net_conf;
|
||||
|
||||
if (verify_tfm) {
|
||||
strcpy(new_net_conf->verify_alg, p->verify_alg);
|
||||
strscpy(new_net_conf->verify_alg, p->verify_alg);
|
||||
new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1;
|
||||
crypto_free_shash(peer_device->connection->verify_tfm);
|
||||
peer_device->connection->verify_tfm = verify_tfm;
|
||||
drbd_info(device, "using verify-alg: \"%s\"\n", p->verify_alg);
|
||||
}
|
||||
if (csums_tfm) {
|
||||
strcpy(new_net_conf->csums_alg, p->csums_alg);
|
||||
strscpy(new_net_conf->csums_alg, p->csums_alg);
|
||||
new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1;
|
||||
crypto_free_shash(peer_device->connection->csums_tfm);
|
||||
peer_device->connection->csums_tfm = csums_tfm;
|
||||
|
|
|
|||
|
|
@ -621,7 +621,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,
|
|||
break;
|
||||
|
||||
case READ_COMPLETED_WITH_ERROR:
|
||||
drbd_set_out_of_sync(peer_device, req->i.sector, req->i.size);
|
||||
drbd_set_out_of_sync(first_peer_device(device),
|
||||
req->i.sector, req->i.size);
|
||||
drbd_report_io_error(device, req);
|
||||
__drbd_chk_io_error(device, DRBD_READ_ERROR);
|
||||
fallthrough;
|
||||
|
|
|
|||
|
|
@ -542,6 +542,21 @@ static void zloop_rw(struct zloop_cmd *cmd)
|
|||
zloop_put_cmd(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sync the entire FS containing the zone files instead of walking all files.
|
||||
*/
|
||||
static int zloop_flush(struct zloop_device *zlo)
|
||||
{
|
||||
struct super_block *sb = file_inode(zlo->data_dir)->i_sb;
|
||||
int ret;
|
||||
|
||||
down_read(&sb->s_umount);
|
||||
ret = sync_filesystem(sb);
|
||||
up_read(&sb->s_umount);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void zloop_handle_cmd(struct zloop_cmd *cmd)
|
||||
{
|
||||
struct request *rq = blk_mq_rq_from_pdu(cmd);
|
||||
|
|
@ -562,11 +577,7 @@ static void zloop_handle_cmd(struct zloop_cmd *cmd)
|
|||
zloop_rw(cmd);
|
||||
return;
|
||||
case REQ_OP_FLUSH:
|
||||
/*
|
||||
* Sync the entire FS containing the zone files instead of
|
||||
* walking all files
|
||||
*/
|
||||
cmd->ret = sync_filesystem(file_inode(zlo->data_dir)->i_sb);
|
||||
cmd->ret = zloop_flush(zlo);
|
||||
break;
|
||||
case REQ_OP_ZONE_RESET:
|
||||
cmd->ret = zloop_reset_zone(zlo, rq_zone_no(rq));
|
||||
|
|
@ -981,7 +992,8 @@ static int zloop_ctl_add(struct zloop_options *opts)
|
|||
struct queue_limits lim = {
|
||||
.max_hw_sectors = SZ_1M >> SECTOR_SHIFT,
|
||||
.chunk_sectors = opts->zone_size,
|
||||
.features = BLK_FEAT_ZONED,
|
||||
.features = BLK_FEAT_ZONED | BLK_FEAT_WRITE_CACHE,
|
||||
|
||||
};
|
||||
unsigned int nr_zones, i, j;
|
||||
struct zloop_device *zlo;
|
||||
|
|
@ -1162,7 +1174,12 @@ static int zloop_ctl_remove(struct zloop_options *opts)
|
|||
int ret;
|
||||
|
||||
if (!(opts->mask & ZLOOP_OPT_ID)) {
|
||||
pr_err("No ID specified\n");
|
||||
pr_err("No ID specified for remove\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (opts->mask & ~ZLOOP_OPT_ID) {
|
||||
pr_err("Invalid option specified for remove\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2046,19 +2046,23 @@ static int qca_setup(struct hci_uart *hu)
|
|||
}
|
||||
|
||||
out:
|
||||
if (ret && retries < MAX_INIT_RETRIES) {
|
||||
bt_dev_warn(hdev, "Retry BT power ON:%d", retries);
|
||||
if (ret) {
|
||||
qca_power_shutdown(hu);
|
||||
if (hu->serdev) {
|
||||
serdev_device_close(hu->serdev);
|
||||
ret = serdev_device_open(hu->serdev);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "failed to open port");
|
||||
return ret;
|
||||
|
||||
if (retries < MAX_INIT_RETRIES) {
|
||||
bt_dev_warn(hdev, "Retry BT power ON:%d", retries);
|
||||
if (hu->serdev) {
|
||||
serdev_device_close(hu->serdev);
|
||||
ret = serdev_device_open(hu->serdev);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "failed to open port");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
retries++;
|
||||
goto retry;
|
||||
}
|
||||
retries++;
|
||||
goto retry;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup bdaddr */
|
||||
|
|
|
|||
|
|
@ -202,11 +202,16 @@ static int ipmi_ipmb_slave_cb(struct i2c_client *client,
|
|||
break;
|
||||
|
||||
case I2C_SLAVE_READ_REQUESTED:
|
||||
*val = 0xff;
|
||||
ipmi_ipmb_check_msg_done(iidev);
|
||||
break;
|
||||
|
||||
case I2C_SLAVE_STOP:
|
||||
ipmi_ipmb_check_msg_done(iidev);
|
||||
break;
|
||||
|
||||
case I2C_SLAVE_READ_PROCESSED:
|
||||
*val = 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -602,6 +602,22 @@ static int __ipmi_bmc_register(struct ipmi_smi *intf,
|
|||
static int __scan_channels(struct ipmi_smi *intf,
|
||||
struct ipmi_device_id *id, bool rescan);
|
||||
|
||||
static void ipmi_lock_xmit_msgs(struct ipmi_smi *intf, int run_to_completion,
|
||||
unsigned long *flags)
|
||||
{
|
||||
if (run_to_completion)
|
||||
return;
|
||||
spin_lock_irqsave(&intf->xmit_msgs_lock, *flags);
|
||||
}
|
||||
|
||||
static void ipmi_unlock_xmit_msgs(struct ipmi_smi *intf, int run_to_completion,
|
||||
unsigned long *flags)
|
||||
{
|
||||
if (run_to_completion)
|
||||
return;
|
||||
spin_unlock_irqrestore(&intf->xmit_msgs_lock, *flags);
|
||||
}
|
||||
|
||||
static void free_ipmi_user(struct kref *ref)
|
||||
{
|
||||
struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount);
|
||||
|
|
@ -1869,21 +1885,32 @@ static struct ipmi_smi_msg *smi_add_send_msg(struct ipmi_smi *intf,
|
|||
return smi_msg;
|
||||
}
|
||||
|
||||
static void smi_send(struct ipmi_smi *intf,
|
||||
static int smi_send(struct ipmi_smi *intf,
|
||||
const struct ipmi_smi_handlers *handlers,
|
||||
struct ipmi_smi_msg *smi_msg, int priority)
|
||||
{
|
||||
int run_to_completion = READ_ONCE(intf->run_to_completion);
|
||||
unsigned long flags = 0;
|
||||
int rv = 0;
|
||||
|
||||
if (!run_to_completion)
|
||||
spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
|
||||
ipmi_lock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
smi_msg = smi_add_send_msg(intf, smi_msg, priority);
|
||||
if (!run_to_completion)
|
||||
spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags);
|
||||
ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
|
||||
if (smi_msg)
|
||||
handlers->sender(intf->send_info, smi_msg);
|
||||
if (smi_msg) {
|
||||
rv = handlers->sender(intf->send_info, smi_msg);
|
||||
if (rv) {
|
||||
ipmi_lock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
intf->curr_msg = NULL;
|
||||
ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
/*
|
||||
* Something may have been added to the transmit
|
||||
* queue, so schedule a check for that.
|
||||
*/
|
||||
queue_work(system_wq, &intf->smi_work);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static bool is_maintenance_mode_cmd(struct kernel_ipmi_msg *msg)
|
||||
|
|
@ -2296,6 +2323,7 @@ static int i_ipmi_request(struct ipmi_user *user,
|
|||
struct ipmi_recv_msg *recv_msg;
|
||||
int run_to_completion = READ_ONCE(intf->run_to_completion);
|
||||
int rv = 0;
|
||||
bool in_seq_table = false;
|
||||
|
||||
if (supplied_recv) {
|
||||
recv_msg = supplied_recv;
|
||||
|
|
@ -2349,33 +2377,50 @@ static int i_ipmi_request(struct ipmi_user *user,
|
|||
rv = i_ipmi_req_ipmb(intf, addr, msgid, msg, smi_msg, recv_msg,
|
||||
source_address, source_lun,
|
||||
retries, retry_time_ms);
|
||||
in_seq_table = true;
|
||||
} else if (is_ipmb_direct_addr(addr)) {
|
||||
rv = i_ipmi_req_ipmb_direct(intf, addr, msgid, msg, smi_msg,
|
||||
recv_msg, source_lun);
|
||||
} else if (is_lan_addr(addr)) {
|
||||
rv = i_ipmi_req_lan(intf, addr, msgid, msg, smi_msg, recv_msg,
|
||||
source_lun, retries, retry_time_ms);
|
||||
in_seq_table = true;
|
||||
} else {
|
||||
/* Unknown address type. */
|
||||
/* Unknown address type. */
|
||||
ipmi_inc_stat(intf, sent_invalid_commands);
|
||||
rv = -EINVAL;
|
||||
}
|
||||
|
||||
if (rv) {
|
||||
if (!rv) {
|
||||
dev_dbg(intf->si_dev, "Send: %*ph\n",
|
||||
smi_msg->data_size, smi_msg->data);
|
||||
|
||||
rv = smi_send(intf, intf->handlers, smi_msg, priority);
|
||||
if (rv != IPMI_CC_NO_ERROR)
|
||||
/* smi_send() returns an IPMI err, return a Linux one. */
|
||||
rv = -EIO;
|
||||
if (rv && in_seq_table) {
|
||||
/*
|
||||
* If it's in the sequence table, it will be
|
||||
* retried later, so ignore errors.
|
||||
*/
|
||||
rv = 0;
|
||||
/* But we need to fix the timeout. */
|
||||
intf_start_seq_timer(intf, smi_msg->msgid);
|
||||
ipmi_free_smi_msg(smi_msg);
|
||||
smi_msg = NULL;
|
||||
}
|
||||
}
|
||||
out_err:
|
||||
if (!run_to_completion)
|
||||
mutex_unlock(&intf->users_mutex);
|
||||
|
||||
if (rv) {
|
||||
if (!supplied_smi)
|
||||
ipmi_free_smi_msg(smi_msg);
|
||||
if (!supplied_recv)
|
||||
ipmi_free_recv_msg(recv_msg);
|
||||
} else {
|
||||
dev_dbg(intf->si_dev, "Send: %*ph\n",
|
||||
smi_msg->data_size, smi_msg->data);
|
||||
|
||||
smi_send(intf, intf->handlers, smi_msg, priority);
|
||||
}
|
||||
if (!run_to_completion)
|
||||
mutex_unlock(&intf->users_mutex);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -3949,12 +3994,12 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
|
|||
dev_dbg(intf->si_dev, "Invalid command: %*ph\n",
|
||||
msg->data_size, msg->data);
|
||||
|
||||
smi_send(intf, intf->handlers, msg, 0);
|
||||
/*
|
||||
* We used the message, so return the value that
|
||||
* causes it to not be freed or queued.
|
||||
*/
|
||||
rv = -1;
|
||||
if (smi_send(intf, intf->handlers, msg, 0) == IPMI_CC_NO_ERROR)
|
||||
/*
|
||||
* We used the message, so return the value that
|
||||
* causes it to not be freed or queued.
|
||||
*/
|
||||
rv = -1;
|
||||
} else if (!IS_ERR(recv_msg)) {
|
||||
/* Extract the source address from the data. */
|
||||
ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr;
|
||||
|
|
@ -4028,12 +4073,12 @@ static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf,
|
|||
msg->data[4] = IPMI_INVALID_CMD_COMPLETION_CODE;
|
||||
msg->data_size = 5;
|
||||
|
||||
smi_send(intf, intf->handlers, msg, 0);
|
||||
/*
|
||||
* We used the message, so return the value that
|
||||
* causes it to not be freed or queued.
|
||||
*/
|
||||
rv = -1;
|
||||
if (smi_send(intf, intf->handlers, msg, 0) == IPMI_CC_NO_ERROR)
|
||||
/*
|
||||
* We used the message, so return the value that
|
||||
* causes it to not be freed or queued.
|
||||
*/
|
||||
rv = -1;
|
||||
} else if (!IS_ERR(recv_msg)) {
|
||||
/* Extract the source address from the data. */
|
||||
daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr;
|
||||
|
|
@ -4173,7 +4218,7 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
|
|||
struct ipmi_smi_msg *msg)
|
||||
{
|
||||
struct cmd_rcvr *rcvr;
|
||||
int rv = 0;
|
||||
int rv = 0; /* Free by default */
|
||||
unsigned char netfn;
|
||||
unsigned char cmd;
|
||||
unsigned char chan;
|
||||
|
|
@ -4226,12 +4271,12 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf,
|
|||
dev_dbg(intf->si_dev, "Invalid command: %*ph\n",
|
||||
msg->data_size, msg->data);
|
||||
|
||||
smi_send(intf, intf->handlers, msg, 0);
|
||||
/*
|
||||
* We used the message, so return the value that
|
||||
* causes it to not be freed or queued.
|
||||
*/
|
||||
rv = -1;
|
||||
if (smi_send(intf, intf->handlers, msg, 0) == IPMI_CC_NO_ERROR)
|
||||
/*
|
||||
* We used the message, so return the value that
|
||||
* causes it to not be freed or queued.
|
||||
*/
|
||||
rv = -1;
|
||||
} else if (!IS_ERR(recv_msg)) {
|
||||
/* Extract the source address from the data. */
|
||||
lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr;
|
||||
|
|
@ -4824,8 +4869,7 @@ static void smi_work(struct work_struct *t)
|
|||
* message delivery.
|
||||
*/
|
||||
restart:
|
||||
if (!run_to_completion)
|
||||
spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
|
||||
ipmi_lock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
if (intf->curr_msg == NULL && !intf->in_shutdown) {
|
||||
struct list_head *entry = NULL;
|
||||
|
||||
|
|
@ -4841,8 +4885,7 @@ static void smi_work(struct work_struct *t)
|
|||
intf->curr_msg = newmsg;
|
||||
}
|
||||
}
|
||||
if (!run_to_completion)
|
||||
spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags);
|
||||
ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
|
||||
if (newmsg) {
|
||||
cc = intf->handlers->sender(intf->send_info, newmsg);
|
||||
|
|
@ -4850,8 +4893,11 @@ static void smi_work(struct work_struct *t)
|
|||
if (newmsg->recv_msg)
|
||||
deliver_err_response(intf,
|
||||
newmsg->recv_msg, cc);
|
||||
else
|
||||
ipmi_free_smi_msg(newmsg);
|
||||
ipmi_lock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
intf->curr_msg = NULL;
|
||||
ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
ipmi_free_smi_msg(newmsg);
|
||||
newmsg = NULL;
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
|
|
@ -4919,16 +4965,14 @@ void ipmi_smi_msg_received(struct ipmi_smi *intf,
|
|||
spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock,
|
||||
flags);
|
||||
|
||||
if (!run_to_completion)
|
||||
spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
|
||||
ipmi_lock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
/*
|
||||
* We can get an asynchronous event or receive message in addition
|
||||
* to commands we send.
|
||||
*/
|
||||
if (msg == intf->curr_msg)
|
||||
intf->curr_msg = NULL;
|
||||
if (!run_to_completion)
|
||||
spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags);
|
||||
ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags);
|
||||
|
||||
if (run_to_completion)
|
||||
smi_work(&intf->smi_work);
|
||||
|
|
@ -5041,7 +5085,12 @@ static void check_msg_timeout(struct ipmi_smi *intf, struct seq_table *ent,
|
|||
ipmi_inc_stat(intf,
|
||||
retransmitted_ipmb_commands);
|
||||
|
||||
smi_send(intf, intf->handlers, smi_msg, 0);
|
||||
/* If this fails we'll retry later or timeout. */
|
||||
if (smi_send(intf, intf->handlers, smi_msg, 0) != IPMI_CC_NO_ERROR) {
|
||||
/* But fix the timeout. */
|
||||
intf_start_seq_timer(intf, smi_msg->msgid);
|
||||
ipmi_free_smi_msg(smi_msg);
|
||||
}
|
||||
} else
|
||||
ipmi_free_smi_msg(smi_msg);
|
||||
|
||||
|
|
|
|||
|
|
@ -809,6 +809,12 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
|
|||
*/
|
||||
return_hosed_msg(smi_info, IPMI_BUS_ERR);
|
||||
}
|
||||
if (smi_info->waiting_msg != NULL) {
|
||||
/* Also handle if there was a message waiting. */
|
||||
smi_info->curr_msg = smi_info->waiting_msg;
|
||||
smi_info->waiting_msg = NULL;
|
||||
return_hosed_msg(smi_info, IPMI_BUS_ERR);
|
||||
}
|
||||
smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_HOSED);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -918,9 +924,14 @@ static int sender(void *send_info, struct ipmi_smi_msg *msg)
|
|||
{
|
||||
struct smi_info *smi_info = send_info;
|
||||
unsigned long flags;
|
||||
int rv = IPMI_CC_NO_ERROR;
|
||||
|
||||
debug_timestamp(smi_info, "Enqueue");
|
||||
|
||||
/*
|
||||
* Check here for run to completion mode. A check under lock is
|
||||
* later.
|
||||
*/
|
||||
if (smi_info->si_state == SI_HOSED)
|
||||
return IPMI_BUS_ERR;
|
||||
|
||||
|
|
@ -934,18 +945,15 @@ static int sender(void *send_info, struct ipmi_smi_msg *msg)
|
|||
}
|
||||
|
||||
spin_lock_irqsave(&smi_info->si_lock, flags);
|
||||
/*
|
||||
* The following two lines don't need to be under the lock for
|
||||
* the lock's sake, but they do need SMP memory barriers to
|
||||
* avoid getting things out of order. We are already claiming
|
||||
* the lock, anyway, so just do it under the lock to avoid the
|
||||
* ordering problem.
|
||||
*/
|
||||
BUG_ON(smi_info->waiting_msg);
|
||||
smi_info->waiting_msg = msg;
|
||||
check_start_timer_thread(smi_info);
|
||||
if (smi_info->si_state == SI_HOSED) {
|
||||
rv = IPMI_BUS_ERR;
|
||||
} else {
|
||||
BUG_ON(smi_info->waiting_msg);
|
||||
smi_info->waiting_msg = msg;
|
||||
check_start_timer_thread(smi_info);
|
||||
}
|
||||
spin_unlock_irqrestore(&smi_info->si_lock, flags);
|
||||
return IPMI_CC_NO_ERROR;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void set_run_to_completion(void *send_info, bool i_run_to_completion)
|
||||
|
|
@ -1113,7 +1121,9 @@ static void smi_timeout(struct timer_list *t)
|
|||
* SI_USEC_PER_JIFFY);
|
||||
smi_result = smi_event_handler(smi_info, time_diff);
|
||||
|
||||
if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) {
|
||||
if (smi_info->si_state == SI_HOSED) {
|
||||
timeout = jiffies + SI_TIMEOUT_HOSED;
|
||||
} else if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) {
|
||||
/* Running with interrupts, only do long timeouts. */
|
||||
timeout = jiffies + SI_TIMEOUT_JIFFIES;
|
||||
smi_inc_stat(smi_info, long_timeouts);
|
||||
|
|
@ -2226,7 +2236,8 @@ static void wait_msg_processed(struct smi_info *smi_info)
|
|||
unsigned long jiffies_now;
|
||||
long time_diff;
|
||||
|
||||
while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
|
||||
while (smi_info->si_state != SI_HOSED &&
|
||||
(smi_info->curr_msg || (smi_info->si_state != SI_NORMAL))) {
|
||||
jiffies_now = jiffies;
|
||||
time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
|
||||
* SI_USEC_PER_JIFFY);
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ static void ipmi_ls2k_remove(struct platform_device *pdev)
|
|||
ipmi_si_remove_by_dev(&pdev->dev);
|
||||
}
|
||||
|
||||
struct platform_driver ipmi_ls2k_platform_driver = {
|
||||
static struct platform_driver ipmi_ls2k_platform_driver = {
|
||||
.driver = {
|
||||
.name = "ls2k-ipmi-si",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -96,8 +96,7 @@ static ATOMIC_NOTIFIER_HEAD(random_ready_notifier);
|
|||
/* Control how we warn userspace. */
|
||||
static struct ratelimit_state urandom_warning =
|
||||
RATELIMIT_STATE_INIT_FLAGS("urandom_warning", HZ, 3, RATELIMIT_MSG_ON_RELEASE);
|
||||
static int ratelimit_disable __read_mostly =
|
||||
IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM);
|
||||
static int ratelimit_disable __read_mostly = 0;
|
||||
module_param_named(ratelimit_disable, ratelimit_disable, int, 0644);
|
||||
MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
|
||||
|
||||
|
|
@ -168,12 +167,6 @@ int __cold execute_with_initialized_rng(struct notifier_block *nb)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define warn_unseeded_randomness() \
|
||||
if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \
|
||||
printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \
|
||||
__func__, (void *)_RET_IP_, crng_init)
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Fast key erasure RNG, the "crng".
|
||||
|
|
@ -434,7 +427,6 @@ static void _get_random_bytes(void *buf, size_t len)
|
|||
*/
|
||||
void get_random_bytes(void *buf, size_t len)
|
||||
{
|
||||
warn_unseeded_randomness();
|
||||
_get_random_bytes(buf, len);
|
||||
}
|
||||
EXPORT_SYMBOL(get_random_bytes);
|
||||
|
|
@ -523,8 +515,6 @@ type get_random_ ##type(void) \
|
|||
struct batch_ ##type *batch; \
|
||||
unsigned long next_gen; \
|
||||
\
|
||||
warn_unseeded_randomness(); \
|
||||
\
|
||||
if (!crng_ready()) { \
|
||||
_get_random_bytes(&ret, sizeof(ret)); \
|
||||
return ret; \
|
||||
|
|
|
|||
|
|
@ -346,7 +346,29 @@ static struct platform_driver imx8qxp_clk_driver = {
|
|||
},
|
||||
.probe = imx8qxp_clk_probe,
|
||||
};
|
||||
module_platform_driver(imx8qxp_clk_driver);
|
||||
|
||||
static int __init imx8qxp_clk_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&imx8qxp_clk_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = imx_clk_scu_module_init();
|
||||
if (ret)
|
||||
platform_driver_unregister(&imx8qxp_clk_driver);
|
||||
|
||||
return ret;
|
||||
}
|
||||
module_init(imx8qxp_clk_init);
|
||||
|
||||
static void __exit imx8qxp_clk_exit(void)
|
||||
{
|
||||
imx_clk_scu_module_exit();
|
||||
platform_driver_unregister(&imx8qxp_clk_driver);
|
||||
}
|
||||
module_exit(imx8qxp_clk_exit);
|
||||
|
||||
MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");
|
||||
|
|
|
|||
|
|
@ -191,6 +191,16 @@ static bool imx_scu_clk_is_valid(u32 rsrc_id)
|
|||
return p != NULL;
|
||||
}
|
||||
|
||||
int __init imx_clk_scu_module_init(void)
|
||||
{
|
||||
return platform_driver_register(&imx_clk_scu_driver);
|
||||
}
|
||||
|
||||
void __exit imx_clk_scu_module_exit(void)
|
||||
{
|
||||
return platform_driver_unregister(&imx_clk_scu_driver);
|
||||
}
|
||||
|
||||
int imx_clk_scu_init(struct device_node *np,
|
||||
const struct imx_clk_scu_rsrc_table *data)
|
||||
{
|
||||
|
|
@ -215,7 +225,7 @@ int imx_clk_scu_init(struct device_node *np,
|
|||
rsrc_table = data;
|
||||
}
|
||||
|
||||
return platform_driver_register(&imx_clk_scu_driver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl;
|
|||
extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp;
|
||||
extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm;
|
||||
|
||||
int __init imx_clk_scu_module_init(void);
|
||||
void __exit imx_clk_scu_module_exit(void);
|
||||
int imx_clk_scu_init(struct device_node *np,
|
||||
const struct imx_clk_scu_rsrc_table *data);
|
||||
struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,
|
||||
|
|
|
|||
|
|
@ -1476,13 +1476,13 @@ static void __intel_pstate_update_max_freq(struct cpufreq_policy *policy,
|
|||
refresh_frequency_limits(policy);
|
||||
}
|
||||
|
||||
static bool intel_pstate_update_max_freq(struct cpudata *cpudata)
|
||||
static bool intel_pstate_update_max_freq(int cpu)
|
||||
{
|
||||
struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu);
|
||||
struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);
|
||||
if (!policy)
|
||||
return false;
|
||||
|
||||
__intel_pstate_update_max_freq(policy, cpudata);
|
||||
__intel_pstate_update_max_freq(policy, all_cpu_data[cpu]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1501,7 +1501,7 @@ static void intel_pstate_update_limits_for_all(void)
|
|||
int cpu;
|
||||
|
||||
for_each_possible_cpu(cpu)
|
||||
intel_pstate_update_max_freq(all_cpu_data[cpu]);
|
||||
intel_pstate_update_max_freq(cpu);
|
||||
|
||||
mutex_lock(&hybrid_capacity_lock);
|
||||
|
||||
|
|
@ -1647,8 +1647,8 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b,
|
|||
static void update_cpu_qos_request(int cpu, enum freq_qos_req_type type)
|
||||
{
|
||||
struct cpudata *cpudata = all_cpu_data[cpu];
|
||||
unsigned int freq = cpudata->pstate.turbo_freq;
|
||||
struct freq_qos_request *req;
|
||||
unsigned int freq;
|
||||
|
||||
struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu);
|
||||
if (!policy)
|
||||
|
|
@ -1661,6 +1661,8 @@ static void update_cpu_qos_request(int cpu, enum freq_qos_req_type type)
|
|||
if (hwp_active)
|
||||
intel_pstate_get_hwp_cap(cpudata);
|
||||
|
||||
freq = cpudata->pstate.turbo_freq;
|
||||
|
||||
if (type == FREQ_QOS_MIN) {
|
||||
freq = DIV_ROUND_UP(freq * global.min_perf_pct, 100);
|
||||
} else {
|
||||
|
|
@ -1908,7 +1910,7 @@ static void intel_pstate_notify_work(struct work_struct *work)
|
|||
struct cpudata *cpudata =
|
||||
container_of(to_delayed_work(work), struct cpudata, hwp_notify_work);
|
||||
|
||||
if (intel_pstate_update_max_freq(cpudata)) {
|
||||
if (intel_pstate_update_max_freq(cpudata->cpu)) {
|
||||
/*
|
||||
* The driver will not be unregistered while this function is
|
||||
* running, so update the capacity without acquiring the driver
|
||||
|
|
|
|||
|
|
@ -152,6 +152,24 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c);
|
|||
int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port,
|
||||
struct access_coordinate *c);
|
||||
|
||||
static inline struct device *port_to_host(struct cxl_port *port)
|
||||
{
|
||||
struct cxl_port *parent = is_cxl_root(port) ? NULL :
|
||||
to_cxl_port(port->dev.parent);
|
||||
|
||||
/*
|
||||
* The host of CXL root port and the first level of ports is
|
||||
* the platform firmware device, the host of all other ports
|
||||
* is their parent port.
|
||||
*/
|
||||
if (!parent)
|
||||
return port->uport_dev;
|
||||
else if (is_cxl_root(parent))
|
||||
return parent->uport_dev;
|
||||
else
|
||||
return &parent->dev;
|
||||
}
|
||||
|
||||
static inline struct device *dport_to_host(struct cxl_dport *dport)
|
||||
{
|
||||
struct cxl_port *port = dport->port;
|
||||
|
|
|
|||
|
|
@ -904,7 +904,7 @@ static void cxl_decoder_reset(struct cxl_decoder *cxld)
|
|||
if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
|
||||
return;
|
||||
|
||||
if (test_bit(CXL_DECODER_F_LOCK, &cxld->flags))
|
||||
if (cxld->flags & CXL_DECODER_F_LOCK)
|
||||
return;
|
||||
|
||||
if (port->commit_end == id)
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ static bool cxl_mem_raw_command_allowed(u16 opcode)
|
|||
* cxl_payload_from_user_allowed() - Check contents of in_payload.
|
||||
* @opcode: The mailbox command opcode.
|
||||
* @payload_in: Pointer to the input payload passed in from user space.
|
||||
* @in_size: Size of @payload_in in bytes.
|
||||
*
|
||||
* Return:
|
||||
* * true - payload_in passes check for @opcode.
|
||||
|
|
@ -325,12 +326,15 @@ static bool cxl_mem_raw_command_allowed(u16 opcode)
|
|||
*
|
||||
* The specific checks are determined by the opcode.
|
||||
*/
|
||||
static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in)
|
||||
static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in,
|
||||
size_t in_size)
|
||||
{
|
||||
switch (opcode) {
|
||||
case CXL_MBOX_OP_SET_PARTITION_INFO: {
|
||||
struct cxl_mbox_set_partition_info *pi = payload_in;
|
||||
|
||||
if (in_size < sizeof(*pi))
|
||||
return false;
|
||||
if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG)
|
||||
return false;
|
||||
break;
|
||||
|
|
@ -338,6 +342,8 @@ static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in)
|
|||
case CXL_MBOX_OP_CLEAR_LOG: {
|
||||
const uuid_t *uuid = (uuid_t *)payload_in;
|
||||
|
||||
if (in_size < sizeof(uuid_t))
|
||||
return false;
|
||||
/*
|
||||
* Restrict the ‘Clear log’ action to only apply to
|
||||
* Vendor debug logs.
|
||||
|
|
@ -365,7 +371,8 @@ static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd,
|
|||
if (IS_ERR(mbox_cmd->payload_in))
|
||||
return PTR_ERR(mbox_cmd->payload_in);
|
||||
|
||||
if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in)) {
|
||||
if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in,
|
||||
in_size)) {
|
||||
dev_dbg(cxl_mbox->host, "%s: input payload not allowed\n",
|
||||
cxl_mem_opcode_to_name(opcode));
|
||||
kvfree(mbox_cmd->payload_in);
|
||||
|
|
|
|||
|
|
@ -1089,10 +1089,8 @@ static int cxlmd_add(struct cxl_memdev *cxlmd, struct cxl_dev_state *cxlds)
|
|||
DEFINE_FREE(put_cxlmd, struct cxl_memdev *,
|
||||
if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))
|
||||
|
||||
static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd)
|
||||
static bool cxl_memdev_attach_failed(struct cxl_memdev *cxlmd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* If @attach is provided fail if the driver is not attached upon
|
||||
* return. Note that failure here could be the result of a race to
|
||||
|
|
@ -1100,7 +1098,14 @@ static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd)
|
|||
* succeeded and then cxl_mem unbound before the lock is acquired.
|
||||
*/
|
||||
guard(device)(&cxlmd->dev);
|
||||
if (cxlmd->attach && !cxlmd->dev.driver) {
|
||||
return (cxlmd->attach && !cxlmd->dev.driver);
|
||||
}
|
||||
|
||||
static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (cxl_memdev_attach_failed(cxlmd)) {
|
||||
cxl_memdev_unregister(cxlmd);
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,15 +115,17 @@ static void unregister_nvb(void *_cxl_nvb)
|
|||
device_unregister(&cxl_nvb->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_cxl_add_nvdimm_bridge() - add the root of a LIBNVDIMM topology
|
||||
* @host: platform firmware root device
|
||||
* @port: CXL port at the root of a CXL topology
|
||||
*
|
||||
* Return: bridge device that can host cxl_nvdimm objects
|
||||
*/
|
||||
struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host,
|
||||
struct cxl_port *port)
|
||||
static bool cxl_nvdimm_bridge_failed_attach(struct cxl_nvdimm_bridge *cxl_nvb)
|
||||
{
|
||||
struct device *dev = &cxl_nvb->dev;
|
||||
|
||||
guard(device)(dev);
|
||||
/* If the device has no driver, then it failed to attach. */
|
||||
return dev->driver == NULL;
|
||||
}
|
||||
|
||||
struct cxl_nvdimm_bridge *__devm_cxl_add_nvdimm_bridge(struct device *host,
|
||||
struct cxl_port *port)
|
||||
{
|
||||
struct cxl_nvdimm_bridge *cxl_nvb;
|
||||
struct device *dev;
|
||||
|
|
@ -145,6 +147,11 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host,
|
|||
if (rc)
|
||||
goto err;
|
||||
|
||||
if (cxl_nvdimm_bridge_failed_attach(cxl_nvb)) {
|
||||
unregister_nvb(cxl_nvb);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
rc = devm_add_action_or_reset(host, unregister_nvb, cxl_nvb);
|
||||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
|
|
@ -155,7 +162,7 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host,
|
|||
put_device(dev);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm_bridge, "CXL");
|
||||
EXPORT_SYMBOL_FOR_MODULES(__devm_cxl_add_nvdimm_bridge, "cxl_pmem");
|
||||
|
||||
static void cxl_nvdimm_release(struct device *dev)
|
||||
{
|
||||
|
|
@ -255,6 +262,21 @@ int devm_cxl_add_nvdimm(struct device *host, struct cxl_port *port,
|
|||
if (!cxl_nvb)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Take the uport_dev lock to guard against race of nvdimm_bus object.
|
||||
* cxl_acpi_probe() registers the nvdimm_bus and is done under the
|
||||
* root port uport_dev lock.
|
||||
*
|
||||
* Take the cxl_nvb device lock to ensure that cxl_nvb driver is in a
|
||||
* consistent state. And the driver registers nvdimm_bus.
|
||||
*/
|
||||
guard(device)(cxl_nvb->port->uport_dev);
|
||||
guard(device)(&cxl_nvb->dev);
|
||||
if (!cxl_nvb->nvdimm_bus) {
|
||||
rc = -ENODEV;
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
cxl_nvd = cxl_nvdimm_alloc(cxl_nvb, cxlmd);
|
||||
if (IS_ERR(cxl_nvd)) {
|
||||
rc = PTR_ERR(cxl_nvd);
|
||||
|
|
|
|||
|
|
@ -615,22 +615,8 @@ struct cxl_port *parent_port_of(struct cxl_port *port)
|
|||
static void unregister_port(void *_port)
|
||||
{
|
||||
struct cxl_port *port = _port;
|
||||
struct cxl_port *parent = parent_port_of(port);
|
||||
struct device *lock_dev;
|
||||
|
||||
/*
|
||||
* CXL root port's and the first level of ports are unregistered
|
||||
* under the platform firmware device lock, all other ports are
|
||||
* unregistered while holding their parent port lock.
|
||||
*/
|
||||
if (!parent)
|
||||
lock_dev = port->uport_dev;
|
||||
else if (is_cxl_root(parent))
|
||||
lock_dev = parent->uport_dev;
|
||||
else
|
||||
lock_dev = &parent->dev;
|
||||
|
||||
device_lock_assert(lock_dev);
|
||||
device_lock_assert(port_to_host(port));
|
||||
port->dead = true;
|
||||
device_unregister(&port->dev);
|
||||
}
|
||||
|
|
@ -1427,20 +1413,11 @@ static struct device *grandparent(struct device *dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct device *endpoint_host(struct cxl_port *endpoint)
|
||||
{
|
||||
struct cxl_port *port = to_cxl_port(endpoint->dev.parent);
|
||||
|
||||
if (is_cxl_root(port))
|
||||
return port->uport_dev;
|
||||
return &port->dev;
|
||||
}
|
||||
|
||||
static void delete_endpoint(void *data)
|
||||
{
|
||||
struct cxl_memdev *cxlmd = data;
|
||||
struct cxl_port *endpoint = cxlmd->endpoint;
|
||||
struct device *host = endpoint_host(endpoint);
|
||||
struct device *host = port_to_host(endpoint);
|
||||
|
||||
scoped_guard(device, host) {
|
||||
if (host->driver && !endpoint->dead) {
|
||||
|
|
@ -1456,7 +1433,7 @@ static void delete_endpoint(void *data)
|
|||
|
||||
int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
|
||||
{
|
||||
struct device *host = endpoint_host(endpoint);
|
||||
struct device *host = port_to_host(endpoint);
|
||||
struct device *dev = &cxlmd->dev;
|
||||
|
||||
get_device(host);
|
||||
|
|
@ -1790,7 +1767,16 @@ static struct cxl_dport *find_or_add_dport(struct cxl_port *port,
|
|||
{
|
||||
struct cxl_dport *dport;
|
||||
|
||||
device_lock_assert(&port->dev);
|
||||
/*
|
||||
* The port is already visible in CXL hierarchy, but it may still
|
||||
* be in the process of binding to the CXL port driver at this point.
|
||||
*
|
||||
* port creation and driver binding are protected by the port's host
|
||||
* lock, so acquire the host lock here to ensure the port has completed
|
||||
* driver binding before proceeding with dport addition.
|
||||
*/
|
||||
guard(device)(port_to_host(port));
|
||||
guard(device)(&port->dev);
|
||||
dport = cxl_find_dport_by_dev(port, dport_dev);
|
||||
if (!dport) {
|
||||
dport = probe_dport(port, dport_dev);
|
||||
|
|
@ -1857,13 +1843,11 @@ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
|
|||
* RP port enumerated by cxl_acpi without dport will
|
||||
* have the dport added here.
|
||||
*/
|
||||
scoped_guard(device, &port->dev) {
|
||||
dport = find_or_add_dport(port, dport_dev);
|
||||
if (IS_ERR(dport)) {
|
||||
if (PTR_ERR(dport) == -EAGAIN)
|
||||
goto retry;
|
||||
return PTR_ERR(dport);
|
||||
}
|
||||
dport = find_or_add_dport(port, dport_dev);
|
||||
if (IS_ERR(dport)) {
|
||||
if (PTR_ERR(dport) == -EAGAIN)
|
||||
goto retry;
|
||||
return PTR_ERR(dport);
|
||||
}
|
||||
|
||||
rc = cxl_add_ep(dport, &cxlmd->dev);
|
||||
|
|
|
|||
|
|
@ -1100,12 +1100,12 @@ static int cxl_rr_assign_decoder(struct cxl_port *port, struct cxl_region *cxlr,
|
|||
static void cxl_region_setup_flags(struct cxl_region *cxlr,
|
||||
struct cxl_decoder *cxld)
|
||||
{
|
||||
if (test_bit(CXL_DECODER_F_LOCK, &cxld->flags)) {
|
||||
if (cxld->flags & CXL_DECODER_F_LOCK) {
|
||||
set_bit(CXL_REGION_F_LOCK, &cxlr->flags);
|
||||
clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
|
||||
}
|
||||
|
||||
if (test_bit(CXL_DECODER_F_NORMALIZED_ADDRESSING, &cxld->flags))
|
||||
if (cxld->flags & CXL_DECODER_F_NORMALIZED_ADDRESSING)
|
||||
set_bit(CXL_REGION_F_NORMALIZED_ADDRESSING, &cxlr->flags);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -574,11 +574,16 @@ struct cxl_nvdimm_bridge {
|
|||
|
||||
#define CXL_DEV_ID_LEN 19
|
||||
|
||||
enum {
|
||||
CXL_NVD_F_INVALIDATED = 0,
|
||||
};
|
||||
|
||||
struct cxl_nvdimm {
|
||||
struct device dev;
|
||||
struct cxl_memdev *cxlmd;
|
||||
u8 dev_id[CXL_DEV_ID_LEN]; /* for nvdimm, string of 'serial' */
|
||||
u64 dirty_shutdowns;
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
struct cxl_pmem_region_mapping {
|
||||
|
|
@ -920,6 +925,8 @@ void cxl_driver_unregister(struct cxl_driver *cxl_drv);
|
|||
struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev);
|
||||
struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host,
|
||||
struct cxl_port *port);
|
||||
struct cxl_nvdimm_bridge *__devm_cxl_add_nvdimm_bridge(struct device *host,
|
||||
struct cxl_port *port);
|
||||
struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev);
|
||||
bool is_cxl_nvdimm(struct device *dev);
|
||||
int devm_cxl_add_nvdimm(struct device *host, struct cxl_port *port,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,20 @@
|
|||
|
||||
static __read_mostly DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX);
|
||||
|
||||
/**
|
||||
* devm_cxl_add_nvdimm_bridge() - add the root of a LIBNVDIMM topology
|
||||
* @host: platform firmware root device
|
||||
* @port: CXL port at the root of a CXL topology
|
||||
*
|
||||
* Return: bridge device that can host cxl_nvdimm objects
|
||||
*/
|
||||
struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host,
|
||||
struct cxl_port *port)
|
||||
{
|
||||
return __devm_cxl_add_nvdimm_bridge(host, port);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm_bridge, "CXL");
|
||||
|
||||
static void clear_exclusive(void *mds)
|
||||
{
|
||||
clear_exclusive_cxl_commands(mds, exclusive_cmds);
|
||||
|
|
@ -129,6 +143,9 @@ static int cxl_nvdimm_probe(struct device *dev)
|
|||
struct nvdimm *nvdimm;
|
||||
int rc;
|
||||
|
||||
if (test_bit(CXL_NVD_F_INVALIDATED, &cxl_nvd->flags))
|
||||
return -EBUSY;
|
||||
|
||||
set_exclusive_cxl_commands(mds, exclusive_cmds);
|
||||
rc = devm_add_action_or_reset(dev, clear_exclusive, mds);
|
||||
if (rc)
|
||||
|
|
@ -309,8 +326,10 @@ static int detach_nvdimm(struct device *dev, void *data)
|
|||
scoped_guard(device, dev) {
|
||||
if (dev->driver) {
|
||||
cxl_nvd = to_cxl_nvdimm(dev);
|
||||
if (cxl_nvd->cxlmd && cxl_nvd->cxlmd->cxl_nvb == data)
|
||||
if (cxl_nvd->cxlmd && cxl_nvd->cxlmd->cxl_nvb == data) {
|
||||
release = true;
|
||||
set_bit(CXL_NVD_F_INVALIDATED, &cxl_nvd->flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (release)
|
||||
|
|
@ -353,6 +372,7 @@ static struct cxl_driver cxl_nvdimm_bridge_driver = {
|
|||
.probe = cxl_nvdimm_bridge_probe,
|
||||
.id = CXL_DEVICE_NVDIMM_BRIDGE,
|
||||
.drv = {
|
||||
.probe_type = PROBE_FORCE_SYNCHRONOUS,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -981,11 +981,7 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
|
|||
}
|
||||
|
||||
/* Add devres action to release DPLL related resources */
|
||||
rc = devm_add_action_or_reset(zldev->dev, zl3073x_dev_dpll_fini, zldev);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
return devm_add_action_or_reset(zldev->dev, zl3073x_dev_dpll_fini, zldev);
|
||||
|
||||
error:
|
||||
zl3073x_dev_dpll_fini(zldev);
|
||||
|
|
@ -1026,6 +1022,7 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev,
|
|||
"Unknown or non-match chip ID: 0x%0x\n",
|
||||
id);
|
||||
}
|
||||
zldev->chip_id = id;
|
||||
|
||||
/* Read revision, firmware version and custom config version */
|
||||
rc = zl3073x_read_u16(zldev, ZL_REG_REVISION, &revision);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ struct zl3073x_dpll;
|
|||
* @dev: pointer to device
|
||||
* @regmap: regmap to access device registers
|
||||
* @multiop_lock: to serialize multiple register operations
|
||||
* @chip_id: chip ID read from hardware
|
||||
* @ref: array of input references' invariants
|
||||
* @out: array of outs' invariants
|
||||
* @synth: array of synths' invariants
|
||||
|
|
@ -48,6 +49,7 @@ struct zl3073x_dev {
|
|||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct mutex multiop_lock;
|
||||
u16 chip_id;
|
||||
|
||||
/* Invariants */
|
||||
struct zl3073x_ref ref[ZL3073X_NUM_REFS];
|
||||
|
|
@ -144,6 +146,32 @@ int zl3073x_write_hwreg_seq(struct zl3073x_dev *zldev,
|
|||
|
||||
int zl3073x_ref_phase_offsets_update(struct zl3073x_dev *zldev, int channel);
|
||||
|
||||
/**
|
||||
* zl3073x_dev_is_ref_phase_comp_32bit - check ref phase comp register size
|
||||
* @zldev: pointer to zl3073x device
|
||||
*
|
||||
* Some chip IDs have a 32-bit wide ref_phase_offset_comp register instead
|
||||
* of the default 48-bit.
|
||||
*
|
||||
* Return: true if the register is 32-bit, false if 48-bit
|
||||
*/
|
||||
static inline bool
|
||||
zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev *zldev)
|
||||
{
|
||||
switch (zldev->chip_id) {
|
||||
case 0x0E30:
|
||||
case 0x0E93:
|
||||
case 0x0E94:
|
||||
case 0x0E95:
|
||||
case 0x0E96:
|
||||
case 0x0E97:
|
||||
case 0x1F60:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
zl3073x_is_n_pin(u8 id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -475,8 +475,11 @@ zl3073x_dpll_input_pin_phase_adjust_get(const struct dpll_pin *dpll_pin,
|
|||
ref_id = zl3073x_input_pin_ref_get(pin->id);
|
||||
ref = zl3073x_ref_state_get(zldev, ref_id);
|
||||
|
||||
/* Perform sign extension for 48bit signed value */
|
||||
phase_comp = sign_extend64(ref->phase_comp, 47);
|
||||
/* Perform sign extension based on register width */
|
||||
if (zl3073x_dev_is_ref_phase_comp_32bit(zldev))
|
||||
phase_comp = sign_extend64(ref->phase_comp, 31);
|
||||
else
|
||||
phase_comp = sign_extend64(ref->phase_comp, 47);
|
||||
|
||||
/* Reverse two's complement negation applied during set and convert
|
||||
* to 32bit signed int
|
||||
|
|
|
|||
|
|
@ -121,8 +121,16 @@ int zl3073x_ref_state_fetch(struct zl3073x_dev *zldev, u8 index)
|
|||
return rc;
|
||||
|
||||
/* Read phase compensation register */
|
||||
rc = zl3073x_read_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP,
|
||||
&ref->phase_comp);
|
||||
if (zl3073x_dev_is_ref_phase_comp_32bit(zldev)) {
|
||||
u32 val;
|
||||
|
||||
rc = zl3073x_read_u32(zldev, ZL_REG_REF_PHASE_OFFSET_COMP_32,
|
||||
&val);
|
||||
ref->phase_comp = val;
|
||||
} else {
|
||||
rc = zl3073x_read_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP,
|
||||
&ref->phase_comp);
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
|
@ -179,9 +187,16 @@ int zl3073x_ref_state_set(struct zl3073x_dev *zldev, u8 index,
|
|||
if (!rc && dref->sync_ctrl != ref->sync_ctrl)
|
||||
rc = zl3073x_write_u8(zldev, ZL_REG_REF_SYNC_CTRL,
|
||||
ref->sync_ctrl);
|
||||
if (!rc && dref->phase_comp != ref->phase_comp)
|
||||
rc = zl3073x_write_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP,
|
||||
ref->phase_comp);
|
||||
if (!rc && dref->phase_comp != ref->phase_comp) {
|
||||
if (zl3073x_dev_is_ref_phase_comp_32bit(zldev))
|
||||
rc = zl3073x_write_u32(zldev,
|
||||
ZL_REG_REF_PHASE_OFFSET_COMP_32,
|
||||
ref->phase_comp);
|
||||
else
|
||||
rc = zl3073x_write_u48(zldev,
|
||||
ZL_REG_REF_PHASE_OFFSET_COMP,
|
||||
ref->phase_comp);
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@
|
|||
#define ZL_REF_CONFIG_DIFF_EN BIT(2)
|
||||
|
||||
#define ZL_REG_REF_PHASE_OFFSET_COMP ZL_REG(10, 0x28, 6)
|
||||
#define ZL_REG_REF_PHASE_OFFSET_COMP_32 ZL_REG(10, 0x28, 4)
|
||||
|
||||
#define ZL_REG_REF_SYNC_CTRL ZL_REG(10, 0x2e, 1)
|
||||
#define ZL_REF_SYNC_CTRL_MODE GENMASK(2, 0)
|
||||
|
|
|
|||
|
|
@ -848,7 +848,7 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci,
|
|||
{
|
||||
struct device *dev = ohci->card.device;
|
||||
unsigned int i;
|
||||
struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES];
|
||||
struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES] = { NULL };
|
||||
dma_addr_t dma_addrs[AR_BUFFERS];
|
||||
void *vaddr;
|
||||
struct descriptor *d;
|
||||
|
|
|
|||
|
|
@ -748,14 +748,14 @@ static bool gpio_shared_entry_is_really_shared(struct gpio_shared_entry *entry)
|
|||
static void gpio_shared_free_exclusive(void)
|
||||
{
|
||||
struct gpio_shared_entry *entry, *epos;
|
||||
struct gpio_shared_ref *ref, *rpos;
|
||||
|
||||
list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) {
|
||||
if (gpio_shared_entry_is_really_shared(entry))
|
||||
continue;
|
||||
|
||||
gpio_shared_drop_ref(list_first_entry(&entry->refs,
|
||||
struct gpio_shared_ref,
|
||||
list));
|
||||
list_for_each_entry_safe(ref, rpos, &entry->refs, list)
|
||||
gpio_shared_drop_ref(ref);
|
||||
gpio_shared_drop_entry(entry);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3267,8 +3267,12 @@ static int gpiochip_get(struct gpio_chip *gc, unsigned int offset)
|
|||
|
||||
/* Make sure this is called after checking for gc->get(). */
|
||||
ret = gc->get(gc, offset);
|
||||
if (ret > 1)
|
||||
ret = -EBADE;
|
||||
if (ret > 1) {
|
||||
gpiochip_warn(gc,
|
||||
"invalid return value from gc->get(): %d, consider fixing the driver\n",
|
||||
ret);
|
||||
ret = !!ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -641,6 +641,7 @@ static void aca_error_fini(struct aca_error *aerr)
|
|||
aca_bank_error_remove(aerr, bank_error);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&aerr->lock);
|
||||
mutex_destroy(&aerr->lock);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7059,6 +7059,15 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
|
|||
dev_info(adev->dev, "PCI error: slot reset callback!!\n");
|
||||
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive) {
|
||||
mutex_lock(&hive->hive_lock);
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
} else {
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
}
|
||||
|
||||
if (adev->pcie_reset_ctx.swus)
|
||||
link_dev = adev->pcie_reset_ctx.swus;
|
||||
|
|
@ -7099,19 +7108,13 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
|
|||
reset_context.reset_req_dev = adev;
|
||||
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive) {
|
||||
mutex_lock(&hive->hive_lock);
|
||||
reset_context.hive = hive;
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
|
||||
tmp_adev->pcie_reset_ctx.in_link_reset = true;
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
}
|
||||
} else {
|
||||
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
}
|
||||
|
||||
r = amdgpu_device_asic_reset(adev, &device_list, &reset_context);
|
||||
|
|
|
|||
|
|
@ -332,13 +332,13 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
|
|||
if (!context || !context->initialized) {
|
||||
dev_err(adev->dev, "TA is not initialized\n");
|
||||
ret = -EINVAL;
|
||||
goto err_free_shared_buf;
|
||||
goto free_shared_buf;
|
||||
}
|
||||
|
||||
if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_invoke) {
|
||||
dev_err(adev->dev, "Unsupported function to invoke TA\n");
|
||||
ret = -EOPNOTSUPP;
|
||||
goto err_free_shared_buf;
|
||||
goto free_shared_buf;
|
||||
}
|
||||
|
||||
context->session_id = ta_id;
|
||||
|
|
@ -346,7 +346,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
|
|||
mutex_lock(&psp->ras_context.mutex);
|
||||
ret = prep_ta_mem_context(&context->mem_context, shared_buf, shared_buf_len);
|
||||
if (ret)
|
||||
goto err_free_shared_buf;
|
||||
goto unlock;
|
||||
|
||||
ret = psp_fn_ta_invoke(psp, cmd_id);
|
||||
if (ret || context->resp_status) {
|
||||
|
|
@ -354,15 +354,17 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
|
|||
ret, context->resp_status);
|
||||
if (!ret) {
|
||||
ret = -EINVAL;
|
||||
goto err_free_shared_buf;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user((char *)&buf[copy_pos], context->mem_context.shared_buf, shared_buf_len))
|
||||
ret = -EFAULT;
|
||||
|
||||
err_free_shared_buf:
|
||||
unlock:
|
||||
mutex_unlock(&psp->ras_context.mutex);
|
||||
|
||||
free_shared_buf:
|
||||
kfree(shared_buf);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
static const struct dma_fence_ops amdgpu_userq_fence_ops;
|
||||
static struct kmem_cache *amdgpu_userq_fence_slab;
|
||||
|
||||
#define AMDGPU_USERQ_MAX_HANDLES (1U << 16)
|
||||
|
||||
int amdgpu_userq_fence_slab_init(void)
|
||||
{
|
||||
amdgpu_userq_fence_slab = kmem_cache_create("amdgpu_userq_fence",
|
||||
|
|
@ -478,6 +480,11 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
|
|||
if (!amdgpu_userq_enabled(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (args->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES ||
|
||||
args->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
|
||||
args->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)
|
||||
return -EINVAL;
|
||||
|
||||
num_syncobj_handles = args->num_syncobj_handles;
|
||||
syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles),
|
||||
size_mul(sizeof(u32), num_syncobj_handles));
|
||||
|
|
@ -664,6 +671,11 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
if (!amdgpu_userq_enabled(dev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (wait_info->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES ||
|
||||
wait_info->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES ||
|
||||
wait_info->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES)
|
||||
return -EINVAL;
|
||||
|
||||
num_read_bo_handles = wait_info->num_bo_read_handles;
|
||||
bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles),
|
||||
size_mul(sizeof(u32), num_read_bo_handles));
|
||||
|
|
@ -833,7 +845,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
dma_resv_for_each_fence(&resv_cursor, gobj_read[i]->resv,
|
||||
DMA_RESV_USAGE_READ, fence) {
|
||||
if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) {
|
||||
if (num_fences >= wait_info->num_fences) {
|
||||
r = -EINVAL;
|
||||
goto free_fences;
|
||||
}
|
||||
|
|
@ -850,7 +862,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
dma_resv_for_each_fence(&resv_cursor, gobj_write[i]->resv,
|
||||
DMA_RESV_USAGE_WRITE, fence) {
|
||||
if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) {
|
||||
if (num_fences >= wait_info->num_fences) {
|
||||
r = -EINVAL;
|
||||
goto free_fences;
|
||||
}
|
||||
|
|
@ -874,8 +886,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
goto free_fences;
|
||||
|
||||
dma_fence_unwrap_for_each(f, &iter, fence) {
|
||||
if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) {
|
||||
if (num_fences >= wait_info->num_fences) {
|
||||
r = -EINVAL;
|
||||
dma_fence_put(fence);
|
||||
goto free_fences;
|
||||
}
|
||||
|
||||
|
|
@ -898,8 +911,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||
if (r)
|
||||
goto free_fences;
|
||||
|
||||
if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) {
|
||||
if (num_fences >= wait_info->num_fences) {
|
||||
r = -EINVAL;
|
||||
dma_fence_put(fence);
|
||||
goto free_fences;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -720,11 +720,6 @@ static int mes_v11_0_set_hw_resources(struct amdgpu_mes *mes)
|
|||
mes_set_hw_res_pkt.enable_reg_active_poll = 1;
|
||||
mes_set_hw_res_pkt.enable_level_process_quantum_check = 1;
|
||||
mes_set_hw_res_pkt.oversubscription_timer = 50;
|
||||
if ((mes->adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x7f)
|
||||
mes_set_hw_res_pkt.enable_lr_compute_wa = 1;
|
||||
else
|
||||
dev_info_once(mes->adev->dev,
|
||||
"MES FW version must be >= 0x7f to enable LR compute workaround.\n");
|
||||
|
||||
if (amdgpu_mes_log_enable) {
|
||||
mes_set_hw_res_pkt.enable_mes_event_int_logging = 1;
|
||||
|
|
|
|||
|
|
@ -779,11 +779,6 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe)
|
|||
mes_set_hw_res_pkt.use_different_vmid_compute = 1;
|
||||
mes_set_hw_res_pkt.enable_reg_active_poll = 1;
|
||||
mes_set_hw_res_pkt.enable_level_process_quantum_check = 1;
|
||||
if ((mes->adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x82)
|
||||
mes_set_hw_res_pkt.enable_lr_compute_wa = 1;
|
||||
else
|
||||
dev_info_once(adev->dev,
|
||||
"MES FW version must be >= 0x82 to enable LR compute workaround.\n");
|
||||
|
||||
/*
|
||||
* Keep oversubscribe timer for sdma . When we have unmapped doorbell
|
||||
|
|
|
|||
|
|
@ -174,6 +174,10 @@ static int vcn_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
|
||||
fw_shared->sq.is_enabled = 1;
|
||||
|
||||
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG);
|
||||
fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?
|
||||
AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;
|
||||
|
||||
if (amdgpu_vcnfw_log)
|
||||
amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
|
||||
|
||||
|
|
|
|||
|
|
@ -170,11 +170,11 @@ struct dc_stream_state *dc_create_stream_for_sink(
|
|||
if (sink == NULL)
|
||||
goto fail;
|
||||
|
||||
stream = kzalloc_obj(struct dc_stream_state);
|
||||
stream = kzalloc_obj(struct dc_stream_state, GFP_ATOMIC);
|
||||
if (stream == NULL)
|
||||
goto fail;
|
||||
|
||||
stream->update_scratch = kzalloc((int32_t) dc_update_scratch_space_size(), GFP_KERNEL);
|
||||
stream->update_scratch = kzalloc((int32_t) dc_update_scratch_space_size(), GFP_ATOMIC);
|
||||
if (stream->update_scratch == NULL)
|
||||
goto fail;
|
||||
|
||||
|
|
|
|||
|
|
@ -1881,6 +1881,14 @@ static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)
|
||||
{
|
||||
if (dsi->te_gpio) {
|
||||
free_irq(gpiod_to_irq(dsi->te_gpio), dsi);
|
||||
gpiod_put(dsi->te_gpio);
|
||||
}
|
||||
}
|
||||
|
||||
static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
|
||||
struct mipi_dsi_device *device)
|
||||
{
|
||||
|
|
@ -1961,7 +1969,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
|
|||
if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
|
||||
ret = samsung_dsim_register_te_irq(dsi, &device->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_bridge;
|
||||
}
|
||||
|
||||
// The next bridge can be used by host_ops->attach
|
||||
|
|
@ -1982,15 +1990,12 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
|
|||
err_release_next_bridge:
|
||||
drm_bridge_put(dsi->bridge.next_bridge);
|
||||
dsi->bridge.next_bridge = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)
|
||||
{
|
||||
if (dsi->te_gpio) {
|
||||
free_irq(gpiod_to_irq(dsi->te_gpio), dsi);
|
||||
gpiod_put(dsi->te_gpio);
|
||||
}
|
||||
if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO))
|
||||
samsung_dsim_unregister_te_irq(dsi);
|
||||
err_remove_bridge:
|
||||
drm_bridge_remove(&dsi->bridge);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
|
||||
|
|
|
|||
|
|
@ -2049,7 +2049,9 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
|
|||
bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
|
||||
bridge->ycbcr_420_allowed = true;
|
||||
|
||||
devm_drm_bridge_add(dev, bridge);
|
||||
ret = devm_drm_bridge_add(dev, bridge);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
dp->aux.dev = dev;
|
||||
dp->aux.drm_dev = encoder->dev;
|
||||
|
|
|
|||
|
|
@ -1415,6 +1415,7 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
|
|||
{
|
||||
struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);
|
||||
struct device_node *np = pdata->dev->of_node;
|
||||
const struct i2c_client *client = to_i2c_client(pdata->dev);
|
||||
int ret;
|
||||
|
||||
pdata->next_bridge = devm_drm_of_get_bridge(&adev->dev, np, 1, 0);
|
||||
|
|
@ -1433,8 +1434,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,
|
|||
? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP;
|
||||
|
||||
if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) {
|
||||
pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT |
|
||||
DRM_BRIDGE_OP_HPD;
|
||||
pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;
|
||||
if (client->irq)
|
||||
pdata->bridge.ops |= DRM_BRIDGE_OP_HPD;
|
||||
/*
|
||||
* If comms were already enabled they would have been enabled
|
||||
* with the wrong value of HPD_DISABLE. Update it now. Comms
|
||||
|
|
|
|||
|
|
@ -930,7 +930,8 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
|
|||
mutex_unlock(&client->modeset_mutex);
|
||||
out:
|
||||
kfree(crtcs);
|
||||
modes_destroy(dev, modes, connector_count);
|
||||
if (modes)
|
||||
modes_destroy(dev, modes, connector_count);
|
||||
kfree(modes);
|
||||
kfree(offsets);
|
||||
kfree(enabled);
|
||||
|
|
|
|||
|
|
@ -1338,14 +1338,14 @@ bool drm_gpusvm_range_pages_valid(struct drm_gpusvm *gpusvm,
|
|||
EXPORT_SYMBOL_GPL(drm_gpusvm_range_pages_valid);
|
||||
|
||||
/**
|
||||
* drm_gpusvm_range_pages_valid_unlocked() - GPU SVM range pages valid unlocked
|
||||
* drm_gpusvm_pages_valid_unlocked() - GPU SVM pages valid unlocked
|
||||
* @gpusvm: Pointer to the GPU SVM structure
|
||||
* @range: Pointer to the GPU SVM range structure
|
||||
* @svm_pages: Pointer to the GPU SVM pages structure
|
||||
*
|
||||
* This function determines if a GPU SVM range pages are valid. Expected be
|
||||
* called without holding gpusvm->notifier_lock.
|
||||
* This function determines if a GPU SVM pages are valid. Expected be called
|
||||
* without holding gpusvm->notifier_lock.
|
||||
*
|
||||
* Return: True if GPU SVM range has valid pages, False otherwise
|
||||
* Return: True if GPU SVM pages are valid, False otherwise
|
||||
*/
|
||||
static bool drm_gpusvm_pages_valid_unlocked(struct drm_gpusvm *gpusvm,
|
||||
struct drm_gpusvm_pages *svm_pages)
|
||||
|
|
|
|||
|
|
@ -562,12 +562,7 @@ void intel_alpm_disable(struct intel_dp *intel_dp)
|
|||
mutex_lock(&intel_dp->alpm.lock);
|
||||
|
||||
intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder),
|
||||
ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE |
|
||||
ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
|
||||
|
||||
intel_de_rmw(display,
|
||||
PORT_ALPM_CTL(cpu_transcoder),
|
||||
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
|
||||
ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE, 0);
|
||||
|
||||
drm_dbg_kms(display->drm, "Disabling ALPM\n");
|
||||
mutex_unlock(&intel_dp->alpm.lock);
|
||||
|
|
|
|||
|
|
@ -256,7 +256,9 @@ static int imx_pd_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, imxpd);
|
||||
|
||||
devm_drm_bridge_add(dev, &imxpd->bridge);
|
||||
ret = devm_drm_bridge_add(dev, &imxpd->bridge);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return component_add(dev, &imx_pd_ops);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@ static int logicvc_drm_config_parse(struct logicvc_drm *logicvc)
|
|||
struct device *dev = drm_dev->dev;
|
||||
struct device_node *of_node = dev->of_node;
|
||||
struct logicvc_drm_config *config = &logicvc->config;
|
||||
struct device_node *layers_node;
|
||||
int ret;
|
||||
|
||||
logicvc_of_property_parse_bool(of_node, LOGICVC_OF_PROPERTY_DITHERING,
|
||||
|
|
@ -128,7 +127,8 @@ static int logicvc_drm_config_parse(struct logicvc_drm *logicvc)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
layers_node = of_get_child_by_name(of_node, "layers");
|
||||
struct device_node *layers_node __free(device_node) =
|
||||
of_get_child_by_name(of_node, "layers");
|
||||
if (!layers_node) {
|
||||
drm_err(drm_dev, "Missing non-optional layers node\n");
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -737,8 +737,8 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
|
|||
if (!obj)
|
||||
goto done;
|
||||
|
||||
if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
WARN_ON(obj->buffer.length != 4))
|
||||
if (obj->type != ACPI_TYPE_BUFFER ||
|
||||
obj->buffer.length != 4)
|
||||
goto done;
|
||||
|
||||
caps->status = 0;
|
||||
|
|
@ -773,8 +773,8 @@ r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt)
|
|||
if (!obj)
|
||||
goto done;
|
||||
|
||||
if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
WARN_ON(obj->buffer.length != 4))
|
||||
if (obj->type != ACPI_TYPE_BUFFER ||
|
||||
obj->buffer.length != 4)
|
||||
goto done;
|
||||
|
||||
jt->status = 0;
|
||||
|
|
@ -861,8 +861,8 @@ r535_gsp_acpi_dod(acpi_handle handle, DOD_METHOD_DATA *dod)
|
|||
|
||||
_DOD = output.pointer;
|
||||
|
||||
if (WARN_ON(_DOD->type != ACPI_TYPE_PACKAGE) ||
|
||||
WARN_ON(_DOD->package.count > ARRAY_SIZE(dod->acpiIdList)))
|
||||
if (_DOD->type != ACPI_TYPE_PACKAGE ||
|
||||
_DOD->package.count > ARRAY_SIZE(dod->acpiIdList))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _DOD->package.count; i++) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user