Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Cross-merge networking fixes after downstream PR (net-7.1-rc4).

No conflicts, or adjacent changes.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2026-04-30 12:49:56 -07:00
323 changed files with 3944 additions and 2235 deletions

View File

@@ -682,6 +682,7 @@ Peter A Jonsson <pj@ludd.ltu.se>
Peter Hilber <peter.hilber@oss.qualcomm.com> <quic_philber@quicinc.com>
Peter Oruba <peter.oruba@amd.com>
Peter Oruba <peter@oruba.de>
Peter Rosin <peda@lysator.liu.se> <peda@axentia.se>
Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> <pierre-louis.bossart@linux.intel.com>
Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com>
Pratyush Yadav <pratyush@kernel.org> <ptyadav@amazon.de>

View File

@@ -16,10 +16,15 @@ allOf:
properties:
compatible:
enum:
- amlogic,meson6-i2c # Meson6, Meson8 and compatible SoCs
- amlogic,meson-gxbb-i2c # GXBB and compatible SoCs
- amlogic,meson-axg-i2c # AXG and compatible SoCs
oneOf:
- items:
- enum:
- amlogic,t7-i2c
- const: amlogic,meson-axg-i2c
- enum:
- amlogic,meson6-i2c # Meson6, Meson8 and compatible SoCs
- amlogic,meson-gxbb-i2c # GXBB and compatible SoCs
- amlogic,meson-axg-i2c # AXG and compatible SoCs
reg:
maxItems: 1

View File

@@ -22,7 +22,9 @@ properties:
compatible:
oneOf:
- items:
- const: apple,t6020-i2c
- enum:
- apple,t6020-i2c
- apple,t8122-i2c
- const: apple,t8103-i2c
- items:
- enum:

View File

@@ -135,4 +135,4 @@ References
4. **Lenovo IdeaPad Laptop Driver:** Reference for DMI-based hardware
feature gating in Lenovo laptops.
https://github.com/torvalds/linux/blob/master/drivers/platform/x86/ideapad-laptop.c
https://github.com/torvalds/linux/blob/master/drivers/platform/x86/lenovo/ideapad-laptop.c

View File

@@ -69,6 +69,15 @@ properties:
header:
description: For C-compatible languages, header which already defines this value.
type: string
scope:
description: |
Visibility of this definition. "uapi" (default) renders into
the uAPI header, "kernel" renders into the kernel-side
generated header, "user" renders into the user-side
generated header. When combined with `header:`, the
definition is not rendered, and the named header is
included only by code matching the scope.
enum: [ uapi, kernel, user ]
type:
enum: [ const, enum, flags ]
doc:

View File

@@ -83,6 +83,15 @@ properties:
header:
description: For C-compatible languages, header which already defines this value.
type: string
scope:
description: |
Visibility of this definition. "uapi" (default) renders into
the uAPI header, "kernel" renders into the kernel-side
generated header, "user" renders into the user-side
generated header. When combined with `header:`, the
definition is not rendered, and the named header is
included only by code matching the scope.
enum: [ uapi, kernel, user ]
type:
enum: [ const, enum, flags, struct ] # Trim
doc:

View File

@@ -55,6 +55,15 @@ properties:
header:
description: For C-compatible languages, header which already defines this value.
type: string
scope:
description: |
Visibility of this definition. "uapi" (default) renders into
the uAPI header, "kernel" renders into the kernel-side
generated header, "user" renders into the user-side
generated header. When combined with `header:`, the
definition is not rendered, and the named header is
included only by code matching the scope.
enum: [ uapi, kernel, user ]
type:
enum: [ const, enum, flags ]
doc:

View File

@@ -87,6 +87,15 @@ properties:
header:
description: For C-compatible languages, header which already defines this value.
type: string
scope:
description: |
Visibility of this definition. "uapi" (default) renders into
the uAPI header, "kernel" renders into the kernel-side
generated header, "user" renders into the user-side
generated header. When combined with `header:`, the
definition is not rendered, and the named header is
included only by code matching the scope.
enum: [ uapi, kernel, user ]
type:
enum: [ const, enum, flags, struct ] # Trim
doc:

View File

@@ -33,6 +33,11 @@ doc: |
@cap-get operation.
definitions:
-
type: const
name: max-handle-id
value: 0x3fffffe
scope: kernel
-
type: enum
name: scope
@@ -140,6 +145,8 @@ attribute-sets:
-
name: id
type: u32
checks:
max: max-handle-id
doc: |
Numeric identifier of a shaper. The id semantic depends on
the scope. For @queue scope it's the queue id and for @node

View File

@@ -24,6 +24,97 @@ Quick access to CPU number, node ID
Allows to implement per CPU data efficiently. Documentation is in code and
selftests. :(
Optimized RSEQ V2
-----------------
On architectures which utilize the generic entry code and generic TIF bits
the kernel supports runtime optimizations for RSEQ, which also enable
enhanced features like scheduler time slice extensions.
To enable them a task has to register the RSEQ region with at least the
length advertised by getauxval(AT_RSEQ_FEATURE_SIZE).
If existing binaries register with RSEQ_ORIG_SIZE (32 bytes), the kernel
keeps the legacy low performance mode enabled to fulfil the expectations
of existing users regarding the original RSEQ implementation behaviour.
The following table documents the ABI and behavioral guarantees of the
legacy and the optimized V2 mode.
.. list-table:: RSEQ modes
:header-rows: 1
* - Nr
- What
- Legacy
- Optimized V2
* - 1
- The cpu_id_start, cpu_id, node_id and mm_cid fields (User mode read
only)
.. Legacy
- Updated by the kernel unconditionally after each context switch and
before signal delivery
.. Optimized V2
- Updated by the kernel if and only if they change, i.e. if the task
is migrated or mm_cid changes
* - 2
- The rseq_cs critical section field
.. Legacy
- Evaluated and handled unconditionally after each context switch and
before signal delivery
.. Optimized V2
- Evaluated and handled conditionally only when user space was
interrupted and was scheduled out or before delivering a signal in
the interrupted context.
* - 3
- Read only fields
.. Legacy
- No strict enforcement except in debug mode
.. Optimized V2
- Strict enforcement
* - 4
- membarrier(...RSEQ)
.. Legacy
- All running threads of the process are interrupted and the ID fields
are rewritten and eventually active critical sections are aborted
before they return to user space. All threads which are scheduled
out whether voluntary or not are covered by #1/#2 above.
.. Optimized V2
- All running threads of the process are interrupted and eventually
active critical sections are aborted before these threads return to
user space. The ID fields are only updated if changed as a
consequence of the interrupt. All threads which are scheduled out
whether voluntary or not are covered by #1/#2 above.
* - 5
- Time slice extensions
.. Legacy
- Not supported
.. Optimized V2
- Supported
The legacy mode is obviously less performant as it does unconditional
updates and critical section checks even if not strictly required by the
ABI contract. That can't be changed anymore as some users depend on that
observed behavior, which in turn enables them to violate the ABI and
overwrite the cpu_id_start field for their own purposes. This is obviously
discouraged as it renders RSEQ incompatible with the intended usage and
breaks the expectation of other libraries in the same application.
The ABI compliant optimized v2 mode, which respects the read only fields,
does not require unconditional updates and therefore is way more
performant. The kernel validates the read only fields for compliance. If
user space modifies them, the process is killed. Compliant usage allows
multiple libraries in the same application to benefit from the RSEQ
functionality without disturbing each other. The ABI compliant optimized v2
mode also enables extended RSEQ features like time slice extensions.
Scheduler time slice extensions
-------------------------------
@@ -37,7 +128,8 @@ The prerequisites for this functionality are:
* Enabled at boot time (default is enabled)
* A rseq userspace pointer has been registered for the thread
* A rseq userspace pointer has been registered for the thread in
optimized V2 mode
The thread has to enable the functionality via prctl(2)::

View File

@@ -656,8 +656,8 @@ References
See [white-paper]_, [api-spec]_, [amd-apm]_, [kvm-forum]_, and [snp-fw-abi]_
for more info.
.. [white-paper] https://developer.amd.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf
.. [api-spec] https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf
.. [amd-apm] https://support.amd.com/TechDocs/24593.pdf (section 15.34)
.. [white-paper] https://docs.amd.com/v/u/en-US/memory-encryption-white-paper
.. [api-spec] https://docs.amd.com/v/u/en-US/55766_PUB_3.24_SEV_API
.. [amd-apm] https://docs.amd.com/v/u/en-US/24593_3.44_APM_Vol2 (section 15.34)
.. [kvm-forum] https://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf
.. [snp-fw-abi] https://www.amd.com/system/files/TechDocs/56860.pdf
.. [snp-fw-abi] https://www.amd.com/content/dam/amd/en/documents/developer/56860.pdf

View File

@@ -68,6 +68,12 @@ Maintainers List
first. When adding to this list, please keep the entries in
alphabetical order.
3C509 NETWORK DRIVER
M: "Maciej W. Rozycki" <macro@orcam.me.uk>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/3com/3c509.c
3C59X NETWORK DRIVER
M: Steffen Klassert <klassert@kernel.org>
L: netdev@vger.kernel.org
@@ -2015,7 +2021,7 @@ F: Documentation/hwmon/aquacomputer_d5next.rst
F: drivers/hwmon/aquacomputer_d5next.c
AQUANTIA ETHERNET DRIVER (atlantic)
M: Igor Russkikh <irusskikh@marvell.com>
M: Sukhdeep Singh <sukhdeeps@marvell.com>
L: netdev@vger.kernel.org
S: Maintained
W: https://www.marvell.com/
@@ -2024,7 +2030,7 @@ F: Documentation/networking/device_drivers/ethernet/aquantia/atlantic.rst
F: drivers/net/ethernet/aquantia/atlantic/
AQUANTIA ETHERNET DRIVER PTP SUBSYSTEM
M: Egor Pomozov <epomozov@marvell.com>
M: Sukhdeep Singh <sukhdeeps@marvell.com>
L: netdev@vger.kernel.org
S: Maintained
W: http://www.aquantia.com
@@ -4181,8 +4187,8 @@ F: include/uapi/linux/sonet.h
F: net/atm/
ATMEL MACB ETHERNET DRIVER
M: Nicolas Ferre <nicolas.ferre@microchip.com>
M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
M: Théo Lebrun <theo.lebrun@bootlin.com>
R: Conor Dooley <conor.dooley@microchip.com>
S: Maintained
F: drivers/net/ethernet/cadence/
@@ -4299,18 +4305,16 @@ F: Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml
F: drivers/video/backlight/aw99706.c
AXENTIA ARM DEVICES
M: Peter Rosin <peda@axentia.se>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
S: Orphan
F: arch/arm/boot/dts/microchip/at91-linea.dtsi
F: arch/arm/boot/dts/microchip/at91-natte.dtsi
F: arch/arm/boot/dts/microchip/at91-nattis-2-natte-2.dts
F: arch/arm/boot/dts/microchip/at91-tse850-3.dts
AXENTIA ASOC DRIVERS
M: Peter Rosin <peda@axentia.se>
L: linux-sound@vger.kernel.org
S: Maintained
S: Orphan
F: Documentation/devicetree/bindings/sound/axentia,*
F: sound/soc/atmel/tse850-pcm5142.c
@@ -6358,6 +6362,7 @@ F: include/uapi/linux/comedi.h
COMMON CLK FRAMEWORK
M: Michael Turquette <mturquette@baylibre.com>
M: Stephen Boyd <sboyd@kernel.org>
R: Brian Masney <bmasney@redhat.com>
L: linux-clk@vger.kernel.org
S: Maintained
Q: http://patchwork.kernel.org/project/linux-clk/list/
@@ -8199,10 +8204,9 @@ F: include/uapi/drm/nouveau_drm.h
CORE DRIVER FOR NVIDIA GPUS [RUST]
M: Danilo Krummrich <dakr@kernel.org>
M: Alexandre Courbot <acourbot@nvidia.com>
L: nouveau@lists.freedesktop.org
L: nova-gpu@lists.linux.dev
S: Supported
W: https://rust-for-linux.com/nova-gpu-driver
Q: https://patchwork.freedesktop.org/project/nouveau/
B: https://gitlab.freedesktop.org/drm/nova/-/issues
C: irc://irc.oftc.net/nouveau
T: git https://gitlab.freedesktop.org/drm/rust/kernel.git drm-rust-next
@@ -8211,10 +8215,9 @@ F: drivers/gpu/nova-core/
DRM DRIVER FOR NVIDIA GPUS [RUST]
M: Danilo Krummrich <dakr@kernel.org>
L: nouveau@lists.freedesktop.org
L: nova-gpu@lists.linux.dev
S: Supported
W: https://rust-for-linux.com/nova-gpu-driver
Q: https://patchwork.freedesktop.org/project/nouveau/
B: https://gitlab.freedesktop.org/drm/nova/-/issues
C: irc://irc.oftc.net/nouveau
T: git https://gitlab.freedesktop.org/drm/rust/kernel.git drm-rust-next
@@ -12052,7 +12055,7 @@ F: Documentation/i2c/busses/i2c-nvidia-gpu.rst
F: drivers/i2c/busses/i2c-nvidia-gpu.c
I2C MUXES
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
L: linux-i2c@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/i2c/i2c-arb*
@@ -12453,7 +12456,7 @@ F: drivers/iio/industrialio-backend.c
F: include/linux/iio/backend.h
IIO DIGITAL POTENTIOMETER DAC
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-iio-dac-dpot-dac
@@ -12461,7 +12464,7 @@ F: Documentation/devicetree/bindings/iio/dac/dpot-dac.yaml
F: drivers/iio/dac/dpot-dac.c
IIO ENVELOPE DETECTOR
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-iio-adc-envelope-detector
@@ -12477,7 +12480,7 @@ F: include/linux/iio/iio-gts-helper.h
F: drivers/iio/test/iio-test-gts.c
IIO MULTIPLEXER
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/multiplexer/io-channel-mux.yaml
@@ -12508,7 +12511,7 @@ F: include/linux/iio/
F: tools/iio/
IIO UNIT CONVERTER
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/afe/current-sense-amplifier.yaml
@@ -14058,6 +14061,7 @@ KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
M: Marc Zyngier <maz@kernel.org>
M: Oliver Upton <oupton@kernel.org>
R: Joey Gouly <joey.gouly@arm.com>
R: Steffen Eiden <seiden@linux.ibm.com>
R: Suzuki K Poulose <suzuki.poulose@arm.com>
R: Zenghui Yu <yuzenghui@huawei.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -15724,7 +15728,7 @@ F: Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
F: drivers/media/i2c/max96717.c
MAX9860 MONO AUDIO VOICE CODEC DRIVER
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
L: linux-sound@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/sound/max9860.txt
@@ -15939,7 +15943,7 @@ F: Documentation/devicetree/bindings/net/can/microchip,mcp251xfd.yaml
F: drivers/net/can/spi/mcp251xfd/
MCP4018 AND MCP4531 MICROCHIP DIGITAL POTENTIOMETER DRIVERS
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531
@@ -18244,7 +18248,7 @@ F: include/linux/mmc/
F: include/uapi/linux/mmc/
MULTIPLEXER SUBSYSTEM
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
S: Odd Fixes
F: Documentation/ABI/testing/sysfs-class-mux*
F: Documentation/devicetree/bindings/mux/
@@ -19353,7 +19357,7 @@ F: include/dt-bindings/display/tda998x.h
K: "nxp,tda998x"
NXP TFA9879 DRIVER
M: Peter Rosin <peda@axentia.se>
M: Peter Rosin <peda@lysator.liu.se>
L: linux-sound@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/sound/trivial-codec.yaml
@@ -20354,13 +20358,14 @@ F: Documentation/devicetree/bindings/pci/marvell,armada8k-pcie.yaml
F: drivers/pci/controller/dwc/pcie-armada8k.c
PCI DRIVER FOR CADENCE PCIE IP
R: Aksh Garg <a-garg7@ti.com>
L: linux-pci@vger.kernel.org
S: Orphan
F: Documentation/devicetree/bindings/pci/cdns,*
F: drivers/pci/controller/cadence/*cadence*
F: drivers/pci/controller/cadence/
PCI DRIVER FOR CIX Sky1
M: Hans Zhang <hans.zhang@cixtech.com>
M: Hans Zhang <18255117159@163.com>
L: linux-pci@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/pci/cix,sky1-pcie-*.yaml
@@ -20472,7 +20477,7 @@ F: drivers/pci/controller/plda/pcie-plda-host.c
F: drivers/pci/controller/plda/pcie-plda.h
PCI DRIVER FOR RENESAS R-CAR
M: Marek Vasut <marek.vasut+renesas@gmail.com>
M: Marek Vasut <marek.vasut+renesas@mailbox.org>
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
L: linux-pci@vger.kernel.org
L: linux-renesas-soc@vger.kernel.org

View File

@@ -2,7 +2,7 @@
VERSION = 7
PATCHLEVEL = 1
SUBLEVEL = 0
EXTRAVERSION = -rc2
EXTRAVERSION = -rc3
NAME = Baby Opossum Posse
# *DOCUMENTATION*
@@ -486,6 +486,8 @@ export rust_common_flags := --edition=2021 \
-Wclippy::as_ptr_cast_mut \
-Wclippy::as_underscore \
-Wclippy::cast_lossless \
-Aclippy::collapsible_if \
-Aclippy::collapsible_match \
-Wclippy::ignored_unit_patterns \
-Aclippy::incompatible_msrv \
-Wclippy::mut_mut \

View File

@@ -23,6 +23,7 @@ static inline u64 tcr_el2_ps_to_tcr_el1_ips(u64 tcr_el2)
static inline u64 translate_tcr_el2_to_tcr_el1(u64 tcr)
{
return TCR_EPD1_MASK | /* disable TTBR1_EL1 */
((tcr & TCR_EL2_DS) ? TCR_DS : 0) |
((tcr & TCR_EL2_TBI) ? TCR_TBI0 : 0) |
tcr_el2_ps_to_tcr_el1_ips(tcr) |
(tcr & TCR_EL2_TG0_MASK) |

View File

@@ -844,7 +844,7 @@
#define INIT_SCTLR_EL2_MMU_ON \
(SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA | SCTLR_ELx_I | \
SCTLR_ELx_IESB | SCTLR_ELx_WXN | ENDIAN_SET_EL2 | \
SCTLR_ELx_ITFSB | SCTLR_EL2_RES1)
SCTLR_ELx_ITFSB | SCTLR_ELx_EIS | SCTLR_ELx_EOS | SCTLR_EL2_RES1)
#define INIT_SCTLR_EL2_MMU_OFF \
(SCTLR_EL2_RES1 | ENDIAN_SET_EL2)

View File

@@ -983,8 +983,8 @@ static int sve_set_common(struct task_struct *target,
}
/* Always zero V regs, FPSR, and FPCR */
memset(&current->thread.uw.fpsimd_state, 0,
sizeof(current->thread.uw.fpsimd_state));
memset(&target->thread.uw.fpsimd_state, 0,
sizeof(target->thread.uw.fpsimd_state));
/* Registers: FPSIMD-only case */

View File

@@ -4,6 +4,7 @@
* Author: Christoffer Dall <c.dall@virtualopensystems.com>
*/
#include <linux/arm-smccc.h>
#include <linux/bug.h>
#include <linux/cpu_pm.h>
#include <linux/errno.h>
@@ -2638,6 +2639,22 @@ static int init_pkvm_host_sve_state(void)
return 0;
}
static int pkvm_check_sme_dvmsync_fw_call(void)
{
struct arm_smccc_res res;
if (!cpus_have_final_cap(ARM64_WORKAROUND_4193714))
return 0;
arm_smccc_1_1_smc(ARM_SMCCC_CPU_WORKAROUND_4193714, &res);
if (res.a0) {
kvm_err("pKVM requires firmware support for C1-Pro erratum 4193714\n");
return -ENODEV;
}
return 0;
}
/*
* Finalizes the initialization of hyp mode, once everything else is initialized
* and the initialziation process cannot fail.
@@ -2838,6 +2855,10 @@ static int __init init_hyp_mode(void)
if (err)
goto out_err;
err = pkvm_check_sme_dvmsync_fw_call();
if (err)
goto out_err;
err = kvm_hyp_init_protection(hyp_va_bits);
if (err) {
kvm_err("Failed to init hyp memory protection\n");

View File

@@ -245,7 +245,7 @@ static inline void __activate_traps_ich_hfgxtr(struct kvm_vcpu *vcpu)
__activate_fgt(hctxt, vcpu, ICH_HFGITR_EL2);
}
#define __deactivate_fgt(htcxt, vcpu, reg) \
#define __deactivate_fgt(hctxt, vcpu, reg) \
do { \
write_sysreg_s(ctxt_sys_reg(hctxt, reg), \
SYS_ ## reg); \

View File

@@ -35,6 +35,9 @@ void trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc)
struct clock_data *clock = &trace_clock_data;
u64 bank = clock->cur ^ 1;
if (!mult || shift >= 64)
return;
clock->data[bank].mult = mult;
clock->data[bank].shift = shift;
clock->data[bank].epoch_ns = epoch_ns;

View File

@@ -5,6 +5,7 @@
*/
#include <linux/kvm_host.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_hyp.h>
#include <asm/kvm_mmu.h>
@@ -14,6 +15,7 @@
#include <hyp/fault.h>
#include <nvhe/arm-smccc.h>
#include <nvhe/gfp.h>
#include <nvhe/memory.h>
#include <nvhe/mem_protect.h>
@@ -29,6 +31,19 @@ static struct hyp_pool host_s2_pool;
static DEFINE_PER_CPU(struct pkvm_hyp_vm *, __current_vm);
#define current_vm (*this_cpu_ptr(&__current_vm))
static void pkvm_sme_dvmsync_fw_call(void)
{
if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714)) {
struct arm_smccc_res res;
/*
* Ignore the return value. Probing for the workaround
* availability took place in init_hyp_mode().
*/
hyp_smccc_1_1_smc(ARM_SMCCC_CPU_WORKAROUND_4193714, &res);
}
}
static void guest_lock_component(struct pkvm_hyp_vm *vm)
{
hyp_spin_lock(&vm->lock);
@@ -574,8 +589,14 @@ static int host_stage2_set_owner_metadata_locked(phys_addr_t addr, u64 size,
ret = host_stage2_try(kvm_pgtable_stage2_annotate, &host_mmu.pgt,
addr, size, &host_s2_pool,
KVM_HOST_INVALID_PTE_TYPE_DONATION, annotation);
if (!ret)
if (!ret) {
/*
* After stage2 maintenance has happened, but before the page
* owner has changed.
*/
pkvm_sme_dvmsync_fw_call();
__host_update_page_state(addr, size, PKVM_NOPAGE);
}
return ret;
}
@@ -1369,6 +1390,22 @@ int __pkvm_host_reclaim_page_guest(u64 gfn, struct pkvm_hyp_vm *vm)
return ret && ret != -EHWPOISON ? ret : 0;
}
/*
* share/donate install at most one stage-2 leaf (PAGE_SIZE, or one
* KVM_PGTABLE_LAST_LEVEL - 1 block for share). kvm_mmu_cache_min_pages()
* bounds the worst-case allocation: exact for the PAGE_SIZE leaf,
* conservative by one for the block.
*/
static int __guest_check_pgtable_memcache(struct pkvm_hyp_vcpu *vcpu)
{
struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
if (vcpu->vcpu.arch.pkvm_memcache.nr_pages < kvm_mmu_cache_min_pages(vm->pgt.mmu))
return -ENOMEM;
return 0;
}
int __pkvm_host_donate_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu)
{
struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(vcpu);
@@ -1388,6 +1425,10 @@ int __pkvm_host_donate_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu)
if (ret)
goto unlock;
ret = __guest_check_pgtable_memcache(vcpu);
if (ret)
goto unlock;
meta = host_stage2_encode_gfn_meta(vm, gfn);
WARN_ON(host_stage2_set_owner_metadata_locked(phys, PAGE_SIZE,
PKVM_ID_GUEST, meta));
@@ -1453,6 +1494,10 @@ int __pkvm_host_share_guest(u64 pfn, u64 gfn, u64 nr_pages, struct pkvm_hyp_vcpu
}
}
ret = __guest_check_pgtable_memcache(vcpu);
if (ret)
goto unlock;
for_each_hyp_page(page, phys, size) {
set_host_state(page, PKVM_PAGE_SHARED_OWNED);
page->host_share_guest_count++;

View File

@@ -752,16 +752,30 @@ static struct pkvm_hyp_vcpu selftest_vcpu = {
struct pkvm_hyp_vcpu *init_selftest_vm(void *virt)
{
struct hyp_page *p = hyp_virt_to_page(virt);
unsigned long min_pages, seeded = 0;
int i;
selftest_vm.kvm.arch.mmu.vtcr = host_mmu.arch.mmu.vtcr;
WARN_ON(kvm_guest_prepare_stage2(&selftest_vm, virt));
/*
* Mirror pkvm_refill_memcache() for the share/donate pre-checks;
* the selftest invokes those functions directly and would
* otherwise see an empty memcache.
*/
min_pages = kvm_mmu_cache_min_pages(&selftest_vm.kvm.arch.mmu);
for (i = 0; i < pkvm_selftest_pages(); i++) {
if (p[i].refcount)
continue;
p[i].refcount = 1;
hyp_put_page(&selftest_vm.pool, hyp_page_to_virt(&p[i]));
if (seeded < min_pages) {
push_hyp_memcache(&selftest_vcpu.vcpu.arch.pkvm_memcache,
hyp_page_to_virt(&p[i]), hyp_virt_to_phys);
seeded++;
} else {
hyp_put_page(&selftest_vm.pool, hyp_page_to_virt(&p[i]));
}
}
selftest_vm.kvm.arch.pkvm.handle = __pkvm_reserve_vm();

View File

@@ -663,7 +663,8 @@ static void __noreturn __hyp_call_panic(u64 spsr, u64 elr, u64 par)
host_ctxt = host_data_ptr(host_ctxt);
vcpu = host_ctxt->__hyp_running_vcpu;
__deactivate_traps(vcpu);
if (vcpu)
__deactivate_traps(vcpu);
sysreg_restore_host_state_vhe(host_ctxt);
panic("HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n",

View File

@@ -1576,21 +1576,24 @@ struct kvm_s2_fault_desc {
static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
{
bool write_fault, exec_fault;
bool perm_fault = kvm_vcpu_trap_is_permission_fault(s2fd->vcpu);
enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt;
unsigned long mmu_seq;
struct page *page;
struct kvm *kvm = s2fd->vcpu->kvm;
void *memcache;
void *memcache = NULL;
kvm_pfn_t pfn;
gfn_t gfn;
int ret;
memcache = get_mmu_memcache(s2fd->vcpu);
ret = topup_mmu_memcache(s2fd->vcpu, memcache);
if (ret)
return ret;
if (!perm_fault) {
memcache = get_mmu_memcache(s2fd->vcpu);
ret = topup_mmu_memcache(s2fd->vcpu, memcache);
if (ret)
return ret;
}
if (s2fd->nested)
gfn = kvm_s2_trans_output(s2fd->nested) >> PAGE_SHIFT;
@@ -1631,9 +1634,19 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
goto out_unlock;
}
ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
__pfn_to_phys(pfn), prot,
memcache, flags);
if (perm_fault) {
/*
* Drop the SW bits in favour of those stored in the
* PTE, which will be preserved.
*/
prot &= ~KVM_NV_GUEST_MAP_SZ;
ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, s2fd->fault_ipa,
prot, flags);
} else {
ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
__pfn_to_phys(pfn), prot,
memcache, flags);
}
out_unlock:
kvm_release_faultin_page(kvm, page, !!ret, prot & KVM_PGTABLE_PROT_W);

View File

@@ -76,7 +76,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_RADEON=y
CONFIG_FB_3DFX=y

View File

@@ -76,7 +76,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_NVRAM=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y

View File

@@ -121,7 +121,6 @@ CONFIG_I2C_CHARDEV=y
CONFIG_AGP=m
CONFIG_AGP_UNINORTH=m
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_OF=y
CONFIG_FB_NVIDIA=y

View File

@@ -98,7 +98,6 @@ CONFIG_SENSORS_LM85=y
CONFIG_SENSORS_LM90=y
CONFIG_DRM=y
CONFIG_DRM_RADEON=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_TILEBLITTING=y
CONFIG_FB_VGA16=y
CONFIG_FB_NVIDIA=y

View File

@@ -196,7 +196,6 @@ CONFIG_I2C_CHARDEV=y
# CONFIG_PTP_1588_CLOCK is not set
CONFIG_DRM=y
CONFIG_DRM_AST=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=m
CONFIG_FB_MATROX_MILLENIUM=y

View File

@@ -249,7 +249,6 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_AMD8111=y
CONFIG_I2C_PASEMI=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y

View File

@@ -118,7 +118,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_AMD8111=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_OF=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y

View File

@@ -214,7 +214,6 @@ CONFIG_SENSORS_IBMPOWERNV=m
CONFIG_DRM=m
CONFIG_DRM_AST=m
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y

View File

@@ -62,6 +62,12 @@ CC32FLAGSREMOVE += -fno-stack-clash-protection
# 32-bit one. clang validates the values passed to these arguments during
# parsing, even when -fno-stack-protector is passed afterwards.
CC32FLAGSREMOVE += -mstack-protector-guard%
# ftrace is disabled for the vdso but arch/powerpc/Makefile adds this define to
# KBUILD_CPPFLAGS, which enables use of the 'patchable_function_entry'
# attribute in the 'inline' define via 'notrace'. This attribute is not
# supported for the powerpcle target, resulting in many instances of
# -Wunknown-attributes.
CC32FLAGSREMOVE += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
endif
LD32FLAGS := -Wl,-soname=linux-vdso32.so.1
AS32FLAGS := -D__VDSO32__

View File

@@ -16,4 +16,4 @@ GCOV_PROFILE_core_$(BITS).o := n
KCOV_INSTRUMENT_core_$(BITS).o := n
UBSAN_SANITIZE_core_$(BITS).o := n
KASAN_SANITIZE_core.o := n
KASAN_SANITIZE_core_$(BITS) := n
KASAN_SANITIZE_core_$(BITS).o := n

View File

@@ -52,7 +52,14 @@ int exit_vmx_usercopy(void)
}
EXPORT_SYMBOL(exit_vmx_usercopy);
int enter_vmx_ops(void)
/*
* Can be called from kexec copy_page() path with MMU off. The kexec
* code sets preempt_count to HARDIRQ_OFFSET so we return early here.
* Since in_interrupt() is always inline, __no_sanitize_address on this
* function is sufficient to avoid KASAN shadow memory accesses in real
* mode.
*/
int __no_sanitize_address enter_vmx_ops(void)
{
if (in_interrupt())
return 0;

View File

@@ -2242,6 +2242,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
const u64 last_period = event->hw.last_period;
s64 prev, delta, left;
int record = 0;
int mark_event = regs->dsisr & MMCRA_SAMPLE_ENABLE;
if (event->hw.state & PERF_HES_STOPPED) {
write_pmc(event->hw.idx, 0);
@@ -2304,9 +2305,9 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
* In ISA v3.0 and before values "0" and "7" are considered reserved.
* In ISA v3.1, value "7" has been used to indicate "larx/stcx".
* Drop the sample if "type" has reserved values for this field with a
* ISA version check.
* ISA version check for marked events.
*/
if (event->attr.sample_type & PERF_SAMPLE_DATA_SRC &&
if (mark_event && event->attr.sample_type & PERF_SAMPLE_DATA_SRC &&
ppmu->get_mem_data_src) {
val = (regs->dar & SIER_TYPE_MASK) >> SIER_TYPE_SHIFT;
if (val == 0 || (val == 7 && !cpu_has_feature(CPU_FTR_ARCH_31))) {

View File

@@ -477,7 +477,7 @@ int cpm1_gpiochip_add16(struct device *dev)
struct device_node *np = dev->of_node;
struct cpm1_gpio16_chip *cpm1_gc;
struct gpio_chip *gc;
u16 mask;
u32 mask;
cpm1_gc = devm_kzalloc(dev, sizeof(*cpm1_gc), GFP_KERNEL);
if (!cpm1_gc)
@@ -485,7 +485,7 @@ int cpm1_gpiochip_add16(struct device *dev)
spin_lock_init(&cpm1_gc->lock);
if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
if (!of_property_read_u32(np, "fsl,cpm1-gpio-irq-mask", &mask)) {
int i, j;
for (i = 0, j = 0; i < 16; i++)

View File

@@ -272,13 +272,12 @@ void __init pas_pci_init(void)
{
struct device_node *root = of_find_node_by_path("/");
struct device_node *np;
int res;
pci_set_flags(PCI_SCAN_ALL_PCIE_DEVS);
np = of_find_compatible_node(root, NULL, "pasemi,rootbus");
if (np) {
res = pas_add_bridge(np);
pas_add_bridge(np);
of_node_put(np);
}
of_node_put(root);

View File

@@ -950,8 +950,6 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
static int __init ps3_register_devices(void)
{
int result;
if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
return -ENODEV;
@@ -959,7 +957,7 @@ static int __init ps3_register_devices(void)
/* ps3_repository_dump_bus_info(); */
result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
ps3_register_vuart_devices();

View File

@@ -16,6 +16,7 @@ static void *htm_buf;
static void *htm_status_buf;
static void *htm_info_buf;
static void *htm_caps_buf;
static void *htm_mem_buf;
static u32 nodeindex;
static u32 nodalchipindex;
static u32 coreindexonchip;
@@ -86,7 +87,7 @@ static ssize_t htm_return_check(long rc)
static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
void *htm_buf = filp->private_data;
void *htm_buf_data = filp->private_data;
unsigned long page, read_size, available;
loff_t offset;
long rc, ret;
@@ -100,7 +101,7 @@ static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
* - last three values are address, size and offset
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf),
htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf_data),
PAGE_SIZE, page);
ret = htm_return_check(rc);
@@ -112,7 +113,61 @@ static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
available = PAGE_SIZE;
read_size = min(count, available);
*ppos += read_size;
return simple_read_from_buffer(ubuf, count, &offset, htm_buf, available);
return simple_read_from_buffer(ubuf, count, &offset, htm_buf_data, available);
}
static ssize_t htmsystem_mem_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
void *htm_mem_data = filp->private_data;
long rc, ret;
u64 *num_entries;
u64 to_copy = 0;
loff_t offset = 0;
u64 mem_offset = 0;
/*
* Invoke H_HTM call with:
* - operation as htm status (H_HTM_OP_STATUS)
* - last three values as addr, size and offset. "offset"
* is value from output buffer header that points to next
* entry to dump. 0 is the first entry to dump. next entry
* is read from the output bufferbyte offset 0x8.
*
* When first time hcall is invoked, mem_offset should be
* zero because zero is the first entry.
* In the next hcall, offset of next entry to read from is
* picked from output buffer header itself. So don't fill
* mem_offset for first read.
*
* If there is no further data to read in next iteration,
* offset value from output buffer header will point to -1.
*/
if (*ppos) {
mem_offset = *(u64 *)(htm_mem_data + 0x8);
if (mem_offset == -1)
return 0;
}
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_DUMP_SYSMEM_CONF, virt_to_phys(htm_mem_data),
PAGE_SIZE, be64_to_cpu(mem_offset));
ret = htm_return_check(rc);
if (ret <= 0) {
pr_debug("H_HTM hcall returned for op: H_HTM_OP_DUMP_SYSMEM_CONF with hcall returning %ld\n", ret);
return ret;
}
/*
* HTM system mem buffer, start of buffer + 0x10 gives the
* number of HTM entries in the buffer.
* So total count to copy is:
* 32 bytes (for first 5 fields) + (number of HTM entries * entry size)
*/
num_entries = htm_mem_data + 0x10;
to_copy = 32 + (be64_to_cpu(*num_entries) * 32);
*ppos += to_copy;
return simple_read_from_buffer(ubuf, count, &offset, htm_mem_data, to_copy);
}
static const struct file_operations htmdump_fops = {
@@ -121,6 +176,12 @@ static const struct file_operations htmdump_fops = {
.open = simple_open,
};
static const struct file_operations htmsystem_mem_fops = {
.llseek = NULL,
.read = htmsystem_mem_read,
.open = simple_open,
};
static int htmconfigure_set(void *data, u64 val)
{
long rc, ret;
@@ -226,20 +287,31 @@ static int htmstart_get(void *data, u64 *val)
static ssize_t htmstatus_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
void *htm_status_buf = filp->private_data;
void *htm_status_data = filp->private_data;
long rc, ret;
u64 *num_entries;
u64 to_copy;
int htmstatus_flag;
loff_t offset = 0;
u64 status_offset = 0;
/*
* Invoke H_HTM call with:
* - operation as htm status (H_HTM_OP_STATUS)
* - last three values as addr, size and offset
* - last three values as addr, size and offset.
* "offset" is value from output buffer header
* that points to next entry to dump. 0 is the first
* entry to dump. next entry is read from the output
* bufferbyte offset 0x8.
*/
if (*ppos) {
status_offset = *(u64 *)(htm_status_data + 0x8);
if (status_offset == -1)
return 0;
}
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_buf),
PAGE_SIZE, 0);
htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_data),
PAGE_SIZE, be64_to_cpu(status_offset));
ret = htm_return_check(rc);
if (ret <= 0) {
@@ -255,13 +327,15 @@ static ssize_t htmstatus_read(struct file *filp, char __user *ubuf,
* So total count to copy is:
* 32 bytes (for first 7 fields) + (number of HTM entries * entry size)
*/
num_entries = htm_status_buf + 0x10;
num_entries = htm_status_data + 0x10;
if (htmtype == 0x2)
htmstatus_flag = 0x8;
else
htmstatus_flag = 0x6;
to_copy = 32 + (be64_to_cpu(*num_entries) * htmstatus_flag);
return simple_read_from_buffer(ubuf, count, ppos, htm_status_buf, to_copy);
*ppos += to_copy;
return simple_read_from_buffer(ubuf, count, &offset, htm_status_data, to_copy);
}
static const struct file_operations htmstatus_fops = {
@@ -273,19 +347,30 @@ static const struct file_operations htmstatus_fops = {
static ssize_t htminfo_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
void *htm_info_buf = filp->private_data;
void *htm_info_data = filp->private_data;
long rc, ret;
u64 *num_entries;
u64 to_copy;
loff_t offset = 0;
u64 info_offset = 0;
/*
* Invoke H_HTM call with:
* - operation as htm status (H_HTM_OP_STATUS)
* - last three values as addr, size and offset
* "offset" is value from output buffer header
* that points to next entry to dump. 0 is the first
* entry to dump. next entry is read from the output
* bufferbyte offset 0x8.
*/
if (*ppos) {
info_offset = *(u64 *)(htm_info_data + 0x8);
if (info_offset == -1)
return 0;
}
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_buf),
PAGE_SIZE, 0);
htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_data),
PAGE_SIZE, be64_to_cpu(info_offset));
ret = htm_return_check(rc);
if (ret <= 0) {
@@ -301,15 +386,17 @@ static ssize_t htminfo_read(struct file *filp, char __user *ubuf,
* So total count to copy is:
* 32 bytes (for first 5 fields) + (number of HTM entries * entry size)
*/
num_entries = htm_info_buf + 0x10;
num_entries = htm_info_data + 0x10;
to_copy = 32 + (be64_to_cpu(*num_entries) * 16);
return simple_read_from_buffer(ubuf, count, ppos, htm_info_buf, to_copy);
*ppos += to_copy;
return simple_read_from_buffer(ubuf, count, &offset, htm_info_data, to_copy);
}
static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
size_t count, loff_t *ppos)
{
void *htm_caps_buf = filp->private_data;
void *htm_caps_data = filp->private_data;
long rc, ret;
/*
@@ -319,7 +406,7 @@ static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
* and zero
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_CAPABILITIES, virt_to_phys(htm_caps_buf),
htmtype, H_HTM_OP_CAPABILITIES, virt_to_phys(htm_caps_data),
0x80, 0);
ret = htm_return_check(rc);
@@ -328,7 +415,7 @@ static ssize_t htmcaps_read(struct file *filp, char __user *ubuf,
return ret;
}
return simple_read_from_buffer(ubuf, count, ppos, htm_caps_buf, 0x80);
return simple_read_from_buffer(ubuf, count, ppos, htm_caps_data, 0x80);
}
static const struct file_operations htminfo_fops = {
@@ -457,9 +544,17 @@ static int htmdump_init_debugfs(void)
return -ENOMEM;
}
/* Memory to present HTM system memory configuration */
htm_mem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!htm_mem_buf) {
pr_err("Failed to allocate htm mem buf\n");
return -ENOMEM;
}
debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops);
debugfs_create_file("htminfo", 0400, htmdump_debugfs_dir, htm_info_buf, &htminfo_fops);
debugfs_create_file("htmcaps", 0400, htmdump_debugfs_dir, htm_caps_buf, &htmcaps_fops);
debugfs_create_file("htmsystem_mem", 0400, htmdump_debugfs_dir, htm_mem_buf, &htmsystem_mem_fops);
return 0;
}
@@ -482,6 +577,10 @@ static void __exit htmdump_exit(void)
{
debugfs_remove_recursive(htmdump_debugfs_dir);
kfree(htm_buf);
kfree(htm_status_buf);
kfree(htm_info_buf);
kfree(htm_caps_buf);
kfree(htm_mem_buf);
}
module_init(htmdump_init);

View File

@@ -190,33 +190,34 @@ static int hvpipe_rtas_recv_msg(char __user *buf, int size)
return -ENOMEM;
}
ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID,
&bytes_written);
if (!ret) {
/*
* Recv HVPIPE RTAS is successful.
* When releasing FD or no one is waiting on the
* specific source, issue recv HVPIPE RTAS call
* so that pipe is not blocked - this func is called
* with NULL buf.
*/
if (buf) {
if (size < bytes_written) {
pr_err("Received the payload size = %d, but the buffer size = %d\n",
bytes_written, size);
bytes_written = size;
}
ret = copy_to_user(buf,
rtas_work_area_raw_buf(work_area),
bytes_written);
if (!ret)
ret = bytes_written;
}
} else {
pr_err("ibm,receive-hvpipe-msg failed with %d\n",
ret);
/*
* Recv HVPIPE RTAS is successful.
* When releasing FD or no one is waiting on the
* specific source, issue recv HVPIPE RTAS call
* so that pipe is not blocked - this func is called
* with NULL buf.
*/
ret = rtas_ibm_receive_hvpipe_msg(work_area, &srcID, &bytes_written);
if (ret) {
pr_err("ibm,receive-hvpipe-msg failed with %d\n", ret);
goto out;
}
if (!buf)
goto out;
if (size < bytes_written) {
pr_err("Received the payload size = %d, but the buffer size = %d\n",
bytes_written, size);
bytes_written = size;
}
if (copy_to_user(buf, rtas_work_area_raw_buf(work_area), bytes_written))
ret = -EFAULT;
else
ret = bytes_written;
out:
rtas_work_area_free(work_area);
return ret;
}
@@ -327,8 +328,8 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
{
struct hvpipe_source_info *src_info = file->private_data;
struct papr_hvpipe_hdr hdr;
long ret;
struct papr_hvpipe_hdr hdr = {};
ssize_t ret = 0;
/*
* Return -ENXIO during migration
@@ -376,7 +377,7 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
ret = copy_to_user(buf, &hdr, HVPIPE_HDR_LEN);
if (ret)
return ret;
return -EFAULT;
/*
* Message event has payload, so get the payload with
@@ -385,19 +386,23 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
if (hdr.flags & HVPIPE_MSG_AVAILABLE) {
ret = hvpipe_rtas_recv_msg(buf + HVPIPE_HDR_LEN,
size - HVPIPE_HDR_LEN);
if (ret > 0) {
/*
* Always clear MSG_AVAILABLE once the RTAS call has drained
* the message, regardless of whether copy_to_user succeeded.
*/
if (ret >= 0 || ret == -EFAULT)
src_info->hvpipe_status &= ~HVPIPE_MSG_AVAILABLE;
ret += HVPIPE_HDR_LEN;
}
} else if (hdr.flags & HVPIPE_LOST_CONNECTION) {
/*
* Hypervisor is closing the pipe for the specific
* source. So notify user space.
*/
src_info->hvpipe_status &= ~HVPIPE_LOST_CONNECTION;
ret = HVPIPE_HDR_LEN;
}
if (ret >= 0)
ret += HVPIPE_HDR_LEN;
return ret;
}
@@ -444,16 +449,18 @@ static int papr_hvpipe_handle_release(struct inode *inode,
struct file *file)
{
struct hvpipe_source_info *src_info;
unsigned long flags;
/*
* Hold the lock, remove source from src_list, reset the
* hvpipe status and release the lock to prevent any race
* with message event IRQ.
*/
spin_lock(&hvpipe_src_list_lock);
spin_lock_irqsave(&hvpipe_src_list_lock, flags);
src_info = file->private_data;
list_del(&src_info->list);
file->private_data = NULL;
spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
/*
* If the pipe for this specific source has any pending
* payload, issue recv HVPIPE RTAS so that pipe will not
@@ -461,10 +468,8 @@ static int papr_hvpipe_handle_release(struct inode *inode,
*/
if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE) {
src_info->hvpipe_status = 0;
spin_unlock(&hvpipe_src_list_lock);
hvpipe_rtas_recv_msg(NULL, 0);
} else
spin_unlock(&hvpipe_src_list_lock);
}
kfree(src_info);
return 0;
@@ -479,50 +484,53 @@ static const struct file_operations papr_hvpipe_handle_ops = {
static int papr_hvpipe_dev_create_handle(u32 srcID)
{
struct hvpipe_source_info *src_info __free(kfree) = NULL;
spin_lock(&hvpipe_src_list_lock);
/*
* Do not allow more than one process communicates with
* each source.
*/
src_info = hvpipe_find_source(srcID);
if (src_info) {
spin_unlock(&hvpipe_src_list_lock);
pr_err("pid(%d) is already using the source(%d)\n",
src_info->tsk->pid, srcID);
return -EALREADY;
}
spin_unlock(&hvpipe_src_list_lock);
struct hvpipe_source_info *src_info;
int fd;
unsigned long flags;
src_info = kzalloc_obj(*src_info, GFP_KERNEL_ACCOUNT);
if (!src_info)
return -ENOMEM;
src_info->srcID = srcID;
src_info->tsk = current;
init_waitqueue_head(&src_info->recv_wqh);
FD_PREPARE(fdf, O_RDONLY | O_CLOEXEC,
anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops,
(void *)src_info, O_RDWR));
if (fdf.err)
return fdf.err;
retain_and_null_ptr(src_info);
spin_lock(&hvpipe_src_list_lock);
/*
* If two processes are executing ioctl() for the same
* source ID concurrently, prevent the second process to
* acquire FD.
* Do not allow more than one process communicates with
* each source.
*/
spin_lock_irqsave(&hvpipe_src_list_lock, flags);
if (hvpipe_find_source(srcID)) {
spin_unlock(&hvpipe_src_list_lock);
spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
pr_err("pid(%s:%d) could not get the source(%d)\n",
current->comm, task_pid_nr(current), srcID);
kfree(src_info);
return -EALREADY;
}
list_add(&src_info->list, &hvpipe_src_list);
spin_unlock(&hvpipe_src_list_lock);
return fd_publish(fdf);
spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
fd = FD_ADD(O_RDONLY | O_CLOEXEC,
anon_inode_getfile("[papr-hvpipe]", &papr_hvpipe_handle_ops,
(void *)src_info, O_RDWR));
if (fd < 0) {
spin_lock_irqsave(&hvpipe_src_list_lock, flags);
list_del(&src_info->list);
spin_unlock_irqrestore(&hvpipe_src_list_lock, flags);
/*
* if we fail to add FD, that means no userspace program is
* polling. In that case if there is a msg pending because the
* interrupt was fired after the src_info was added to the
* global list, then let's consume it here, to unblock the
* hvpipe
*/
if (src_info->hvpipe_status & HVPIPE_MSG_AVAILABLE)
hvpipe_rtas_recv_msg(NULL, 0);
kfree(src_info);
return fd;
}
return fd;
}
/*
@@ -685,20 +693,19 @@ static int __init enable_hvpipe_IRQ(void)
struct device_node *np;
hvpipe_check_exception_token = rtas_function_token(RTAS_FN_CHECK_EXCEPTION);
if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE)
if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE)
return -ENODEV;
/* hvpipe events */
np = of_find_node_by_path("/event-sources/ibm,hvpipe-msg-events");
if (np != NULL) {
request_event_sources_irqs(np, hvpipe_event_interrupt,
"HPIPE_EVENT");
of_node_put(np);
} else {
pr_err("Can not enable hvpipe event IRQ\n");
if (!np) {
pr_err("No device node found, could not enable hvpipe event IRQ\n");
return -ENODEV;
}
request_event_sources_irqs(np, hvpipe_event_interrupt, "HPIPE_EVENT");
of_node_put(np);
return 0;
}
@@ -775,23 +782,29 @@ static int __init papr_hvpipe_init(void)
}
ret = enable_hvpipe_IRQ();
if (!ret) {
ret = set_hvpipe_sys_param(1);
if (!ret)
ret = misc_register(&papr_hvpipe_dev);
}
if (ret)
goto out_wq;
if (!ret) {
pr_info("hvpipe feature is enabled\n");
hvpipe_feature = true;
return 0;
}
ret = misc_register(&papr_hvpipe_dev);
if (ret)
goto out_wq;
pr_err("hvpipe feature is not enabled %d\n", ret);
ret = set_hvpipe_sys_param(1);
if (ret)
goto out_misc;
pr_info("hvpipe feature is enabled\n");
hvpipe_feature = true;
return 0;
out_misc:
misc_deregister(&papr_hvpipe_dev);
out_wq:
destroy_workqueue(papr_hvpipe_wq);
out:
kfree(papr_hvpipe_work);
papr_hvpipe_work = NULL;
pr_err("hvpipe feature is not enabled %d\n", ret);
return ret;
}
machine_device_initcall(pseries, papr_hvpipe_init);

View File

@@ -21,7 +21,6 @@ struct hvpipe_source_info {
u32 srcID;
u32 hvpipe_status;
wait_queue_head_t recv_wqh; /* wake up poll() waitq */
struct task_struct *tsk;
};
/*

View File

@@ -3310,8 +3310,7 @@ static void aen_host_forward(unsigned long si)
struct zpci_gaite *gaite;
struct kvm *kvm;
gaite = (struct zpci_gaite *)aift->gait +
(si * sizeof(struct zpci_gaite));
gaite = aift->gait + si;
if (gaite->count == 0)
return;
if (gaite->aisb != 0)

View File

@@ -166,7 +166,7 @@ static int kvm_zpci_set_airq(struct zpci_dev *zdev)
fib.fmt0.noi = airq_iv_end(zdev->aibv);
fib.fmt0.aibv = virt_to_phys(zdev->aibv->vector);
fib.fmt0.aibvo = 0;
fib.fmt0.aisb = virt_to_phys(aift->sbv->vector + (zdev->aisb / 64) * 8);
fib.fmt0.aisb = virt_to_phys(aift->sbv->vector) + (zdev->aisb / 64) * 8;
fib.fmt0.aisbo = zdev->aisb & 63;
fib.gd = zdev->gisa;
@@ -290,8 +290,7 @@ static int kvm_s390_pci_aif_enable(struct zpci_dev *zdev, struct zpci_fib *fib,
phys_to_virt(fib->fmt0.aibv));
spin_lock_irq(&aift->gait_lock);
gaite = (struct zpci_gaite *)aift->gait + (zdev->aisb *
sizeof(struct zpci_gaite));
gaite = aift->gait + zdev->aisb;
/* If assist not requested, host will get all alerts */
if (assist)
@@ -309,7 +308,7 @@ static int kvm_s390_pci_aif_enable(struct zpci_dev *zdev, struct zpci_fib *fib,
/* Update guest FIB for re-issue */
fib->fmt0.aisbo = zdev->aisb & 63;
fib->fmt0.aisb = virt_to_phys(aift->sbv->vector + (zdev->aisb / 64) * 8);
fib->fmt0.aisb = virt_to_phys(aift->sbv->vector) + (zdev->aisb / 64) * 8;
fib->fmt0.isc = gisc;
/* Save some guest fib values in the host for later use */
@@ -357,8 +356,7 @@ static int kvm_s390_pci_aif_disable(struct zpci_dev *zdev, bool force)
if (zdev->kzdev->fib.fmt0.aibv == 0)
goto out;
spin_lock_irq(&aift->gait_lock);
gaite = (struct zpci_gaite *)aift->gait + (zdev->aisb *
sizeof(struct zpci_gaite));
gaite = aift->gait + zdev->aisb;
isc = gaite->gisc;
gaite->count--;
if (gaite->count == 0) {

View File

@@ -1294,13 +1294,16 @@ int x86_perf_rdpmc_index(struct perf_event *event)
return event->hw.event_base_rdpmc;
}
static inline int match_prev_assignment(struct hw_perf_event *hwc,
static inline int match_prev_assignment(struct perf_event *event,
struct cpu_hw_events *cpuc,
int i)
{
struct hw_perf_event *hwc = &event->hw;
return hwc->idx == cpuc->assign[i] &&
hwc->last_cpu == smp_processor_id() &&
hwc->last_tag == cpuc->tags[i];
hwc->last_cpu == smp_processor_id() &&
hwc->last_tag == cpuc->tags[i] &&
!is_acr_event_group(event);
}
static void x86_pmu_start(struct perf_event *event, int flags);
@@ -1346,7 +1349,7 @@ static void x86_pmu_enable(struct pmu *pmu)
* - no other event has used the counter since
*/
if (hwc->idx == -1 ||
match_prev_assignment(hwc, cpuc, i))
match_prev_assignment(event, cpuc, i))
continue;
/*
@@ -1367,7 +1370,7 @@ static void x86_pmu_enable(struct pmu *pmu)
event = cpuc->event_list[i];
hwc = &event->hw;
if (!match_prev_assignment(hwc, cpuc, i))
if (!match_prev_assignment(event, cpuc, i))
x86_assign_hw_event(event, cpuc, i);
else if (i < n_running)
continue;

View File

@@ -3118,11 +3118,11 @@ static void intel_pmu_enable_fixed(struct perf_event *event)
intel_set_masks(event, idx);
/*
* Enable IRQ generation (0x8), if not PEBS,
* and enable ring-3 counting (0x2) and ring-0 counting (0x1)
* if requested:
* Enable IRQ generation (0x8), if not PEBS or self-reloaded
* ACR event, and enable ring-3 counting (0x2) and ring-0
* counting (0x1) if requested:
*/
if (!event->attr.precise_ip)
if (!event->attr.precise_ip && !is_acr_self_reload_event(event))
bits |= INTEL_FIXED_0_ENABLE_PMI;
if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
bits |= INTEL_FIXED_0_USER;
@@ -3306,6 +3306,15 @@ static void intel_pmu_enable_event(struct perf_event *event)
intel_set_masks(event, idx);
static_call_cond(intel_pmu_enable_acr_event)(event);
static_call_cond(intel_pmu_enable_event_ext)(event);
/*
* For self-reloaded ACR event, don't enable PMI since
* HW won't set overflow bit in GLOBAL_STATUS. Otherwise,
* the PMI would be recognized as a suspicious NMI.
*/
if (is_acr_self_reload_event(event))
hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
else if (!event->attr.precise_ip)
hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
__x86_pmu_enable_event(hwc, enable_mask);
break;
case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS - 1:
@@ -3332,23 +3341,41 @@ static void intel_pmu_enable_event(struct perf_event *event)
static void intel_pmu_acr_late_setup(struct cpu_hw_events *cpuc)
{
struct perf_event *event, *leader;
int i, j, idx;
int i, j, k, bit, idx;
/*
* FIXME: ACR mask parsing relies on cpuc->event_list[] (active events only).
* Disabling an ACR event causes bit-shifting errors in the acr_mask of
* remaining group members. As ACR sampling requires all events to be active,
* this limitation is acceptable for now. Revisit if independent event toggling
* is required.
*/
for (i = 0; i < cpuc->n_events; i++) {
leader = cpuc->event_list[i];
if (!is_acr_event_group(leader))
continue;
/* The ACR events must be contiguous. */
/* Find the last event of the ACR group. */
for (j = i; j < cpuc->n_events; j++) {
event = cpuc->event_list[j];
if (event->group_leader != leader->group_leader)
break;
for_each_set_bit(idx, (unsigned long *)&event->attr.config2, X86_PMC_IDX_MAX) {
if (i + idx >= cpuc->n_events ||
!is_acr_event_group(cpuc->event_list[i + idx]))
return;
__set_bit(cpuc->assign[i + idx], (unsigned long *)&event->hw.config1);
}
/*
* Translate the user-space ACR mask (attr.config2) into the physical
* counter bitmask (hw.config1) for each ACR event in the group.
* NOTE: ACR event contiguity is guaranteed by intel_pmu_hw_config().
*/
for (k = i; k < j; k++) {
event = cpuc->event_list[k];
event->hw.config1 = 0;
for_each_set_bit(bit, (unsigned long *)&event->attr.config2, X86_PMC_IDX_MAX) {
idx = i + bit;
/* Event index of ACR group must locate in [i, j). */
if (idx >= j || !is_acr_event_group(cpuc->event_list[idx]))
continue;
__set_bit(cpuc->assign[idx], (unsigned long *)&event->hw.config1);
}
}
i = j - 1;
@@ -7504,6 +7531,7 @@ static __always_inline void intel_pmu_init_pnc(struct pmu *pmu)
hybrid(pmu, event_constraints) = intel_pnc_event_constraints;
hybrid(pmu, pebs_constraints) = intel_pnc_pebs_event_constraints;
hybrid(pmu, extra_regs) = intel_pnc_extra_regs;
static_call_update(intel_pmu_enable_acr_event, intel_pmu_enable_acr);
}
static __always_inline void intel_pmu_init_skt(struct pmu *pmu)

View File

@@ -137,6 +137,16 @@ static inline bool is_acr_event_group(struct perf_event *event)
return check_leader_group(event->group_leader, PERF_X86_EVENT_ACR);
}
static inline bool is_acr_self_reload_event(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
if (hwc->idx < 0)
return false;
return test_bit(hwc->idx, (unsigned long *)&hwc->config1);
}
struct amd_nb {
int nb_id; /* NorthBridge id */
int refcnt; /* reference count */

View File

@@ -803,9 +803,10 @@
#define MSR_AMD64_LBR_SELECT 0xc000010e
/* Zen4 */
#define MSR_ZEN4_BP_CFG 0xc001102e
#define MSR_ZEN4_BP_CFG 0xc001102e
#define MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT 4
#define MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT 5
#define MSR_ZEN2_BP_CFG_BUG_FIX_BIT 33
/* Fam 19h MSRs */
#define MSR_F19H_UMC_PERF_CTL 0xc0010800

View File

@@ -989,6 +989,9 @@ static void init_amd_zen2(struct cpuinfo_x86 *c)
/* Correct misconfigured CPUID on some clients. */
clear_cpu_cap(c, X86_FEATURE_INVLPGB);
if (!cpu_has(c, X86_FEATURE_HYPERVISOR))
msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN2_BP_CFG_BUG_FIX_BIT);
}
static void init_amd_zen3(struct cpuinfo_x86 *c)

View File

@@ -450,6 +450,10 @@ __init static int append_e820_table(struct boot_e820_entry *entries, u32 nr_entr
{
struct boot_e820_entry *entry = entries;
/* If there aren't any entries, we'll want to fall back to another source: */
if (!nr_entries)
return -ENOENT;
while (nr_entries) {
u64 start = entry->addr;
u64 size = entry->size;
@@ -458,7 +462,7 @@ __init static int append_e820_table(struct boot_e820_entry *entries, u32 nr_entr
/* Ignore the remaining entries on 64-bit overflow: */
if (start > end && likely(size))
return -1;
return -EINVAL;
e820__range_add(start, size, type);

View File

@@ -4481,7 +4481,7 @@ static const struct opcode opcode_map_0f_38[256] = {
X16(N), X16(N),
/* 0x20 - 0x2f */
X8(N),
X2(N), GP(SrcReg | DstMem | ModRM | Mov | Aligned, &pfx_0f_e7_0f_38_2a), N, N, N, N, N,
X2(N), GP(SrcMem | DstReg | ModRM | Mov | Aligned, &pfx_0f_e7_0f_38_2a), N, N, N, N, N,
/* 0x30 - 0x7f */
X16(N), X16(N), X16(N), X16(N), X16(N),
/* 0x80 - 0xef */

View File

@@ -2526,6 +2526,23 @@ static void shadow_walk_next(struct kvm_shadow_walk_iterator *iterator)
__shadow_walk_next(iterator, *iterator->sptep);
}
/*
* Note: while normally KVM uses a "bool flush" return value to let
* the caller batch flushes, __link_shadow_page() flushes immediately
* before populating the parent PTE with the new shadow page. The
* typical callers, direct_map() and FNAME(fetch)(), are not going
* to zap more than one huge SPTE anyway.
*
* The only exception, where @flush can be false, is when a huge SPTE
* is replaced with a shadow page SPTE with a fully populated page table,
* which can happen from shadow_mmu_split_huge_page(). In this case,
* no memory is unmapped across the change to the page tables and no
* immediate flush is needed for correctness.
*
* Even in that case, calls to kvm_mmu_commit_zap_page() are not
* batched. Doing so would require adding an invalid_list argument
* all the way down to __walk_slot_rmaps().
*/
static void __link_shadow_page(struct kvm *kvm,
struct kvm_mmu_memory_cache *cache, u64 *sptep,
struct kvm_mmu_page *sp, bool flush)
@@ -2541,8 +2558,10 @@ static void __link_shadow_page(struct kvm *kvm,
parent_sp = sptep_to_sp(sptep);
WARN_ON_ONCE(parent_sp->role.level == PG_LEVEL_4K);
mmu_page_zap_pte(kvm, parent_sp, sptep, &invalid_list);
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, true);
if (mmu_page_zap_pte(kvm, parent_sp, sptep, &invalid_list))
kvm_mmu_commit_zap_page(kvm, &invalid_list);
else if (flush)
kvm_flush_remote_tlbs_sptep(kvm, sptep);
}
spte = make_nonleaf_spte(sp->spt, sp_ad_disabled(sp));

View File

@@ -160,6 +160,16 @@ void nested_vmcb02_recalc_intercepts(struct vcpu_svm *svm)
if (!intercept_smi)
vmcb_clr_intercept(&vmcb02->control, INTERCEPT_SMI);
/*
* Intercept PAUSE if and only if L1 wants to. KVM intercepts PAUSE so
* that a vCPU that may be spinning waiting for a lock can be scheduled
* out in favor of the vCPU that holds said lock. KVM doesn't support
* yielding across L2 vCPUs, as KVM has limited visilibity into which
* L2 vCPUs are in the same L2 VM, i.e. may be contending for locks.
*/
if (!vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_PAUSE))
vmcb_clr_intercept(&vmcb02->control, INTERCEPT_PAUSE);
if (nested_vmcb_needs_vls_intercept(svm)) {
/*
* If the virtual VMLOAD/VMSAVE is not enabled for the L2,
@@ -819,7 +829,6 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm)
struct vmcb *vmcb02 = svm->nested.vmcb02.ptr;
struct vmcb *vmcb01 = svm->vmcb01.ptr;
struct kvm_vcpu *vcpu = &svm->vcpu;
u32 pause_count12, pause_thresh12;
nested_svm_transition_tlb_flush(vcpu);
@@ -947,31 +956,13 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm)
vmcb02->control.misc_ctl2 |= SVM_MISC2_ENABLE_V_VMLOAD_VMSAVE;
if (guest_cpu_cap_has(vcpu, X86_FEATURE_PAUSEFILTER))
pause_count12 = vmcb12_ctrl->pause_filter_count;
vmcb02->control.pause_filter_count = vmcb12_ctrl->pause_filter_count;
else
pause_count12 = 0;
vmcb02->control.pause_filter_count = 0;
if (guest_cpu_cap_has(vcpu, X86_FEATURE_PFTHRESHOLD))
pause_thresh12 = vmcb12_ctrl->pause_filter_thresh;
vmcb02->control.pause_filter_thresh = vmcb12_ctrl->pause_filter_thresh;
else
pause_thresh12 = 0;
if (kvm_pause_in_guest(svm->vcpu.kvm)) {
/* use guest values since host doesn't intercept PAUSE */
vmcb02->control.pause_filter_count = pause_count12;
vmcb02->control.pause_filter_thresh = pause_thresh12;
} else {
/* start from host values otherwise */
vmcb02->control.pause_filter_count = vmcb01->control.pause_filter_count;
vmcb02->control.pause_filter_thresh = vmcb01->control.pause_filter_thresh;
/* ... but ensure filtering is disabled if so requested. */
if (vmcb12_is_intercept(vmcb12_ctrl, INTERCEPT_PAUSE)) {
if (!pause_count12)
vmcb02->control.pause_filter_count = 0;
if (!pause_thresh12)
vmcb02->control.pause_filter_thresh = 0;
}
}
vmcb02->control.pause_filter_thresh = 0;
/*
* Take ALLOW_LARGER_RAP from vmcb12 even though it should be safe to
@@ -1298,12 +1289,6 @@ void nested_svm_vmexit(struct vcpu_svm *svm)
/* in case we halted in L2 */
kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
if (!kvm_pause_in_guest(vcpu->kvm)) {
vmcb01->control.pause_filter_count = vmcb02->control.pause_filter_count;
vmcb_mark_dirty(vmcb01, VMCB_INTERCEPTS);
}
/*
* Invalidate last_bus_lock_rip unless KVM is still waiting for the
* guest to make forward progress before re-enabling bus lock detection.

View File

@@ -913,7 +913,15 @@ static void grow_ple_window(struct kvm_vcpu *vcpu)
struct vmcb_control_area *control = &svm->vmcb->control;
int old = control->pause_filter_count;
if (kvm_pause_in_guest(vcpu->kvm))
/* Adjusting pause_filter_count makes no sense if PLE is disabled. */
WARN_ON_ONCE(kvm_pause_in_guest(vcpu->kvm));
/*
* While running L2, KVM should intercept PAUSE if and only if L1 wants
* to intercept PAUSE, and L1's intercept should take priority, i.e.
* KVM should never handle a PAUSE intercept from L2.
*/
if (WARN_ON_ONCE(is_guest_mode(vcpu)))
return;
control->pause_filter_count = __grow_ple_window(old,
@@ -934,7 +942,10 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu)
struct vmcb_control_area *control = &svm->vmcb->control;
int old = control->pause_filter_count;
if (kvm_pause_in_guest(vcpu->kvm))
/* Adjusting pause_filter_count makes no sense if PLE is disabled. */
WARN_ON_ONCE(kvm_pause_in_guest(vcpu->kvm));
if (is_guest_mode(vcpu))
return;
control->pause_filter_count =

View File

@@ -154,7 +154,7 @@ TRACE_EVENT(kvm_xen_hypercall,
__entry->a2 = a2;
__entry->a3 = a3;
__entry->a4 = a4;
__entry->a4 = a5;
__entry->a5 = a5;
),
TP_printk("cpl %d nr 0x%lx a0 0x%lx a1 0x%lx a2 0x%lx a3 0x%lx a4 0x%lx a5 %lx",

View File

@@ -14,6 +14,7 @@ extern bool __read_mostly flexpriority_enabled;
extern bool __read_mostly enable_ept;
extern bool __read_mostly enable_unrestricted_guest;
extern bool __read_mostly enable_ept_ad_bits;
extern bool __read_mostly enable_cet;
extern bool __read_mostly enable_pml;
extern int __read_mostly pt_mode;

View File

@@ -108,6 +108,9 @@ module_param_named(unrestricted_guest,
bool __read_mostly enable_ept_ad_bits = 1;
module_param_named(eptad, enable_ept_ad_bits, bool, 0444);
bool __read_mostly enable_cet = 1;
module_param_named(cet, enable_cet, bool, 0444);
static bool __read_mostly emulate_invalid_guest_state = true;
module_param(emulate_invalid_guest_state, bool, 0444);
@@ -4476,7 +4479,7 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
* SSP is reloaded from IA32_PL3_SSP. Check SDM Vol.2A/B Chapter
* 3 and 4 for details.
*/
if (cpu_has_load_cet_ctrl()) {
if (enable_cet) {
vmcs_writel(HOST_S_CET, kvm_host.s_cet);
vmcs_writel(HOST_SSP, 0);
vmcs_writel(HOST_INTR_SSP_TABLE, 0);
@@ -4532,6 +4535,10 @@ static u32 vmx_get_initial_vmentry_ctrl(void)
if (vmx_pt_mode_is_system())
vmentry_ctrl &= ~(VM_ENTRY_PT_CONCEAL_PIP |
VM_ENTRY_LOAD_IA32_RTIT_CTL);
if (!enable_cet)
vmentry_ctrl &= ~VM_ENTRY_LOAD_CET_STATE;
/*
* IA32e mode, and loading of EFER and PERF_GLOBAL_CTRL are toggled dynamically.
*/
@@ -4546,6 +4553,9 @@ static u32 vmx_get_initial_vmexit_ctrl(void)
{
u32 vmexit_ctrl = vmcs_config.vmexit_ctrl;
if (!enable_cet)
vmexit_ctrl &= ~VM_EXIT_LOAD_CET_STATE;
/*
* Not used by KVM and never set in vmcs01 or vmcs02, but emulated for
* nested virtualization and thus allowed to be set in vmcs12.
@@ -8155,7 +8165,7 @@ static __init void vmx_set_cpu_caps(void)
* VMX_BASIC[bit56] == 0, inject #CP at VMX entry with error code
* fails, so disable CET in this case too.
*/
if (!cpu_has_load_cet_ctrl() || !enable_unrestricted_guest ||
if (!enable_cet || !enable_unrestricted_guest ||
!cpu_has_vmx_basic_no_hw_errcode_cc()) {
kvm_cpu_cap_clear(X86_FEATURE_SHSTK);
kvm_cpu_cap_clear(X86_FEATURE_IBT);
@@ -8630,6 +8640,9 @@ __init int vmx_hardware_setup(void)
!cpu_has_vmx_invept_global())
enable_ept = 0;
if (!cpu_has_load_cet_ctrl())
enable_cet = 0;
/* NX support is required for shadow paging. */
if (!enable_ept && !boot_cpu_has(X86_FEATURE_NX)) {
pr_err_ratelimited("NX (Execute Disable) not supported\n");

View File

@@ -695,17 +695,22 @@ static void __init xen_e820_resolve_conflicts(phys_addr_t start,
return;
end = start + size;
entry = xen_e820_table.entries;
mapcnt = 0;
for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
while (mapcnt < xen_e820_table.nr_entries) {
entry = xen_e820_table.entries + mapcnt;
if (entry->addr >= end)
return;
if (entry->addr + entry->size > start &&
entry->type == E820_TYPE_NVS)
entry->type == E820_TYPE_NVS) {
xen_e820_swap_entry_with_ram(entry);
/* E820 map has been changed, restart loop! */
mapcnt = 0;
continue;
}
entry++;
mapcnt++;
}
}

View File

@@ -857,6 +857,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
#endif
struct blk_iou_cmd {
u64 start;
u64 len;
int res;
bool nowait;
};
@@ -946,23 +948,27 @@ int blkdev_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
{
struct block_device *bdev = I_BDEV(cmd->file->f_mapping->host);
struct blk_iou_cmd *bic = io_uring_cmd_to_pdu(cmd, struct blk_iou_cmd);
const struct io_uring_sqe *sqe = cmd->sqe;
u32 cmd_op = cmd->cmd_op;
uint64_t start, len;
if (unlikely(sqe->ioprio || sqe->__pad1 || sqe->len ||
sqe->rw_flags || sqe->file_index))
return -EINVAL;
/* Read what we need from the SQE on the first issue */
if (!(issue_flags & IORING_URING_CMD_REISSUE)) {
const struct io_uring_sqe *sqe = cmd->sqe;
if (unlikely(sqe->ioprio || sqe->__pad1 || sqe->len ||
sqe->rw_flags || sqe->file_index))
return -EINVAL;
bic->start = READ_ONCE(sqe->addr);
bic->len = READ_ONCE(sqe->addr3);
}
bic->res = 0;
bic->nowait = issue_flags & IO_URING_F_NONBLOCK;
start = READ_ONCE(sqe->addr);
len = READ_ONCE(sqe->addr3);
switch (cmd_op) {
case BLOCK_URING_CMD_DISCARD:
return blkdev_cmd_discard(cmd, bdev, start, len, bic->nowait);
return blkdev_cmd_discard(cmd, bdev, bic->start, bic->len,
bic->nowait);
}
return -EINVAL;
}

View File

@@ -537,6 +537,26 @@ static const struct file_operations ivpu_fops = {
#endif
};
static int ivpu_gem_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv,
u32 handle, u32 flags, int *prime_fd)
{
struct drm_gem_object *obj;
obj = drm_gem_object_lookup(file_priv, handle);
if (!obj)
return -ENOENT;
if (drm_gem_is_imported(obj)) {
/* Do not allow re-exporting */
drm_gem_object_put(obj);
return -EOPNOTSUPP;
}
drm_gem_object_put(obj);
return drm_gem_prime_handle_to_fd(dev, file_priv, handle, flags, prime_fd);
}
static const struct drm_driver driver = {
.driver_features = DRIVER_GEM | DRIVER_COMPUTE_ACCEL,
@@ -545,6 +565,7 @@ static const struct drm_driver driver = {
.gem_create_object = ivpu_gem_create_object,
.gem_prime_import = ivpu_gem_prime_import,
.prime_handle_to_fd = ivpu_gem_prime_handle_to_fd,
.ioctls = ivpu_drm_ioctls,
.num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls),

View File

@@ -497,11 +497,11 @@ static void decode_ras_msg(struct qaic_device *qdev, struct ras_data *msg)
qdev->ce_count++;
break;
case UE:
if (qdev->ce_count != UINT_MAX)
if (qdev->ue_count != UINT_MAX)
qdev->ue_count++;
break;
case UE_NF:
if (qdev->ce_count != UINT_MAX)
if (qdev->ue_nf_count != UINT_MAX)
qdev->ue_nf_count++;
break;
default:

View File

@@ -204,7 +204,6 @@ pub(crate) fn reservation_abort(&mut self, offset: usize) -> Result<FreedRange>
// caller will mark them as unused, which means that they can be freed if the system comes
// under memory pressure.
let mut freed_range = FreedRange::interior_pages(offset, size);
#[expect(clippy::collapsible_if)] // reads better like this
if offset % PAGE_SIZE != 0 {
if i == 0 || self.ranges[i - 1].endpoint() <= (offset & PAGE_MASK) {
freed_range.start_page_idx -= 1;

View File

@@ -900,6 +900,20 @@ static int ublk_validate_params(const struct ublk_device *ub)
if (p->logical_bs_shift > PAGE_SHIFT || p->logical_bs_shift < 9)
return -EINVAL;
/*
* 256M is a reasonable upper bound for physical block size,
* io_min and io_opt; it aligns with the maximum physical
* block size possible in NVMe.
*/
if (p->physical_bs_shift > ilog2(SZ_256M))
return -EINVAL;
if (p->io_min_shift > ilog2(SZ_256M))
return -EINVAL;
if (p->io_opt_shift > ilog2(SZ_256M))
return -EINVAL;
if (p->logical_bs_shift > p->physical_bs_shift)
return -EINVAL;
@@ -2397,8 +2411,14 @@ static void ublk_reset_ch_dev(struct ublk_device *ub)
{
int i;
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
ublk_queue_reinit(ub, ublk_get_queue(ub, i));
for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
struct ublk_queue *ubq = ublk_get_queue(ub, i);
/* Sync with ublk_cancel_cmd() */
spin_lock(&ubq->cancel_lock);
ublk_queue_reinit(ub, ubq);
spin_unlock(&ubq->cancel_lock);
}
/* set to NULL, otherwise new tasks cannot mmap io_cmd_buf */
ub->mm = NULL;
@@ -2739,6 +2759,7 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, unsigned tag,
{
struct ublk_io *io = &ubq->ios[tag];
struct ublk_device *ub = ubq->dev;
struct io_uring_cmd *cmd = NULL;
struct request *req;
bool done;
@@ -2761,12 +2782,15 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, unsigned tag,
spin_lock(&ubq->cancel_lock);
done = !!(io->flags & UBLK_IO_FLAG_CANCELED);
if (!done)
if (!done) {
io->flags |= UBLK_IO_FLAG_CANCELED;
cmd = io->cmd;
io->cmd = NULL;
}
spin_unlock(&ubq->cancel_lock);
if (!done)
io_uring_cmd_done(io->cmd, UBLK_IO_RES_ABORT, issue_flags);
if (!done && cmd)
io_uring_cmd_done(cmd, UBLK_IO_RES_ABORT, issue_flags);
}
/*
@@ -3496,8 +3520,10 @@ static void ublk_ch_uring_cmd_cb(struct io_tw_req tw_req, io_tw_token_t tw)
{
unsigned int issue_flags = IO_URING_CMD_TASK_WORK_ISSUE_FLAGS;
struct io_uring_cmd *cmd = io_uring_cmd_from_tw(tw_req);
int ret = ublk_ch_uring_cmd_local(cmd, issue_flags);
int ret = -ECANCELED;
if (!tw.cancel)
ret = ublk_ch_uring_cmd_local(cmd, issue_flags);
if (ret != -EIOCBQUEUED)
io_uring_cmd_done(cmd, ret, issue_flags);
}
@@ -4990,13 +5016,15 @@ static int ublk_ctrl_set_params(struct ublk_device *ub,
*/
ret = -EACCES;
} else if (copy_from_user(&ub->params, argp, ph.len)) {
/* zero out partial copy so no stale params survive */
memset(&ub->params, 0, sizeof(ub->params));
ret = -EFAULT;
} else {
/* clear all we don't support yet */
ub->params.types &= UBLK_PARAM_TYPE_ALL;
ret = ublk_validate_params(ub);
if (ret)
ub->params.types = 0;
memset(&ub->params, 0, sizeof(ub->params));
}
mutex_unlock(&ub->mutex);

View File

@@ -110,6 +110,7 @@ struct eqc_match_data {
const char *reset_auxdev_name;
const char *pinctrl_auxdev_name;
const char *eth_phy_auxdev_name;
unsigned int early_clk_count;
};
@@ -321,38 +322,18 @@ static void eqc_probe_init_fixed_factors(struct device *dev,
}
}
static void eqc_auxdev_release(struct device *dev)
{
struct auxiliary_device *adev = to_auxiliary_dev(dev);
kfree(adev);
}
static int eqc_auxdev_create(struct device *dev, void __iomem *base,
const char *name, u32 id)
static void eqc_auxdev_create_optional(struct device *dev, void __iomem *base,
const char *name)
{
struct auxiliary_device *adev;
int ret;
adev = kzalloc_obj(*adev);
if (!adev)
return -ENOMEM;
adev->name = name;
adev->dev.parent = dev;
adev->dev.platform_data = (void __force *)base;
adev->dev.release = eqc_auxdev_release;
adev->id = id;
ret = auxiliary_device_init(adev);
if (ret)
return ret;
ret = auxiliary_device_add(adev);
if (ret)
auxiliary_device_uninit(adev);
return ret;
if (name) {
adev = devm_auxiliary_device_create(dev, name,
(void __force *)base);
if (!adev)
dev_warn(dev, "failed creating auxiliary device %s.%s\n",
KBUILD_MODNAME, name);
}
}
static int eqc_probe(struct platform_device *pdev)
@@ -364,7 +345,6 @@ static int eqc_probe(struct platform_device *pdev)
unsigned int i, clk_count;
struct resource *res;
void __iomem *base;
int ret;
data = device_get_match_data(dev);
if (!data)
@@ -378,21 +358,10 @@ static int eqc_probe(struct platform_device *pdev)
if (!base)
return -ENOMEM;
/* Init optional reset auxiliary device. */
if (data->reset_auxdev_name) {
ret = eqc_auxdev_create(dev, base, data->reset_auxdev_name, 0);
if (ret)
dev_warn(dev, "failed creating auxiliary device %s.%s: %d\n",
KBUILD_MODNAME, data->reset_auxdev_name, ret);
}
/* Init optional pinctrl auxiliary device. */
if (data->pinctrl_auxdev_name) {
ret = eqc_auxdev_create(dev, base, data->pinctrl_auxdev_name, 0);
if (ret)
dev_warn(dev, "failed creating auxiliary device %s.%s: %d\n",
KBUILD_MODNAME, data->pinctrl_auxdev_name, ret);
}
/* Init optional auxiliary devices. */
eqc_auxdev_create_optional(dev, base, data->reset_auxdev_name);
eqc_auxdev_create_optional(dev, base, data->pinctrl_auxdev_name);
eqc_auxdev_create_optional(dev, base, data->eth_phy_auxdev_name);
if (data->pll_count + data->div_count + data->fixed_factor_count == 0)
return 0; /* Zero clocks, we are done. */
@@ -553,6 +522,7 @@ static const struct eqc_match_data eqc_eyeq5_match_data = {
.reset_auxdev_name = "reset",
.pinctrl_auxdev_name = "pinctrl",
.eth_phy_auxdev_name = "phy",
.early_clk_count = ARRAY_SIZE(eqc_eyeq5_early_plls) +
ARRAY_SIZE(eqc_eyeq5_early_fixed_factors),

View File

@@ -153,7 +153,7 @@ static int rk808_clkout_probe(struct platform_device *pdev)
struct rk808_clkout *rk808_clkout;
int ret;
dev->of_node = pdev->dev.parent->of_node;
device_set_of_node_from_dev(dev, dev->parent);
rk808_clkout = devm_kzalloc(dev,
sizeof(*rk808_clkout), GFP_KERNEL);

View File

@@ -846,7 +846,7 @@ static const struct clk_parent_data top_parents[] = {
CCU_PARENT_HW(pll6_d3),
};
CCU_MUX_DIV_GATE_FC_DEFINE(top_dclk, top_parents, APMU_TOP_DCLK_CTRL, 5, 3,
BIT(8), 2, 3, BIT(1), 0);
BIT(8), 2, 3, BIT(1), CLK_IS_CRITICAL);
static const struct clk_parent_data ucie_parents[] = {
CCU_PARENT_HW(pll1_d8_307p2),

View File

@@ -777,9 +777,9 @@ static int init_one_mc(struct mc_priv *priv, struct platform_device *pdev, int i
u32 num_chans, rank, dwidth, config;
struct edac_mc_layer layers[2];
struct mem_ctl_info *mci;
char name[MC_NAME_LEN];
struct device *dev;
enum dev_type dt;
char *name;
int rc;
config = priv->adec[CONF + i * ADEC_NUM];
@@ -813,13 +813,9 @@ static int init_one_mc(struct mc_priv *priv, struct platform_device *pdev, int i
layers[1].is_virt_csrow = false;
rc = -ENOMEM;
name = kzalloc(MC_NAME_LEN, GFP_KERNEL);
if (!name)
return rc;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
goto err_name_free;
return rc;
mci = edac_mc_alloc(i, ARRAY_SIZE(layers), layers, sizeof(struct mc_priv));
if (!mci) {
@@ -858,8 +854,6 @@ static int init_one_mc(struct mc_priv *priv, struct platform_device *pdev, int i
edac_mc_free(mci);
err_dev_free:
kfree(dev);
err_name_free:
kfree(name);
return rc;
}

View File

@@ -3149,11 +3149,7 @@ static int __init amdgpu_init(void)
r = amdgpu_sync_init();
if (r)
goto error_sync;
r = amdgpu_userq_fence_slab_init();
if (r)
goto error_fence;
return r;
amdgpu_register_atpx_handler();
amdgpu_acpi_detect();
@@ -3161,7 +3157,7 @@ static int __init amdgpu_init(void)
/* Ignore KFD init failures when CONFIG_HSA_AMD is not set. */
r = amdgpu_amdkfd_init();
if (r && r != -ENOENT)
goto error_fence;
goto error_fini_sync;
if (amdgpu_pp_feature_mask & PP_OVERDRIVE_MASK) {
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
@@ -3172,10 +3168,8 @@ static int __init amdgpu_init(void)
/* let modprobe override vga console setting */
return pci_register_driver(&amdgpu_kms_pci_driver);
error_fence:
error_fini_sync:
amdgpu_sync_fini();
error_sync:
return r;
}
@@ -3186,7 +3180,6 @@ static void __exit amdgpu_exit(void)
amdgpu_unregister_atpx_handler();
amdgpu_acpi_release();
amdgpu_sync_fini();
amdgpu_userq_fence_slab_fini();
mmu_notifier_synchronize();
amdgpu_xcp_drv_release();
}

View File

@@ -262,12 +262,19 @@ void amdgpu_gart_table_ram_free(struct amdgpu_device *adev)
*/
int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
{
int r;
if (adev->gart.bo != NULL)
return 0;
return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.bo,
NULL, (void *)&adev->gart.ptr);
r = amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.bo,
NULL, (void *)&adev->gart.ptr);
if (r)
return r;
memset_io(adev->gart.ptr, adev->gart.gart_pte_flags, adev->gart.table_size);
return 0;
}
/**

View File

@@ -32,29 +32,9 @@
#include "amdgpu.h"
#include "amdgpu_userq_fence.h"
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",
sizeof(struct amdgpu_userq_fence),
0,
SLAB_HWCACHE_ALIGN,
NULL);
if (!amdgpu_userq_fence_slab)
return -ENOMEM;
return 0;
}
void amdgpu_userq_fence_slab_fini(void)
{
rcu_barrier();
kmem_cache_destroy(amdgpu_userq_fence_slab);
}
static const struct dma_fence_ops amdgpu_userq_fence_ops;
static inline struct amdgpu_userq_fence *to_amdgpu_userq_fence(struct dma_fence *f)
{
@@ -231,7 +211,7 @@ void amdgpu_userq_fence_driver_put(struct amdgpu_userq_fence_driver *fence_drv)
static int amdgpu_userq_fence_alloc(struct amdgpu_userq_fence **userq_fence)
{
*userq_fence = kmem_cache_alloc(amdgpu_userq_fence_slab, GFP_ATOMIC);
*userq_fence = kmalloc(sizeof(**userq_fence), GFP_KERNEL);
return *userq_fence ? 0 : -ENOMEM;
}
@@ -342,7 +322,7 @@ static void amdgpu_userq_fence_free(struct rcu_head *rcu)
amdgpu_userq_fence_driver_put(fence_drv);
kvfree(userq_fence->fence_drv_array);
kmem_cache_free(amdgpu_userq_fence_slab, userq_fence);
kfree(userq_fence);
}
static void amdgpu_userq_fence_release(struct dma_fence *f)
@@ -545,7 +525,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
r = amdgpu_userq_fence_create(queue, userq_fence, wptr, &fence);
if (r) {
mutex_unlock(&userq_mgr->userq_mutex);
kmem_cache_free(amdgpu_userq_fence_slab, userq_fence);
kfree(userq_fence);
goto put_gobj_write;
}

View File

@@ -58,9 +58,6 @@ struct amdgpu_userq_fence_driver {
char timeline_name[TASK_COMM_LEN];
};
int amdgpu_userq_fence_slab_init(void);
void amdgpu_userq_fence_slab_fini(void);
void amdgpu_userq_fence_driver_get(struct amdgpu_userq_fence_driver *fence_drv);
void amdgpu_userq_fence_driver_put(struct amdgpu_userq_fence_driver *fence_drv);
int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,

View File

@@ -5660,9 +5660,6 @@ static void gfx_v9_0_ring_emit_fence_kiq(struct amdgpu_ring *ring, u64 addr,
{
struct amdgpu_device *adev = ring->adev;
/* we only allocate 32bit for each seq wb address */
BUG_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
/* write fence seq to the "addr" */
amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |

View File

@@ -30,34 +30,6 @@
#define AMDGPU_USERQ_PROC_CTX_SZ PAGE_SIZE
#define AMDGPU_USERQ_GANG_CTX_SZ PAGE_SIZE
static int
mes_userq_map_gtt_bo_to_gart(struct amdgpu_bo *bo)
{
int ret;
ret = amdgpu_bo_reserve(bo, true);
if (ret) {
DRM_ERROR("Failed to reserve bo. ret %d\n", ret);
goto err_reserve_bo_failed;
}
ret = amdgpu_ttm_alloc_gart(&bo->tbo);
if (ret) {
DRM_ERROR("Failed to bind bo to GART. ret %d\n", ret);
goto err_map_bo_gart_failed;
}
amdgpu_bo_unreserve(bo);
bo = amdgpu_bo_ref(bo);
return 0;
err_map_bo_gart_failed:
amdgpu_bo_unreserve(bo);
err_reserve_bo_failed:
return ret;
}
static int
mes_userq_create_wptr_mapping(struct amdgpu_device *adev,
struct amdgpu_userq_mgr *uq_mgr,
@@ -65,55 +37,62 @@ mes_userq_create_wptr_mapping(struct amdgpu_device *adev,
uint64_t wptr)
{
struct amdgpu_bo_va_mapping *wptr_mapping;
struct amdgpu_vm *wptr_vm;
struct amdgpu_userq_obj *wptr_obj = &queue->wptr_obj;
struct amdgpu_bo *obj;
struct amdgpu_vm *vm = queue->vm;
struct drm_exec exec;
int ret;
wptr_vm = queue->vm;
ret = amdgpu_bo_reserve(wptr_vm->root.bo, false);
if (ret)
return ret;
wptr &= AMDGPU_GMC_HOLE_MASK;
wptr_mapping = amdgpu_vm_bo_lookup_mapping(wptr_vm, wptr >> PAGE_SHIFT);
amdgpu_bo_unreserve(wptr_vm->root.bo);
if (!wptr_mapping) {
DRM_ERROR("Failed to lookup wptr bo\n");
return -EINVAL;
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 2);
drm_exec_until_all_locked(&exec) {
ret = amdgpu_vm_lock_pd(vm, &exec, 1);
drm_exec_retry_on_contention(&exec);
if (unlikely(ret))
goto fail_lock;
wptr_mapping = amdgpu_vm_bo_lookup_mapping(vm, wptr >> PAGE_SHIFT);
if (!wptr_mapping) {
ret = -EINVAL;
goto fail_lock;
}
obj = wptr_mapping->bo_va->base.bo;
ret = drm_exec_lock_obj(&exec, &obj->tbo.base);
drm_exec_retry_on_contention(&exec);
if (unlikely(ret))
goto fail_lock;
}
wptr_obj->obj = wptr_mapping->bo_va->base.bo;
wptr_obj->obj = amdgpu_bo_ref(wptr_mapping->bo_va->base.bo);
if (wptr_obj->obj->tbo.base.size > PAGE_SIZE) {
DRM_ERROR("Requested GART mapping for wptr bo larger than one page\n");
return -EINVAL;
}
ret = mes_userq_map_gtt_bo_to_gart(wptr_obj->obj);
if (ret) {
DRM_ERROR("Failed to map wptr bo to GART\n");
return ret;
}
ret = amdgpu_bo_reserve(wptr_obj->obj, true);
if (ret) {
DRM_ERROR("Failed to reserve wptr bo\n");
return ret;
ret = -EINVAL;
goto fail_map;
}
/* TODO use eviction fence instead of pinning. */
ret = amdgpu_bo_pin(wptr_obj->obj, AMDGPU_GEM_DOMAIN_GTT);
if (ret) {
drm_file_err(uq_mgr->file, "[Usermode queues] Failed to pin wptr bo\n");
goto unresv_bo;
DRM_ERROR("Failed to pin wptr bo. ret %d\n", ret);
goto fail_map;
}
ret = amdgpu_ttm_alloc_gart(&wptr_obj->obj->tbo);
if (ret) {
DRM_ERROR("Failed to bind bo to GART. ret %d\n", ret);
goto fail_map;
}
queue->wptr_obj.gpu_addr = amdgpu_bo_gpu_offset(wptr_obj->obj);
amdgpu_bo_unreserve(wptr_obj->obj);
drm_exec_fini(&exec);
return 0;
unresv_bo:
amdgpu_bo_unreserve(wptr_obj->obj);
fail_map:
amdgpu_bo_unref(&wptr_obj->obj);
fail_lock:
drm_exec_fini(&exec);
return ret;
}

View File

@@ -889,7 +889,7 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
/* write the fence */
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE));
/* zero in first two bits */
BUG_ON(addr & 0x3);
WARN_ON(addr & 0x3);
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, lower_32_bits(seq));
@@ -899,7 +899,7 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
addr += 4;
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE));
/* zero in first two bits */
BUG_ON(addr & 0x3);
WARN_ON(addr & 0x3);
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(seq));

View File

@@ -1360,7 +1360,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
if (WARN_ON_ONCE(!peer_pdd))
continue;
kfd_flush_tlb(peer_pdd, TLB_FLUSH_LEGACY);
kfd_flush_tlb(peer_pdd);
}
kfree(devices_arr);
@@ -1455,7 +1455,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
if (WARN_ON_ONCE(!peer_pdd))
continue;
if (flush_tlb)
kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
kfd_flush_tlb(peer_pdd);
/* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */
err = amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv);

View File

@@ -1737,37 +1737,6 @@ bool kgd2kfd_vmfault_fast_path(struct amdgpu_device *adev, struct amdgpu_iv_entr
return false;
}
/* check if there is kfd process still uses adev */
static bool kgd2kfd_check_device_idle(struct amdgpu_device *adev)
{
struct kfd_process *p;
struct hlist_node *p_temp;
unsigned int temp;
struct kfd_node *dev;
mutex_lock(&kfd_processes_mutex);
if (hash_empty(kfd_processes_table)) {
mutex_unlock(&kfd_processes_mutex);
return true;
}
/* check if there is device still use adev */
hash_for_each_safe(kfd_processes_table, temp, p_temp, p, kfd_processes) {
for (int i = 0; i < p->n_pdds; i++) {
dev = p->pdds[i]->dev;
if (dev->adev == adev) {
mutex_unlock(&kfd_processes_mutex);
return false;
}
}
}
mutex_unlock(&kfd_processes_mutex);
return true;
}
/** kgd2kfd_teardown_processes - gracefully tear down existing
* kfd processes that use adev
*
@@ -1800,7 +1769,7 @@ void kgd2kfd_teardown_processes(struct amdgpu_device *adev)
mutex_unlock(&kfd_processes_mutex);
/* wait all kfd processes use adev terminate */
while (!kgd2kfd_check_device_idle(adev))
while (!!atomic_read(&adev->kfd.dev->kfd_processes_count))
cond_resched();
}

View File

@@ -572,7 +572,7 @@ static int allocate_vmid(struct device_queue_manager *dqm,
qpd->vmid,
qpd->page_table_base);
/* invalidate the VM context after pasid and vmid mapping is set up */
kfd_flush_tlb(qpd_to_pdd(qpd), TLB_FLUSH_LEGACY);
kfd_flush_tlb(qpd_to_pdd(qpd));
if (dqm->dev->kfd2kgd->set_scratch_backing_va)
dqm->dev->kfd2kgd->set_scratch_backing_va(dqm->dev->adev,
@@ -610,7 +610,7 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
if (flush_texture_cache_nocpsch(q->device, qpd))
dev_err(dev, "Failed to flush TC\n");
kfd_flush_tlb(qpd_to_pdd(qpd), TLB_FLUSH_LEGACY);
kfd_flush_tlb(qpd_to_pdd(qpd));
/* Release the vmid mapping */
set_pasid_vmid_mapping(dqm, 0, qpd->vmid);
@@ -1284,7 +1284,7 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm,
dqm->dev->adev,
qpd->vmid,
qpd->page_table_base);
kfd_flush_tlb(pdd, TLB_FLUSH_LEGACY);
kfd_flush_tlb(pdd);
}
/* Take a safe reference to the mm_struct, which may otherwise

View File

@@ -1554,13 +1554,13 @@ void kfd_signal_reset_event(struct kfd_node *dev);
void kfd_signal_poison_consumed_event(struct kfd_node *dev, u32 pasid);
void kfd_signal_process_terminate_event(struct kfd_process *p);
static inline void kfd_flush_tlb(struct kfd_process_device *pdd,
enum TLB_FLUSH_TYPE type)
static inline void kfd_flush_tlb(struct kfd_process_device *pdd)
{
struct amdgpu_device *adev = pdd->dev->adev;
struct amdgpu_vm *vm = drm_priv_to_vm(pdd->drm_priv);
amdgpu_vm_flush_compute_tlb(adev, vm, type, pdd->dev->xcc_mask);
amdgpu_vm_flush_compute_tlb(adev, vm, TLB_FLUSH_HEAVYWEIGHT,
pdd->dev->xcc_mask);
}
static inline bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev)

View File

@@ -1424,7 +1424,7 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start,
if (r)
break;
}
kfd_flush_tlb(pdd, TLB_FLUSH_HEAVYWEIGHT);
kfd_flush_tlb(pdd);
}
return r;
@@ -1571,7 +1571,7 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset,
}
}
kfd_flush_tlb(pdd, TLB_FLUSH_LEGACY);
kfd_flush_tlb(pdd);
}
return r;

View File

@@ -1333,12 +1333,13 @@ static int ci_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
dev_id = adev->pdev->device;
if ((dpm_table->mclk_table.count >= 2)
&& ((dev_id == 0x67B0) || (dev_id == 0x67B1))) {
smu_data->smc_state_table.MemoryLevel[1].MinVddci =
smu_data->smc_state_table.MemoryLevel[0].MinVddci;
smu_data->smc_state_table.MemoryLevel[1].MinMvdd =
smu_data->smc_state_table.MemoryLevel[0].MinMvdd;
if ((dpm_table->mclk_table.count >= 2) &&
((dev_id == 0x67B0) || (dev_id == 0x67B1)) &&
(adev->pdev->revision == 0)) {
smu_data->smc_state_table.MemoryLevel[1].MinVddc =
smu_data->smc_state_table.MemoryLevel[0].MinVddc;
smu_data->smc_state_table.MemoryLevel[1].MinVddcPhases =
smu_data->smc_state_table.MemoryLevel[0].MinVddcPhases;
}
smu_data->smc_state_table.MemoryLevel[0].ActivityLevel = 0x1F;
CONVERT_FROM_HOST_TO_SMC_US(smu_data->smc_state_table.MemoryLevel[0].ActivityLevel);

View File

@@ -1293,7 +1293,7 @@ static const struct drm_edid *tda998x_edid_read(struct tda998x_priv *priv,
* can't handle signals gracefully.
*/
if (tda998x_edid_delay_wait(priv))
return 0;
return NULL;
if (priv->rev == TDA19988)
reg_clear(priv, REG_TX4, TX4_PD_RAM);
@@ -1762,7 +1762,7 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = {
static int tda998x_get_audio_ports(struct tda998x_priv *priv,
struct device_node *np)
{
const u32 *port_data;
const __be32 *port_data;
u32 size;
int i;

View File

@@ -490,7 +490,7 @@ static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off,
* the number of horizontal pixels that need an update.
*/
off_t bit_off = (off % line_length) * 8;
off_t bit_end = (end % line_length) * 8;
off_t bit_end = bit_off + len * 8;
x1 = bit_off / info->var.bits_per_pixel;
x2 = DIV_ROUND_UP(bit_end, info->var.bits_per_pixel);

View File

@@ -1019,7 +1019,7 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_gem_change_handle *args = data;
struct drm_gem_object *obj;
struct drm_gem_object *obj, *idrobj;
int handle, ret;
if (!drm_core_check_feature(dev, DRIVER_GEM))
@@ -1042,8 +1042,29 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
mutex_lock(&file_priv->prime.lock);
spin_lock(&file_priv->table_lock);
/* When create_tail allocs an obj idr, it needs to first alloc as NULL,
* then later replace with the correct object. This is not necessary
* here, because the only operations that could race are drm_prime
* bookkeeping, and we hold the prime lock.
*/
ret = idr_alloc(&file_priv->object_idr, obj, handle, handle + 1,
GFP_NOWAIT);
if (ret < 0) {
spin_unlock(&file_priv->table_lock);
goto out_unlock;
}
idrobj = idr_replace(&file_priv->object_idr, NULL, handle);
if (idrobj != obj) {
idr_replace(&file_priv->object_idr, idrobj, handle);
idr_remove(&file_priv->object_idr, args->new_handle);
spin_unlock(&file_priv->table_lock);
ret = -ENOENT;
goto out_unlock;
}
spin_unlock(&file_priv->table_lock);
if (ret < 0)
@@ -1055,6 +1076,8 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
if (ret < 0) {
spin_lock(&file_priv->table_lock);
idr_remove(&file_priv->object_idr, handle);
idrobj = idr_replace(&file_priv->object_idr, obj, handle);
WARN_ON(idrobj != NULL);
spin_unlock(&file_priv->table_lock);
goto out_unlock;
}

View File

@@ -116,16 +116,18 @@ int etnaviv_sched_push_job(struct etnaviv_gem_submit *submit)
*/
mutex_lock(&gpu->sched_lock);
ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
NULL, xa_limit_32b, &gpu->next_user_fence,
GFP_KERNEL);
if (ret < 0)
goto out_unlock;
drm_sched_job_arm(&submit->sched_job);
submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
ret = xa_alloc_cyclic(&gpu->user_fences, &submit->out_fence_id,
submit->out_fence, xa_limit_32b,
&gpu->next_user_fence, GFP_KERNEL);
if (ret < 0) {
drm_sched_job_cleanup(&submit->sched_job);
goto out_unlock;
}
xa_store(&gpu->user_fences, submit->out_fence_id,
submit->out_fence, GFP_KERNEL);
/* the scheduler holds on to the job now */
kref_get(&submit->refcount);

View File

@@ -423,7 +423,9 @@ static int exynos_mic_probe(struct platform_device *pdev)
mic->bridge.of_node = dev->of_node;
drm_bridge_add(&mic->bridge);
ret = devm_drm_bridge_add(dev, &mic->bridge);
if (ret)
goto err;
pm_runtime_enable(dev);
@@ -443,12 +445,8 @@ static int exynos_mic_probe(struct platform_device *pdev)
static void exynos_mic_remove(struct platform_device *pdev)
{
struct exynos_mic *mic = platform_get_drvdata(pdev);
component_del(&pdev->dev, &exynos_mic_component_ops);
pm_runtime_disable(&pdev->dev);
drm_bridge_remove(&mic->bridge);
}
static const struct of_device_id exynos_mic_of_match[] = {

View File

@@ -750,9 +750,8 @@ static bool has_auxccs(struct drm_device *drm)
{
struct drm_i915_private *i915 = to_i915(drm);
return IS_GRAPHICS_VER(i915, 9, 12) ||
IS_ALDERLAKE_P(i915) ||
IS_METEORLAKE(i915);
return IS_GRAPHICS_VER(i915, 9, 12) &&
!HAS_FLAT_CCS(i915);
}
static bool has_fenced_regions(struct drm_device *drm)

View File

@@ -2513,6 +2513,7 @@ static const struct nvkm_device_chip
nv170_chipset = {
.name = "GA100",
.bar = { 0x00000001, tu102_bar_new },
.bios = { 0x00000001, nvkm_bios_new },
.devinit = { 0x00000001, ga100_devinit_new },
.fault = { 0x00000001, tu102_fault_new },
.fb = { 0x00000001, ga100_fb_new },
@@ -2529,7 +2530,6 @@ nv170_chipset = {
.vfn = { 0x00000001, ga100_vfn_new },
.ce = { 0x000003ff, ga100_ce_new },
.fifo = { 0x00000001, ga100_fifo_new },
.sec2 = { 0x00000001, tu102_sec2_new },
};
static const struct nvkm_device_chip
@@ -3341,7 +3341,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x166: device->chip = &nv166_chipset; break;
case 0x167: device->chip = &nv167_chipset; break;
case 0x168: device->chip = &nv168_chipset; break;
case 0x170: device->chip = &nv170_chipset; break;
case 0x172: device->chip = &nv172_chipset; break;
case 0x173: device->chip = &nv173_chipset; break;
case 0x174: device->chip = &nv174_chipset; break;
@@ -3361,6 +3360,14 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x1b6: device->chip = &nv1b6_chipset; break;
case 0x1b7: device->chip = &nv1b7_chipset; break;
default:
if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) {
switch (device->chipset) {
case 0x170: device->chip = &nv170_chipset; break;
default:
break;
}
}
if (!device->chip) {
nvdev_error(device, "unknown chipset (%08x)\n", boot0);
ret = -ENODEV;

View File

@@ -41,11 +41,15 @@ ga100_gsp_flcn = {
static const struct nvkm_gsp_func
ga100_gsp = {
.flcn = &ga100_gsp_flcn,
.fwsec = &tu102_gsp_fwsec,
.sig_section = ".fwsignature_ga100",
.booter.ctor = tu102_gsp_booter_ctor,
.fwsec_sb.ctor = tu102_gsp_fwsec_sb_ctor,
.fwsec_sb.dtor = tu102_gsp_fwsec_sb_dtor,
.dtor = r535_gsp_dtor,
.oneinit = tu102_gsp_oneinit,
.init = tu102_gsp_init,

View File

@@ -318,13 +318,8 @@ tu102_gsp_oneinit(struct nvkm_gsp *gsp)
if (ret)
return ret;
/*
* Calculate FB layout. FRTS is a memory region created by the FWSEC-FRTS firmware.
* FWSEC comes from VBIOS. So on systems with no VBIOS (e.g. GA100), the FRTS does
* not exist. Therefore, use the existence of VBIOS to determine whether to reserve
* an FRTS region.
*/
gsp->fb.wpr2.frts.size = device->bios ? 0x100000 : 0;
/* Calculate FB layout. */
gsp->fb.wpr2.frts.size = 0x100000;
gsp->fb.wpr2.frts.addr = ALIGN_DOWN(gsp->fb.bios.addr, 0x20000) - gsp->fb.wpr2.frts.size;
gsp->fb.wpr2.boot.size = gsp->boot.fw.size;
@@ -348,12 +343,9 @@ tu102_gsp_oneinit(struct nvkm_gsp *gsp)
if (ret)
return ret;
/* Only boot FWSEC-FRTS if it actually exists */
if (gsp->fb.wpr2.frts.size) {
ret = nvkm_gsp_fwsec_frts(gsp);
if (WARN_ON(ret))
return ret;
}
ret = nvkm_gsp_fwsec_frts(gsp);
if (WARN_ON(ret))
return ret;
/* Reset GSP into RISC-V mode. */
ret = gsp->func->reset(gsp);

View File

@@ -208,6 +208,7 @@ config DRM_PANEL_HIMAX_HX83121A
depends on OF
depends on DRM_MIPI_DSI
depends on BACKLIGHT_CLASS_DEVICE
select DRM_DISPLAY_DSC_HELPER
select DRM_KMS_HELPER
help
Say Y here if you want to enable support for Himax HX83121A-based

View File

@@ -1324,6 +1324,8 @@ static int boe_panel_disable(struct drm_panel *panel)
mipi_dsi_dcs_set_display_off_multi(&ctx);
mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
boe->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
mipi_dsi_msleep(&ctx, 150);
return ctx.accum_err;

View File

@@ -98,9 +98,7 @@ static int feiyang_enable(struct drm_panel *panel)
/* T12 (video & logic signal rise + backlight rise) T12 >= 200ms */
msleep(200);
mipi_dsi_dcs_set_display_on(ctx->dsi);
return 0;
return mipi_dsi_dcs_set_display_on(ctx->dsi);
}
static int feiyang_disable(struct drm_panel *panel)

View File

@@ -937,6 +937,8 @@ static int hx83102_disable(struct drm_panel *panel)
mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
mipi_dsi_msleep(&dsi_ctx, 150);
return dsi_ctx.accum_err;

View File

@@ -596,8 +596,8 @@ static int himax_probe(struct mipi_dsi_device *dsi)
ctx = devm_drm_panel_alloc(dev, struct himax, panel, &himax_panel_funcs,
DRM_MODE_CONNECTOR_DSI);
if (!ctx)
return -ENOMEM;
if (IS_ERR(ctx))
return PTR_ERR(ctx);
ret = devm_regulator_bulk_get_const(&dsi->dev,
ARRAY_SIZE(himax_supplies),

View File

@@ -118,12 +118,13 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Complete initialization. */
ret = drm_dev_register(&qdev->ddev, ent->driver_data);
if (ret)
goto modeset_cleanup;
goto poll_fini;
drm_client_setup(&qdev->ddev, NULL);
return 0;
modeset_cleanup:
poll_fini:
drm_kms_helper_poll_fini(&qdev->ddev);
qxl_modeset_fini(qdev);
unload:
qxl_device_fini(qdev);
@@ -154,6 +155,7 @@ qxl_pci_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
drm_kms_helper_poll_fini(dev);
drm_dev_unregister(dev);
drm_atomic_helper_shutdown(dev);
if (pci_is_vga(pdev) && pdev->revision < 5)

View File

@@ -2461,7 +2461,8 @@ static void ci_register_patching_mc_arb(struct radeon_device *rdev,
if (patch &&
((rdev->pdev->device == 0x67B0) ||
(rdev->pdev->device == 0x67B1))) {
(rdev->pdev->device == 0x67B1)) &&
(rdev->pdev->revision == 0)) {
if ((memory_clock > 100000) && (memory_clock <= 125000)) {
tmp2 = (((0x31 * engine_clock) / 125000) - 1) & 0xff;
*dram_timimg2 &= ~0x00ff0000;
@@ -3304,7 +3305,8 @@ static int ci_populate_all_memory_levels(struct radeon_device *rdev)
pi->smc_state_table.MemoryLevel[0].EnabledForActivity = 1;
if ((dpm_table->mclk_table.count >= 2) &&
((rdev->pdev->device == 0x67B0) || (rdev->pdev->device == 0x67B1))) {
((rdev->pdev->device == 0x67B0) || (rdev->pdev->device == 0x67B1)) &&
(rdev->pdev->revision == 0)) {
pi->smc_state_table.MemoryLevel[1].MinVddc =
pi->smc_state_table.MemoryLevel[0].MinVddc;
pi->smc_state_table.MemoryLevel[1].MinVddcPhases =
@@ -4493,7 +4495,8 @@ static int ci_register_patching_mc_seq(struct radeon_device *rdev,
if (patch &&
((rdev->pdev->device == 0x67B0) ||
(rdev->pdev->device == 0x67B1))) {
(rdev->pdev->device == 0x67B1)) &&
(rdev->pdev->revision == 0)) {
for (i = 0; i < table->last; i++) {
if (table->last >= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
return -EINVAL;

View File

@@ -741,6 +741,7 @@ static int sti_hda_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct sti_hda *hda;
struct resource *res;
int ret;
DRM_INFO("%s\n", __func__);
@@ -779,7 +780,9 @@ static int sti_hda_probe(struct platform_device *pdev)
return PTR_ERR(hda->clk_hddac);
}
drm_bridge_add(&hda->bridge);
ret = devm_drm_bridge_add(dev, &hda->bridge);
if (ret)
return ret;
platform_set_drvdata(pdev, hda);
@@ -788,10 +791,7 @@ static int sti_hda_probe(struct platform_device *pdev)
static void sti_hda_remove(struct platform_device *pdev)
{
struct sti_hda *hda = platform_get_drvdata(pdev);
component_del(&pdev->dev, &sti_hda_ops);
drm_bridge_remove(&hda->bridge);
}
static const struct of_device_id hda_of_match[] = {

View File

@@ -761,25 +761,21 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent
ret = pcim_enable_device(pdev);
if (ret)
goto err_free_dev;
return ret;
pci_set_drvdata(pdev, dev);
ret = bochs_load(bochs);
if (ret)
goto err_free_dev;
return ret;
ret = drm_dev_register(dev, 0);
if (ret)
goto err_free_dev;
return ret;
drm_client_setup(dev, NULL);
return ret;
err_free_dev:
drm_dev_put(dev);
return ret;
}
static void bochs_pci_remove(struct pci_dev *pdev)

View File

@@ -206,6 +206,14 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
return NULL;
}
static void __free_pages_gpu_account(struct page *p, unsigned int order,
bool reclaim)
{
mod_lruvec_page_state(p, reclaim ? NR_GPU_RECLAIM : NR_GPU_ACTIVE,
-(1 << order));
__free_pages(p, order);
}
/* Reset the caching and pages of size 1 << order */
static void ttm_pool_free_page(struct ttm_pool *pool, enum ttm_caching caching,
unsigned int order, struct page *p, bool reclaim)
@@ -223,9 +231,7 @@ static void ttm_pool_free_page(struct ttm_pool *pool, enum ttm_caching caching,
#endif
if (!pool || !ttm_pool_uses_dma_alloc(pool)) {
mod_lruvec_page_state(p, reclaim ? NR_GPU_RECLAIM : NR_GPU_ACTIVE,
-(1 << order));
__free_pages(p, order);
__free_pages_gpu_account(p, order, reclaim);
return;
}
@@ -606,7 +612,7 @@ static int ttm_pool_restore_commit(struct ttm_pool_tt_restore *restore,
*/
ttm_pool_split_for_swap(restore->pool, p);
copy_highpage(restore->alloced_page + i, p);
__free_pages(p, 0);
__free_pages_gpu_account(p, 0, false);
}
restore->restored_pages++;
@@ -1068,7 +1074,7 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
if (flags->purge) {
shrunken += num_pages;
page->private = 0;
__free_pages(page, order);
__free_pages_gpu_account(page, order, false);
memset(tt->pages + i, 0,
num_pages * sizeof(*tt->pages));
}
@@ -1109,7 +1115,7 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
}
handle = shandle;
tt->pages[i] = ttm_backup_handle_to_page_ptr(handle);
put_page(page);
__free_pages_gpu_account(page, 0, false);
shrunken++;
}

View File

@@ -37,9 +37,17 @@ static bool intel_hdcp_gsc_check_status(struct drm_device *drm)
struct xe_device *xe = to_xe_device(drm);
struct xe_tile *tile = xe_device_get_root_tile(xe);
struct xe_gt *gt = tile->media_gt;
struct xe_gsc *gsc = &gt->uc.gsc;
struct xe_gsc *gsc;
if (!gsc || !xe_uc_fw_is_available(&gsc->fw)) {
if (!gt) {
drm_dbg_kms(&xe->drm,
"not checking GSC status for HDCP2.x: media GT not present or disabled\n");
return false;
}
gsc = &gt->uc.gsc;
if (!xe_uc_fw_is_available(&gsc->fw)) {
drm_dbg_kms(&xe->drm,
"GSC Components not ready for HDCP2.x\n");
return false;

Some files were not shown because too many files have changed in this diff Show More