This is the start of the stable review cycle for the 4.14.268 release.
There are 45 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Wed, 23 Feb 2022 08:48:58 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.268-r…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 4.14.268-rc1
Marc St-Amand <mstamand(a)ciena.com>
net: macb: Align the dma and coherent dma masks
Slark Xiao <slark_xiao(a)163.com>
net: usb: qmi_wwan: Add support for Dell DW5829e
JaeSang Yoo <js.yoo.5b(a)gmail.com>
tracing: Fix tp_printk option related with tp_printk_stop_on_boot
Zoltán Böszörményi <zboszor(a)gmail.com>
ata: libata-core: Disable TRIM on M88V29
Wan Jiabing <wanjiabing(a)vivo.com>
ARM: OMAP2+: hwmod: Add of_node_put() before break
Trond Myklebust <trond.myklebust(a)hammerspace.com>
NFS: Do not report writeback errors in nfs_getattr()
Jim Mattson <jmattson(a)google.com>
KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW
david regan <dregan(a)mail.com>
mtd: rawnand: brcmnand: Fixed incorrect sub-page ECC status
Kamal Dasu <kdasu.kdev(a)gmail.com>
mtd: rawnand: brcmnand: Refactored code to introduce helper functions
Rafał Miłecki <rafal(a)milecki.pl>
i2c: brcmstb: fix support for DSL and CM variants
Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
dmaengine: sh: rcar-dmac: Check for error num after setting mask
Eric Dumazet <edumazet(a)google.com>
net: sched: limit TC_ACT_REPEAT loops
Eliav Farber <farbere(a)amazon.com>
EDAC: Fix calculation of returned address and next offset in edac_align_ptr()
Trond Myklebust <trond.myklebust(a)hammerspace.com>
NFS: LOOKUP_DIRECTORY is also ok with symlinks
Anders Roxell <anders.roxell(a)linaro.org>
powerpc/lib/sstep: fix 'ptesync' build error
Mark Brown <broonie(a)kernel.org>
ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw_range()
Mark Brown <broonie(a)kernel.org>
ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw()
Takashi Iwai <tiwai(a)suse.de>
ALSA: hda: Fix missing codec probe on Shenker Dock 15
Takashi Iwai <tiwai(a)suse.de>
ALSA: hda: Fix regression on forced probe mask option
Kees Cook <keescook(a)chromium.org>
libsubcmd: Fix use-after-free for realloc(..., 0)
Eric Dumazet <edumazet(a)google.com>
bonding: fix data-races around agg_select_timer
Eric Dumazet <edumazet(a)google.com>
drop_monitor: fix data-race in dropmon_net_event / trace_napi_poll_hit
Xin Long <lucien.xin(a)gmail.com>
ping: fix the dif and sdif check in ping_lookup
Miquel Raynal <miquel.raynal(a)bootlin.com>
net: ieee802154: ca8210: Fix lifs/sifs periods
Johannes Berg <johannes.berg(a)intel.com>
iwlwifi: pcie: gen2: fix locking when "HW not ready"
Johannes Berg <johannes.berg(a)intel.com>
iwlwifi: pcie: fix locking when "HW not ready"
Seth Forshee <sforshee(a)digitalocean.com>
vsock: remove vsock from connected table when connect is interrupted by a signal
Eric W. Biederman <ebiederm(a)xmission.com>
taskstats: Cleanup the use of task->exit_code
Guillaume Nault <gnault(a)redhat.com>
xfrm: Don't accidentally set RTO_ONLINK in decode_session4()
Nicholas Bishop <nicholasbishop(a)google.com>
drm/radeon: Fix backlight control on iMac 12,1
Johannes Berg <johannes.berg(a)intel.com>
iwlwifi: fix use-after-free
Igor Pylypiv <ipylypiv(a)google.com>
Revert "module, async: async_synchronize_full() on module init iff async is used"
Darrick J. Wong <djwong(a)kernel.org>
quota: make dquot_quota_sync return errors from ->sync_fs
Darrick J. Wong <djwong(a)kernel.org>
vfs: make freeze_super abort when sync_filesystem returns error
Duoming Zhou <duoming(a)zju.edu.cn>
ax25: improve the incomplete fix to avoid UAF and NPD bugs
Yang Xu <xuyang2018.jy(a)fujitsu.com>
selftests/zram: Adapt the situation that /dev/zram0 is being used
Yang Xu <xuyang2018.jy(a)fujitsu.com>
selftests/zram01.sh: Fix compression ratio calculation
Yang Xu <xuyang2018.jy(a)fujitsu.com>
selftests/zram: Skip max_comp_streams interface on newer kernel
Miquel Raynal <miquel.raynal(a)bootlin.com>
net: ieee802154: at86rf230: Stop leaking skb's
Dāvis Mosāns <davispuh(a)gmail.com>
btrfs: send: in case of IO error log it
John David Anglin <dave.anglin(a)bell.net>
parisc: Fix sglist access in ccio-dma.c
John David Anglin <dave.anglin(a)bell.net>
parisc: Fix data TLB miss in sba_unmap_sg
Randy Dunlap <rdunlap(a)infradead.org>
serial: parisc: GSC: fix build when IOSAPIC is not set
Jann Horn <jannh(a)google.com>
net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup
Nathan Chancellor <nathan(a)kernel.org>
Makefile.extrawarn: Move -Wunaligned-access to W=1
-------------
Diffstat:
Makefile | 4 +-
arch/arm/mach-omap2/omap_hwmod.c | 4 +-
arch/powerpc/lib/sstep.c | 2 +
arch/x86/kvm/pmu.c | 2 +-
drivers/ata/libata-core.c | 1 +
drivers/dma/sh/rcar-dmac.c | 4 +-
drivers/edac/edac_mc.c | 2 +-
drivers/gpu/drm/radeon/atombios_encoders.c | 3 +-
drivers/i2c/busses/i2c-brcmstb.c | 2 +-
drivers/mtd/nand/brcmnand/brcmnand.c | 102 ++++++++++------
drivers/net/bonding/bond_3ad.c | 30 ++++-
drivers/net/ethernet/cadence/macb_main.c | 2 +-
drivers/net/ieee802154/at86rf230.c | 13 +-
drivers/net/ieee802154/ca8210.c | 4 +-
drivers/net/usb/ax88179_178a.c | 68 ++++++-----
drivers/net/usb/qmi_wwan.c | 2 +
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 2 +
.../net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 3 +-
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +-
drivers/parisc/ccio-dma.c | 3 +-
drivers/parisc/sba_iommu.c | 3 +-
drivers/tty/serial/8250/8250_gsc.c | 2 +-
fs/btrfs/send.c | 4 +
fs/nfs/dir.c | 4 +-
fs/nfs/inode.c | 7 +-
fs/quota/dquot.c | 11 +-
fs/super.c | 19 +--
include/linux/sched.h | 1 -
include/net/bond_3ad.h | 2 +-
kernel/async.c | 3 -
kernel/module.c | 25 +---
kernel/trace/trace.c | 4 +
kernel/tsacct.c | 7 +-
net/ax25/af_ax25.c | 9 +-
net/core/drop_monitor.c | 11 +-
net/ipv4/ping.c | 11 +-
net/ipv4/xfrm4_policy.c | 3 +-
net/sched/act_api.c | 13 +-
net/vmw_vsock/af_vsock.c | 1 +
scripts/Makefile.extrawarn | 1 +
sound/pci/hda/hda_intel.c | 5 +-
sound/soc/soc-ops.c | 29 +++--
tools/lib/subcmd/subcmd-util.h | 11 +-
tools/testing/selftests/zram/zram.sh | 15 +--
tools/testing/selftests/zram/zram01.sh | 33 ++---
tools/testing/selftests/zram/zram02.sh | 1 -
tools/testing/selftests/zram/zram_lib.sh | 134 ++++++++++++++-------
47 files changed, 371 insertions(+), 254 deletions(-)
My Name is Scott Godfrey. I wish to inform you that The sum of $2,500,000(Million)has been donated to you.I
won a fortune of $699.8 Million in the Million Dollars Power-Ball Jackpot Lottery,2021.And I am
donating part of it to five lucky people and five Charity
organization. Your email came out victorious. Please contact via email: scottgodfrey.net(a)gmail.com. For more information about your claims. Thanks.
--
This email has been checked for viruses by AVG.
https://www.avg.com
commit aceeafefff736057e8f93f19bbfbef26abd94604 upstream
Adds a driver private tee_context to struct optee.
The new driver internal tee_context is used when allocating driver
private shared memory. This decouples the shared memory object from its
original tee_context. This is needed when the life time of such a memory
allocation outlives the client tee_context.
This patch fixes the problem described below:
The addition of a shutdown hook by commit f25889f93184 ("optee: fix tee out
of memory failure seen during kexec reboot") introduced a kernel shutdown
regression that can be triggered after running the OP-TEE xtest suites.
Once the shutdown hook is called it is not possible to communicate any more
with the supplicant process because the system is not scheduling task any
longer. Thus if the optee driver shutdown path receives a supplicant RPC
request from the OP-TEE we will deadlock the kernel's shutdown.
Fixes: f25889f93184 ("optee: fix tee out of memory failure seen during kexec reboot")
Fixes: 217e0250cccb ("tee: use reference counting for tee_context")
Reported-by: Lars Persson <larper(a)axis.com>
Cc: stable(a)vger.kernel.org # 1e2c3ef0496e tee: export teedev_open() and teedev_close_context()
Cc: stable(a)vger.kernel.org
Reviewed-by: Sumit Garg <sumit.garg(a)linaro.org>
[JW: backport to 5.15-stable + update commit message]
Signed-off-by: Jens Wiklander <jens.wiklander(a)linaro.org>
---
Hi,
This is an update to the previous patch posted with the same name.
Please note that this patch depends on 1e2c3ef0496e ("tee: export
teedev_open() and teedev_close_context()") which needs be cherry-picked
before this patch is applied.
Thanks,
Jens
drivers/tee/optee/core.c | 8 ++++++++
drivers/tee/optee/optee_private.h | 2 ++
drivers/tee/optee/rpc.c | 8 +++++---
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 5363ebebfc35..50c0d839fe75 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -588,6 +588,7 @@ static int optee_remove(struct platform_device *pdev)
/* Unregister OP-TEE specific client devices on TEE bus */
optee_unregister_devices();
+ teedev_close_context(optee->ctx);
/*
* Ask OP-TEE to free all cached shared memory objects to decrease
* reference counters and also avoid wild pointers in secure world
@@ -633,6 +634,7 @@ static int optee_probe(struct platform_device *pdev)
struct optee *optee = NULL;
void *memremaped_shm = NULL;
struct tee_device *teedev;
+ struct tee_context *ctx;
u32 sec_caps;
int rc;
@@ -719,6 +721,12 @@ static int optee_probe(struct platform_device *pdev)
optee_supp_init(&optee->supp);
optee->memremaped_shm = memremaped_shm;
optee->pool = pool;
+ ctx = teedev_open(optee->teedev);
+ if (IS_ERR(ctx)) {
+ rc = PTR_ERR(ctx);
+ goto err;
+ }
+ optee->ctx = ctx;
/*
* Ensure that there are no pre-existing shm objects before enabling
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index f6bb4a763ba9..ea09533e30cd 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -70,6 +70,7 @@ struct optee_supp {
* struct optee - main service struct
* @supp_teedev: supplicant device
* @teedev: client device
+ * @ctx: driver internal TEE context
* @invoke_fn: function to issue smc or hvc
* @call_queue: queue of threads waiting to call @invoke_fn
* @wait_queue: queue of threads from secure world waiting for a
@@ -87,6 +88,7 @@ struct optee {
struct tee_device *supp_teedev;
struct tee_device *teedev;
optee_invoke_fn *invoke_fn;
+ struct tee_context *ctx;
struct optee_call_queue call_queue;
struct optee_wait_queue wait_queue;
struct optee_supp supp;
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index efbaff7ad7e5..456833d82007 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -285,6 +285,7 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
}
static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
+ struct optee *optee,
struct optee_msg_arg *arg,
struct optee_call_ctx *call_ctx)
{
@@ -314,7 +315,8 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
shm = cmd_alloc_suppl(ctx, sz);
break;
case OPTEE_RPC_SHM_TYPE_KERNEL:
- shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
+ shm = tee_shm_alloc(optee->ctx, sz,
+ TEE_SHM_MAPPED | TEE_SHM_PRIV);
break;
default:
arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -471,7 +473,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
break;
case OPTEE_RPC_CMD_SHM_ALLOC:
free_pages_list(call_ctx);
- handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
+ handle_rpc_func_cmd_shm_alloc(ctx, optee, arg, call_ctx);
break;
case OPTEE_RPC_CMD_SHM_FREE:
handle_rpc_func_cmd_shm_free(ctx, arg);
@@ -502,7 +504,7 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
case OPTEE_SMC_RPC_FUNC_ALLOC:
- shm = tee_shm_alloc(ctx, param->a1,
+ shm = tee_shm_alloc(optee->ctx, param->a1,
TEE_SHM_MAPPED | TEE_SHM_PRIV);
if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
reg_pair_from_64(¶m->a1, ¶m->a2, pa);
--
2.31.1
This is a note to let you know that I've just added the patch titled
driver core: Free DMA range map when device is released
to my driver-core git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
in the driver-core-linus branch.
The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the
next -rc kernel release.
If you have any questions about this process, please let me know.
From d8f7a5484f2188e9af2d9e4e587587d724501b12 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A5rten=20Lindahl?= <marten.lindahl(a)axis.com>
Date: Wed, 16 Feb 2022 10:41:28 +0100
Subject: driver core: Free DMA range map when device is released
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When unbinding/binding a driver with DMA mapped memory, the DMA map is
not freed before the driver is reloaded. This leads to a memory leak
when the DMA map is overwritten when reprobing the driver.
This can be reproduced with a platform driver having a dma-range:
dummy {
...
#address-cells = <0x2>;
#size-cells = <0x2>;
ranges;
dma-ranges = <...>;
...
};
and then unbinding/binding it:
~# echo soc:dummy >/sys/bus/platform/drivers/<driver>/unbind
DMA map object 0xffffff800b0ae540 still being held by &pdev->dev
~# echo soc:dummy >/sys/bus/platform/drivers/<driver>/bind
~# echo scan > /sys/kernel/debug/kmemleak
~# cat /sys/kernel/debug/kmemleak
unreferenced object 0xffffff800b0ae540 (size 64):
comm "sh", pid 833, jiffies 4295174550 (age 2535.352s)
hex dump (first 32 bytes):
00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 80 00 00 00 00 00 00 00 80 00 00 00 00 ................
backtrace:
[<ffffffefd1694708>] create_object.isra.0+0x108/0x344
[<ffffffefd1d1a850>] kmemleak_alloc+0x8c/0xd0
[<ffffffefd167e2d0>] __kmalloc+0x440/0x6f0
[<ffffffefd1a960a4>] of_dma_get_range+0x124/0x220
[<ffffffefd1a8ce90>] of_dma_configure_id+0x40/0x2d0
[<ffffffefd198b68c>] platform_dma_configure+0x5c/0xa4
[<ffffffefd198846c>] really_probe+0x8c/0x514
[<ffffffefd1988990>] __driver_probe_device+0x9c/0x19c
[<ffffffefd1988cd8>] device_driver_attach+0x54/0xbc
[<ffffffefd1986634>] bind_store+0xc4/0x120
[<ffffffefd19856e0>] drv_attr_store+0x30/0x44
[<ffffffefd173c9b0>] sysfs_kf_write+0x50/0x60
[<ffffffefd173c1c4>] kernfs_fop_write_iter+0x124/0x1b4
[<ffffffefd16a013c>] new_sync_write+0xdc/0x160
[<ffffffefd16a256c>] vfs_write+0x23c/0x2a0
[<ffffffefd16a2758>] ksys_write+0x64/0xec
To prevent this we should free the dma_range_map when the device is
released.
Fixes: e0d072782c73 ("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset")
Cc: stable <stable(a)vger.kernel.org>
Suggested-by: Rob Herring <robh(a)kernel.org>
Reviewed-by: Rob Herring <robh(a)kernel.org>
Signed-off-by: Mårten Lindahl <marten.lindahl(a)axis.com>
Link: https://lore.kernel.org/r/20220216094128.4025861-1-marten.lindahl@axis.com
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/base/dd.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 9eaaff2f556c..f47cab21430f 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -629,6 +629,9 @@ static int really_probe(struct device *dev, struct device_driver *drv)
drv->remove(dev);
devres_release_all(dev);
+ arch_teardown_dma_ops(dev);
+ kfree(dev->dma_range_map);
+ dev->dma_range_map = NULL;
driver_sysfs_remove(dev);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
@@ -1209,6 +1212,8 @@ static void __device_release_driver(struct device *dev, struct device *parent)
devres_release_all(dev);
arch_teardown_dma_ops(dev);
+ kfree(dev->dma_range_map);
+ dev->dma_range_map = NULL;
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
if (dev->pm_domain && dev->pm_domain->dismiss)
--
2.35.1
Expand KVM's mask for the AVIC host physical ID to the full 12 bits defined
by the architecture. The number of bits consumed by hardware is model
specific, e.g. early CPUs ignored bits 11:8, but there is no way for KVM
to enumerate the "true" size. So, KVM must allow using all bits, else it
risks rejecting completely legal x2APIC IDs on newer CPUs.
This means KVM relies on hardware to not assign x2APIC IDs that exceed the
"true" width of the field, but presumably hardware is smart enough to tie
the width to the max x2APIC ID. KVM also relies on hardware to support at
least 8 bits, as the legacy xAPIC ID is writable by software. But, those
assumptions are unavoidable due to the lack of any way to enumerate the
"true" width.
Cc: stable(a)vger.kernel.org
Cc: Maxim Levitsky <mlevitsk(a)redhat.com>
Suggested-by: Sean Christopherson <seanjc(a)google.com>
Reviewed-by: Sean Christopherson <seanjc(a)google.com>
Fixes: 44a95dae1d22 ("KVM: x86: Detect and Initialize AVIC support")
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit(a)amd.com>
---
arch/x86/kvm/svm/avic.c | 7 +------
arch/x86/kvm/svm/svm.h | 2 +-
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 90364d02f22a..e4cfd8bf4f24 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -974,17 +974,12 @@ avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, bool r)
void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
u64 entry;
- /* ID = 0xff (broadcast), ID > 0xff (reserved) */
int h_physical_id = kvm_cpu_get_apicid(cpu);
struct vcpu_svm *svm = to_svm(vcpu);
lockdep_assert_preemption_disabled();
- /*
- * Since the host physical APIC id is 8 bits,
- * we can support host APIC ID upto 255.
- */
- if (WARN_ON(h_physical_id > AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK))
+ if (WARN_ON(h_physical_id & ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK))
return;
/*
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 47ef8f4a9358..cede59cd8999 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -565,7 +565,7 @@ extern struct kvm_x86_nested_ops svm_nested_ops;
#define AVIC_LOGICAL_ID_ENTRY_VALID_BIT 31
#define AVIC_LOGICAL_ID_ENTRY_VALID_MASK (1 << 31)
-#define AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK (0xFFULL)
+#define AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK GENMASK_ULL(11, 0)
#define AVIC_PHYSICAL_ID_ENTRY_BACKING_PAGE_MASK (0xFFFFFFFFFFULL << 12)
#define AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK (1ULL << 62)
#define AVIC_PHYSICAL_ID_ENTRY_VALID_MASK (1ULL << 63)
--
2.25.1
commit aceeafefff736057e8f93f19bbfbef26abd94604 upstream
Adds a driver private tee_context to struct optee.
The new driver internal tee_context is used when allocating driver
private shared memory. This decouples the shared memory object from its
original tee_context. This is needed when the life time of such a memory
allocation outlives the client tee_context.
This fixes a problem where the tee_context allocated on behalf of a
process outlives the process because some longer lived driver internal
shared memory has been allocated using that tee_context.
Fixes: 217e0250cccb ("tee: use reference counting for tee_context")
Reported-by: Lars Persson <larper(a)axis.com>
Cc: stable(a)vger.kernel.org # 1e2c3ef0496e tee: export teedev_open() and teedev_close_context()
Cc: stable(a)vger.kernel.org
Reviewed-by: Sumit Garg <sumit.garg(a)linaro.org>
[JW: backport to 5.4-stable + update commit message]
Signed-off-by: Jens Wiklander <jens.wiklander(a)linaro.org>
---
Hi,
This is an update to the previous patch posted with the same name.
Please note that this patch depends on 1e2c3ef0496e ("tee: export
teedev_open() and teedev_close_context()") which needs be cherry-picked
before this patch is applied.
This differs from the previous backports (5.16, 5.15, 5.10) in the way that
f25889f93184 ("optee: fix tee out of memory failure seen during kexec
reboot") isn't in this branch. So we can't claim to fix that problem, but
this patch still makes sense since the lifetime problem can manifest itself
in other ways too.
Thanks,
Jens
drivers/tee/optee/core.c | 8 ++++++++
drivers/tee/optee/optee_private.h | 2 ++
drivers/tee/optee/rpc.c | 8 +++++---
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 5eaef45799e6..344f48c90918 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -552,6 +552,7 @@ static struct optee *optee_probe(struct device_node *np)
struct optee *optee = NULL;
void *memremaped_shm = NULL;
struct tee_device *teedev;
+ struct tee_context *ctx;
u32 sec_caps;
int rc;
@@ -631,6 +632,12 @@ static struct optee *optee_probe(struct device_node *np)
optee_supp_init(&optee->supp);
optee->memremaped_shm = memremaped_shm;
optee->pool = pool;
+ ctx = teedev_open(optee->teedev);
+ if (IS_ERR(ctx)) {
+ rc = PTR_ERR(ctx);
+ goto err;
+ }
+ optee->ctx = ctx;
/*
* Ensure that there are no pre-existing shm objects before enabling
@@ -667,6 +674,7 @@ static struct optee *optee_probe(struct device_node *np)
static void optee_remove(struct optee *optee)
{
+ teedev_close_context(optee->ctx);
/*
* Ask OP-TEE to free all cached shared memory objects to decrease
* reference counters and also avoid wild pointers in secure world
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 54c3fa01d002..0250cfde6312 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -69,6 +69,7 @@ struct optee_supp {
* struct optee - main service struct
* @supp_teedev: supplicant device
* @teedev: client device
+ * @ctx: driver internal TEE context
* @invoke_fn: function to issue smc or hvc
* @call_queue: queue of threads waiting to call @invoke_fn
* @wait_queue: queue of threads from secure world waiting for a
@@ -83,6 +84,7 @@ struct optee {
struct tee_device *supp_teedev;
struct tee_device *teedev;
optee_invoke_fn *invoke_fn;
+ struct tee_context *ctx;
struct optee_call_queue call_queue;
struct optee_wait_queue wait_queue;
struct optee_supp supp;
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index aecf62016e7b..be45ee620299 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -191,6 +191,7 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
}
static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
+ struct optee *optee,
struct optee_msg_arg *arg,
struct optee_call_ctx *call_ctx)
{
@@ -220,7 +221,8 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
shm = cmd_alloc_suppl(ctx, sz);
break;
case OPTEE_MSG_RPC_SHM_TYPE_KERNEL:
- shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
+ shm = tee_shm_alloc(optee->ctx, sz,
+ TEE_SHM_MAPPED | TEE_SHM_PRIV);
break;
default:
arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -377,7 +379,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
break;
case OPTEE_MSG_RPC_CMD_SHM_ALLOC:
free_pages_list(call_ctx);
- handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
+ handle_rpc_func_cmd_shm_alloc(ctx, optee, arg, call_ctx);
break;
case OPTEE_MSG_RPC_CMD_SHM_FREE:
handle_rpc_func_cmd_shm_free(ctx, arg);
@@ -405,7 +407,7 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
case OPTEE_SMC_RPC_FUNC_ALLOC:
- shm = tee_shm_alloc(ctx, param->a1,
+ shm = tee_shm_alloc(optee->ctx, param->a1,
TEE_SHM_MAPPED | TEE_SHM_PRIV);
if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
reg_pair_from_64(¶m->a1, ¶m->a2, pa);
--
2.31.1
commit aceeafefff736057e8f93f19bbfbef26abd94604 upstream
Adds a driver private tee_context to struct optee.
The new driver internal tee_context is used when allocating driver
private shared memory. This decouples the shared memory object from its
original tee_context. This is needed when the life time of such a memory
allocation outlives the client tee_context.
This patch fixes the problem described below:
The addition of a shutdown hook by commit f25889f93184 ("optee: fix tee out
of memory failure seen during kexec reboot") introduced a kernel shutdown
regression that can be triggered after running the OP-TEE xtest suites.
Once the shutdown hook is called it is not possible to communicate any more
with the supplicant process because the system is not scheduling task any
longer. Thus if the optee driver shutdown path receives a supplicant RPC
request from the OP-TEE we will deadlock the kernel's shutdown.
Fixes: f25889f93184 ("optee: fix tee out of memory failure seen during kexec reboot")
Fixes: 217e0250cccb ("tee: use reference counting for tee_context")
Reported-by: Lars Persson <larper(a)axis.com>
Cc: stable(a)vger.kernel.org # 1e2c3ef0496e tee: export teedev_open() and teedev_close_context()
Cc: stable(a)vger.kernel.org
Reviewed-by: Sumit Garg <sumit.garg(a)linaro.org>
[JW: backport to 5.10-stable + update commit message]
Signed-off-by: Jens Wiklander <jens.wiklander(a)linaro.org>
---
Hi,
This is an update to the previous patch posted with the same name.
Please note that this patch depends on 1e2c3ef0496e ("tee: export
teedev_open() and teedev_close_context()") which needs be cherry-picked
before this patch is applied.
Thanks,
Jens
drivers/tee/optee/core.c | 8 ++++++++
drivers/tee/optee/optee_private.h | 2 ++
drivers/tee/optee/rpc.c | 8 +++++---
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index f255a96ae5a4..6ea80add7378 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -588,6 +588,7 @@ static int optee_remove(struct platform_device *pdev)
/* Unregister OP-TEE specific client devices on TEE bus */
optee_unregister_devices();
+ teedev_close_context(optee->ctx);
/*
* Ask OP-TEE to free all cached shared memory objects to decrease
* reference counters and also avoid wild pointers in secure world
@@ -633,6 +634,7 @@ static int optee_probe(struct platform_device *pdev)
struct optee *optee = NULL;
void *memremaped_shm = NULL;
struct tee_device *teedev;
+ struct tee_context *ctx;
u32 sec_caps;
int rc;
@@ -719,6 +721,12 @@ static int optee_probe(struct platform_device *pdev)
optee_supp_init(&optee->supp);
optee->memremaped_shm = memremaped_shm;
optee->pool = pool;
+ ctx = teedev_open(optee->teedev);
+ if (IS_ERR(ctx)) {
+ rc = PTR_ERR(ctx);
+ goto err;
+ }
+ optee->ctx = ctx;
/*
* Ensure that there are no pre-existing shm objects before enabling
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index f6bb4a763ba9..ea09533e30cd 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -70,6 +70,7 @@ struct optee_supp {
* struct optee - main service struct
* @supp_teedev: supplicant device
* @teedev: client device
+ * @ctx: driver internal TEE context
* @invoke_fn: function to issue smc or hvc
* @call_queue: queue of threads waiting to call @invoke_fn
* @wait_queue: queue of threads from secure world waiting for a
@@ -87,6 +88,7 @@ struct optee {
struct tee_device *supp_teedev;
struct tee_device *teedev;
optee_invoke_fn *invoke_fn;
+ struct tee_context *ctx;
struct optee_call_queue call_queue;
struct optee_wait_queue wait_queue;
struct optee_supp supp;
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index 9dbdd783d6f2..f1e0332b0f6e 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -284,6 +284,7 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
}
static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
+ struct optee *optee,
struct optee_msg_arg *arg,
struct optee_call_ctx *call_ctx)
{
@@ -313,7 +314,8 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
shm = cmd_alloc_suppl(ctx, sz);
break;
case OPTEE_MSG_RPC_SHM_TYPE_KERNEL:
- shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
+ shm = tee_shm_alloc(optee->ctx, sz,
+ TEE_SHM_MAPPED | TEE_SHM_PRIV);
break;
default:
arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -470,7 +472,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
break;
case OPTEE_MSG_RPC_CMD_SHM_ALLOC:
free_pages_list(call_ctx);
- handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
+ handle_rpc_func_cmd_shm_alloc(ctx, optee, arg, call_ctx);
break;
case OPTEE_MSG_RPC_CMD_SHM_FREE:
handle_rpc_func_cmd_shm_free(ctx, arg);
@@ -501,7 +503,7 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
case OPTEE_SMC_RPC_FUNC_ALLOC:
- shm = tee_shm_alloc(ctx, param->a1,
+ shm = tee_shm_alloc(optee->ctx, param->a1,
TEE_SHM_MAPPED | TEE_SHM_PRIV);
if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
reg_pair_from_64(¶m->a1, ¶m->a2, pa);
--
2.31.1
There is a limited amount of SGX memory (EPC) on each system. When that
memory is used up, SGX has its own swapping mechanism which is similar
in concept but totally separate from the core mm/* code. Instead of
swapping to disk, SGX swaps from EPC to normal RAM. That normal RAM
comes from a shared memory pseudo-file and can itself be swapped by the
core mm code. There is a hierarchy like this:
EPC <-> shmem <-> disk
After data is swapped back in from shmem to EPC, the shmem backing
storage needs to be freed. Currently, the backing shmem is not freed.
This effectively wastes the shmem while the enclave is running. The
memory is recovered when the enclave is destroyed and the backing
storage freed.
Sort this out by freeing memory with shmem_truncate_range(), as soon as
a page is faulted back to the EPC. In addition, free the memory for
PCMD pages as soon as all PCMD's in a page have been marked as unused
by zeroing its contents.
Reported-by: Dave Hansen <dave.hansen(a)linux.intel.com>
Cc: stable(a)vger.kernel.org
Fixes: 1728ab54b4be ("x86/sgx: Add a page reclaimer")
Signed-off-by: Jarkko Sakkinen <jarkko(a)kernel.org>
---
v3:
* Resend.
v2:
* Rewrite commit message as proposed by Dave.
* Truncate PCMD pages (Dave).
---
arch/x86/kernel/cpu/sgx/encl.c | 48 +++++++++++++++++++++++++++++++---
1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
index 001808e3901c..ea43c10e5458 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
@@ -12,6 +12,27 @@
#include "encls.h"
#include "sgx.h"
+
+/*
+ * Get the page number of the page in the backing storage, which stores the PCMD
+ * of the enclave page in the given page index. PCMD pages are located after
+ * the backing storage for the visible enclave pages and SECS.
+ */
+static inline pgoff_t sgx_encl_get_backing_pcmd_nr(struct sgx_encl *encl, pgoff_t index)
+{
+ return PFN_DOWN(encl->size) + 1 + (index / sizeof(struct sgx_pcmd));
+}
+
+/*
+ * Free a page from the backing storage in the given page index.
+ */
+static inline void sgx_encl_truncate_backing_page(struct sgx_encl *encl, pgoff_t index)
+{
+ struct inode *inode = file_inode(encl->backing);
+
+ shmem_truncate_range(inode, PFN_PHYS(index), PFN_PHYS(index) + PAGE_SIZE - 1);
+}
+
/*
* ELDU: Load an EPC page as unblocked. For more info, see "OS Management of EPC
* Pages" in the SDM.
@@ -24,7 +45,10 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
struct sgx_encl *encl = encl_page->encl;
struct sgx_pageinfo pginfo;
struct sgx_backing b;
+ bool pcmd_page_empty;
pgoff_t page_index;
+ pgoff_t pcmd_index;
+ u8 *pcmd_page;
int ret;
if (secs_page)
@@ -38,8 +62,8 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
pginfo.addr = encl_page->desc & PAGE_MASK;
pginfo.contents = (unsigned long)kmap_atomic(b.contents);
- pginfo.metadata = (unsigned long)kmap_atomic(b.pcmd) +
- b.pcmd_offset;
+ pcmd_page = kmap_atomic(b.pcmd);
+ pginfo.metadata = (unsigned long)pcmd_page + b.pcmd_offset;
if (secs_page)
pginfo.secs = (u64)sgx_get_epc_virt_addr(secs_page);
@@ -55,11 +79,27 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
ret = -EFAULT;
}
- kunmap_atomic((void *)(unsigned long)(pginfo.metadata - b.pcmd_offset));
+ memset(pcmd_page + b.pcmd_offset, 0, sizeof(struct sgx_pcmd));
+
+ /*
+ * The area for the PCMD in the page was zeroed above. Check if the
+ * whole page is now empty meaning that all PCMD's have been zeroed:
+ */
+ pcmd_page_empty = !memchr_inv(pcmd_page, 0, PAGE_SIZE);
+
+ kunmap_atomic(pcmd_page);
kunmap_atomic((void *)(unsigned long)pginfo.contents);
sgx_encl_put_backing(&b, false);
+ /* Free the backing memory. */
+ sgx_encl_truncate_backing_page(encl, page_index);
+
+ if (pcmd_page_empty) {
+ pcmd_index = sgx_encl_get_backing_pcmd_nr(encl, page_index);
+ sgx_encl_truncate_backing_page(encl, pcmd_index);
+ }
+
return ret;
}
@@ -577,7 +617,7 @@ static struct page *sgx_encl_get_backing_page(struct sgx_encl *encl,
int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
struct sgx_backing *backing)
{
- pgoff_t pcmd_index = PFN_DOWN(encl->size) + 1 + (page_index >> 5);
+ pgoff_t pcmd_index = sgx_encl_get_backing_pcmd_nr(encl, page_index);
struct page *contents;
struct page *pcmd;
--
2.34.1