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

Cross-merge networking fixes after downstream PR (net-7.3-rc7).

Conflicts:

include/net/strparser.h
  0984ebc631 ("strparser: make sure __strp_recv isn't running before tearing down the parser")
  02fd0a2111 ("net: strparser: removed the aborted bit and aborts counter")
https://lore.kernel.org/asYfmLsfy-SCxXjr@sirena.co.uk

Adjacent changes:

Documentation/networking/strparser.rst
  5f193cdabf ("docs: networking: strparser: remove general mode")
  0984ebc631 ("strparser: make sure __strp_recv isn't running before tearing down the parser")

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-10-08 22:20:04 -07:00
commit d8674294ae
563 changed files with 8265 additions and 3376 deletions

View File

@ -102,6 +102,7 @@ Andy Chiu <andybnac@gmail.com> <andy.chiu@sifive.com>
Andy Chiu <andybnac@gmail.com> <taochiu@synology.com>
Andy Shevchenko <andy@kernel.org> <andy@smile.org.ua>
Andy Shevchenko <andy@kernel.org> <ext-andriy.shevchenko@nokia.com>
Andy Yan <andyshrk@163.com> <andy.yan@rock-chips.com>
Anilkumar Kolli <quic_akolli@quicinc.com> <akolli@codeaurora.org>
Anirudh Ghayal <quic_aghayal@quicinc.com> <aghayal@codeaurora.org>
Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com>
@ -463,7 +464,8 @@ Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
John Crispin <john@phrozen.org> <blogic@openwrt.org>
John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com>
John Garry <john.g.garry@oracle.com> <john.garry@huawei.com>
John Garry <john.garry@linux.dev> <john.garry@huawei.com>
John Garry <john.garry@linux.dev> <john.g.garry@oracle.com>
John Keeping <john@keeping.me.uk> <john@metanate.com>
John Moon <john@jmoon.dev> <quic_johmoo@quicinc.com>
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
@ -488,6 +490,7 @@ Juha Yrjola <juha.yrjola@nokia.com>
Juha Yrjola <juha.yrjola@solidboot.com>
Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com>
Justin Iurman <justin.iurman@gmail.com> <justin.iurman@uliege.be>
Imre Kaloz <kaloz@kernel.org> <kaloz@openwrt.org>
Ira Weiny <iweiny@kernel.org> <ira.weiny@intel.com>
Iskren Chernev <me@iskren.info> <iskren.chernev@gmail.com>
Kalle Valo <kvalo@kernel.org> <kvalo@codeaurora.org>

View File

@ -172,7 +172,8 @@ When mounting an ext4 filesystem, the following option are accepted:
data=journal
All data are committed into the journal prior to being written into the
main file system. Enabling this mode will disable delayed allocation
and O_DIRECT support.
and O_DIRECT support. This feature is deprecated and support
will be removed in January 2028.
data=ordered (*)
All data are forced directly out to the main file system prior to its
@ -418,7 +419,8 @@ There are 3 different data modes:
consistent state. This mode is the slowest except when data needs to be read
from and written to disk at the same time where it outperforms all others
modes. Enabling this mode will disable delayed allocation and O_DIRECT
support.
support. The data=journal feature is deprecated and support will be
removed in January 2028.
/proc entries
=============

View File

@ -174,6 +174,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3821522 | ARM64_ERRATUM_3821522 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #1502854 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |

View File

@ -12,19 +12,19 @@ maintainers:
properties:
compatible:
oneOf:
- const: rockchip,saradc
- const: rockchip,rk3066-tsadc
- const: rockchip,rk3399-saradc
- const: rockchip,rk3528-saradc
- enum:
- rockchip,saradc
- rockchip,rk3066-tsadc
- rockchip,rk3399-saradc
- rockchip,rk3528-saradc
- rockchip,rk3562-saradc
- rockchip,rk3588-saradc
- rockchip,rv1106-saradc
- items:
- const: rockchip,rk3506-saradc
- const: rockchip,rk3528-saradc
- const: rockchip,rk3562-saradc
- const: rockchip,rk3588-saradc
- items:
- enum:
- rockchip,rk3576-saradc
- rockchip,rv1106-saradc
- const: rockchip,rk3576-saradc
- const: rockchip,rk3588-saradc
- items:
- enum:

View File

@ -451,6 +451,32 @@ one.
The inode should be marked ``NETFS_ICTX_SINGLE_NO_UPLOAD`` if this API is to be
used. The writeback function requires the buffer to be of ITER_FOLIOQ type.
Clearing Stale Post-EOF Pagecache
---------------------------------
When a file is extended, data left in the pagecache past the old EOF by a write
through an mmap must not be exposed as file content. Netfslib clears this on
its own write paths, and exports a helper so a filesystem can do the same from
a resize path (truncate, setattr, fallocate and the like) that holds the
inode's ``i_rwsem`` exclusively across the whole resize::
void netfs_clear_stale_post_isize(struct inode *inode, uoff_t from,
uoff_t to);
This zeroes any such data within the ``[from, to)`` hole to be made, where
@from is the old EOF and @to is the new one, and the caller must have already
updated ``i_size`` to @to before calling it. Only the folio straddling @from
can hold data written past the EOF through an mmap, as pages wholly beyond the
EOF can't be faulted in, so the zeroing is limited to that folio. The folio is
zeroed rather than dropped so that a concurrent extending write can't lose
data.
This overlaps with ``pagecache_isize_extended()`` but can't reuse it: that
helper is keyed on a sub-page block size and is a no-op when the block size is
``>= PAGE_SIZE`` (as on network filesystems), and it doesn't wait for
writeback. As both address the same problem, a change to one should probably
be reflected in the other to keep them in sync.
High-Level VM API
==================

View File

@ -68,7 +68,7 @@ Functions
strp_done is called to release any resources held by the stream
parser instance. This must be called after the stream processor
has been stopped.
has been stopped. The socket lock must not be held.
::

View File

@ -3012,7 +3012,7 @@ F: arch/arm/boot/dts/ti/omap/omap3-igep*
ARM/INTEL IXP4XX ARM ARCHITECTURE
M: Linus Walleij <linusw@kernel.org>
M: Imre Kaloz <kaloz@openwrt.org>
M: Imre Kaloz <kaloz@kernel.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
@ -9863,7 +9863,7 @@ L: linux-ext4@vger.kernel.org
S: Maintained
W: http://ext4.wiki.kernel.org
Q: http://patchwork.ozlabs.org/project/linux-ext4/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git dev
F: Documentation/filesystems/ext4/
F: fs/ext4/
F: include/trace/events/ext4.h
@ -24503,6 +24503,11 @@ R: Marc Murphy <marc.murphy@sancloud.com>
S: Supported
F: arch/arm/boot/dts/ti/omap/am335x-sancloud*
SB1250-DUART BROADCOM SOC SERIAL DRIVER
M: "Maciej W. Rozycki" <macro@orcam.me.uk>
S: Maintained
F: drivers/tty/serial/sb1250-duart.c
SBOM
M: Luis Augenstein <luis.augenstein@tngtech.com>
M: Maximilian Huber <maximilian.huber@tngtech.com>
@ -25213,7 +25218,7 @@ R: David Rientjes <rientjes@google.com>
R: Roman Gushchin <roman.gushchin@linux.dev>
L: linux-mm@kvack.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mm/slab.git
F: Documentation/admin-guide/mm/slab.rst
F: Documentation/mm/slab.rst
F: include/linux/mempool.h

View File

@ -2,7 +2,7 @@
VERSION = 7
PATCHLEVEL = 3
SUBLEVEL = 0
EXTRAVERSION = -rc5
EXTRAVERSION = -rc6
NAME = Baby Opossum Posse
# *DOCUMENTATION*

View File

@ -1040,9 +1040,17 @@ config ARM64_ERRATUM_1902691
If unsure, say Y.
config ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
bool
# Targeting errata affecting AMEVCNTR01, the AMU constant counter.
# On affected CPUs the counter may not increment at the expected rate,
# making it unreliable. As a result, AMU users should treat it as
# unavailable rather than relying on misleading counter values.
config ARM64_ERRATUM_2457168
bool "Cortex-A510: 2457168: workaround for AMEVCNTR01 incrementing incorrectly"
depends on ARM64_AMU_EXTN
select ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
default y
help
This option adds the workaround for ARM Cortex-A510 erratum 2457168.
@ -1073,6 +1081,28 @@ config ARM64_ERRATUM_2645198
If unsure, say Y.
config ARM64_ERRATUM_3821522
bool "Cortex-A725: 3821522: workaround for possible CNT_CYCLES increment error due to WFE/WFI"
depends on ARM64_AMU_EXTN
select ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
default y
help
This option adds the workaround for ARM Cortex-A725 erratum 3821522.
On affected A725 cores, the CNT_CYCLES event may incur a significant
increment error when entering and subsequently exiting WFx.
As a result, the CNT_CYCLES may diverge from the system counter
frequency at which it is expected to increment.
This renders the AMU counter AMEVCNTR01, that implements CNT_CYCLES,
being unreliable and unsuitable for use.
Since there is no hardware workaround, reads of the affected CNT_CYCLES
counter return 0 in the relevant paths. This causes users of the counter
to treat it as unavailable and is functionally equivalent to firmware
disabling the affected counter.
If unsure, say Y.
config ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
bool

View File

@ -1602,7 +1602,7 @@ esdhc0_clksync_pins: iic5-sdhc-clk-pins {
};
dspi2_miso_mosi_pins: iic5-spi3-pins {
pinctrl-single,bits = <0x3 (0x2 << 9) (0x7 << 9)>;
pinctrl-single,bits = <0x0 (0x3 << 9) (0x7 << 9)>;
};
i2c5_pins: iic6-i2c-pins {
@ -1622,7 +1622,7 @@ fspi_data74_pins: xspi1-data74-pins {
};
gpio1_31_28_pins: xspi1-data74-gpio-pins {
pinctrl-single,bits = <0x0 0x1 (0x7 << 15)>;
pinctrl-single,bits = <0x0 (0x1 << 15) (0x7 << 15)>;
};
fspi_data30_pins: xspi1-data30-pins {
@ -1630,7 +1630,7 @@ fspi_data30_pins: xspi1-data30-pins {
};
gpio1_27_24_pins: xspi1-data30-gpio-pins {
pinctrl-single,bits = <0x0 0x1 (0x7 << 18)>;
pinctrl-single,bits = <0x0 (0x1 << 18) (0x7 << 18)>;
};
fspi_dqs_sck_cs10_pins: xspi1-base-pins {
@ -1638,7 +1638,7 @@ fspi_dqs_sck_cs10_pins: xspi1-base-pins {
};
gpio1_23_20_pins: xspi1-base-gpio-pins {
pinctrl-single,bits = <0x0 0x1 (0x7 << 21)>;
pinctrl-single,bits = <0x0 (0x1 << 21) (0x7 << 21)>;
};
esdhc0_cmd_data30_clk_vsel_pins: sdhc1-base-sdhc-vsel-pins {
@ -1687,12 +1687,19 @@ i2c6_i2c7_pins: iic8-iic7-i2c-pins {
};
/* RCWSR14 */
/*
* IIC1_PMUX is a single bit at RCWSR14[10], but bit-per-mux
* uses the mask for the field to clear before applying the
* value.
* So bits 11 and 12, which are reserved, are written as 0
* on every mux switch, it is harmless.
*/
i2c0_pins: iic1-i2c-pins {
pinctrl-single,bits = <0x8 0x0 (0x1 << 10)>;
pinctrl-single,bits = <0x8 0x0 (0x7 << 10)>;
};
gpio0_3_2_pins: iic1-gpio-pins {
pinctrl-single,bits = <0x8 (0x1 << 10) (0x1 << 10)>;
pinctrl-single,bits = <0x8 (0x1 << 10) (0x7 << 10)>;
};
};

View File

@ -511,6 +511,7 @@ &usdhc2 {
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
vmmc-supply = <&reg_usdhc2_vmmc>;
vqmmc-supply = <&ldo5>;
bus-width = <4>;
status = "okay";
};

View File

@ -863,11 +863,11 @@ spkr_01_sd_n_active: spkr-01-sd-n-active-state {
};
&lpass_vamacro {
pinctrl-0 = <&dmic01_default>, <&dmic23_default>;
pinctrl-0 = <&dmic01_default>;
pinctrl-names = "default";
vdd-micb-supply = <&vreg_l1b_1p8>;
qcom,dmic-sample-rate = <4800000>;
qcom,dmic-sample-rate = <2400000>;
};
&mdss {

View File

@ -384,6 +384,20 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
};
#endif
#ifdef CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
static const struct midr_range workaround_amu_constcnt_list[] = {
#ifdef CONFIG_ARM64_ERRATUM_2457168
/* Cortex-A510 r0p0-r1p1 */
MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1),
#endif
#ifdef CONFIG_ARM64_ERRATUM_3821522
/* Cortex-A725 r0p0 - r0p2 */
MIDR_RANGE(MIDR_CORTEX_A725, 0, 0, 0, 2),
#endif
{}
};
#endif /* CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT */
#ifdef CONFIG_CAVIUM_ERRATUM_23154
static const struct midr_range cavium_erratum_23154_cpus[] = {
MIDR_ALL_VERSIONS(MIDR_THUNDERX),
@ -919,14 +933,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2457168
#ifdef CONFIG_ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT
{
.desc = "ARM erratum 2457168",
.capability = ARM64_WORKAROUND_2457168,
.desc = "Broken AMU AMEVCNTR01 (const counter)",
.capability = ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT,
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
/* Cortex-A510 r0p0-r1p1 */
CAP_MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1)
CAP_MIDR_RANGE_LIST(workaround_amu_constcnt_list)
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2038923

View File

@ -2089,7 +2089,7 @@ static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap)
cpumask_set_cpu(smp_processor_id(), &amu_cpus);
/* 0 reference values signal broken/disabled counters */
if (!this_cpu_has_cap(ARM64_WORKAROUND_2457168))
if (!this_cpu_has_cap(ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT))
update_freq_counters_refs();
}
}

View File

@ -433,6 +433,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
unsigned int vl, vq;
struct user_fpsimd_state fpsimd;
u16 user_vl, flags;
bool fpsimd_only;
bool sm;
if (user->sve_size < sizeof(*user->sve))
@ -443,19 +444,33 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
if (err)
return err;
fpsimd_only = (user->sve_size == sizeof(*user->sve));
sm = flags & SVE_SIG_FLAG_SM;
if (sm) {
if (!system_supports_sme())
return -EINVAL;
/*
* Streaming SVE state is always preserved with an SVE payload.
* Only accept streaming state which has an SVE payload.
*/
if (fpsimd_only)
return -EINVAL;
vl = task_get_sme_vl(current);
} else {
/*
* A SME only system use SVE for streaming mode so can
* have a SVE formatted context with a zero VL and no
* payload data.
* Non-streaming SVE state may be preserved without an SVE
* payload, in which case all state is saved in the FPSIMD
* context.
*
* On SME-only systems, non-streaming (FPSIMD-only) state is
* always preserved without an SVE payload, and with VL==0. On
* such systems, only accept non-streaming state without an SVE
* payload.
*/
if (!system_supports_sve() && !system_supports_sme())
if (!system_supports_sve() && !fpsimd_only)
return -EINVAL;
vl = task_get_sve_vl(current);
@ -464,16 +479,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
if (user_vl != vl)
return -EINVAL;
/*
* Non-streaming SVE state may be preserved without an SVE payload, in
* which case the SVE context only has a header with VL==0, and all
* state can be restored from the FPSIMD context.
*
* Streaming SVE state is always preserved with an SVE payload. For
* consistency and robustness, reject restoring streaming SVE state
* without an SVE payload.
*/
if (!sm && user->sve_size == sizeof(*user->sve))
if (fpsimd_only)
return restore_fpsimd_context(user);
vq = sve_vq_from_vl(vl);

View File

@ -186,7 +186,6 @@ int arch_freq_get_on_cpu(int cpu)
struct amu_cntr_sample *amu_sample;
unsigned int start_cpu = cpu;
unsigned long last_update;
unsigned int freq = 0;
u64 scale;
if (!amu_fie_cpu_supported(cpu) || !arch_scale_freq_ref(cpu))
@ -245,9 +244,8 @@ int arch_freq_get_on_cpu(int cpu)
* (see amu_scale_freq_tick for details)
*/
scale = arch_scale_freq_capacity(cpu);
freq = scale * arch_scale_freq_ref(cpu);
freq >>= SCHED_CAPACITY_SHIFT;
return freq;
return (scale * arch_scale_freq_ref(cpu)) >> SCHED_CAPACITY_SHIFT;
}
static void amu_fie_setup(const struct cpumask *cpus)
@ -397,12 +395,13 @@ static void cpu_read_corecnt(void *val)
static void cpu_read_constcnt(void *val)
{
/*
* Return 0 if the current CPU is affected by erratum 2457168. A value
* of 0 is also returned if the current CPU does not support AMUs or if
* the counter is disabled. A return value of 0 at counter read is
* properly handled as an error case by the users of the counter.
* Return 0 if the current CPU is affected by a HW erratum.
* A value of 0 is also returned if the current CPU does not
* support AMUs or if the counter is disabled. A return
* value of 0 at counter read is properly handled as an error
* case by the users of the counter.
*/
*(u64 *)val = this_cpu_has_cap(ARM64_WORKAROUND_2457168) ?
*(u64 *)val = this_cpu_has_cap(ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT) ?
0UL : read_constcnt();
}
@ -463,8 +462,9 @@ static void amu_read_core_const_ctrs(void *val)
/*
* cpu_read_constcnt() incurs slight latency due to the
* ARM64_WORKAROUND_2457168 check. Read it first to minimize
* the sampling skew between the const and core counters.
* ARM64_WORKAROUND_BROKEN_AMU_CONSTCNT check.
* Read it first to minimize the sampling skew between the const
* and core counters.
*/
cpu_read_constcnt(&ctrs->constcnt);
cpu_read_corecnt(&ctrs->corecnt);

View File

@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
$(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
-Wmissing-prototypes -Wmissing-declarations
CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)

View File

@ -2386,9 +2386,6 @@ int __init populate_nv_trap_config(void)
print_nv_trap_error(fgt, "FGT bit is reserved", ret);
}
if (!cpus_have_final_cap(ARM64_HAS_FGT))
continue;
prev = xa_store(&sr_forward_xa, enc,
xa_mk_value(tc.val), GFP_KERNEL);

View File

@ -12,6 +12,15 @@
#include <nvhe/gfp.h>
#include <nvhe/spinlock.h>
/*
* HCR_EL2 bits EL2 takes from the host on each entry, per VM type. The rest
* are EL2's own and nothing the host sets there reaches the guest.
*/
#define PKVM_HCR_EL2_HOST_PVM (HCR_EL2_TWI | HCR_EL2_TWE | HCR_EL2_VSE)
#define PKVM_HCR_EL2_HOST_NPVM (PKVM_HCR_EL2_HOST_PVM | HCR_EL2_VI | HCR_EL2_VF | \
HCR_EL2_TVM | HCR_EL2_TID2 | HCR_EL2_TID4 | \
HCR_EL2_TID5 | HCR_EL2_TTLBOS)
/*
* Holds the relevant data for maintaining the vcpu state completely at hyp.
*/

View File

@ -216,6 +216,7 @@ static void sync_debug_state(struct pkvm_hyp_vcpu *hyp_vcpu)
static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
{
struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
u64 host_hcr_mask = PKVM_HCR_EL2_HOST_PVM;
fpsimd_sve_flush();
flush_debug_state(hyp_vcpu);
@ -228,6 +229,7 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
if (!pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
if (vcpu_get_flag(host_vcpu, PKVM_HOST_STATE_DIRTY))
flush_hyp_vcpu_state(hyp_vcpu);
host_hcr_mask = PKVM_HCR_EL2_HOST_NPVM;
} else {
hyp_vcpu->vcpu.arch.ctxt = host_vcpu->arch.ctxt;
}
@ -241,9 +243,8 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
* trap-control bit, so it must flow to the hyp vCPU alongside TWI/TWE
* for the vSError to be delivered. sync_hyp_vcpu() reflects it back.
*/
hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE | HCR_VSE);
hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) &
(HCR_TWI | HCR_TWE | HCR_VSE);
hyp_vcpu->vcpu.arch.hcr_el2 &= ~host_hcr_mask;
hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) & host_hcr_mask;
hyp_vcpu->vcpu.arch.iflags = host_vcpu->arch.iflags;

View File

@ -30,6 +30,7 @@ unsigned int kvm_host_sve_max_vl;
*/
static DEFINE_PER_CPU(struct pkvm_hyp_vcpu *, loaded_hyp_vcpu);
/* The PKVM_HCR_EL2_HOST_{PVM,NPVM} bits of this value come from the host on each entry. */
static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
{
vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
@ -47,18 +48,17 @@ static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
vcpu->arch.hcr_el2 |= HCR_FWB;
if (cpus_have_final_cap(ARM64_HAS_EVT) &&
!cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE) &&
kvm_read_vm_id_reg(vcpu->kvm, SYS_CTR_EL0) == read_cpuid(CTR_EL0))
vcpu->arch.hcr_el2 |= HCR_TID4;
else
vcpu->arch.hcr_el2 |= HCR_TID2;
/*
* Without AArch32 EL1, leave RW set and let the entry fail with an
* illegal exception return: the *32_EL2 registers EL2 would otherwise
* switch are UNDEFINED there.
*/
if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT) &&
cpus_have_final_cap(ARM64_HAS_32BIT_EL1))
vcpu->arch.hcr_el2 &= ~HCR_EL2_RW;
if (vcpu_has_ptrauth(vcpu))
vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
if (kvm_has_mte(vcpu->kvm))
vcpu->arch.hcr_el2 |= HCR_ATA;
}
static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
@ -76,6 +76,13 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
*/
val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
if (cpus_have_final_cap(ARM64_HAS_EVT) &&
!cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE) &&
kvm_read_vm_id_reg(kvm, SYS_CTR_EL0) == read_cpuid(CTR_EL0))
val |= HCR_EL2_TID4;
else
val |= HCR_EL2_TID2;
if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
val |= HCR_TERR | HCR_TEA;
val &= ~(HCR_FIEN);

View File

@ -1468,32 +1468,11 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
return PAGE_SIZE;
}
static int get_vma_page_shift(struct vm_area_struct *vma, unsigned long hva)
static int get_vma_page_shift(struct vm_area_struct *vma)
{
unsigned long pa;
if (is_vm_hugetlb_page(vma) && !(vma->vm_flags & VM_PFNMAP))
if (is_vm_hugetlb_page(vma))
return huge_page_shift(hstate_vma(vma));
if (!(vma->vm_flags & VM_PFNMAP))
return PAGE_SHIFT;
VM_BUG_ON(is_vm_hugetlb_page(vma));
pa = (vma->vm_pgoff << PAGE_SHIFT) + (hva - vma->vm_start);
#ifndef __PAGETABLE_PMD_FOLDED
if ((hva & (PUD_SIZE - 1)) == (pa & (PUD_SIZE - 1)) &&
ALIGN_DOWN(hva, PUD_SIZE) >= vma->vm_start &&
ALIGN(hva, PUD_SIZE) <= vma->vm_end)
return PUD_SHIFT;
#endif
if ((hva & (PMD_SIZE - 1)) == (pa & (PMD_SIZE - 1)) &&
ALIGN_DOWN(hva, PMD_SIZE) >= vma->vm_start &&
ALIGN(hva, PMD_SIZE) <= vma->vm_end)
return PMD_SHIFT;
return PAGE_SHIFT;
}
@ -1794,7 +1773,7 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
vma_shift = PAGE_SHIFT;
} else {
s2vi->max_map_size = PUD_SIZE;
vma_shift = get_vma_page_shift(vma, s2fd->hva);
vma_shift = get_vma_page_shift(vma);
}
switch (vma_shift) {
@ -1952,16 +1931,6 @@ static int kvm_s2_fault_pin_pfn(const struct kvm_s2_fault_desc *s2fd,
return -EFAULT;
}
} else {
/*
* If the page was identified as device early by looking at
* the VMA flags, vma_pagesize is already representing the
* largest quantity we can map. If instead it was mapped
* via __kvm_faultin_pfn(), vma_pagesize is set to PAGE_SIZE
* and must not be upgraded.
*
* In both cases, we don't let transparent_hugepage_adjust()
* change things at the last minute.
*/
s2vi->map_non_cacheable = true;
}
@ -2051,10 +2020,10 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
/*
* If we are not forced to use page mapping, check if we are
* backed by a THP and thus use block mapping if possible.
* backed by a huge stage-1 mapping and thus use block mapping if
* possible.
*/
if (mapping_size == PAGE_SIZE &&
!(s2vi->max_map_size == PAGE_SIZE || s2vi->map_non_cacheable)) {
if (mapping_size == PAGE_SIZE && s2vi->max_map_size != PAGE_SIZE) {
if (perm_fault_granule > PAGE_SIZE) {
mapping_size = perm_fault_granule;
} else {
@ -2135,10 +2104,6 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
return ret;
}
/*
* Let's check if we will get back a huge page backed by hugetlbfs, or
* get block mapping for device MMIO region.
*/
ret = kvm_s2_fault_pin_pfn(s2fd, &s2vi);
if (ret != 1)
return ret;

View File

@ -97,6 +97,9 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
/*
* - Acquiring the vCPU mutex for every *online* vCPU to prevent
* concurrent vCPU ioctls for vCPUs already visible to userspace.
* This also ensures KVM isn't in the middle of creating a vCPU,
* i.e. that there are no vCPUs that have been created but aren't
* yet fully online.
*/
ret = -EBUSY;
if (kvm_trylock_all_vcpus(kvm))
@ -105,18 +108,11 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
/*
* - Taking the config_lock which protects VGIC data structures such
* as the per-vCPU arrays of private IRQs (SGIs, PPIs).
*/
mutex_lock(&kvm->arch.config_lock);
/*
* - Bailing on the entire thing if a vCPU is in the middle of creation,
* dropped the kvm->lock, but hasn't reached kvm_arch_vcpu_create().
*
* The whole combination of this guarantees that no vCPU can get into
* KVM with a VGIC configuration inconsistent with the VM's VGIC.
*/
if (kvm->created_vcpus != atomic_read(&kvm->online_vcpus))
goto out_unlock;
mutex_lock(&kvm->arch.config_lock);
if (irqchip_in_kernel(kvm)) {
ret = -EEXIST;

View File

@ -319,12 +319,16 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
return ret;
}
static int update_affinity(struct vgic_irq *irq, struct kvm_vcpu *vcpu)
static int update_affinity(struct vgic_irq *irq,
struct kvm_vcpu *from_vcpu, struct kvm_vcpu *vcpu)
{
struct its_vlpi_map map;
int ret;
guard(raw_spinlock_irqsave)(&irq->irq_lock);
if (from_vcpu && irq->target_vcpu != from_vcpu)
return 0;
irq->target_vcpu = vcpu;
if (!irq->hw)
@ -362,7 +366,7 @@ static void update_affinity_ite(struct kvm *kvm, struct its_ite *ite)
return;
vcpu = collection_to_vcpu(kvm, ite->collection);
update_affinity(ite->irq, vcpu);
update_affinity(ite->irq, NULL, vcpu);
}
/*
@ -856,7 +860,7 @@ static int vgic_its_cmd_handle_movi(struct kvm *kvm, struct vgic_its *its,
vgic_its_invalidate_cache(its);
return update_affinity(ite->irq, vcpu);
return update_affinity(ite->irq, NULL, vcpu);
}
static bool __is_visible_gfn_locked(struct vgic_its *its, gpa_t gpa)
@ -1383,7 +1387,7 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
if (!irq)
continue;
update_affinity(irq, vcpu2);
update_affinity(irq, vcpu1, vcpu2);
vgic_put_irq(kvm, irq);
}

View File

@ -122,6 +122,10 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
for (int lr = 0; lr < vgic_cpu->vgic_v2.used_lrs; lr++)
vgic_v2_fold_lr(vcpu, cpuif->vgic_lr[lr]);
cpuif->used_lrs = 0;
if (!irq)
return;
/* See the GICv3 equivalent for the EOIcount handling rationale */
list_for_each_entry_continue(irq, &vgic_cpu->ap_list_head, ap_list) {
u32 lr;
@ -144,8 +148,6 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
vgic_v2_fold_lr(vcpu, lr);
eoicount--;
}
cpuif->used_lrs = 0;
}
void vgic_v2_deactivate(struct kvm_vcpu *vcpu, u32 val)

View File

@ -155,6 +155,10 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
for (int lr = 0; lr < cpuif->used_lrs; lr++)
vgic_v3_fold_lr(vcpu, cpuif->vgic_lr[lr]);
cpuif->used_lrs = 0;
if (!irq)
return;
/*
* EOIMode=0: use EOIcount to emulate deactivation. We are
* guaranteed to deactivate in reverse order of the activation, so
@ -188,8 +192,6 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
vgic_v3_fold_lr(vcpu, lr);
eoicount--;
}
cpuif->used_lrs = 0;
}
void vgic_v3_deactivate(struct kvm_vcpu *vcpu, u64 val)

View File

@ -853,6 +853,17 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
goto retry;
}
/*
* Fix the last_lr_irq refcount which was obtained while
* populating the LRs. This can also result in the LPI being
* deleted.
*/
irq = *host_data_ptr(last_lr_irq);
if (irq) {
deleted_lpis |= vgic_put_irq_norelease(vcpu->kvm, irq);
*host_data_ptr(last_lr_irq) = NULL;
}
raw_spin_unlock(&vgic_cpu->ap_list_lock);
if (unlikely(deleted_lpis))
@ -866,9 +877,6 @@ static void vgic_fold_state(struct kvm_vcpu *vcpu)
return;
}
if (!*host_data_ptr(last_lr_irq))
return;
if (kvm_vgic_global_state.type == VGIC_V2)
vgic_v2_fold_lr_state(vcpu);
else
@ -1021,11 +1029,14 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
scoped_guard(raw_spinlock, &irq->irq_lock) {
if (likely(vgic_target_oracle(irq) == vcpu)) {
vgic_populate_lr(vcpu, irq, count++);
*host_data_ptr(last_lr_irq) = irq;
if (count == kvm_vgic_global_state.nr_lr) {
vgic_get_irq_ref(irq);
*host_data_ptr(last_lr_irq) = irq;
}
}
}
if (count == kvm_vgic_global_state.nr_lr)
if (*host_data_ptr(last_lr_irq))
break;
}

View File

@ -2295,7 +2295,7 @@ pte_t modify_prot_start_ptes(struct vm_area_struct *vma, unsigned long addr,
* in cases where cpu is affected with errata #2645198.
*/
if (pte_accessible(vma->vm_mm, pte) && pte_user_exec(pte))
__flush_tlb_range(vma, addr, nr * PAGE_SIZE,
__flush_tlb_range(vma, addr, addr + nr * PAGE_SIZE,
PAGE_SIZE, 3, TLBF_NOWALKCACHE);
}

View File

@ -2418,10 +2418,11 @@ bool bpf_jit_supports_subprog_tailcalls(void)
return true;
}
static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_node *node,
int bargs_off, int retval_off, int run_ctx_off,
bool save_ret)
static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_image *im,
struct bpf_tramp_node *node, int bargs_off,
int retval_off, int run_ctx_off, bool save_ret)
{
void *skip;
__le32 *branch;
u64 enter_prog;
u64 exit_prog;
@ -2431,6 +2432,10 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_node *node,
enter_prog = (u64)bpf_trampoline_enter(p);
exit_prog = (u64)bpf_trampoline_exit(p);
/* nop, patched to skip this prog when it is detached */
skip = ctx->ro_image + ctx->idx;
emit(A64_NOP, ctx);
if (node->cookie == 0) {
/* if cookie is zero, one instruction is enough to store it */
emit(A64_STR64I(A64_ZR, A64_SP, run_ctx_off + cookie_off), ctx);
@ -2483,11 +2488,13 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_node *node,
emit(A64_ADD_I(1, A64_R(2), A64_SP, run_ctx_off), ctx);
emit_call(exit_prog, ctx);
bpf_tramp_image_add_skip(im, p, skip, ctx->ro_image + ctx->idx);
}
static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_nodes *tn,
int bargs_off, int retval_off, int run_ctx_off,
__le32 **branches)
static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_image *im,
struct bpf_tramp_nodes *tn, int bargs_off,
int retval_off, int run_ctx_off, __le32 **branches)
{
int i;
@ -2496,7 +2503,7 @@ static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_nodes *tn,
*/
emit(A64_STR64I(A64_ZR, A64_SP, retval_off), ctx);
for (i = 0; i < tn->nr_nodes; i++) {
invoke_bpf_prog(ctx, tn->nodes[i], bargs_off, retval_off,
invoke_bpf_prog(ctx, im, tn->nodes[i], bargs_off, retval_off,
run_ctx_off, true);
/* if (*(u64 *)(sp + retval_off) != 0)
* goto do_fexit;
@ -2882,7 +2889,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
store_func_meta(ctx, meta, func_meta_off);
cookie_bargs_off--;
}
invoke_bpf_prog(ctx, fentry->nodes[i], bargs_off,
invoke_bpf_prog(ctx, im, fentry->nodes[i], bargs_off,
retval_off, run_ctx_off,
flags & BPF_TRAMP_F_RET_FENTRY_RET);
}
@ -2893,7 +2900,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
if (!branches)
return -ENOMEM;
invoke_bpf_mod_ret(ctx, fmod_ret, bargs_off, retval_off,
invoke_bpf_mod_ret(ctx, im, fmod_ret, bargs_off, retval_off,
run_ctx_off, branches);
}
@ -2906,9 +2913,6 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
emit(A64_RET(A64_R(10)), ctx);
/* store return value */
emit(A64_STR64I(A64_R(0), A64_SP, retval_off), ctx);
/* reserve a nop for bpf_tramp_image_put */
im->ip_after_call = ctx->ro_image + ctx->idx;
emit(A64_NOP, ctx);
}
/* update the branches saved in invoke_bpf_mod_ret with cbnz */
@ -2930,12 +2934,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
store_func_meta(ctx, meta, func_meta_off);
cookie_bargs_off--;
}
invoke_bpf_prog(ctx, fexit->nodes[i], bargs_off, retval_off,
invoke_bpf_prog(ctx, im, fexit->nodes[i], bargs_off, retval_off,
run_ctx_off, false);
}
if (flags & BPF_TRAMP_F_CALL_ORIG) {
im->ip_epilogue = ctx->ro_image + ctx->idx;
/* for the first pass, assume the worst case */
if (!ctx->image)
ctx->idx += 4;
@ -2994,7 +2997,7 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
.image = NULL,
.idx = 0,
};
struct bpf_tramp_image im;
struct bpf_tramp_image im = {};
struct arg_aux aaux;
int ret;
@ -3281,6 +3284,10 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
* longer reachable, since bpf_tramp_image_put() function already
* uses percpu_ref and task-based rcu to do the sync, no need to call
* the sync version here, see bpf_tramp_image_put() for details.
*
* 3. when a detached prog is patched out of a trampoline, a CPU that
* still executes the old nop calls the prog before it went through
* a quiescent state, and the prog is freed after grace periods.
*/
ret = aarch64_insn_patch_text_nosync(ip, new_insn);
out:

View File

@ -105,7 +105,6 @@ WORKAROUND_1902691
WORKAROUND_2038923
WORKAROUND_2064142
WORKAROUND_2077057
WORKAROUND_2457168
WORKAROUND_2645198
WORKAROUND_2658417
WORKAROUND_4193714
@ -132,3 +131,4 @@ WORKAROUND_REPEAT_TLBI_SYNC
WORKAROUND_SPECULATIVE_AT
WORKAROUND_SPECULATIVE_SSBS
WORKAROUND_SPECULATIVE_UNPRIV_LOAD
WORKAROUND_BROKEN_AMU_CONSTCNT

View File

@ -1578,6 +1578,24 @@ void *bpf_arch_text_copy(void *dst, void *src, size_t len)
return ret ? ERR_PTR(-EINVAL) : dst;
}
int arch_bpf_trampoline_skip(void *nop, void *target)
{
u32 old_insn = INSN_NOP;
u32 new_insn = larch_insn_gen_b((unsigned long)nop, (unsigned long)target);
int ret;
if (memcmp(nop, &old_insn, LOONGARCH_INSN_SIZE))
return -EFAULT;
cpus_read_lock();
mutex_lock(&text_mutex);
ret = larch_insn_text_copy(nop, &new_insn, LOONGARCH_INSN_SIZE);
mutex_unlock(&text_mutex);
cpus_read_unlock();
return ret;
}
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
enum bpf_text_poke_type new_t, void *old_addr,
void *new_addr)
@ -1696,13 +1714,18 @@ static void restore_stk_args(struct jit_ctx *ctx, int nr_stk_args, int args_off,
}
}
static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_node *n,
int args_off, int retval_off, int run_ctx_off, bool save_ret)
static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_image *im,
struct bpf_tramp_node *n, int args_off, int retval_off,
int run_ctx_off, bool save_ret)
{
int ret;
u32 *branch;
struct bpf_prog *p = n->link->prog;
int cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie);
void *skip = ctx->ro_image + ctx->idx;
/* nop, patched to a b over this prog when it is detached */
emit_insn(ctx, nop);
if (n->cookie)
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1,
@ -1755,13 +1778,17 @@ static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_node *n,
/* arg3: &run_ctx */
emit_insn(ctx, addid, LOONGARCH_GPR_A2, LOONGARCH_GPR_FP, -run_ctx_off);
ret = emit_call(ctx, (const u64)bpf_trampoline_exit(p));
if (ret)
return ret;
return ret;
bpf_tramp_image_add_skip(im, p, skip, ctx->ro_image + ctx->idx);
return 0;
}
static int invoke_bpf(struct jit_ctx *ctx, struct bpf_tramp_nodes *tn,
int args_off, int retval_off, int run_ctx_off,
int func_meta_off, bool save_ret, u64 func_meta, int cookie_off)
static int invoke_bpf(struct jit_ctx *ctx, struct bpf_tramp_image *im,
struct bpf_tramp_nodes *tn, int args_off, int retval_off,
int run_ctx_off, int func_meta_off, bool save_ret,
u64 func_meta, int cookie_off)
{
int i, cur_cookie = (cookie_off - args_off) / 8;
@ -1774,7 +1801,8 @@ static int invoke_bpf(struct jit_ctx *ctx, struct bpf_tramp_nodes *tn,
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, meta);
cur_cookie--;
}
err = invoke_bpf_prog(ctx, tn->nodes[i], args_off, retval_off, run_ctx_off, save_ret);
err = invoke_bpf_prog(ctx, im, tn->nodes[i], args_off, retval_off,
run_ctx_off, save_ret);
if (err)
return err;
}
@ -2017,7 +2045,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
}
if (fentry->nr_nodes) {
ret = invoke_bpf(ctx, fentry, args_off, retval_off, run_ctx_off, func_meta_off,
ret = invoke_bpf(ctx, im, fentry, args_off, retval_off, run_ctx_off, func_meta_off,
flags & BPF_TRAMP_F_RET_FENTRY_RET, func_meta, cookie_off);
if (ret)
return ret;
@ -2029,7 +2057,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off);
for (i = 0; i < fmod_ret->nr_nodes; i++) {
ret = invoke_bpf_prog(ctx, fmod_ret->nodes[i],
ret = invoke_bpf_prog(ctx, im, fmod_ret->nodes[i],
args_off, retval_off, run_ctx_off, true);
if (ret)
goto out;
@ -2051,10 +2079,6 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
goto out;
emit_insn(ctx, std, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -retval_off);
emit_insn(ctx, std, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - 8));
im->ip_after_call = ctx->ro_image + ctx->idx;
/* Reserve space for the move_imm + jirl instruction */
for (i = 0; i < LOONGARCH_LONG_JUMP_NINSNS; i++)
emit_insn(ctx, nop);
}
for (i = 0; ctx->image && i < fmod_ret->nr_nodes; i++) {
@ -2068,14 +2092,13 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
if (fexit->nr_nodes) {
ret = invoke_bpf(ctx, fexit, args_off, retval_off, run_ctx_off,
ret = invoke_bpf(ctx, im, fexit, args_off, retval_off, run_ctx_off,
func_meta_off, false, func_meta, cookie_off);
if (ret)
goto out;
}
if (flags & BPF_TRAMP_F_CALL_ORIG) {
im->ip_epilogue = ctx->ro_image + ctx->idx;
move_addr(ctx, LOONGARCH_GPR_A0, (const u64)im);
ret = emit_call(ctx, (const u64)__bpf_tramp_exit);
if (ret)
@ -2177,11 +2200,8 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
struct bpf_tramp_nodes *tnodes, void *func_addr)
{
int ret;
struct jit_ctx ctx;
struct bpf_tramp_image im;
ctx.image = NULL;
ctx.idx = 0;
struct jit_ctx ctx = {};
struct bpf_tramp_image im = {};
ret = __arch_prepare_bpf_trampoline(&ctx, &im, m, tnodes, func_addr, flags);

View File

@ -16,6 +16,7 @@ ccflags-vdso := \
$(filter -m64,$(KBUILD_CFLAGS)) \
$(filter -march=%,$(KBUILD_CFLAGS)) \
$(filter -m%-float,$(KBUILD_CFLAGS)) \
$(CONFIG_CC_OPT_INLINE_MEMSET) \
$(CLANG_FLAGS) \
-D__VDSO__

View File

@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
ccflags-y += $(call cc-option, -fno-stack-protector)
ccflags-y += -DDISABLE_BRANCH_PROFILING
ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
ccflags-y += -ffreestanding -fasynchronous-unwind-tables
ccflags-remove-y := $(CC_FLAGS_FTRACE)
ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)

View File

@ -3058,7 +3058,6 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu)
init_waitqueue_head(&vcpu->arch.cpu_run);
mutex_lock(&kvm->lock);
vcore = NULL;
err = -EINVAL;
if (cpu_has_feature(CPU_FTR_ARCH_300)) {
@ -3091,7 +3090,6 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu)
mutex_unlock(&kvm->arch.mmu_setup_lock);
}
}
mutex_unlock(&kvm->lock);
if (!vcore)
return err;

View File

@ -602,14 +602,18 @@ int arch_protect_bpf_trampoline(void *image, unsigned int size)
}
static int invoke_bpf_prog(u32 *image, u32 *ro_image, struct codegen_context *ctx,
struct bpf_tramp_node *n, int regs_off, int retval_off,
int run_ctx_off, bool save_ret)
struct bpf_tramp_image *im, struct bpf_tramp_node *n,
int regs_off, int retval_off, int run_ctx_off, bool save_ret)
{
struct bpf_prog *p = n->link->prog;
ppc_inst_t branch_insn;
u32 jmp_idx;
u32 jmp_idx, skip_idx;
int ret = 0;
/* nop, patched to skip this prog when it is detached */
skip_idx = ctx->idx;
EMIT(PPC_RAW_NOP());
/* Save cookie */
if (IS_ENABLED(CONFIG_PPC64)) {
PPC_LI64(_R3, n->cookie);
@ -679,13 +683,17 @@ static int invoke_bpf_prog(u32 *image, u32 *ro_image, struct codegen_context *ct
EMIT(PPC_RAW_ADDI(_R5, _R1, run_ctx_off));
ret = bpf_jit_emit_func_call_rel(image, ro_image, ctx,
(unsigned long)bpf_trampoline_exit(p));
if (ret)
return ret;
return ret;
if (ro_image) /* image is NULL for dummy pass */
bpf_tramp_image_add_skip(im, p, &ro_image[skip_idx], &ro_image[ctx->idx]);
return 0;
}
static int invoke_bpf_mod_ret(u32 *image, u32 *ro_image, struct codegen_context *ctx,
struct bpf_tramp_nodes *tn, int regs_off, int retval_off,
int run_ctx_off, u32 *branches)
struct bpf_tramp_image *im, struct bpf_tramp_nodes *tn,
int regs_off, int retval_off, int run_ctx_off, u32 *branches)
{
int i;
@ -696,8 +704,8 @@ static int invoke_bpf_mod_ret(u32 *image, u32 *ro_image, struct codegen_context
EMIT(PPC_RAW_LI(_R3, 0));
EMIT(PPC_RAW_STL(_R3, _R1, retval_off));
for (i = 0; i < tn->nr_nodes; i++) {
if (invoke_bpf_prog(image, ro_image, ctx, tn->nodes[i], regs_off, retval_off,
run_ctx_off, true))
if (invoke_bpf_prog(image, ro_image, ctx, im, tn->nodes[i], regs_off,
retval_off, run_ctx_off, true))
return -EINVAL;
/*
@ -1043,8 +1051,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
cookie_ctx_off--;
}
if (invoke_bpf_prog(image, ro_image, ctx, fentry->nodes[i], regs_off, retval_off,
run_ctx_off, flags & BPF_TRAMP_F_RET_FENTRY_RET))
if (invoke_bpf_prog(image, ro_image, ctx, im, fentry->nodes[i], regs_off,
retval_off, run_ctx_off, flags & BPF_TRAMP_F_RET_FENTRY_RET))
return -EINVAL;
}
@ -1053,7 +1061,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
if (!branches)
return -ENOMEM;
if (invoke_bpf_mod_ret(image, ro_image, ctx, fmod_ret, regs_off, retval_off,
if (invoke_bpf_mod_ret(image, ro_image, ctx, im, fmod_ret, regs_off, retval_off,
run_ctx_off, branches)) {
ret = -EINVAL;
goto cleanup;
@ -1090,11 +1098,6 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
/* Restore updated tail_call_cnt */
if (flags & BPF_TRAMP_F_TAIL_CALL_CTX)
bpf_trampoline_restore_tail_call_cnt(image, ctx, bpf_frame_size, r4_off);
/* Reserve space to patch branch instruction to skip fexit progs */
if (ro_image) /* image is NULL for dummy pass */
im->ip_after_call = &((u32 *)ro_image)[ctx->idx];
EMIT(PPC_RAW_NOP());
}
/* Update branches saved in invoke_bpf_mod_ret with address of do_fexit */
@ -1123,16 +1126,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
cookie_ctx_off--;
}
if (invoke_bpf_prog(image, ro_image, ctx, fexit->nodes[i], regs_off, retval_off,
run_ctx_off, false)) {
if (invoke_bpf_prog(image, ro_image, ctx, im, fexit->nodes[i], regs_off,
retval_off, run_ctx_off, false)) {
ret = -EINVAL;
goto cleanup;
}
}
if (flags & BPF_TRAMP_F_CALL_ORIG) {
if (ro_image) /* image is NULL for dummy pass */
im->ip_epilogue = &((u32 *)ro_image)[ctx->idx];
PPC_LI_ADDR(_R3, im);
ret = bpf_jit_emit_func_call_rel(image, ro_image, ctx,
(unsigned long)__bpf_tramp_exit);
@ -1192,7 +1193,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
struct bpf_tramp_nodes *tnodes, void *func_addr)
{
struct bpf_tramp_image im;
struct bpf_tramp_image im = {};
int ret;
ret = __arch_prepare_bpf_trampoline(&im, NULL, NULL, NULL, m, flags, tnodes, func_addr);
@ -1320,7 +1321,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
/*
* If we are not poking at bpf prog entry, then we are simply patching in/out
* an unconditional branch instruction at im->ip_after_call
* an unconditional branch instruction in a trampoline image
*/
if (offset) {
if (old_t == BPF_MOD_CALL || new_t == BPF_MOD_CALL) {

View File

@ -1275,6 +1275,8 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem,
struct perf_event_header *header,
struct perf_event *event)
{
u16 misc = 0;
/* Sanity checks for a valid record */
if (be64_to_cpu(READ_ONCE(mem->tb1)) > *prev_tb)
*prev_tb = be64_to_cpu(READ_ONCE(mem->tb1));
@ -1289,23 +1291,19 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem,
data->ip = be64_to_cpu(READ_ONCE(mem->ip));
data->period = event->hw.last_period;
header->type = PERF_RECORD_SAMPLE;
header->size = sizeof(*header) + event->header_size;
header->misc = 0;
if (cpu_has_feature(CPU_FTR_ARCH_31)) {
switch (IMC_TRACE_RECORD_VAL_HVPR(be64_to_cpu(READ_ONCE(mem->val)))) {
case 0:/* when MSR HV and PR not set in the trace-record */
header->misc |= PERF_RECORD_MISC_GUEST_KERNEL;
misc |= PERF_RECORD_MISC_GUEST_KERNEL;
break;
case 1: /* MSR HV is 0 and PR is 1 */
header->misc |= PERF_RECORD_MISC_GUEST_USER;
misc |= PERF_RECORD_MISC_GUEST_USER;
break;
case 2: /* MSR HV is 1 and PR is 0 */
header->misc |= PERF_RECORD_MISC_KERNEL;
misc |= PERF_RECORD_MISC_KERNEL;
break;
case 3: /* MSR HV is 1 and PR is 1 */
header->misc |= PERF_RECORD_MISC_USER;
misc |= PERF_RECORD_MISC_USER;
break;
default:
pr_info("IMC: Unable to set the flag based on MSR bits\n");
@ -1313,11 +1311,14 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem,
}
} else {
if (is_kernel_addr(data->ip))
header->misc |= PERF_RECORD_MISC_KERNEL;
misc |= PERF_RECORD_MISC_KERNEL;
else
header->misc |= PERF_RECORD_MISC_USER;
misc |= PERF_RECORD_MISC_USER;
}
perf_event_header__init_id(header, data, event);
perf_event_header__init(header, data,
PERF_RECORD_SAMPLE, misc,
sizeof(*header) + event->header_size,
event);
return 0;
}

View File

@ -36,6 +36,7 @@ endif
ccflags-y := -fno-stack-protector
ccflags-y += -DDISABLE_BRANCH_PROFILING
ccflags-y += -fno-builtin
ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
ccflags-y += $(CFI_FULL)
asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)

View File

@ -237,7 +237,7 @@ static int aia_init(struct kvm *kvm)
return -EBUSY;
/* We might be in the middle of creating a VCPU? */
if (kvm->created_vcpus != atomic_read(&kvm->online_vcpus))
if (kvm_is_vcpu_creation_in_progress(kvm))
return -EBUSY;
/* Number of sources should be less than or equals number of IDs */

View File

@ -822,6 +822,24 @@ static int gen_jump_or_nops(void *target, void *ip, u32 *insns, bool is_call)
return emit_jump_and_link(is_call ? RV_REG_T0 : RV_REG_ZERO, rvoff, false, &ctx);
}
int arch_bpf_trampoline_skip(void *nop, void *target)
{
u32 old_insn = rv_nop();
u32 new_insn = rv_jal(RV_REG_ZERO, (target - nop) >> 1);
int ret;
if (memcmp(nop, &old_insn, sizeof(old_insn)))
return -EFAULT;
cpus_read_lock();
mutex_lock(&text_mutex);
ret = patch_text(nop, &new_insn, sizeof(new_insn));
mutex_unlock(&text_mutex);
cpus_read_unlock();
return ret;
}
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
enum bpf_text_poke_type new_t, void *old_addr,
void *new_addr)
@ -904,12 +922,17 @@ static void emit_store_stack_imm64(u8 reg, int stack_off, u64 imm64,
emit_sd(RV_REG_FP, stack_off, reg, ctx);
}
static int invoke_bpf_prog(struct bpf_tramp_node *node, int args_off, int retval_off,
int run_ctx_off, bool save_ret, struct rv_jit_context *ctx)
static int invoke_bpf_prog(struct bpf_tramp_image *im, struct bpf_tramp_node *node,
int args_off, int retval_off, int run_ctx_off, bool save_ret,
struct rv_jit_context *ctx)
{
int ret, branch_off;
struct bpf_prog *p = node->link->prog;
int cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie);
void *skip = ctx->ro_insns + ctx->ninsns;
/* nop, patched to a jal over this prog when it is detached */
emit(rv_nop(), ctx);
if (node->cookie)
emit_store_stack_imm64(RV_REG_T1, -run_ctx_off + cookie_off, node->cookie, ctx);
@ -962,13 +985,17 @@ static int invoke_bpf_prog(struct bpf_tramp_node *node, int args_off, int retval
/* arg3: &run_ctx */
emit_addi(RV_REG_A2, RV_REG_FP, -run_ctx_off, ctx);
ret = emit_call((const u64)bpf_trampoline_exit(p), true, ctx);
if (ret)
return ret;
return ret;
bpf_tramp_image_add_skip(im, p, skip, ctx->ro_insns + ctx->ninsns);
return 0;
}
static int invoke_bpf(struct bpf_tramp_nodes *tn, int args_off, int retval_off,
int run_ctx_off, int func_meta_off, bool save_ret, u64 func_meta,
int cookie_off, struct rv_jit_context *ctx)
static int invoke_bpf(struct bpf_tramp_image *im, struct bpf_tramp_nodes *tn,
int args_off, int retval_off, int run_ctx_off, int func_meta_off,
bool save_ret, u64 func_meta, int cookie_off,
struct rv_jit_context *ctx)
{
int i, cur_cookie = (cookie_off - args_off) / 8;
@ -981,8 +1008,8 @@ static int invoke_bpf(struct bpf_tramp_nodes *tn, int args_off, int retval_off,
emit_store_stack_imm64(RV_REG_T1, -func_meta_off, meta, ctx);
cur_cookie--;
}
err = invoke_bpf_prog(tn->nodes[i], args_off, retval_off, run_ctx_off,
save_ret, ctx);
err = invoke_bpf_prog(im, tn->nodes[i], args_off, retval_off,
run_ctx_off, save_ret, ctx);
if (err)
return err;
}
@ -1170,7 +1197,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
}
if (fentry->nr_nodes) {
ret = invoke_bpf(fentry, args_off, retval_off, run_ctx_off, func_meta_off,
ret = invoke_bpf(im, fentry, args_off, retval_off, run_ctx_off, func_meta_off,
flags & BPF_TRAMP_F_RET_FENTRY_RET, func_meta, cookie_off, ctx);
if (ret)
return ret;
@ -1184,7 +1211,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
/* cleanup to avoid garbage return value confusion */
emit_sd(RV_REG_FP, -retval_off, RV_REG_ZERO, ctx);
for (i = 0; i < fmod_ret->nr_nodes; i++) {
ret = invoke_bpf_prog(fmod_ret->nodes[i], args_off, retval_off,
ret = invoke_bpf_prog(im, fmod_ret->nodes[i], args_off, retval_off,
run_ctx_off, true, ctx);
if (ret)
goto out;
@ -1211,10 +1238,6 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
emit_sd(RV_REG_FP, -tcc_off, RV_REG_TCC, ctx);
emit_sd(RV_REG_FP, -retval_off, RV_REG_A0, ctx);
emit_sd(RV_REG_FP, -(retval_off - 8), regmap[BPF_REG_0], ctx);
im->ip_after_call = ctx->ro_insns + ctx->ninsns;
/* 2 nops reserved for auipc+jalr pair */
emit(rv_nop(), ctx);
emit(rv_nop(), ctx);
}
/* update branches saved in invoke_bpf_mod_ret with bnez */
@ -1230,14 +1253,13 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
emit_store_stack_imm64(RV_REG_T1, -func_meta_off, func_meta, ctx);
if (fexit->nr_nodes) {
ret = invoke_bpf(fexit, args_off, retval_off, run_ctx_off, func_meta_off,
ret = invoke_bpf(im, fexit, args_off, retval_off, run_ctx_off, func_meta_off,
false, func_meta, cookie_off, ctx);
if (ret)
goto out;
}
if (flags & BPF_TRAMP_F_CALL_ORIG) {
im->ip_epilogue = ctx->ro_insns + ctx->ninsns;
emit_imm(RV_REG_A0, ctx->insns ? (const s64)im : RV_MAX_COUNT_IMM, ctx);
ret = emit_call((const u64)__bpf_tramp_exit, true, ctx);
if (ret)
@ -1299,7 +1321,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
struct bpf_tramp_nodes *tnodes, void *func_addr)
{
struct bpf_tramp_image im;
struct bpf_tramp_image im = {};
struct rv_jit_context ctx;
int ret;

View File

@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
ldflags-y := -shared -soname=linux-vdso.so.1 \
--hash-style=both --build-id=sha1 \
$(call ld-option, --eh-frame-hdr) -T

View File

@ -3579,12 +3579,11 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
{
mutex_lock(&vcpu->kvm->lock);
preempt_disable();
vcpu->arch.sie_block->epoch = vcpu->kvm->arch.epoch;
vcpu->arch.sie_block->epdx = vcpu->kvm->arch.epdx;
preempt_enable();
mutex_unlock(&vcpu->kvm->lock);
if (!kvm_is_ucontrol(vcpu->kvm)) {
vcpu->arch.gmap = vcpu->kvm->arch.gmap;
sca_add_vcpu(vcpu);
@ -3757,13 +3756,11 @@ static int kvm_s390_vcpu_setup(struct kvm_vcpu *vcpu)
kvm_s390_vcpu_pci_setup(vcpu);
mutex_lock(&vcpu->kvm->lock);
if (kvm_s390_pv_is_protected(vcpu->kvm)) {
rc = kvm_s390_pv_create_cpu(vcpu, &uvrc, &uvrrc);
if (rc)
kvm_s390_vcpu_unsetup_cmma(vcpu);
}
mutex_unlock(&vcpu->kvm->lock);
return rc;
}

View File

@ -2566,6 +2566,8 @@ struct bpf_tramp_jit {
int r14_off; /* Offset of saved %r14, has to be at the
* bottom */
int do_fexit; /* do_fexit: label */
int skip[BPF_MAX_TRAMP_LINKS]; /* skip: labels after each prog */
int nr_progs;
};
static void load_imm64(struct bpf_jit *jit, int dst_reg, u64 val)
@ -2584,6 +2586,7 @@ static void emit_store_stack_imm64(struct bpf_jit *jit, int tmp_reg, int stack_o
}
static int invoke_bpf_prog(struct bpf_tramp_jit *tjit,
struct bpf_tramp_image *im,
const struct btf_func_model *m,
struct bpf_tramp_node *node, bool save_ret)
{
@ -2591,8 +2594,20 @@ static int invoke_bpf_prog(struct bpf_tramp_jit *tjit,
int cookie_off = tjit->run_ctx_off +
offsetof(struct bpf_tramp_run_ctx, bpf_cookie);
struct bpf_prog *p = node->link->prog;
void *skip = jit->prg_buf + jit->prg;
int idx = tjit->nr_progs++;
int patch;
if (idx >= ARRAY_SIZE(tjit->skip))
return -E2BIG;
/*
* nop, patched to skip this prog when it is detached
*/
/* brcl 0,skip */
EMIT6_PCREL_RILC(0xc0040000, 0, tjit->skip[idx]);
/*
* run_ctx.cookie = node->cookie;
*/
@ -2652,10 +2667,15 @@ static int invoke_bpf_prog(struct bpf_tramp_jit *tjit,
/* brasl %r14,__bpf_prog_exit */
EMIT6_PCREL_RILB_PTR(0xc0050000, REG_14, bpf_trampoline_exit(p));
/* skip: */
tjit->skip[idx] = jit->prg;
bpf_tramp_image_add_skip(im, p, skip, jit->prg_buf + jit->prg);
return 0;
}
static int invoke_bpf(struct bpf_tramp_jit *tjit,
struct bpf_tramp_image *im,
const struct btf_func_model *m,
struct bpf_tramp_nodes *tn, bool save_ret,
u64 func_meta, int cookie_off)
@ -2670,7 +2690,7 @@ static int invoke_bpf(struct bpf_tramp_jit *tjit,
emit_store_stack_imm64(jit, REG_0, tjit->func_meta_off, meta);
cur_cookie--;
}
if (invoke_bpf_prog(tjit, m, tn->nodes[i], save_ret))
if (invoke_bpf_prog(tjit, im, m, tn->nodes[i], save_ret))
return -EINVAL;
}
@ -2712,6 +2732,11 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
u64 func_meta;
int i, j;
/* The skip labels are taken from the previous pass. */
tjit->nr_progs = 0;
if (im)
im->nr_skips = 0;
/* Support as many stack arguments as "mvc" instruction can handle. */
nr_reg_args = min_t(int, m->nr_args, MAX_NR_REG_ARGS);
nr_stack_args = m->nr_args - nr_reg_args;
@ -2875,7 +2900,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
emit_store_stack_imm64(jit, REG_0, tjit->retval_off, 0);
}
if (invoke_bpf(tjit, m, fentry, flags & BPF_TRAMP_F_RET_FENTRY_RET,
if (invoke_bpf(tjit, im, m, fentry, flags & BPF_TRAMP_F_RET_FENTRY_RET,
func_meta, cookie_off))
return -EINVAL;
@ -2889,7 +2914,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
0xf000 | tjit->retval_off);
for (i = 0; i < fmod_ret->nr_nodes; i++) {
if (invoke_bpf_prog(tjit, m, fmod_ret->nodes[i], true))
if (invoke_bpf_prog(tjit, im, m, fmod_ret->nodes[i], true))
return -EINVAL;
/*
@ -2943,15 +2968,6 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
/* mvc tccnt_off(%r15),tail_call_cnt(4,%r15) */
_EMIT6(0xd203f000 | tjit->tccnt_off,
0xf000 | offsetof(struct prog_frame, tail_call_cnt));
im->ip_after_call = jit->prg_buf + jit->prg;
/*
* The following nop will be patched by bpf_tramp_image_put().
*/
/* brcl 0,im->ip_epilogue */
EMIT6_PCREL_RILC(0xc0040000, 0, (u64)im->ip_epilogue);
}
/* Set the "is_return" flag for fsession. */
@ -2962,12 +2978,10 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
/* do_fexit: */
tjit->do_fexit = jit->prg;
if (invoke_bpf(tjit, m, fexit, false, func_meta, cookie_off))
if (invoke_bpf(tjit, im, m, fexit, false, func_meta, cookie_off))
return -EINVAL;
if (flags & BPF_TRAMP_F_CALL_ORIG) {
im->ip_epilogue = jit->prg_buf + jit->prg;
/*
* __bpf_tramp_exit(im);
*/
@ -3016,7 +3030,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
struct bpf_tramp_nodes *tnodes, void *orig_call)
{
struct bpf_tramp_image im;
struct bpf_tramp_image im = {};
struct bpf_tramp_jit tjit;
int ret;

View File

@ -209,6 +209,7 @@ static int raw_verify_header(
if ((vheader->flags & VIRTIO_NET_HDR_F_DATA_VALID) > 0)
return 1;
skb_set_network_header(skb, ETH_HLEN);
virtio_net_hdr_to_skb(skb, vheader, virtio_legacy_is_little_endian());
return 0;
}

View File

@ -1293,6 +1293,7 @@ static void gcm_process_assoc(const struct aes_gcm_key *key, u8 ghash_acc[16],
unsigned int len;
const u8 *src = walk.addr;
assoclen -= orig_len_this_step;
if (unlikely(pos)) {
len = min(len_this_step, 16 - pos);
memcpy(&buf[pos], src, len);
@ -1320,7 +1321,6 @@ static void gcm_process_assoc(const struct aes_gcm_key *key, u8 ghash_acc[16],
kernel_fpu_end();
kernel_fpu_begin();
}
assoclen -= orig_len_this_step;
}
if (unlikely(pos))
aes_gcm_aad_update(key, ghash_acc, buf, pos, flags);

View File

@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
# Compilation flags
flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
# The location of this include matters!
include $(src)/../common/Makefile.include

View File

@ -2,6 +2,7 @@
#ifndef _ASM_X86_PTRACE_ABI_H
#define _ASM_X86_PTRACE_ABI_H
#if defined(__ASSEMBLER__) || defined(__FRAME_OFFSETS)
#ifdef __i386__
#define EBX 0
@ -25,7 +26,6 @@
#else /* __i386__ */
#if defined(__ASSEMBLER__) || defined(__FRAME_OFFSETS)
/*
* C ABI says these regs are callee-preserved. They aren't saved on kernel entry
* unless syscall needs a complete, fully filled "struct pt_regs".
@ -57,12 +57,12 @@
#define EFLAGS 144
#define RSP 152
#define SS 160
#endif /* __ASSEMBLER__ */
/* top of stack page */
#define FRAME_SIZE 168
#endif /* !__i386__ */
#endif /* defined(__ASSEMBLER__) || defined(__FRAME_OFFSETS) */
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
#define PTRACE_GETREGS 12

View File

@ -50,9 +50,16 @@ static unsigned long get_align_mask(struct file *filp)
* value before calling vm_unmapped_area() or ORed directly to the
* address.
*/
static unsigned long get_align_bits(void)
static unsigned long get_align_bits(struct file *filp)
{
return va_align.bits & get_align_mask(NULL);
/*
* va_align.bits is smaller than the huge page size and will
* lead to misaligned huge pages. Ignore it for huge mappings.
*/
if (is_file_hugepages(filp))
return 0;
return va_align.bits & get_align_mask(filp);
}
static int __init control_va_addr_alignment(char *str)
@ -157,7 +164,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len,
}
if (filp) {
info.align_mask = get_align_mask(filp);
info.align_offset += get_align_bits();
info.align_offset += get_align_bits(filp);
}
return vm_unmapped_area(&info);
@ -222,7 +229,7 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
if (filp) {
info.align_mask = get_align_mask(filp);
info.align_offset += get_align_bits();
info.align_offset += get_align_bits(filp);
}
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))

View File

@ -2512,6 +2512,12 @@ static void shadow_walk_init_using_root(struct kvm_shadow_walk_iterator *iterato
iterator->addr = addr;
iterator->shadow_addr = root;
if (WARN_ON_ONCE(!VALID_PAGE(root)) || kvm_mmu_is_dummy_root(root)) {
iterator->level = 0;
return;
}
iterator->level = vcpu->arch.mmu->root_role.level;
if (iterator->level >= PT64_ROOT_4LEVEL &&

View File

@ -488,6 +488,20 @@ static void snp_guest_req_cleanup(struct kvm *kvm)
sev->guest_resp_buf = NULL;
}
static int sev_alloc_have_run_cpus(struct kvm_sev_info *sev)
{
if (!zalloc_cpumask_var(&sev->have_run_cpus, GFP_KERNEL_ACCOUNT))
return -ENOMEM;
return 0;
}
static void sev_free_have_run_cpus(struct kvm_sev_info *sev)
{
free_cpumask_var(sev->have_run_cpus);
memset(&sev->have_run_cpus, 0, sizeof(sev->have_run_cpus));
}
static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
struct kvm_sev_init *data,
unsigned long vm_type)
@ -545,10 +559,9 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
if (ret)
goto e_free_asid;
if (!zalloc_cpumask_var(&sev->have_run_cpus, GFP_KERNEL_ACCOUNT)) {
ret = -ENOMEM;
ret = sev_alloc_have_run_cpus(sev);
if (ret)
goto e_free_asid;
}
/* This needs to happen after SEV/SNP firmware initialization. */
if (snp_active) {
@ -566,7 +579,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
return 0;
e_free:
free_cpumask_var(sev->have_run_cpus);
sev_free_have_run_cpus(sev);
e_free_asid:
argp->error = init_args.error;
sev_asid_free(sev);
@ -1125,9 +1138,6 @@ static int sev_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_es_guest(kvm))
return -ENOTTY;
if (kvm_is_vcpu_creation_in_progress(kvm))
return -EBUSY;
ret = kvm_lock_all_vcpus(kvm);
if (ret)
return ret;
@ -2035,6 +2045,13 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
struct kvm_sev_info *mirror;
unsigned long i;
/*
* Do cache maintenance on the source VM *before* clearing "SEV active",
* as memory reclaim flows won't trigger cache maintenance on the VM
* once it's no longer an SEV VM.
*/
sev_writeback_caches(src_kvm);
dst->active = true;
dst->asid = src->asid;
dst->handle = src->handle;
@ -2048,12 +2065,6 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
src->pages_locked = 0;
src->es_active = false;
/*
* Do cache maintenance on the source VM as it is no longer an SEV VM,
* i.e. memory reclaim flows won't trigger cache maintenance on the VM.
*/
sev_writeback_caches(src_kvm);
list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list);
mutex_lock(&sev_mirror_lock);
@ -2121,10 +2132,6 @@ static int sev_check_source_vcpus(struct kvm *dst, struct kvm *src)
struct kvm_vcpu *src_vcpu;
unsigned long i;
if (kvm_is_vcpu_creation_in_progress(src) ||
kvm_is_vcpu_creation_in_progress(dst))
return -EBUSY;
if (!sev_es_guest(src))
return 0;
@ -2198,10 +2205,9 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
* does not, i.e. KVM could skip flushes if memory is reclaimed from
* the old VM but not the new VM.
*/
if (!zalloc_cpumask_var(&dst_sev->have_run_cpus, GFP_KERNEL_ACCOUNT)) {
ret = -ENOMEM;
ret = sev_alloc_have_run_cpus(dst_sev);
if (ret)
goto out_source_vcpu;
}
sev_migrate_from(kvm, source_kvm);
kvm_vm_dead(source_kvm);
@ -2520,9 +2526,6 @@ static int snp_launch_update_vmsa(struct kvm *kvm, struct kvm_sev_cmd *argp)
unsigned long i;
int ret;
if (kvm_is_vcpu_creation_in_progress(kvm))
return -EBUSY;
ret = kvm_lock_all_vcpus(kvm);
if (ret)
return ret;
@ -2898,10 +2901,9 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
}
mirror_sev = to_kvm_sev_info(kvm);
if (!zalloc_cpumask_var(&mirror_sev->have_run_cpus, GFP_KERNEL_ACCOUNT)) {
ret = -ENOMEM;
ret = sev_alloc_have_run_cpus(mirror_sev);
if (ret)
goto e_unlock;
}
/*
* The mirror kvm holds an enc_context_owner ref so its asid can't
@ -2994,7 +2996,7 @@ void sev_vm_destroy(struct kvm *kvm)
* Free the mask even if the VM is not *currently* an SEV VM, as it may
* have been an SEV VM prior to intra-host migration.
*/
free_cpumask_var(sev->have_run_cpus);
sev_free_have_run_cpus(sev);
if (!sev_guest(kvm))
return;
@ -3630,7 +3632,6 @@ int pre_sev_run(struct vcpu_svm *svm, int cpu)
sd->sev_vmcbs[asid] = svm->vmcb;
svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID;
vmcb_mark_dirty(svm->vmcb, VMCB_ASID);
return 0;
}

View File

@ -673,16 +673,7 @@ static void clr_dr_intercepts(struct vcpu_svm *svm)
static bool msr_write_intercepted(struct vcpu_svm *svm, u32 msr)
{
/*
* For non-nested case:
* If the L01 MSR bitmap does not intercept the MSR, then we need to
* save it.
*
* For nested case:
* If the L02 MSR bitmap does not intercept the MSR, then we need to
* save it.
*/
void *msrpm = is_guest_mode(&svm->vcpu) ? svm->nested.msrpm : svm->msrpm;
void *msrpm = __va(__sme_clr(svm->vmcb->control.msrpm_base_pa));
return svm_test_msr_bitmap_write(msrpm, msr);
}
@ -1902,8 +1893,7 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
if (sd->next_asid > sd->max_asid) {
++sd->asid_generation;
sd->next_asid = sd->min_asid;
svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;
vmcb_mark_dirty(svm->vmcb, VMCB_ASID);
sd->flush_all_asids = true;
}
svm->current_vmcb->asid_generation = sd->asid_generation;
@ -4528,6 +4518,9 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
svm->vmcb->control.asid = svm->asid;
vmcb_mark_dirty(svm->vmcb, VMCB_ASID);
}
if (this_cpu_ptr(&svm_data)->flush_all_asids)
svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;
svm->vmcb->save.cr2 = vcpu->arch.cr2;
if (guest_cpu_cap_has(vcpu, X86_FEATURE_ERAPS) &&
@ -4618,16 +4611,23 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
vcpu->arch.nested_run_pending = 0;
}
svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING;
if (!svm_is_vmrun_failure(svm->vmcb->control.exit_code)) {
this_cpu_ptr(&svm_data)->flush_all_asids = false;
svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING;
/*
* Unconditionally mask off the CLEAR_RAP bit, the AND is just as cheap
* as the TEST+Jcc to avoid it.
*/
if (cpu_feature_enabled(X86_FEATURE_ERAPS))
svm->vmcb->control.erap_ctl &= ~ERAP_CONTROL_CLEAR_RAP;
/*
* Unconditionally mask off the CLEAR_RAP bit, the AND is just
* as cheap as the TEST+Jcc to avoid it.
*/
if (cpu_feature_enabled(X86_FEATURE_ERAPS))
svm->vmcb->control.erap_ctl &= ~ERAP_CONTROL_CLEAR_RAP;
vmcb_mark_all_clean(svm->vmcb);
vmcb_mark_all_clean(svm->vmcb);
if (!msr_write_intercepted(svm, MSR_AMD64_PERF_CNTR_GLOBAL_CTL))
rdmsrq(MSR_AMD64_PERF_CNTR_GLOBAL_CTL,
vcpu_to_pmu(vcpu)->global_ctrl);
}
/* if exit due to PF check for async PF */
if (svm->vmcb->control.exit_code == SVM_EXIT_EXCP_BASE + PF_VECTOR)
@ -4636,9 +4636,6 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
kvm_clear_available_registers(vcpu, SVM_REGS_LAZY_LOAD_SET);
if (!msr_write_intercepted(svm, MSR_AMD64_PERF_CNTR_GLOBAL_CTL))
rdmsrq(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, vcpu_to_pmu(vcpu)->global_ctrl);
trace_kvm_exit(vcpu, KVM_ISA_SVM);
svm_complete_interrupts(vcpu);

View File

@ -376,6 +376,7 @@ struct svm_cpu_data {
u32 next_asid;
u32 min_asid;
bool flush_all_asids;
bool bp_spec_reduce_set;
struct vmcb *save_area;

View File

@ -1754,6 +1754,9 @@ static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx)
static void copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, u32 hv_clean_fields)
{
#ifdef CONFIG_KVM_HYPERV
const u64 runtime_controls = HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP1 |
HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP2 |
HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC;
struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
struct hv_enlightened_vmcs *evmcs = nested_vmx_evmcs(vmx);
struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(&vmx->vcpu);
@ -1762,6 +1765,9 @@ static void copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, u32 hv_clean_fields
vmcs12->tpr_threshold = evmcs->tpr_threshold;
vmcs12->guest_rip = evmcs->guest_rip;
if ((hv_clean_fields & runtime_controls) != runtime_controls)
vmx->nested.force_msr_bitmap_recalc = true;
if (unlikely(!(hv_clean_fields &
HV_VMX_ENLIGHTENED_CLEAN_FIELD_ENLIGHTENMENTSCONTROL))) {
hv_vcpu->nested.pa_page_gpa = evmcs->partition_assist_page;

View File

@ -2728,11 +2728,6 @@ static tdx_vm_state_guard_t tdx_acquire_vm_state_locks(struct kvm *kvm)
mutex_lock(&kvm->lock);
if (kvm->created_vcpus != atomic_read(&kvm->online_vcpus)) {
r = -EBUSY;
goto out_err;
}
r = kvm_lock_all_vcpus(kvm);
if (r)
goto out_err;

View File

@ -705,47 +705,37 @@ int pmd_clear_huge(pmd_t *pmd)
}
#ifdef CONFIG_X86_64
/**
* pud_free_pmd_page - Clear PUD entry and free PMD page
* @pud: Pointer to a PUD
* @addr: Virtual address associated with PUD
*
* Context: The PUD range has been unmapped and TLB purged.
* Return: 1 if clearing the entry succeeded. 0 otherwise.
*
* NOTE: Callers must allow a single page allocation.
/*
* Given a PUD poitner, detach and free the pointed-to
* PMD page and any PTE page children. The entire range
* under the PUD must not have any valid translations
* and the TLB must have already been flushed.
*/
int pud_free_pmd_page(pud_t *pud, unsigned long addr)
{
pmd_t *pmd, *pmd_sv;
struct ptdesc *pt;
pmd_t *pmd;
int i;
pmd = pud_pgtable(*pud);
pmd_sv = (pmd_t *)__get_free_page(GFP_KERNEL);
if (!pmd_sv)
return 0;
for (i = 0; i < PTRS_PER_PMD; i++) {
pmd_sv[i] = pmd[i];
if (!pmd_none(pmd[i]))
pmd_clear(&pmd[i]);
}
/* Detach the PMD page: */
pud_clear(pud);
/* INVLPG to clear all paging-structure caches */
/*
* PMD and all its descendents are unreachable
* via normal page walks. Make them unreachable
* in cached mid-level walks too:
*/
flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1);
for (i = 0; i < PTRS_PER_PMD; i++) {
if (!pmd_none(pmd_sv[i])) {
pt = page_ptdesc(pmd_page(pmd_sv[i]));
if (!pmd_none(pmd[i])) {
pt = page_ptdesc(pmd_page(pmd[i]));
pagetable_dtor_free(pt);
}
}
free_page((unsigned long)pmd_sv);
pmd_free(&init_mm, pmd);
return 1;

View File

@ -3217,16 +3217,21 @@ static void restore_regs(const struct btf_func_model *m, u8 **prog,
}
static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
struct bpf_tramp_image *im,
struct bpf_tramp_node *node, int stack_size,
int run_ctx_off, bool save_ret,
void *image, void *rw_image)
{
u8 *prog = *pprog;
u8 *jmp_insn;
u8 *jmp_insn, *skip;
int ctx_cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie);
struct bpf_prog *p = node->link->prog;
u64 cookie = node->cookie;
/* nop, patched to skip this prog when it is detached */
skip = image + (prog - (u8 *)rw_image);
emit_nops(&prog, X86_PATCH_SIZE);
/* mov rdi, cookie */
emit_mov_imm64(&prog, BPF_REG_1, (long) cookie >> 32, (u32) (long) cookie);
@ -3301,6 +3306,8 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
if (emit_rsb_call(&prog, bpf_trampoline_exit(p), image + (prog - (u8 *)rw_image)))
return -EINVAL;
bpf_tramp_image_add_skip(im, p, skip, image + (prog - (u8 *)rw_image));
*pprog = prog;
return 0;
}
@ -3332,6 +3339,7 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
}
static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
struct bpf_tramp_image *im,
struct bpf_tramp_nodes *tl, int stack_size,
int run_ctx_off, int func_meta_off, bool save_ret,
void *image, void *rw_image, u64 func_meta,
@ -3346,7 +3354,7 @@ static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
func_meta | (cur_cookie << BPF_TRAMP_COOKIE_INDEX_SHIFT));
cur_cookie--;
}
if (invoke_bpf_prog(m, &prog, tl->nodes[i], stack_size,
if (invoke_bpf_prog(m, &prog, im, tl->nodes[i], stack_size,
run_ctx_off, save_ret, image, rw_image))
return -EINVAL;
}
@ -3355,6 +3363,7 @@ static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
}
static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
struct bpf_tramp_image *im,
struct bpf_tramp_nodes *tl, int stack_size,
int run_ctx_off, u8 **branches,
void *image, void *rw_image)
@ -3368,7 +3377,7 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
emit_mov_imm32(&prog, false, BPF_REG_0, 0);
emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8);
for (i = 0; i < tl->nr_nodes; i++) {
if (invoke_bpf_prog(m, &prog, tl->nodes[i], stack_size, run_ctx_off, true,
if (invoke_bpf_prog(m, &prog, im, tl->nodes[i], stack_size, run_ctx_off, true,
image, rw_image))
return -EINVAL;
@ -3640,7 +3649,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
}
if (fentry->nr_nodes) {
if (invoke_bpf(m, &prog, fentry, regs_off, run_ctx_off, func_meta_off,
if (invoke_bpf(m, &prog, im, fentry, regs_off, run_ctx_off, func_meta_off,
flags & BPF_TRAMP_F_RET_FENTRY_RET, image, rw_image,
func_meta, cookie_off))
return -EINVAL;
@ -3652,7 +3661,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
if (!branches)
return -ENOMEM;
if (invoke_bpf_mod_ret(m, &prog, fmod_ret, regs_off,
if (invoke_bpf_mod_ret(m, &prog, im, fmod_ret, regs_off,
run_ctx_off, branches, image, rw_image)) {
ret = -EINVAL;
goto cleanup;
@ -3682,8 +3691,6 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
}
/* remember return value in a stack for bpf prog to access */
emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8);
im->ip_after_call = image + (prog - (u8 *)rw_image);
emit_nops(&prog, X86_PATCH_SIZE);
}
if (fmod_ret->nr_nodes) {
@ -3708,7 +3715,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
emit_store_stack_imm64(&prog, BPF_REG_0, -func_meta_off, func_meta);
if (fexit->nr_nodes) {
if (invoke_bpf(m, &prog, fexit, regs_off, run_ctx_off, func_meta_off,
if (invoke_bpf(m, &prog, im, fexit, regs_off, run_ctx_off, func_meta_off,
false, image, rw_image, func_meta, cookie_off)) {
ret = -EINVAL;
goto cleanup;
@ -3723,7 +3730,6 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
* restored to R0.
*/
if (flags & BPF_TRAMP_F_CALL_ORIG) {
im->ip_epilogue = image + (prog - (u8 *)rw_image);
/* arg1: mov rdi, im */
emit_mov_imm64(&prog, BPF_REG_1, (long) im >> 32, (u32) (long) im);
if (emit_rsb_call(&prog, __bpf_tramp_exit, image + (prog - (u8 *)rw_image))) {
@ -3811,7 +3817,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
struct bpf_tramp_nodes *tnodes, void *func_addr)
{
struct bpf_tramp_image im;
struct bpf_tramp_image im = {};
void *image;
int ret;

View File

@ -13,9 +13,7 @@ enum {
};
#include <linux/compiler.h>
#ifndef CONFIG_X86_32
#define __FRAME_OFFSETS /* Needed to get the R* macros */
#endif
#define __FRAME_OFFSETS /* Needed to get the register macros */
#include <asm/ptrace-generic.h>
#define user_mode(r) UPT_IS_USER(&(r)->regs)

View File

@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/regset.h>
#define __FRAME_OFFSETS
#include <asm/ptrace-abi.h>
#include <registers.h>
#include <skas.h>

View File

@ -2091,6 +2091,7 @@ static inline struct blkcg_gq *blkg_tryget_closest(struct bio *bio,
struct request_queue *q = bio->bi_bdev->bd_queue;
struct blkcg *blkcg = css_to_blkcg(css);
struct blkcg_gq *blkg;
unsigned long flags;
rcu_read_lock();
blkg = blkg_lookup(blkcg, q);
@ -2105,11 +2106,11 @@ static inline struct blkcg_gq *blkg_tryget_closest(struct bio *bio,
* Fast path failed, we're probably issuing IO in this cgroup the first
* time, hold lock to create new blkg.
*/
spin_lock_irq(&q->queue_lock);
spin_lock_irqsave(&q->queue_lock, flags);
blkg = blkg_lookup_create(blkcg, bio->bi_bdev->bd_disk);
if (blkg)
blkg = blkg_lookup_tryget(blkg);
spin_unlock_irq(&q->queue_lock);
spin_unlock_irqrestore(&q->queue_lock, flags);
return blkg;
}

View File

@ -447,16 +447,6 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
WRITE_ONCE(rq->deadline, 0);
req_ref_set(rq, 1);
if (rq->rq_flags & RQF_USE_SCHED) {
struct elevator_queue *e = data->q->elevator;
INIT_HLIST_NODE(&rq->hash);
RB_CLEAR_NODE(&rq->rb_node);
if (e->type->ops.prepare_request)
e->type->ops.prepare_request(rq);
}
return rq;
}
@ -498,6 +488,12 @@ __blk_mq_alloc_requests_batch(struct blk_mq_alloc_data *data)
return rq_list_pop(data->cached_rqs);
}
static bool blk_op_bypass_sched(blk_opf_t opf)
{
return (opf & REQ_OP_MASK) == REQ_OP_FLUSH ||
blk_op_is_passthrough(opf);
}
static void blk_mq_limit_depth(struct blk_mq_alloc_data *data)
{
struct elevator_mq_ops *ops;
@ -518,12 +514,10 @@ static void blk_mq_limit_depth(struct blk_mq_alloc_data *data)
* Flush/passthrough requests are special and go directly to the
* dispatch list, they are not subject to the async_depth limit.
*/
if ((data->cmd_flags & REQ_OP_MASK) == REQ_OP_FLUSH ||
blk_op_is_passthrough(data->cmd_flags))
if (blk_op_bypass_sched(data->cmd_flags))
return;
WARN_ON_ONCE(data->flags & BLK_MQ_REQ_RESERVED);
data->rq_flags |= RQF_USE_SCHED;
/*
* By default, sync requests have no limit, and async requests are
@ -534,6 +528,29 @@ static void blk_mq_limit_depth(struct blk_mq_alloc_data *data)
ops->limit_depth(data->cmd_flags, data);
}
/*
* Finish initializing a request once it has been claimed for an operation.
* Cached requests are allocated before that operation is known.
*/
static void blk_mq_rq_late_init(struct request *rq, u64 alloc_time_ns)
{
struct elevator_queue *e;
blk_mq_rq_time_init(rq, alloc_time_ns);
if (!(rq->rq_flags & RQF_SCHED_TAGS) || (rq->rq_flags & RQF_RESV) ||
blk_op_bypass_sched(rq->cmd_flags))
return;
rq->rq_flags |= RQF_USE_SCHED;
INIT_HLIST_NODE(&rq->hash);
RB_CLEAR_NODE(&rq->rb_node);
e = rq->q->elevator;
if (e->type->ops.prepare_request)
e->type->ops.prepare_request(rq);
}
static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data)
{
struct request_queue *q = data->q;
@ -562,7 +579,7 @@ static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data)
if (data->nr_tags > 1) {
rq = __blk_mq_alloc_requests_batch(data);
if (rq) {
blk_mq_rq_time_init(rq, alloc_time_ns);
blk_mq_rq_late_init(rq, alloc_time_ns);
return rq;
}
data->nr_tags = 1;
@ -590,7 +607,7 @@ static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data)
if (!(data->rq_flags & RQF_SCHED_TAGS))
blk_mq_inc_active_requests(data->hctx);
rq = blk_mq_rq_ctx_init(data, blk_mq_tags_from_data(data), tag);
blk_mq_rq_time_init(rq, alloc_time_ns);
blk_mq_rq_late_init(rq, alloc_time_ns);
return rq;
}
@ -637,8 +654,6 @@ static struct request *blk_mq_alloc_cached_request(struct request_queue *q,
if (plug->nr_ios == 1)
return NULL;
rq = blk_mq_rq_cache_fill(q, plug, opf, flags);
if (!rq)
return NULL;
} else {
rq = rq_list_peek(&plug->cached_rqs);
if (!rq || rq->q != q)
@ -646,15 +661,13 @@ static struct request *blk_mq_alloc_cached_request(struct request_queue *q,
if (blk_mq_get_hctx_type(opf) != rq->mq_hctx->type)
return NULL;
if (op_is_flush(rq->cmd_flags) != op_is_flush(opf))
return NULL;
rq_list_pop(&plug->cached_rqs);
blk_mq_rq_time_init(rq, blk_time_get_ns());
rq->cmd_flags = opf;
INIT_LIST_HEAD(&rq->queuelist);
blk_mq_rq_late_init(rq, blk_time_get_ns());
}
rq->cmd_flags = opf;
INIT_LIST_HEAD(&rq->queuelist);
return rq;
}
@ -766,7 +779,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
if (!(data.rq_flags & RQF_SCHED_TAGS))
blk_mq_inc_active_requests(data.hctx);
rq = blk_mq_rq_ctx_init(&data, blk_mq_tags_from_data(&data), tag);
blk_mq_rq_time_init(rq, alloc_time_ns);
blk_mq_rq_late_init(rq, alloc_time_ns);
rq->__data_len = 0;
rq->phys_gap_bit = 0;
rq->__sector = (sector_t) -1;
@ -3060,8 +3073,6 @@ static struct request *blk_mq_get_cached_request(struct blk_plug *plug,
if (type != rq->mq_hctx->type &&
(type != HCTX_TYPE_READ || rq->mq_hctx->type != HCTX_TYPE_DEFAULT))
return NULL;
if (op_is_flush(rq->cmd_flags) != op_is_flush(opf))
return NULL;
rq_list_pop(&plug->cached_rqs);
return rq;
}
@ -3163,9 +3174,9 @@ void blk_mq_submit_bio(struct bio *bio)
new_request:
if (rq) {
rq_qos_throttle(rq->q, bio);
blk_mq_rq_time_init(rq, blk_time_get_ns());
rq->cmd_flags = bio->bi_opf;
INIT_LIST_HEAD(&rq->queuelist);
blk_mq_rq_late_init(rq, blk_time_get_ns());
} else {
rq = blk_mq_get_new_requests(q, plug, bio);
if (unlikely(!rq)) {

View File

@ -402,6 +402,11 @@ static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
if (blkdev_dio_invalid(bdev, iocb, iter))
return -EINVAL;
/* HIPRI needs private as bio; HAS_METADATA keeps it as uio_meta */
if ((iocb->ki_flags & IOCB_HIPRI) &&
(iocb->ki_flags & IOCB_HAS_METADATA))
return -EOPNOTSUPP;
if (iov_iter_rw(iter) == WRITE) {
u16 max_write_streams = bdev_max_write_streams(bdev);

View File

@ -685,7 +685,7 @@ static void dd_insert_requests(struct blk_mq_hw_ctx *hctx,
blk_mq_free_requests(&free);
}
/* Callback from inside blk_mq_rq_ctx_init(). */
/* Callback from inside blk_mq_rq_late_init(). */
static void dd_prepare_request(struct request *rq)
{
rq->elv.priv[0] = NULL;

View File

@ -637,7 +637,18 @@ static struct skcipher_alg skcipher_algs[] = {
.decrypt = crypto_aes_cbc_decrypt,
},
#endif
#if IS_ENABLED(CONFIG_CRYPTO_CTS)
/*
* Don't register library-based "cts(cbc(aes))" on architectures where
* it might block a "better" implementation from being instantiated via
* the "cts" template. These exclusions are temporary and will go away
* as the arch-optimized AES code is migrated into the library.
*/
#if IS_ENABLED(CONFIG_CRYPTO_CTS) && \
!(IS_ENABLED(CONFIG_ARM) || \
IS_ENABLED(CONFIG_ARM64) || \
IS_ENABLED(CONFIG_PPC) || \
IS_ENABLED(CONFIG_S390) || \
IS_ENABLED(CONFIG_SPARC))
{
.base.cra_name = "cts(cbc(aes))",
.base.cra_driver_name = "cts-cbc-aes-lib",
@ -687,7 +698,13 @@ static struct skcipher_alg skcipher_algs[] = {
.decrypt = crypto_aes_xctr_crypt,
},
#endif
#if IS_ENABLED(CONFIG_CRYPTO_XTS)
/*
* Don't register library-based "xts(aes)" on architectures where it
* might block a "better" implementation from being instantiated via the
* "xts" template. This exclusion is temporary and will go away when
* the library AES-XTS is optimized for SPARC.
*/
#if IS_ENABLED(CONFIG_CRYPTO_XTS) && !IS_ENABLED(CONFIG_SPARC)
{
.base.cra_name = "xts(aes)",
.base.cra_driver_name = "xts-aes-lib",
@ -980,7 +997,20 @@ static __maybe_unused int crypto_aes_ccm_decrypt(struct aead_request *req)
}
static struct aead_alg aead_algs[] = {
#if IS_ENABLED(CONFIG_CRYPTO_GCM)
/*
* Don't register library-based "gcm(aes)" and "rfc4106(gcm(aes))" on
* architectures where they might block a "better" implementation from
* being instantiated via the "gcm" and "rfc4106" templates. These
* exclusions are temporary and will go away as the arch-optimized AES
* code is migrated into the library.
*/
#if IS_ENABLED(CONFIG_CRYPTO_GCM) && \
!(IS_ENABLED(CONFIG_ARM) || \
IS_ENABLED(CONFIG_ARM64) || \
IS_ENABLED(CONFIG_PPC) || \
IS_ENABLED(CONFIG_RISCV) || \
IS_ENABLED(CONFIG_S390) || \
IS_ENABLED(CONFIG_SPARC))
{
.base.cra_name = "gcm(aes)",
.base.cra_driver_name = "gcm-aes-lib",
@ -1012,7 +1042,20 @@ static struct aead_alg aead_algs[] = {
.chunksize = AES_BLOCK_SIZE,
},
#endif /* CONFIG_CRYPTO_GCM */
#if IS_ENABLED(CONFIG_CRYPTO_CCM)
/*
* Don't register library-based "ccm(aes)" on architectures where it
* might block a "better" implementation from being instantiated via the
* "ccm" template. These exclusions are temporary and will go away as
* the arch-optimized AES code is migrated into the library.
*/
#if IS_ENABLED(CONFIG_CRYPTO_CCM) && \
!(IS_ENABLED(CONFIG_ARM) || \
IS_ENABLED(CONFIG_ARM64) || \
IS_ENABLED(CONFIG_PPC) || \
IS_ENABLED(CONFIG_RISCV) || \
IS_ENABLED(CONFIG_S390) || \
IS_ENABLED(CONFIG_SPARC) || \
IS_ENABLED(CONFIG_X86))
{
.base.cra_name = "ccm(aes)",
.base.cra_driver_name = "ccm-aes-lib",

View File

@ -62,14 +62,50 @@ static void braille_write(u16 *buf)
{
static u16 lastwrite[WIDTH];
unsigned char data[1 + 1 + 2*WIDTH + 2 + 1], csum = 0, *c;
struct nbcon_write_context wctxt = { };
unsigned long flags;
u16 out;
int i;
if (!braille_co)
return;
/*
* Braille console is not registered in console_list. Instead, it
* is integrated with VT and shows what appears on the graphical
* console under console_lock(). From this POV it is a legacy
* console. But it calls serial console driver which might be
* converted to the NBCON API. It is similar to
* nbcon_legacy_emit_next_record() except that we should try
* harder to get the lock. Otherwise, the Braille device won't show
* everything what is displayed on the terminal.
*
* In short, simulate the original locking using NBCON API.
*/
if (braille_co->flags & CON_NBCON) {
if (panic_on_this_cpu()) {
/*
* This should be good enough in practice. Most/all
* serial console drivers have the atomic callback.
*/
if (!braille_co->write_atomic)
return;
local_irq_save(flags);
/* NBCON API strictly requires the ownership. */
if (!nbcon_braille_try_acquire(braille_co, &wctxt)) {
local_irq_restore(flags);
return;
}
} else {
braille_co->device_lock(braille_co, &flags);
while (!nbcon_braille_try_acquire(braille_co, &wctxt))
cpu_relax();
}
}
if (!memcmp(lastwrite, buf, WIDTH * sizeof(*buf)))
return;
goto unlock_nbcon;
memcpy(lastwrite, buf, WIDTH * sizeof(*buf));
#define SOH 1
@ -102,7 +138,24 @@ static void braille_write(u16 *buf)
*c++ = csum;
*c++ = ETX;
braille_co->write(braille_co, data, c - data);
if (braille_co->flags & CON_NBCON) {
nbcon_write_context_set_buf(&wctxt, (char *)data, c - data);
if (panic_on_this_cpu())
braille_co->write_atomic(braille_co, &wctxt);
else
braille_co->write_thread(braille_co, &wctxt);
} else {
braille_co->write(braille_co, data, c - data);
}
unlock_nbcon:
if (braille_co->flags & CON_NBCON) {
nbcon_braille_release(&wctxt);
if (panic_on_this_cpu())
local_irq_restore(flags);
else
braille_co->device_unlock(braille_co, flags);
}
}
/* Follow the VC cursor*/

View File

@ -2930,8 +2930,9 @@ static int binder_proc_transaction(struct binder_transaction *t,
t_outdated->buffer = NULL;
buffer->transaction = NULL;
trace_binder_transaction_update_buffer_release(buffer);
binder_release_entire_buffer(proc, NULL, buffer, false);
binder_release_entire_buffer(proc, NULL, buffer, true);
binder_alloc_free_buf(&proc->alloc, buffer);
binder_free_txn_fixups(t_outdated);
kfree(t_outdated);
binder_stats_deleted(BINDER_STAT_TRANSACTION);
}

View File

@ -51,9 +51,9 @@
/// about to drop the weak reference, then the strong increment could be processed after the
/// other thread has already exited, which would be too late.
///
/// Note that trying to create a `ListArc` to the node can succeed even if `has_normal_push` is
/// Note that trying to create a `ListArc` to the node can succeed even if `has_pushed_node` is
/// set. This is because another thread might just have popped the node from a todo list, but not
/// yet called `do_work`. However, if `has_normal_push` is false, then creating a `ListArc` should
/// yet called `do_work`. However, if `has_pushed_node` is false, then creating a `ListArc` should
/// always succeed.
///
/// Like the other fields in `NodeInner`, the delivery state is protected by the process lock.
@ -738,7 +738,21 @@ fn do_work(
self.do_work_locked(writer, owner_inner)
}
fn cancel(self: DArc<Self>) {}
fn cancel(self: DArc<Self>) {
let _drop_outside_lock;
let mut owner_inner = self.owner.inner.lock();
// We only do something on BINDER_THREAD_EXIT, not process exit.
if owner_inner.is_dead {
return;
}
// If BINDER_THREAD_EXIT is invoked on a thread with a pending node refcount update, we
// should move ourselves to ensure the refcount update is still delivered.
if let Some(node) = ListArc::try_from_arc_borrow(self.as_arc_borrow()) {
_drop_outside_lock = owner_inner.push_work(&self.owner, node);
}
}
fn should_sync_wakeup(&self) -> bool {
false

View File

@ -57,7 +57,39 @@ fn do_work(
node.do_work_locked(writer, owner_inner)
}
fn cancel(self: DArc<Self>) {}
fn cancel(self: DArc<Self>) {
let _drop_outside_lock;
let node = &self.node;
let mut owner_inner = node.owner.inner.lock();
// We only do something on BINDER_THREAD_EXIT, not process exit.
if owner_inner.is_dead {
return;
}
// We transfer the responsibility of the node refcount update to the scheduled Node because
// NodeWrapper has no way to re-create the ListArc.
let inner = node.inner.access_mut(&mut owner_inner);
let ds = &mut inner.delivery_state;
assert!(ds.has_pushed_wrapper);
assert!(ds.has_strong_zero2one);
ds.has_pushed_wrapper = false;
// We are changing the state to one where the Node is the strong zero2one update instead of
// the wrapper.
ds.has_weak_zero2one = false;
if !ds.has_pushed_node {
if let Some(node2) = ListArc::try_from_arc_borrow(node.as_arc_borrow()) {
ds.has_pushed_node = true;
_drop_outside_lock = owner_inner.push_work(&node.owner, node2);
} else {
// This can't actually happen.
ds.has_strong_zero2one = false;
}
}
}
fn should_sync_wakeup(&self) -> bool {
false

View File

@ -72,6 +72,7 @@ struct binder_features {
bool oneway_spam_detection;
bool extended_error;
bool freeze_notification;
bool transaction_report;
};
static const struct constant_table binderfs_param_stats[] = {
@ -89,6 +90,7 @@ static struct binder_features binder_features = {
.oneway_spam_detection = true,
.extended_error = true,
.freeze_notification = true,
.transaction_report = true,
};
static inline struct binderfs_info *BINDERFS_SB(const struct super_block *sb)
@ -566,6 +568,12 @@ static int init_binder_features(struct super_block *sb)
if (IS_ERR(dentry))
return PTR_ERR(dentry);
dentry = rust_binderfs_create_file(dir, "transaction_report",
&binder_features_fops,
&binder_features.transaction_report);
if (IS_ERR(dentry))
return PTR_ERR(dentry);
return 0;
}

View File

@ -686,6 +686,12 @@ pub(crate) fn push_return_work(&self, reply: u32) {
self.inner.lock().push_return_work(reply);
}
pub(crate) fn pop_work_even_if_deferred(&self) -> Option<DLArc<dyn DeliverToRead>> {
let mut thread_inner = self.inner.lock();
thread_inner.process_work_list = true;
thread_inner.pop_work()
}
fn translate_object(
&self,
obj_index: usize,
@ -1678,7 +1684,7 @@ pub(crate) fn release(self: &Arc<Self>) {
self.unwind_transaction_stack();
// Cancel all pending work items.
while let Ok(Some(work)) = self.get_work_local(false) {
while let Some(work) = self.pop_work_even_if_deferred() {
work.into_arc().cancel();
}
}

View File

@ -189,12 +189,11 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
goto err;
}
inode->i_private = device;
binder_add_device(device);
d_make_persistent(dentry, inode);
fsnotify_create(root->d_inode, dentry);
simple_done_creating(dentry);
binder_add_device(device);
return 0;
err:

View File

@ -3059,10 +3059,15 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev)
qc->dev->sdev->locked = 0;
if (cmd->result)
ata_scsi_qc_done(qc, false, 0);
else
ata_scsi_qc_done(qc, true, SAM_STAT_CHECK_CONDITION);
/*
* Report CHECK CONDITION unless the command was terminated
* with a host byte set. Only set the status byte, so that the
* SCSI midlayer internal byte, which scsi_check_sense() may
* have set from the sense data, is preserved.
*/
if (get_host_byte(cmd) == DID_OK)
set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
ata_scsi_qc_done(qc, false, 0);
goto schedule_deferred;
}

View File

@ -638,10 +638,6 @@ const struct genl_split_ops drbd_nl_ops[32] = {
},
};
static const struct genl_multicast_group drbd_nl_mcgrps[] = {
[DRBD_NLGRP_EVENTS] = { "events", },
};
static int __drbd_cfg_context_from_attrs(struct drbd_cfg_context *s,
struct nlattr ***ret_nested_attribute_table,
struct genl_info *info)

View File

@ -743,6 +743,7 @@ static int virtblk_read_zoned_limits(struct virtio_blk *vblk,
dev_warn(&vdev->dev, "zero write granularity reported\n");
return -ENODEV;
}
lim->zone_write_granularity = wg;
lim->physical_block_size = wg;
lim->io_min = wg;

View File

@ -401,7 +401,7 @@ static int btintel_pcie_send_sync(struct btintel_pcie_data *data,
tfd_index = data->ia.tr_hia[BTINTEL_PCIE_TXQ_NUM];
if (tfd_index > txq->count)
if (tfd_index >= txq->count)
return -ERANGE;
if (skb->len > BTINTEL_PCIE_BUFFER_SIZE - BTINTEL_PCIE_HCI_TYPE_LEN) {
@ -1777,7 +1777,7 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
static int btintel_pcie_setup_irq(struct btintel_pcie_data *data)
{
int err;
int num_irqs, i;
int num_irqs, i, j;
for (i = 0; i < BTINTEL_PCIE_MSIX_VEC_MAX; i++)
data->msix_entries[i].entry = i;
@ -1806,6 +1806,10 @@ static int btintel_pcie_setup_irq(struct btintel_pcie_data *data)
KBUILD_MODNAME,
msix_entry);
if (err) {
for (j = 0; j < i; j++)
devm_free_irq(&data->pdev->dev,
data->msix_entries[j].vector,
&data->msix_entries[j]);
pci_free_irq_vectors(data->pdev);
data->alloc_vecs = 0;
return err;
@ -1877,6 +1881,13 @@ static int btintel_pcie_config_pcie(struct pci_dev *pdev,
if (IS_ERR(data->base_addr))
return PTR_ERR(data->base_addr);
/* Do shared hardware reset to ensure a clean start before
* configuring interrupts.
*/
err = btintel_pcie_reset_bt(data);
if (err)
return err;
err = btintel_pcie_setup_irq(data);
if (err)
return err;
@ -3138,7 +3149,7 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
struct msix_entry *msix_entry;
msix_entry = &data->msix_entries[i];
free_irq(msix_entry->vector, msix_entry);
devm_free_irq(&pdev->dev, msix_entry->vector, msix_entry);
}
pci_free_irq_vectors(pdev);

View File

@ -503,7 +503,7 @@ static int mmap_zero_prepare(struct vm_area_desc *desc)
#ifndef CONFIG_MMU
return -ENOSYS;
#endif
if (vma_desc_test(desc, VMA_SHARED_BIT))
if (vma_desc_test(desc, VMA_MAYSHARE_BIT))
return shmem_zero_setup_desc(desc);
/*

View File

@ -268,7 +268,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
int err;
ssize_t len;
len = tpm_transmit(chip, buf->data, PAGE_SIZE);
len = tpm_transmit(chip, buf->data, buf->capacity);
if (len < 0)
return len;

View File

@ -281,8 +281,10 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
}
tpm_buf_append_u16(buf, num_bytes);
err = tpm_buf_fill_hmac_session(chip, buf);
if (err)
if (err) {
tpm2_end_auth_session(chip);
return err;
}
err = tpm_transmit_cmd(chip, buf,
offsetof(struct tpm2_get_random_out,
@ -305,7 +307,7 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
out = (struct tpm2_get_random_out *)&buf->data[offset];
recd = min_t(u32, be16_to_cpu(out->size), num_bytes);
if (tpm_buf_length(buf) <
TPM_HEADER_SIZE +
offset +
offsetof(struct tpm2_get_random_out, buffer) +
recd) {
tpm2_end_auth_session(chip);

View File

@ -975,6 +975,7 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key)
/* Deduce from the name change TPM interference: */
dev_err(&chip->dev, "null key integrity check failed\n");
tpm2_flush_context(chip, tmp_null_key);
rc = -ENODEV;
err:
if (rc) {

View File

@ -3010,8 +3010,6 @@ static const u32 gcc_eliza_critical_cbcrs[] = {
0x26034, /* GCC_CAMERA_XO_CLK */
0x27004, /* GCC_DISP_AHB_CLK */
0x71004, /* GCC_GPU_CFG_AHB_CLK */
0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */
0x52010, /* GCC_PCIE_RSCC_XO_CLK */
0x32004, /* GCC_VIDEO_AHB_CLK */
0x32038, /* GCC_VIDEO_XO_CLK */
};
@ -3045,6 +3043,10 @@ static const struct regmap_config gcc_eliza_regmap_config = {
static void clk_eliza_regs_configure(struct device *dev, struct regmap *regmap)
{
/* Keep clocks always enabled */
regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20)); /* GCC_PCIE_RSCC_CFG_AHB_CLK */
regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21)); /* GCC_PCIE_RSCC_XO_CLK */
/* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true);

View File

@ -3692,8 +3692,6 @@ static const u32 gcc_hawi_critical_cbcrs[] = {
0x67084, /* GCC_PCIE_1_RSC_CORE_CLK */
0x43014, /* GCC_PCIE_LINK_XO_CLK */
0x6b088, /* GCC_PCIE_RSC_CORE_CLK */
0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */
0x52010, /* GCC_PCIE_RSCC_XO_CLK */
0x32004, /* GCC_VIDEO_AHB_CLK */
0x32028, /* GCC_VIDEO_XO_CLK */
};
@ -3763,6 +3761,10 @@ static const struct regmap_config gcc_hawi_regmap_config = {
static void clk_hawi_regs_configure(struct device *dev, struct regmap *regmap)
{
/* Keep clocks always enabled */
regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20)); /* GCC_PCIE_RSCC_CFG_AHB_CLK */
regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21)); /* GCC_PCIE_RSCC_XO_CLK */
/* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
}

View File

@ -3464,8 +3464,6 @@ static const u32 gcc_kaanapali_critical_cbcrs[] = {
0x9f004, /* GCC_EVA_AHB_CLK */
0x9f024, /* GCC_EVA_XO_CLK */
0x71004, /* GCC_GPU_CFG_AHB_CLK */
0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */
0x52010, /* GCC_PCIE_RSCC_XO_CLK */
0x32004, /* GCC_VIDEO_AHB_CLK */
0x32040, /* GCC_VIDEO_XO_CLK */
};
@ -3480,6 +3478,10 @@ static const struct regmap_config gcc_kaanapali_regmap_config = {
static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap)
{
/* Keep clocks always enabled */
regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20)); /* GCC_PCIE_RSCC_CFG_AHB_CLK */
regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21)); /* GCC_PCIE_RSCC_XO_CLK */
/* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
}

View File

@ -510,7 +510,7 @@ static struct gdsc gpu_cc_cx_gdsc = {
.name = "gpu_cc_cx_gdsc",
},
.pwrsts = PWRSTS_OFF_ON,
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
.flags = RETAIN_FF_ENABLE | VOTABLE,
};
static struct clk_regmap *gpu_cc_glymur_clocks[] = {

View File

@ -380,7 +380,7 @@ static struct gdsc gpu_cc_cx_gdsc = {
.name = "gpu_cc_cx_gdsc",
},
.pwrsts = PWRSTS_OFF_ON,
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
.flags = RETAIN_FF_ENABLE | VOTABLE,
};
static struct clk_regmap *gpu_cc_kaanapali_clocks[] = {

View File

@ -30,14 +30,87 @@ static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = {
};
static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = {
CCU_PLLA_RATE(1050000000UL, 0x0b2b3000, 0x00000000, 0xa0458080),
CCU_PLLA_RATE(1100000000UL, 0x0b2d3555, 0x00005500, 0xa0458181),
CCU_PLLA_RATE(1150000000UL, 0x0b2f3aaa, 0x0000ab00, 0xa0458181),
CCU_PLLA_RATE(1200000000UL, 0x0b320000, 0x00000000, 0xa0458181),
CCU_PLLA_RATE(1250000000UL, 0x0b340555, 0x00005500, 0xa0458181),
CCU_PLLA_RATE(1300000000UL, 0x0b360aaa, 0x0000ab00, 0xa0458282),
CCU_PLLA_RATE(1350000000UL, 0x0b381000, 0x00000000, 0xa0458282),
CCU_PLLA_RATE(1400000000UL, 0x0b3a1555, 0x00005500, 0xa0458282),
CCU_PLLA_RATE(1450000000UL, 0x0b3c1aaa, 0x0000ab00, 0xa0458383),
CCU_PLLA_RATE(1500000000UL, 0x0b3e2000, 0x00000000, 0xa0458383),
CCU_PLLA_RATE(1550000000UL, 0x0b402555, 0x00005500, 0xa0458383),
CCU_PLLA_RATE(1600000000UL, 0x0b422aaa, 0x0000ab00, 0xa0458484),
CCU_PLLA_RATE(1650000000UL, 0x0b443000, 0x00000000, 0xa0458484),
CCU_PLLA_RATE(1700000000UL, 0x0b463555, 0x00005500, 0xa0458484),
CCU_PLLA_RATE(1750000000UL, 0x0b483aaa, 0x0000ab00, 0xa0458585),
CCU_PLLA_RATE(1800000000UL, 0x0b4b0000, 0x00000000, 0xa0458585),
CCU_PLLA_RATE(1850000000UL, 0x0b4d0555, 0x00005500, 0xa0458585),
CCU_PLLA_RATE(1900000000UL, 0x0b4f0aaa, 0x0000ab00, 0xa0458686),
CCU_PLLA_RATE(1950000000UL, 0x0b511000, 0x00000000, 0xa0458686),
CCU_PLLA_RATE(2000000000UL, 0x0b292aaa, 0x0000ab00, 0xa0558686),
CCU_PLLA_RATE(2050000000UL, 0x0b2a2d55, 0x00005500, 0xa0558686),
CCU_PLLA_RATE(2100000000UL, 0x0b2b3000, 0x00000000, 0xa0558787),
CCU_PLLA_RATE(2150000000UL, 0x0b2c32aa, 0x0000ab00, 0xa0558787),
CCU_PLLA_RATE(2200000000UL, 0x0b2d3555, 0x00005500, 0xa0558787),
CCU_PLLA_RATE(2250000000UL, 0x0b2e3800, 0x00000000, 0xa0558888),
CCU_PLLA_RATE(2300000000UL, 0x0b2f3aaa, 0x0000ab00, 0xa0558888),
CCU_PLLA_RATE(2350000000UL, 0x0b303d55, 0x00005500, 0xa0558888),
CCU_PLLA_RATE(2400000000UL, 0x0b320000, 0x00000000, 0xa0558989),
};
static const struct ccu_pll_rate_tbl pll4_rate_tbl[] = {
CCU_PLLA_RATE(1050000000UL, 0x0b2b3000, 0x00000000, 0xa0458080),
CCU_PLLA_RATE(1100000000UL, 0x0b2d3555, 0x00005500, 0xa0458181),
CCU_PLLA_RATE(1150000000UL, 0x0b2f3aaa, 0x0000ab00, 0xa0458181),
CCU_PLLA_RATE(1200000000UL, 0x0b320000, 0x00000000, 0xa0458181),
CCU_PLLA_RATE(1250000000UL, 0x0b340555, 0x00005500, 0xa0458181),
CCU_PLLA_RATE(1300000000UL, 0x0b360aaa, 0x0000ab00, 0xa0458282),
CCU_PLLA_RATE(1350000000UL, 0x0b381000, 0x00000000, 0xa0458282),
CCU_PLLA_RATE(1400000000UL, 0x0b3a1555, 0x00005500, 0xa0458282),
CCU_PLLA_RATE(1450000000UL, 0x0b3c1aaa, 0x0000ab00, 0xa0458383),
CCU_PLLA_RATE(1500000000UL, 0x0b3e2000, 0x00000000, 0xa0458383),
CCU_PLLA_RATE(1550000000UL, 0x0b402555, 0x00005500, 0xa0458383),
CCU_PLLA_RATE(1600000000UL, 0x0b422aaa, 0x0000ab00, 0xa0458484),
CCU_PLLA_RATE(1650000000UL, 0x0b443000, 0x00000000, 0xa0458484),
CCU_PLLA_RATE(1700000000UL, 0x0b463555, 0x00005500, 0xa0458484),
CCU_PLLA_RATE(1750000000UL, 0x0b483aaa, 0x0000ab00, 0xa0458585),
CCU_PLLA_RATE(1800000000UL, 0x0b4b0000, 0x00000000, 0xa0458585),
CCU_PLLA_RATE(1850000000UL, 0x0b4d0555, 0x00005500, 0xa0458585),
CCU_PLLA_RATE(1900000000UL, 0x0b4f0aaa, 0x0000ab00, 0xa0458686),
CCU_PLLA_RATE(1950000000UL, 0x0b511000, 0x00000000, 0xa0458686),
CCU_PLLA_RATE(2000000000UL, 0x0b292aaa, 0x0000ab00, 0xa0558686),
CCU_PLLA_RATE(2050000000UL, 0x0b2a2d55, 0x00005500, 0xa0558686),
CCU_PLLA_RATE(2100000000UL, 0x0b2b3000, 0x00000000, 0xa0558787),
CCU_PLLA_RATE(2150000000UL, 0x0b2c32aa, 0x0000ab00, 0xa0558787),
CCU_PLLA_RATE(2200000000UL, 0x0b2d3555, 0x00005500, 0xa0558787),
CCU_PLLA_RATE(2250000000UL, 0x0b2e3800, 0x00000000, 0xa0558888),
CCU_PLLA_RATE(2300000000UL, 0x0b2f3aaa, 0x0000ab00, 0xa0558888),
CCU_PLLA_RATE(2350000000UL, 0x0b303d55, 0x00005500, 0xa0558888),
CCU_PLLA_RATE(2400000000UL, 0x0b320000, 0x00000000, 0xa0558989),
};
static const struct ccu_pll_rate_tbl pll5_rate_tbl[] = {
CCU_PLLA_RATE(1050000000UL, 0x0b2b3000, 0x00000000, 0xa0458080),
CCU_PLLA_RATE(1100000000UL, 0x0b2d3555, 0x00005500, 0xa0458181),
CCU_PLLA_RATE(1150000000UL, 0x0b2f3aaa, 0x0000ab00, 0xa0458181),
CCU_PLLA_RATE(1200000000UL, 0x0b320000, 0x00000000, 0xa0458181),
CCU_PLLA_RATE(1250000000UL, 0x0b340555, 0x00005500, 0xa0458181),
CCU_PLLA_RATE(1300000000UL, 0x0b360aaa, 0x0000ab00, 0xa0458282),
CCU_PLLA_RATE(1350000000UL, 0x0b381000, 0x00000000, 0xa0458282),
CCU_PLLA_RATE(1400000000UL, 0x0b3a1555, 0x00005500, 0xa0458282),
CCU_PLLA_RATE(1450000000UL, 0x0b3c1aaa, 0x0000ab00, 0xa0458383),
CCU_PLLA_RATE(1500000000UL, 0x0b3e2000, 0x00000000, 0xa0458383),
CCU_PLLA_RATE(1550000000UL, 0x0b402555, 0x00005500, 0xa0458383),
CCU_PLLA_RATE(1600000000UL, 0x0b422aaa, 0x0000ab00, 0xa0458484),
CCU_PLLA_RATE(1650000000UL, 0x0b443000, 0x00000000, 0xa0458484),
CCU_PLLA_RATE(1700000000UL, 0x0b463555, 0x00005500, 0xa0458484),
CCU_PLLA_RATE(1750000000UL, 0x0b483aaa, 0x0000ab00, 0xa0458585),
CCU_PLLA_RATE(1800000000UL, 0x0b4b0000, 0x00000000, 0xa0458585),
CCU_PLLA_RATE(1850000000UL, 0x0b4d0555, 0x00005500, 0xa0458585),
CCU_PLLA_RATE(1900000000UL, 0x0b4f0aaa, 0x0000ab00, 0xa0458686),
CCU_PLLA_RATE(1950000000UL, 0x0b511000, 0x00000000, 0xa0458686),
CCU_PLLA_RATE(2000000000UL, 0x0b292aaa, 0x0000ab00, 0xa0558686),
};
@ -50,6 +123,25 @@ static const struct ccu_pll_rate_tbl pll7_rate_tbl[] = {
};
static const struct ccu_pll_rate_tbl pll8_rate_tbl[] = {
CCU_PLLA_RATE(1050000000UL, 0x0b2b3000, 0x00000000, 0xa0458080),
CCU_PLLA_RATE(1100000000UL, 0x0b2d3555, 0x00005500, 0xa0458181),
CCU_PLLA_RATE(1150000000UL, 0x0b2f3aaa, 0x0000ab00, 0xa0458181),
CCU_PLLA_RATE(1200000000UL, 0x0b320000, 0x00000000, 0xa0458181),
CCU_PLLA_RATE(1250000000UL, 0x0b340555, 0x00005500, 0xa0458181),
CCU_PLLA_RATE(1300000000UL, 0x0b360aaa, 0x0000ab00, 0xa0458282),
CCU_PLLA_RATE(1350000000UL, 0x0b381000, 0x00000000, 0xa0458282),
CCU_PLLA_RATE(1400000000UL, 0x0b3a1555, 0x00005500, 0xa0458282),
CCU_PLLA_RATE(1450000000UL, 0x0b3c1aaa, 0x0000ab00, 0xa0458383),
CCU_PLLA_RATE(1500000000UL, 0x0b3e2000, 0x00000000, 0xa0458383),
CCU_PLLA_RATE(1550000000UL, 0x0b402555, 0x00005500, 0xa0458383),
CCU_PLLA_RATE(1600000000UL, 0x0b422aaa, 0x0000ab00, 0xa0458484),
CCU_PLLA_RATE(1650000000UL, 0x0b443000, 0x00000000, 0xa0458484),
CCU_PLLA_RATE(1700000000UL, 0x0b463555, 0x00005500, 0xa0458484),
CCU_PLLA_RATE(1750000000UL, 0x0b483aaa, 0x0000ab00, 0xa0458585),
CCU_PLLA_RATE(1800000000UL, 0x0b4b0000, 0x00000000, 0xa0458585),
CCU_PLLA_RATE(1850000000UL, 0x0b4d0555, 0x00005500, 0xa0458585),
CCU_PLLA_RATE(1900000000UL, 0x0b4f0aaa, 0x0000ab00, 0xa0458686),
CCU_PLLA_RATE(1950000000UL, 0x0b511000, 0x00000000, 0xa0458686),
CCU_PLLA_RATE(2000000000UL, 0x0b292aaa, 0x0000ab00, 0xa0558686),
};

View File

@ -52,7 +52,7 @@ static const struct clk_ops ti_composite_gate_ops = {
struct component_clk {
int num_parents;
struct clk_parent_data *parent_data;
const char **parent_names;
struct device_node *node;
int type;
struct clk_hw *hw;
@ -116,7 +116,7 @@ static void __init _register_composite(void *user,
struct clk_hw_omap_comp *cclk = to_clk_hw_comp(hw);
struct component_clk *comp;
int num_parents = 0;
struct clk_parent_data *parent_data = NULL;
const char **parent_names = NULL;
const char *name;
int i;
int ret;
@ -155,7 +155,7 @@ static void __init _register_composite(void *user,
continue;
if (comp->num_parents) {
num_parents = comp->num_parents;
parent_data = comp->parent_data;
parent_names = comp->parent_names;
break;
}
}
@ -166,8 +166,8 @@ static void __init _register_composite(void *user,
}
name = ti_dt_clk_name(node);
clk = clk_register_composite_pdata(NULL, name,
parent_data, num_parents,
clk = clk_register_composite(NULL, name,
parent_names, num_parents,
_get_hw(cclk, CLK_COMPONENT_TYPE_MUX),
&ti_clk_mux_ops,
_get_hw(cclk, CLK_COMPONENT_TYPE_DIVIDER),
@ -190,7 +190,7 @@ static void __init _register_composite(void *user,
if (!cclk->comp_clks[i])
continue;
list_del(&cclk->comp_clks[i]->link);
kfree(cclk->comp_clks[i]->parent_data);
kfree(cclk->comp_clks[i]->parent_names);
kfree(cclk->comp_clks[i]);
}
@ -237,9 +237,8 @@ int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw,
int type)
{
unsigned int num_parents;
struct clk_parent_data *parent_data;
const char **parent_names;
struct component_clk *clk;
unsigned int i;
num_parents = of_clk_get_parent_count(node);
@ -248,21 +247,20 @@ int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw,
return -EINVAL;
}
parent_data = kzalloc_objs(*parent_data, num_parents);
if (!parent_data)
parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
if (!parent_names)
return -ENOMEM;
for (i = 0; i < num_parents; i++)
parent_data[i].index = i;
of_clk_parent_fill(node, parent_names, num_parents);
clk = kzalloc_obj(*clk);
if (!clk) {
kfree(parent_data);
kfree(parent_names);
return -ENOMEM;
}
clk->num_parents = num_parents;
clk->parent_data = parent_data;
clk->parent_names = parent_names;
clk->hw = hw;
clk->node = node;
clk->type = type;

View File

@ -2590,8 +2590,8 @@ static void cpufreq_update_pressure(struct cpufreq_policy *policy)
cpu = cpumask_first(policy->related_cpus);
max_freq = arch_scale_freq_ref(cpu);
if (!max_freq)
max_freq = policy->cpuinfo.max_freq;
if (!max_freq && cpufreq_driver->scale_freq_ref)
max_freq = cpufreq_driver->scale_freq_ref(policy);
capped_freq = policy->max;

View File

@ -1135,6 +1135,14 @@ static bool hybrid_clear_max_perf_cpu(void)
return ret;
}
static unsigned int intel_pstate_scale_freq_ref(struct cpufreq_policy *policy)
{
if (READ_ONCE(all_cpu_data[policy->cpu]->capacity_perf))
return policy->cpuinfo.max_freq;
return 0;
}
static void intel_pstate_update_freq_limits(struct cpudata *cpu)
{
int scaling = cpu->pstate.scaling;
@ -3088,6 +3096,7 @@ static struct cpufreq_driver intel_pstate = {
.offline = intel_pstate_cpu_offline,
.online = intel_pstate_cpu_online,
.update_limits = intel_pstate_update_limits,
.scale_freq_ref = intel_pstate_scale_freq_ref,
.name = "intel_pstate",
};
@ -3411,6 +3420,7 @@ static struct cpufreq_driver intel_cpufreq = {
.suspend = intel_cpufreq_suspend,
.resume = intel_pstate_resume,
.update_limits = intel_pstate_update_limits,
.scale_freq_ref = intel_pstate_scale_freq_ref,
.name = "intel_cpufreq",
};

View File

@ -453,15 +453,6 @@ static int altr_sdram_probe(struct platform_device *pdev)
return res;
}
static void altr_sdram_remove(struct platform_device *pdev)
{
struct mem_ctl_info *mci = platform_get_drvdata(pdev);
edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci);
platform_set_drvdata(pdev, NULL);
}
/*
* If you want to suspend, need to disable EDAC by removing it
* from the device tree or defconfig.
@ -481,13 +472,13 @@ static const struct dev_pm_ops altr_sdram_pm_ops = {
static struct platform_driver altr_sdram_edac_driver = {
.probe = altr_sdram_probe,
.remove = altr_sdram_remove,
.driver = {
.name = "altr_sdram_edac",
#ifdef CONFIG_PM
.pm = &altr_sdram_pm_ops,
#endif
.of_match_table = altr_sdram_ctrl_of_match,
.suppress_bind_attrs = true,
},
};
@ -517,6 +508,7 @@ static struct platform_driver altr_edac_driver = {
.driver = {
.name = "socfpga_ecc_manager",
.of_match_table = altr_edac_of_match,
.suppress_bind_attrs = true,
},
};
module_platform_driver(altr_edac_driver);
@ -803,22 +795,12 @@ static int altr_edac_device_probe(struct platform_device *pdev)
return res;
}
static void altr_edac_device_remove(struct platform_device *pdev)
{
struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
struct altr_edac_device_dev *drvdata = dci->pvt_info;
debugfs_remove_recursive(drvdata->debugfs_dir);
edac_device_del_device(&pdev->dev);
edac_device_free_ctl_info(dci);
}
static struct platform_driver altr_edac_device_driver = {
.probe = altr_edac_device_probe,
.remove = altr_edac_device_remove,
.driver = {
.name = "altr_edac_device",
.of_match_table = altr_edac_device_of_match,
.suppress_bind_attrs = true,
},
};
module_platform_driver(altr_edac_device_driver);
@ -944,7 +926,7 @@ static int __maybe_unused altr_init_memory_port(void __iomem *ioaddr, int port)
return ret;
}
static __init int __maybe_unused
static int __maybe_unused
altr_init_a10_ecc_block(struct device_node *np, u32 irq_mask,
u32 ecc_ctrl_en_mask, bool dual_port)
{
@ -1019,7 +1001,7 @@ altr_init_a10_ecc_block(struct device_node *np, u32 irq_mask,
static int validate_parent_available(struct device_node *np);
static const struct of_device_id altr_edac_a10_device_of_match[];
static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat)
static int __maybe_unused altr_init_a10_ecc_device_type(char *compat)
{
int irq;
struct device_node *child, *np;
@ -1348,7 +1330,7 @@ static const struct edac_device_prv_data a10_l2ecc_data = {
#ifdef CONFIG_EDAC_ALTERA_ETHERNET
static int __init socfpga_init_ethernet_ecc(struct altr_edac_device_dev *dev)
static int socfpga_init_ethernet_ecc(struct altr_edac_device_dev *dev)
{
int ret;
@ -1378,7 +1360,7 @@ static const struct edac_device_prv_data a10_enetecc_data = {
#ifdef CONFIG_EDAC_ALTERA_NAND
static int __init socfpga_init_nand_ecc(struct altr_edac_device_dev *device)
static int socfpga_init_nand_ecc(struct altr_edac_device_dev *device)
{
int ret;
@ -1408,7 +1390,7 @@ static const struct edac_device_prv_data a10_nandecc_data = {
#ifdef CONFIG_EDAC_ALTERA_DMA
static int __init socfpga_init_dma_ecc(struct altr_edac_device_dev *device)
static int socfpga_init_dma_ecc(struct altr_edac_device_dev *device)
{
int ret;
@ -1438,7 +1420,7 @@ static const struct edac_device_prv_data a10_dmaecc_data = {
#ifdef CONFIG_EDAC_ALTERA_USB
static int __init socfpga_init_usb_ecc(struct altr_edac_device_dev *device)
static int socfpga_init_usb_ecc(struct altr_edac_device_dev *device)
{
int ret;
@ -1468,7 +1450,7 @@ static const struct edac_device_prv_data a10_usbecc_data = {
#ifdef CONFIG_EDAC_ALTERA_QSPI
static int __init socfpga_init_qspi_ecc(struct altr_edac_device_dev *device)
static int socfpga_init_qspi_ecc(struct altr_edac_device_dev *device)
{
int ret;
@ -1524,6 +1506,7 @@ static int altr_portb_setup(struct altr_edac_device_dev *device)
dci = edac_device_alloc_ctl_info(sizeof(*altdev), ecc_name, 1,
ecc_name, 1, 0, edac_idx);
if (!dci) {
of_node_put(np);
edac_printk(KERN_ERR, EDAC_DEVICE,
"%s: Unable to allocate PortB EDAC device\n",
ecc_name);
@ -1534,8 +1517,11 @@ static int altr_portb_setup(struct altr_edac_device_dev *device)
altdev = dci->pvt_info;
*altdev = *device;
if (!devres_open_group(device->edac->dev, altr_portb_setup, GFP_KERNEL))
if (!devres_open_group(device->edac->dev, altr_portb_setup, GFP_KERNEL)) {
edac_device_free_ctl_info(dci);
of_node_put(np);
return -ENOMEM;
}
/* Update PortB specific values */
altdev->edac_dev_name = ecc_name;
@ -1600,6 +1586,8 @@ static int altr_portb_setup(struct altr_edac_device_dev *device)
rc = -ENOMEM;
goto err_release_group_1;
}
of_node_put(np);
altr_create_edacdev_dbgfs(dci, prv);
list_add(&altdev->next, &altdev->edac->a10_ecc_devices);
@ -1609,14 +1597,20 @@ static int altr_portb_setup(struct altr_edac_device_dev *device)
return 0;
err_release_group_1:
edac_device_free_ctl_info(dci);
/*
* Release the devres group first so the managed IRQs are
* unregistered before dci (which contains the IRQ handler's
* data via dci->pvt_info) is freed, avoiding a use-after-free.
*/
devres_release_group(device->edac->dev, altr_portb_setup);
edac_device_free_ctl_info(dci);
of_node_put(np);
edac_printk(KERN_ERR, EDAC_DEVICE,
"%s:Error setting up EDAC device: %d\n", ecc_name, rc);
return rc;
}
static int __init socfpga_init_sdmmc_ecc(struct altr_edac_device_dev *device)
static int socfpga_init_sdmmc_ecc(struct altr_edac_device_dev *device)
{
int rc = -ENODEV;
struct device_node *child;
@ -1638,7 +1632,7 @@ static int __init socfpga_init_sdmmc_ecc(struct altr_edac_device_dev *device)
goto exit;
/* Setup portB */
return altr_portb_setup(device);
rc = altr_portb_setup(device);
exit:
of_node_put(child);
@ -2013,9 +2007,17 @@ static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
return 0;
err_release_group1:
/*
* Release the devres group first so the managed IRQs are
* unregistered before dci (which contains the IRQ handler's
* data via dci->pvt_info) is freed, avoiding a use-after-free.
*/
devres_release_group(edac->dev, NULL);
edac_device_free_ctl_info(dci);
goto err_print;
err_release_group:
devres_release_group(edac->dev, NULL);
err_print:
edac_printk(KERN_ERR, EDAC_DEVICE,
"%s:Error setting up EDAC device: %d\n", ecc_name, rc);
@ -2214,6 +2216,7 @@ static struct platform_driver altr_edac_a10_driver = {
.driver = {
.name = "socfpga_a10_ecc_manager",
.of_match_table = altr_edac_a10_of_match,
.suppress_bind_attrs = true,
},
};
module_platform_driver(altr_edac_a10_driver);

View File

@ -953,6 +953,7 @@ static void mc_remove(struct platform_device *pdev)
remove_versalnet(priv);
rproc_shutdown(priv->mcdi->r5_rproc);
cdx_mcdi_finish(priv->mcdi);
rproc_put(priv->mcdi->r5_rproc);
kfree(priv->mcdi);
}

View File

@ -199,6 +199,7 @@ static int gpio_exar_probe(struct platform_device *pdev)
index = ida_alloc(&ida_index, GFP_KERNEL);
if (index < 0)
return index;
exar_gpio->index = index;
ret = devm_add_action_or_reset(dev, exar_devm_ida_free, exar_gpio);
if (ret)
@ -214,7 +215,6 @@ static int gpio_exar_probe(struct platform_device *pdev)
exar_gpio->gpio_chip.set = exar_set_value;
exar_gpio->gpio_chip.base = -1;
exar_gpio->gpio_chip.ngpio = ngpios;
exar_gpio->index = index;
exar_gpio->first_pin = first_pin;
ret = devm_gpiochip_add_data(dev, &exar_gpio->gpio_chip, exar_gpio);

View File

@ -10,6 +10,7 @@
#include <linux/cleanup.h>
#include <linux/gpio/driver.h>
#include <linux/mutex.h>
#include <linux/rcupdate.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
@ -24,6 +25,7 @@ struct mpsse_priv {
raw_spinlock_t irq_spin; /* protects worker list */
atomic_t irq_type[16]; /* pin -> edge detection type */
atomic_t irq_enabled;
atomic_t dying; /* no new workers after disconnect */
int id;
u8 gpio_outputs[2]; /* Output states for GPIOs [L, H] */
@ -46,6 +48,7 @@ struct mpsse_worker {
atomic_t cancelled;
struct list_head list; /* linked list */
struct list_head destroy; /* teardown linked list */
struct rcu_head rcu; /* deferred free for dying path */
};
struct bulk_desc {
@ -525,10 +528,24 @@ static void gpio_mpsse_irq_enable(struct irq_data *irqd)
worker->priv = priv;
INIT_LIST_HEAD(&worker->list);
INIT_WORK(&worker->work, gpio_mpsse_poll);
schedule_work(&worker->work);
scoped_guard(raw_spinlock_irqsave, &priv->irq_spin)
scoped_guard(raw_spinlock_irqsave, &priv->irq_spin) {
if (atomic_read(&priv->dying)) {
/*
* Cannot kfree() here: this callback
* runs with the IRQ descriptor's raw
* spinlock held and kfree() may sleep
* on PREEMPT_RT. The worker is not
* yet published, so the deferred free
* is unobservable.
*/
kfree_rcu(worker, rcu);
return;
}
list_add(&worker->list, &priv->workers);
schedule_work(&worker->work);
}
}
}
@ -704,6 +721,9 @@ static void gpio_mpsse_disconnect(struct usb_interface *intf)
{
struct mpsse_priv *priv = usb_get_intfdata(intf);
scoped_guard(raw_spinlock_irqsave, &priv->irq_spin)
atomic_set(&priv->dying, 1);
/*
* Lock prevents double-free of worker from here and the teardown
* step at the beginning of gpio_mpsse_poll

View File

@ -271,14 +271,7 @@ static void xgpio_save_regs(struct xgpio_instance *chip)
static int xgpio_request(struct gpio_chip *chip, unsigned int offset)
{
int ret;
ret = pm_runtime_get_sync(chip->parent);
/*
* If the device is already active pm_runtime_get() will return 1 on
* success, but gpio_request still needs to return 0.
*/
return ret < 0 ? ret : 0;
return pm_runtime_resume_and_get(chip->parent);
}
static void xgpio_free(struct gpio_chip *chip, unsigned int offset)

View File

@ -318,7 +318,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
acp_genpd_add_device);
if (r)
goto failure;
goto failure_remove_mfd;
break;
}
default:
@ -443,7 +443,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
acp_genpd_add_device);
if (r)
goto failure;
goto failure_remove_mfd;
}
/* Assert Soft reset of ACP */
@ -461,7 +461,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
if (--count == 0) {
dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
r = -ETIMEDOUT;
goto failure;
goto failure_remove_mfd;
}
udelay(100);
}
@ -479,7 +479,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
if (--count == 0) {
dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
r = -ETIMEDOUT;
goto failure;
goto failure_remove_mfd;
}
udelay(100);
}
@ -489,6 +489,11 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block)
cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
return 0;
failure_remove_mfd:
device_for_each_child(adev->acp.parent, NULL,
acp_genpd_remove_device);
mfd_remove_devices(adev->acp.parent);
failure:
kfree(adev->acp.i2s_pdata);
kfree(adev->acp.acp_res);

View File

@ -1325,6 +1325,8 @@ static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev,
ip_hw_instance->kobj.kset = &ip_hw_id->hw_id_kset;
res = kobject_add(&ip_hw_instance->kobj, NULL,
"%d", ip_hw_instance->num_instance);
if (res)
kobject_put(&ip_hw_instance->kobj);
next_ip:
if (reg_base_64)
ip_offset += struct_size(ip, base_address_64,

View File

@ -2664,6 +2664,14 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev)
struct amdgpu_device *adev = drm_to_adev(drm_dev);
int r;
/*
* A GPU parked by vga_switcheroo has no power and no PCIe link, so the
* ASIC reset below would fail and abort the whole noirq suspend phase.
* Bail out like amdgpu_device_prepare/suspend/resume() already do.
*/
if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
if (amdgpu_acpi_should_gpu_reset(adev)) {
amdgpu_device_lock_reset_domain(adev->reset_domain);
r = amdgpu_asic_reset(adev);

View File

@ -724,8 +724,14 @@ void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
bool is_guilty_fence;
bool is_guilty_context;
last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
last_seq = amdgpu_fence_read(ring);
seq = ring->fence_drv.sync_seq;
/* Hardware completion can precede the interrupt which signals fences. */
if (last_seq == seq) {
amdgpu_fence_process(ring);
return;
}
/* If there is nothing to reemit, return early and set an error on the fence
* if applicable. If all of the fences are siganlled, this will be a nop.
@ -733,7 +739,9 @@ void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
* we are skipping it on purpose.
*/
if (!ring->ring_backup_entries_to_copy) {
amdgpu_fence_driver_force_completion(ring, &guilty_fence->base);
if (guilty_fence)
amdgpu_fence_driver_force_completion(ring,
&guilty_fence->base);
return;
}
ring->reemit = true;
@ -741,9 +749,8 @@ void amdgpu_ring_set_fence_errors_and_reemit(struct amdgpu_ring *ring,
spin_lock_irqsave(&ring->fence_drv.lock, flags);
do {
last_seq++;
last_seq &= ring->fence_drv.num_fences_mask;
ptr = &ring->fence_drv.fences[last_seq];
ptr = &ring->fence_drv.fences[last_seq & ring->fence_drv.num_fences_mask];
rcu_read_lock();
unprocessed = rcu_dereference(*ptr);
@ -800,26 +807,24 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
struct amdgpu_fence *fence;
u32 seq, last_seq;
last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
last_seq = amdgpu_fence_read(ring);
seq = ring->fence_drv.sync_seq;
ring->ring_backup_entries_to_copy = 0;
/* if we've already seen this fence, return early.
* ring->ring_backup_entries_to_copy is set to 0 so
* the reemit helper will return early as well to
* avoid getting stuck in a reemit loop.
/*
* Avoid replay loops for a repeated guilty fence. NULL identifies a
* collateral ring, whose pending commands still need backup.
*/
if (ring->guilty_fence == guilty_fence) {
if (guilty_fence && ring->guilty_fence == guilty_fence) {
ring->guilty_fence = NULL;
return;
}
ring->guilty_fence = guilty_fence;
do {
while (last_seq != seq) {
last_seq++;
last_seq &= ring->fence_drv.num_fences_mask;
ptr = &ring->fence_drv.fences[last_seq];
ptr = &ring->fence_drv.fences[last_seq & ring->fence_drv.num_fences_mask];
rcu_read_lock();
unprocessed = rcu_dereference(*ptr);
@ -829,7 +834,7 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
amdgpu_ring_backup_unprocessed_command(ring, fence);
}
rcu_read_unlock();
} while (last_seq != seq);
}
}
struct amdgpu_fence *

View File

@ -2342,7 +2342,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
{
struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
u32 num_clear_entities, num_move_entities;
u32 num_clear_entities, num_move_entities, sdma_ip_version;
int r, i, j;
if (!adev->mman.initialized || amdgpu_in_reset(adev) ||
@ -2367,6 +2367,12 @@ void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
/* TODO: workaround for DCC corruption when moving BOs from multiple queues at
* the same time: use a single queue until the root cause is identified and fixed.
*/
sdma_ip_version = amdgpu_ip_version(adev, SDMA0_HWIP, 0);
if (sdma_ip_version == IP_VERSION(7, 0, 0) || sdma_ip_version == IP_VERSION(7, 0, 1))
num_move_entities = 1;
adev->mman.clear_entities = kzalloc_objs(struct amdgpu_ttm_buffer_entity,
num_clear_entities);

View File

@ -3808,6 +3808,7 @@ static int gfx_v11_0_cp_gfx_resume(struct amdgpu_device *adev)
rb_bufsz = order_base_2(ring->ring_size / 8);
tmp = REG_SET_FIELD(0, CP_RB0_CNTL, RB_BUFSZ, rb_bufsz);
tmp = REG_SET_FIELD(tmp, CP_RB0_CNTL, RB_BLKSZ, rb_bufsz - 2);
tmp = REG_SET_FIELD(tmp, CP_RB0_CNTL, KMD_QUEUE, 1);
WREG32_SOC15(GC, 0, regCP_RB0_CNTL, tmp);
/* Initialize the ring buffer's write pointers */
@ -4216,6 +4217,7 @@ static int gfx_v11_0_gfx_mqd_init(struct amdgpu_device *adev, void *m,
tmp = regCP_GFX_HQD_CNTL_DEFAULT;
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BUFSZ, rb_bufsz);
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BLKSZ, rb_bufsz - 2);
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, KMD_QUEUE, prop->kernel_queue);
#ifdef __BIG_ENDIAN
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, BUF_SWAP, 1);
#endif

View File

@ -2767,6 +2767,7 @@ static int gfx_v12_0_cp_gfx_resume(struct amdgpu_device *adev)
rb_bufsz = order_base_2(ring->ring_size / 8);
tmp = REG_SET_FIELD(0, CP_RB0_CNTL, RB_BUFSZ, rb_bufsz);
tmp = REG_SET_FIELD(tmp, CP_RB0_CNTL, RB_BLKSZ, rb_bufsz - 2);
tmp = REG_SET_FIELD(tmp, CP_RB0_CNTL, KMD_QUEUE, 1);
WREG32_SOC15(GC, 0, regCP_RB0_CNTL, tmp);
/* Initialize the ring buffer's write pointers */
@ -3059,6 +3060,7 @@ static int gfx_v12_0_gfx_mqd_init(struct amdgpu_device *adev, void *m,
tmp = regCP_GFX_HQD_CNTL_DEFAULT;
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BUFSZ, rb_bufsz);
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BLKSZ, rb_bufsz - 2);
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, KMD_QUEUE, prop->kernel_queue);
#ifdef __BIG_ENDIAN
tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, BUF_SWAP, 1);
#endif

View File

@ -322,6 +322,14 @@ static const u32 verde_rlc_save_restore_register_list[] =
0x00000000
};
static void gfx_v6_0_free_microcode(struct amdgpu_device *adev)
{
amdgpu_ucode_release(&adev->gfx.pfp_fw);
amdgpu_ucode_release(&adev->gfx.me_fw);
amdgpu_ucode_release(&adev->gfx.ce_fw);
amdgpu_ucode_release(&adev->gfx.rlc_fw);
}
static int gfx_v6_0_init_microcode(struct amdgpu_device *adev)
{
const char *chip_name;
@ -3249,6 +3257,7 @@ static int gfx_v6_0_sw_fini(struct amdgpu_ip_block *ip_block)
amdgpu_ring_fini(&adev->gfx.compute_ring[i]);
amdgpu_gfx_rlc_fini(adev);
gfx_v6_0_free_microcode(adev);
return 0;
}

View File

@ -327,7 +327,7 @@ static void gmc_v12_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
return;
}
gmc_v12_0_flush_vm_hub(adev, vmid, vmhub, 0);
gmc_v12_0_flush_vm_hub(adev, vmid, vmhub, flush_type);
return;
}

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