Merge d725757860 on remote branch

Change-Id: I9934c3a8e4d5c9e53b0a99af8c1238d3b6bdc3bf
This commit is contained in:
Linux Build Service Account committed 2023-05-08 05:55:07 -07:00
commit 5b412199cc
24 files changed
+339 -76

No files matched your search

+26 -9
View File
@@ -415,8 +415,8 @@ struct fastrpc_mmap {
int uncached;
int secure;
uintptr_t attr;
bool is_filemap;
/* flag to indicate map used in process init */
bool is_filemap; /* flag to indicate map used in process init */
unsigned int ctx_refs; /* Indicates reference count for context map */
};
enum fastrpc_perfkeys {
@@ -862,8 +862,9 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va,
return 0;
}
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
if (map->refs == 1 && map->raddr == va &&
map->raddr + map->len == va + len &&
/* Remove if only one reference map and no context map */
if (map->refs == 1 && !map->ctx_refs &&
map->raddr == va && map->raddr + map->len == va + len &&
/* Remove map if not used in process initialization */
!map->is_filemap) {
match = map;
@@ -903,14 +904,14 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
spin_lock(&me->hlock);
map->refs--;
if (!map->refs)
if (!map->refs && !map->ctx_refs)
hlist_del_init(&map->hn);
spin_unlock(&me->hlock);
if (map->refs > 0)
return;
} else {
map->refs--;
if (!map->refs)
if (!map->refs && !map->ctx_refs)
hlist_del_init(&map->hn);
if (map->refs > 0 && !flags)
return;
@@ -1008,6 +1009,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
map->fd = fd;
map->attr = attr;
map->is_filemap = false;
map->ctx_refs = 0;
if (mflags == ADSP_MMAP_HEAP_ADDR ||
mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
map->apps = me;
@@ -1533,8 +1535,11 @@ static void context_free(struct smq_invoke_ctx *ctx)
spin_unlock(&ctx->fl->hlock);
mutex_lock(&ctx->fl->map_mutex);
for (i = 0; i < nbufs; ++i)
for (i = 0; i < nbufs; ++i) {
if (ctx->maps[i] && ctx->maps[i]->ctx_refs)
ctx->maps[i]->ctx_refs--;
fastrpc_mmap_free(ctx->maps[i], 0);
}
mutex_unlock(&ctx->fl->map_mutex);
fastrpc_buf_free(ctx->buf, 1);
@@ -1757,6 +1762,8 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
err = fastrpc_mmap_create(ctx->fl, ctx->fds[i],
ctx->attrs[i], buf, len,
mflags, &ctx->maps[i]);
if (ctx->maps[i])
ctx->maps[i]->ctx_refs++;
mutex_unlock(&ctx->fl->map_mutex);
if (err)
goto bail;
@@ -1774,9 +1781,14 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
err = fastrpc_mmap_create(ctx->fl, ctx->fds[i],
FASTRPC_ATTR_NOVA, 0, 0, dmaflags,
&ctx->maps[i]);
if (!err && ctx->maps[i])
ctx->maps[i]->ctx_refs++;
if (err) {
for (j = bufs; j < i; j++)
for (j = bufs; j < i; j++) {
if (ctx->maps[j] && ctx->maps[j]->ctx_refs)
ctx->maps[j]->ctx_refs--;
fastrpc_mmap_free(ctx->maps[j], 0);
}
mutex_unlock(&ctx->fl->map_mutex);
goto bail;
}
@@ -2059,6 +2071,8 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
goto bail;
} else {
mutex_lock(&ctx->fl->map_mutex);
if (ctx->maps[i]->ctx_refs)
ctx->maps[i]->ctx_refs--;
fastrpc_mmap_free(ctx->maps[i], 0);
mutex_unlock(&ctx->fl->map_mutex);
ctx->maps[i] = NULL;
@@ -2070,10 +2084,13 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
if (!fdlist[i])
break;
if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0,
0, 0, &mmap))
0, 0, &mmap)) {
if (mmap && mmap->ctx_refs)
mmap->ctx_refs--;
fastrpc_mmap_free(mmap, 0);
}
}
}
mutex_unlock(&ctx->fl->map_mutex);
if (ctx->crc && crclist && rpra)
K_COPY_TO_USER(err, kernel, ctx->crc,
+1 -4
View File
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __ADRENO_H
#define __ADRENO_H
@@ -16,9 +16,6 @@
#define DEVICE_3D_NAME "kgsl-3d"
#define DEVICE_3D0_NAME "kgsl-3d0"
/* Index to preemption scratch buffer to store KMD postamble */
#define KMD_POSTAMBLE_IDX 100
/* ADRENO_DEVICE - Given a kgsl_device return the adreno device struct */
#define ADRENO_DEVICE(device) \
container_of(device, struct adreno_device, dev)
+3 -10
View File
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/* soc/qcom/cmd-db.h needs types.h */
@@ -388,19 +389,11 @@ static int a6xx_gmu_start(struct kgsl_device *device)
gmu_core_regwrite(device, A6XX_GMU_CM3_SYSRESET, 0);
/* Make sure the request completes before continuing */
wmb();
if (timed_poll_check(device,
A6XX_GMU_CM3_FW_INIT_RESULT,
val, GMU_START_TIMEOUT, mask)) {
u32 val;
/*
* The breadcrumb is written to a gmu virtual mapping
* which points to dtcm byte offset 0x3fdc.
*/
gmu_core_regread(device,
A6XX_GMU_CM3_DTCM_START + (0x3fdc >> 2), &val);
dev_err(&gmu->pdev->dev, "GMU doesn't boot: 0x%x\n", val);
dev_err(&gmu->pdev->dev, "GMU doesn't boot\n");
return -ETIMEDOUT;
}
+14 -11
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "adreno.h"
@@ -558,8 +558,8 @@ unsigned int a6xx_preemption_pre_ibsubmit(
* preemption
*/
if (!adreno_dev->perfcounter) {
u64 kmd_postamble_addr =
PREEMPT_SCRATCH_ADDR(adreno_dev, KMD_POSTAMBLE_IDX);
u64 kmd_postamble_addr = SCRATCH_POSTAMBLE_ADDR
(KGSL_DEVICE(adreno_dev));
*cmds++ = cp_type7_packet(CP_SET_AMBLE, 3);
*cmds++ = lower_32_bits(kmd_postamble_addr);
@@ -763,6 +763,8 @@ void a6xx_preemption_close(struct adreno_device *adreno_dev)
int a6xx_preemption_init(struct adreno_device *adreno_dev)
{
u32 flags = ADRENO_FEATURE(adreno_dev, ADRENO_APRIV) ?
KGSL_MEMDESC_PRIVILEGED : 0;
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct adreno_preemption *preempt = &adreno_dev->preempt;
struct adreno_ringbuffer *rb;
@@ -777,8 +779,8 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev)
timer_setup(&preempt->timer, _a6xx_preemption_timer, 0);
ret = kgsl_allocate_global(device, &preempt->scratch, PAGE_SIZE, 0, 0,
"preemption_scratch");
ret = kgsl_allocate_global(device, &preempt->scratch, PAGE_SIZE, 0,
flags, "preemption_scratch");
/* Allocate mem for storing preemption switch record */
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
@@ -788,14 +790,15 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev)
}
/*
* First 8 dwords of the preemption scratch buffer is used to store the
* address for CP to save/restore VPC data. Reserve 11 dwords in the
* preemption scratch buffer from index KMD_POSTAMBLE_IDX for KMD
* postamble pm4 packets
* First 28 dwords of the device scratch buffer are used to store
* shadow rb data. Reserve 11 dwords in the device scratch buffer
* from SCRATCH_POSTAMBLE_OFFSET for KMD postamble pm4 packets.
* This should be in *device->scratch* so that userspace cannot
* access it.
*/
if (!adreno_dev->perfcounter) {
u32 *postamble = preempt->scratch.hostptr +
(KMD_POSTAMBLE_IDX * sizeof(u64));
u32 *postamble = device->scratch.hostptr +
SCRATCH_POSTAMBLE_OFFSET;
u32 count = 0;
postamble[count++] = cp_type7_packet(CP_REG_RMW, 3);
+6
View File
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __KGSL_H
#define __KGSL_H
@@ -69,6 +70,11 @@
#define SCRATCH_RPTR_GPU_ADDR(dev, id) \
((dev)->scratch.gpuaddr + SCRATCH_RPTR_OFFSET(id))
/* OFFSET to KMD postamble packets in scratch buffer */
#define SCRATCH_POSTAMBLE_OFFSET (100 * sizeof(u64))
#define SCRATCH_POSTAMBLE_ADDR(dev) \
((dev)->scratch.gpuaddr + SCRATCH_POSTAMBLE_OFFSET)
/* Timestamp window used to detect rollovers (half of integer range) */
#define KGSL_TIMESTAMP_WINDOW 0x80000000
+28 -1
View File
@@ -5,7 +5,9 @@
#include <linux/kthread.h>
#include <linux/notifier.h>
#include <linux/pagevec.h>
#include <linux/shmem_fs.h>
#include <linux/swap.h>
#include "kgsl_reclaim.h"
#include "kgsl_sharedmem.h"
@@ -193,6 +195,12 @@ ssize_t kgsl_proc_max_reclaim_limit_show(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "%d\n", kgsl_reclaim_max_page_limit);
}
static void kgsl_release_page_vec(struct pagevec *pvec)
{
check_move_unevictable_pages(pvec->pages, pvec->nr);
__pagevec_release(pvec);
}
static int kgsl_reclaim_callback(struct notifier_block *nb,
unsigned long pid, void *data)
{
@@ -266,20 +274,39 @@ static int kgsl_reclaim_callback(struct notifier_block *nb,
if (!kgsl_mmu_unmap(memdesc->pagetable, memdesc)) {
int i;
struct pagevec pvec;
/*
* Pages that are first allocated are by default added
* to unevictable list. To reclaim them, we first clear
* the AS_UNEVICTABLE flag of the shmem file address
* space thus check_move_unevictable_pages() places
* them on the evictable list.
*
* Once reclaim is done, hint that further shmem
* allocations will have to be on the unevictable list.
*/
mapping_clear_unevictable(
memdesc->shmem_filp->f_mapping);
pagevec_init(&pvec);
for (i = 0; i < memdesc->page_count; i++) {
set_page_dirty_lock(memdesc->pages[i]);
spin_lock(&memdesc->lock);
put_page(memdesc->pages[i]);
pagevec_add(&pvec, memdesc->pages[i]);
memdesc->pages[i] = NULL;
spin_unlock(&memdesc->lock);
if (pagevec_count(&pvec) == PAGEVEC_SIZE)
kgsl_release_page_vec(&pvec);
}
if (pagevec_count(&pvec))
kgsl_release_page_vec(&pvec);
memdesc->priv |= KGSL_MEMDESC_RECLAIMED;
ret = reclaim_address_space
(memdesc->shmem_filp->f_mapping, data);
mapping_set_unevictable(memdesc->shmem_filp->f_mapping);
memdesc->reclaimed_page_count += memdesc->page_count;
atomic_add(memdesc->page_count,
&process->reclaimed_page_count);
+2
View File
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved.
*/
@@ -974,6 +975,7 @@ static int kgsl_memdesc_file_setup(struct kgsl_memdesc *memdesc, uint64_t size)
memdesc->shmem_filp = NULL;
return ret;
}
mapping_set_unevictable(memdesc->shmem_filp->f_mapping);
}
return 0;
+4
View File
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2014-2015, 2017-2019, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */
#include <linux/kernel.h>
#include <linux/module.h>
@@ -143,8 +144,11 @@ static int pmic_spmi_probe(struct spmi_device *sdev)
MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
static void pmic_spmi_remove(struct spmi_device *sdev) {}
static struct spmi_driver pmic_spmi_driver = {
.probe = pmic_spmi_probe,
.remove = pmic_spmi_remove,
.driver = {
.name = "pmic-spmi",
.of_match_table = pmic_spmi_id_table,
+91 -3
View File
@@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "aphost.h"
@@ -242,17 +242,36 @@ static ssize_t jsrequest_store(struct device *dev,
request_t request;
int vibState = 0;
int err = 0;
#ifdef COMPATIBLE_NOT_SUPPORT_DFU
unsigned int getNorVersion = 0;
#endif
if (gspi_client == NULL) {
pr_err("invalid gspi_client\n");
return size;
}
#ifdef COMPATIBLE_NOT_SUPPORT_DFU
getNorVersion = (unsigned int)
atomic_read(&gspi_client->probeGetNordicVersion);
if (getNorVersion <= 0x81000101 && getNorVersion > 0) {
pr_debug("%s DFU not supported version number:%d.%d\n",
__func__, (getNorVersion >> 8) & 0xff,
getNorVersion & 0xff);
} else {
pinctrl_select_state(
gspi_client->pinctrl_info.pinctrl,
gspi_client->pinctrl_info.suspend);
gspi_client->js_ledl_state = 1;
pr_debug("%s DFU supported version number:%d.%d\n",
__func__, (getNorVersion >> 8) & 0xff,
getNorVersion & 0xff);
}
#else
pinctrl_select_state(
gspi_client->pinctrl_info.pinctrl,
gspi_client->pinctrl_info.suspend);
gspi_client->js_ledl_state = 1;
#endif
mutex_lock(&gspi_client->js_mutex);
err = kstrtouint(buf, 16, &input);
if (err) {
@@ -529,6 +548,18 @@ static int js_thread(void *data)
| spi_client->rxbuffer[1]);
atomic_set(&spi_client->nordicAcknowledge,
input);
#ifdef COMPATIBLE_NOT_SUPPORT_DFU
if ((unsigned int)
atomic_read(
&gspi_client->probeGetNordicVersionFlag)) {
atomic_set(
&spi_client->probeGetNordicVersion,
input);
atomic_set(
&spi_client->probeGetNordicVersionFlag,
0);
}
#endif
}
memset(&lastRequest, 0, sizeof(lastRequest));
}
@@ -742,6 +773,59 @@ failed:
return ret;
}
#ifdef COMPATIBLE_NOT_SUPPORT_DFU
static int probe_get_nordic_version(void)
{
unsigned int getNorVersion = 0;
atomic_set(&gspi_client->probeGetNordicVersionFlag, 1);
atomic_set(&gspi_client->userRequest, 0x81000000);
atomic_inc(&gspi_client->dataflag);
wake_up_interruptible(&gspi_client->wait_queue);
pinctrl_select_state(
gspi_client->pinctrl_info.pinctrl,
gspi_client->pinctrl_info.suspend);
gspi_client->js_ledl_state = 1;
while (1) {
if (!((unsigned int)
atomic_read(&gspi_client->probeGetNordicVersionFlag))) {
pr_debug("nordic version flag %d userRequest 0x%x\n",
(unsigned int)atomic_read(
&gspi_client->probeGetNordicVersionFlag),
(unsigned int)atomic_read(
&gspi_client->userRequest));
getNorVersion = (unsigned int)atomic_read(
&gspi_client->probeGetNordicVersion);
pr_debug("nordic version %d.%d getNorVersion 0x%x\n",
(getNorVersion >> 8) & 0xff,
getNorVersion & 0xff, getNorVersion);
pinctrl_select_state(
gspi_client->pinctrl_info.pinctrl,
gspi_client->pinctrl_info.suspend);
gspi_client->js_ledl_state = 0;
} else {
atomic_set(&gspi_client->probeGetNordicVersionFlag, 1);
atomic_set(&gspi_client->userRequest, 0x81000000);
atomic_inc(&gspi_client->dataflag);
wake_up_interruptible(&gspi_client->wait_queue);
pinctrl_select_state(
gspi_client->pinctrl_info.pinctrl,
gspi_client->pinctrl_info.suspend);
gspi_client->js_ledl_state = 1;
pr_err("Failed to get version flag %d userRequest 0x%x\n",
(unsigned int)atomic_read(
&gspi_client->probeGetNordicVersionFlag),
(unsigned int)atomic_read(
&gspi_client->userRequest));
}
break;
}
return 0;
}
#endif
static int js_spi_setup(struct spi_device *spi)
{
struct js_spi_client *spi_client;
@@ -805,6 +889,10 @@ static int js_spi_setup(struct spi_device *spi)
js_io_init(spi_client);
js_set_power(1);
#ifdef COMPATIBLE_NOT_SUPPORT_DFU
msleep(5000);
probe_get_nordic_version();
#endif
return rc;
spi_free:
+9 -2
View File
@@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __APHOST_H__
@@ -70,12 +70,13 @@
#include <linux/string.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <uapi/linux/sched/types.h>
#define MAX_PACK_SIZE 100
#define MAX_DATA_SIZE 32
//#define MANUL_CONTROL_JOYSTICK_RLED
#define COMPATIBLE_NOT_SUPPORT_DFU
#define XFR_SIZE 190
/* Protocol commands to interact with firmware */
@@ -154,6 +155,12 @@ struct js_spi_client {
atomic_t dataflag;
atomic_t userRequest; /* request from userspace */
atomic_t nordicAcknowledge; /* ack from nordic52832 master */
#ifdef COMPATIBLE_NOT_SUPPORT_DFU
atomic_t probeGetNordicVersion; /* ack from nordic52832 master */
atomic_t probeGetNordicVersionFlag;
#endif
unsigned char JoyStickBondState; /* 1:left JoyStick 2:right JoyStick */
bool suspend;
wait_queue_head_t wait_queue;
+1 -1
View File
@@ -525,7 +525,7 @@ static int tap_open(struct inode *inode, struct file *file)
q->sock.state = SS_CONNECTED;
q->sock.file = file;
q->sock.ops = &tap_socket_ops;
sock_init_data(&q->sock, &q->sk);
sock_init_data_uid(&q->sock, &q->sk, inode->i_uid);
q->sk.sk_write_space = tap_sock_write_space;
q->sk.sk_destruct = tap_sock_destruct;
q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
+1 -1
View File
@@ -3257,7 +3257,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
tfile->socket.file = file;
tfile->socket.ops = &tun_socket_ops;
sock_init_data(&tfile->socket, &tfile->sk);
sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid);
tfile->sk.sk_write_space = tun_sock_write_space;
tfile->sk.sk_sndbuf = INT_MAX;
+4 -2
View File
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/cdev.h>
@@ -125,7 +126,6 @@ static int qiib_driver_data_init(void)
*/
static void qiib_driver_data_deinit(void)
{
qiib_cleanup();
if (!qiib_info->log_ctx)
ipc_log_context_destroy(qiib_info->log_ctx);
kfree(qiib_info);
@@ -433,8 +433,10 @@ static void qiib_cleanup(void)
}
mutex_unlock(&qiib_info->list_lock);
if (!IS_ERR_OR_NULL(qiib_info->classp))
if (!IS_ERR_OR_NULL(qiib_info->classp)) {
class_destroy(qiib_info->classp);
qiib_info->classp = NULL;
}
unregister_chrdev_region(MAJOR(qiib_info->dev_num), qiib_info->nports);
}
+2 -1
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/bitmap.h>
@@ -3601,6 +3601,7 @@ static int msm_geni_serial_remove(struct platform_device *pdev)
if (!uart_console(&port->uport)) {
wakeup_source_unregister(port->geni_wake);
port->geni_wake = NULL;
flush_workqueue(port->qwork);
destroy_workqueue(port->qwork);
}
+9 -3
View File
@@ -626,12 +626,13 @@ EXPORT_SYMBOL(fscrypt_has_permitted_context);
#define SDHCI "sdhci"
static int fscrypt_update_context(union fscrypt_context *ctx)
static int fscrypt_update_context(union fscrypt_context *ctx,
const char *file_system_type)
{
char *boot = "ufs";
if (!fscrypt_find_storage_type(&boot)) {
if (!strcmp(boot, SDHCI))
if (!strcmp(boot, SDHCI) && !strcmp(file_system_type, "f2fs"))
ctx->v1.flags |= FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32;
return 0;
}
@@ -654,6 +655,7 @@ int fscrypt_inherit_context(struct inode *parent, struct inode *child,
int ctxsize;
struct fscrypt_info *ci;
int res;
const char *file_system_type;
res = fscrypt_get_encryption_info(parent);
if (res < 0)
@@ -663,10 +665,14 @@ int fscrypt_inherit_context(struct inode *parent, struct inode *child,
if (ci == NULL)
return -ENOKEY;
file_system_type = ci->ci_inode->i_sb->s_type->name;
if (!file_system_type)
return -EINVAL;
ctxsize = fscrypt_new_context_from_policy(&ctx, &ci->ci_policy);
if (fscrypt_policy_contents_mode(&ci->ci_policy) ==
FSCRYPT_MODE_PRIVATE) {
res = fscrypt_update_context(&ctx);
res = fscrypt_update_context(&ctx, file_system_type);
if (res)
return res;
}
+6
View File
@@ -1498,6 +1498,12 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
static inline void vm_write_begin(struct vm_area_struct *vma)
{
/*
* Isolated vma might be freed without exclusive mmap_lock but
* speculative page fault handler still needs to know it was changed.
*/
if (!RB_EMPTY_NODE(&vma->vm_rb))
WARN_ON_ONCE(!rwsem_is_locked(&(vma->vm_mm)->mmap_sem));
/*
* The reads never spins and preemption
* disablement is not required.
+6 -1
View File
@@ -1686,7 +1686,12 @@ void sk_common_release(struct sock *sk);
* Default socket callbacks and setup code
*/
/* Initialise core socket variables */
/* Initialise core socket variables using an explicit uid. */
void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid);
/* Initialise core socket variables
* Assumes struct socket *sock is embedded in a struct socket_alloc.
*/
void sock_init_data(struct socket *sock, struct sock *sk);
/*
+24 -4
View File
@@ -104,14 +104,34 @@ fixup_cumulative_runnable_avg(struct walt_sched_stats *stats,
s64 demand_scaled_delta,
s64 pred_demand_scaled_delta)
{
s64 cumulative_runnable_avg_scaled;
s64 pred_demands_sum_scaled;
if (sched_disable_window_stats)
return;
stats->cumulative_runnable_avg_scaled += demand_scaled_delta;
BUG_ON((s64)stats->cumulative_runnable_avg_scaled < 0);
cumulative_runnable_avg_scaled =
(s64)stats->cumulative_runnable_avg_scaled +
demand_scaled_delta;
pred_demands_sum_scaled =
(s64)stats->pred_demands_sum_scaled + pred_demand_scaled_delta;
stats->pred_demands_sum_scaled += pred_demand_scaled_delta;
BUG_ON((s64)stats->pred_demands_sum_scaled < 0);
if (cumulative_runnable_avg_scaled < 0) {
printk_deferred("WALT-BUG demand_scaled_delta=%lld cumulative_runnable_avg_scaled=%llu\n",
demand_scaled_delta,
stats->cumulative_runnable_avg_scaled);
cumulative_runnable_avg_scaled = 0;
}
stats->cumulative_runnable_avg_scaled =
(u64)cumulative_runnable_avg_scaled;
if (pred_demands_sum_scaled < 0) {
printk_deferred("WALT-BUG task pred_demand_scaled_delta=%lld pred_demands_sum_scaled=%llu\n",
pred_demand_scaled_delta,
stats->pred_demands_sum_scaled);
pred_demands_sum_scaled = 0;
}
stats->pred_demands_sum_scaled = (u64)pred_demands_sum_scaled;
}
static inline void
+49 -1
View File
@@ -2633,7 +2633,9 @@ static struct file *do_async_mmap_readahead(struct vm_fault *vmf,
* it in the page cache, and handles the special cases reasonably without
* having a lot of duplicated code.
*
* vma->vm_mm->mmap_sem must be held on entry (except FAULT_FLAG_SPECULATIVE).
* If FAULT_FLAG_SPECULATIVE is set, this function runs with elevated vma
* refcount and with mmap lock not held.
* Otherwise, vma->vm_mm->mmap_sem must be held on entry.
*
* If our return value has VM_FAULT_RETRY set, it's because
* lock_page_or_retry() returned 0.
@@ -2658,6 +2660,52 @@ vm_fault_t filemap_fault(struct vm_fault *vmf)
struct page *page;
vm_fault_t ret = 0;
if (vmf->flags & FAULT_FLAG_SPECULATIVE) {
page = find_get_page(mapping, offset);
if (unlikely(!page))
return VM_FAULT_RETRY;
if (unlikely(PageReadahead(page)))
goto page_put;
if (!trylock_page(page))
goto page_put;
if (unlikely(compound_head(page)->mapping != mapping))
goto page_unlock;
VM_BUG_ON_PAGE(page_to_pgoff(page) != offset, page);
if (unlikely(!PageUptodate(page)))
goto page_unlock;
max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
if (unlikely(offset >= max_off))
goto page_unlock;
/*
* Update readahead mmap_miss statistic.
*
* Note that we are not sure if finish_fault() will
* manage to complete the transaction. If it fails,
* we'll come back to filemap_fault() non-speculative
* case which will update mmap_miss a second time.
* This is not ideal, we would prefer to guarantee the
* update will happen exactly once.
*/
if (!(vmf->vma->vm_flags & VM_RAND_READ) && ra->ra_pages) {
unsigned int mmap_miss = READ_ONCE(ra->mmap_miss);
if (mmap_miss)
WRITE_ONCE(ra->mmap_miss, --mmap_miss);
}
vmf->page = page;
return VM_FAULT_LOCKED;
page_unlock:
unlock_page(page);
page_put:
put_page(page);
return VM_FAULT_RETRY;
}
max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
if (unlikely(offset >= max_off))
return VM_FAULT_SIGBUS;
+2
View File
@@ -1294,10 +1294,12 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
*/
if (down_write_trylock(&mm->mmap_sem)) {
if (!khugepaged_test_exit(mm)) {
vm_write_begin(vma);
spinlock_t *ptl = pmd_lock(mm, pmd);
/* assume page table is clear */
_pmd = pmdp_collapse_flush(vma, addr, pmd);
spin_unlock(ptl);
vm_write_end(vma);
mm_dec_nr_ptes(mm);
pte_free(mm, pmd_pgtable(_pmd));
}
+23 -15
View File
@@ -1553,7 +1553,6 @@ void unmap_page_range(struct mmu_gather *tlb,
unsigned long next;
BUG_ON(addr >= end);
vm_write_begin(vma);
tlb_start_vma(tlb, vma);
pgd = pgd_offset(vma->vm_mm, addr);
do {
@@ -1563,7 +1562,6 @@ void unmap_page_range(struct mmu_gather *tlb,
next = zap_p4d_range(tlb, vma, pgd, addr, next, details);
} while (pgd++, addr = next, addr != end);
tlb_end_vma(tlb, vma);
vm_write_end(vma);
}
@@ -3207,6 +3205,11 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
int exclusive = 0;
vm_fault_t ret;
if (vmf->flags & FAULT_FLAG_SPECULATIVE) {
pte_unmap(vmf->pte);
return VM_FAULT_RETRY;
}
ret = pte_unmap_same(vmf);
if (ret) {
/*
@@ -3466,6 +3469,10 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
if (vmf->vma_flags & VM_SHARED)
return VM_FAULT_SIGBUS;
/* Do not check unstable pmd, if it's changed will retry later */
if (vmf->flags & FAULT_FLAG_SPECULATIVE)
goto skip_pmd_checks;
/*
* Use pte_alloc() instead of pte_alloc_map(). We can't run
* pte_offset_map() on pmds where a huge pmd might be created
@@ -3483,6 +3490,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
if (unlikely(pmd_trans_unstable(vmf->pmd)))
return 0;
skip_pmd_checks:
/* Use the zero-page for reads */
if (!(vmf->flags & FAULT_FLAG_WRITE) &&
!mm_forbids_zeropage(vma->vm_mm)) {
@@ -3587,6 +3595,10 @@ static vm_fault_t __do_fault(struct vm_fault *vmf)
struct vm_area_struct *vma = vmf->vma;
vm_fault_t ret;
/* Do not check unstable pmd, if it's changed will retry later */
if (vmf->flags & FAULT_FLAG_SPECULATIVE)
goto skip_pmd_checks;
/*
* Preallocate pte before we take page_lock because this might lead to
* deadlocks for memcg reclaim which waits for pages under writeback:
@@ -3610,6 +3622,7 @@ static vm_fault_t __do_fault(struct vm_fault *vmf)
smp_wmb(); /* See comment in __pte_alloc() */
}
skip_pmd_checks:
ret = vma->vm_ops->fault(vmf);
if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY |
VM_FAULT_DONE_COW)))
@@ -3988,7 +4001,8 @@ static vm_fault_t do_fault_around(struct vm_fault *vmf)
end_pgoff = min3(end_pgoff, vma_pages(vmf->vma) + vmf->vma->vm_pgoff - 1,
start_pgoff + nr_pages - 1);
if (pmd_none(*vmf->pmd)) {
if (!(vmf->flags & FAULT_FLAG_SPECULATIVE) &&
pmd_none(*vmf->pmd)) {
vmf->prealloc_pte = pte_alloc_one(vmf->vma->vm_mm,
vmf->address);
if (!vmf->prealloc_pte)
@@ -4356,16 +4370,11 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
pte_t entry;
int ret = 0;
if (unlikely(pmd_none(*vmf->pmd))) {
/*
* In the case of the speculative page fault handler we abort
* the speculative path immediately as the pmd is probably
* in the way to be converted in a huge one. We will try
* again holding the mmap_sem (which implies that the collapse
* operation is done).
*/
/* Do not check unstable pmd, if it's changed will retry later */
if (vmf->flags & FAULT_FLAG_SPECULATIVE)
return VM_FAULT_RETRY;
goto skip_pmd_checks;
if (unlikely(pmd_none(*vmf->pmd))) {
/*
* Leave __pte_alloc() until later: because vm_ops->fault may
* want to allocate huge page, and if we expose page table
@@ -4373,8 +4382,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
* concurrent faults and from rmap lookups.
*/
vmf->pte = NULL;
} else if (!(vmf->flags & FAULT_FLAG_SPECULATIVE)) {
/* See comment in pte_alloc_one_map() */
} else {
if (pmd_devmap_trans_unstable(vmf->pmd))
return 0;
/*
@@ -4404,6 +4412,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
}
}
skip_pmd_checks:
if (!vmf->pte) {
if (vma_is_anonymous(vmf->vma))
return do_anonymous_page(vmf);
@@ -4651,7 +4660,6 @@ int __handle_speculative_fault(struct mm_struct *mm, unsigned long address,
pol = __get_vma_policy(vmf.vma, address);
if (!pol)
pol = get_task_policy(current);
if (!pol)
if (pol && pol->mode == MPOL_INTERLEAVE) {
trace_spf_vma_notsup(_RET_IP_, vmf.vma, address);
return VM_FAULT_RETRY;
-2
View File
@@ -599,11 +599,9 @@ unsigned long change_prot_numa(struct vm_area_struct *vma,
{
int nr_updated;
vm_write_begin(vma);
nr_updated = change_protection(vma, addr, end, PAGE_NONE, 0, 1);
if (nr_updated)
count_vm_numa_events(NUMA_PTE_UPDATES, nr_updated);
vm_write_end(vma);
return nr_updated;
}
+16 -2
View File
@@ -2306,8 +2306,22 @@ struct vm_area_struct *get_vma(struct mm_struct *mm, unsigned long addr)
read_lock(&mm->mm_rb_lock);
vma = __find_vma(mm, addr);
if (vma)
atomic_inc(&vma->vm_ref_count);
/*
* If there is a concurrent fast mremap, bail out since the entire
* PMD/PUD subtree may have been remapped.
*
* This is usually safe for conventional mremap since it takes the
* PTE locks as does SPF. However fast mremap only takes the lock
* at the PMD/PUD level which is ok as it is done with the mmap
* write lock held. But since SPF, as the term implies forgoes,
* taking the mmap read lock and also cannot take PTL lock at the
* larger PMD/PUD granualrity, since it would introduce huge
* contention in the page fault path; fall back to regular fault
* handling.
*/
if (vma && !atomic_inc_unless_negative(&vma->vm_ref_count))
vma = NULL;
read_unlock(&mm->mm_rb_lock);
return vma;
+12 -3
View File
@@ -2777,7 +2777,7 @@ void sk_stop_timer(struct sock *sk, struct timer_list* timer)
}
EXPORT_SYMBOL(sk_stop_timer);
void sock_init_data(struct socket *sock, struct sock *sk)
void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid)
{
sk_init_common(sk);
sk->sk_send_head = NULL;
@@ -2796,11 +2796,10 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_type = sock->type;
sk->sk_wq = sock->wq;
sock->sk = sk;
sk->sk_uid = SOCK_INODE(sock)->i_uid;
} else {
sk->sk_wq = NULL;
sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0);
}
sk->sk_uid = uid;
rwlock_init(&sk->sk_callback_lock);
if (sk->sk_kern_sock)
@@ -2856,6 +2855,16 @@ void sock_init_data(struct socket *sock, struct sock *sk)
refcount_set(&sk->sk_refcnt, 1);
atomic_set(&sk->sk_drops, 0);
}
EXPORT_SYMBOL(sock_init_data_uid);
void sock_init_data(struct socket *sock, struct sock *sk)
{
kuid_t uid = sock ?
SOCK_INODE(sock)->i_uid :
make_kuid(sock_net(sk)->user_ns, 0);
sock_init_data_uid(sock, sk, uid);
}
EXPORT_SYMBOL(sock_init_data);
void lock_sock_nested(struct sock *sk, int subclass)