Merge remote-tracking branch 'sm8250/lineage-20' into lineage-23.0
* sm8250/lineage-20:
disp: msm: sde: fix typo in trace message
disp: msm: dp: avoid dp sw reset on disconnect path
disp: msm: sde: add mutex lock to handle ppdone timeout usecases
disp: msm: dsi: Reset irq_stat_mask in _dsi_ctrl_destroy_isr
msm: Check irq,Restore msm irq.
power: smb139{0,8}: Cast 'cp_role' to smaller integer type
qcom: qpnp-pq: Fix -Wpointer-to-int-cast
msm: cvp: Fix -Wvoid-pointer-to-int-cast
Revert "kbuild: Globally disable (void-)pointer-to-int-cast warnings for Clang"
UPSTREAM: epoll: fix compat syscall wire up of epoll_pwait2
BACKPORT: epoll: wire up syscall epoll_pwait2
UPSTREAM: epoll: add syscall epoll_pwait2
BACKPORT: epoll: convert internal api to timespec64
UPSTREAM: close_range(): fix the logics in descriptor table trimming
UPSTREAM: fs: fix fd table size alignment properly
UPSTREAM: fs: fd tables have to be multiples of BITS_PER_LONG
UPSTREAM: file: simplify logic in __close_range()
UPSTREAM: file: fix close_range() for unshare+cloexec
UPSTREAM: close_range: unshare all fds for CLOSE_RANGE_UNSHARE | CLOSE_RANGE_CLOEXEC
UPSTREAM: fs, close_range: add flag CLOSE_RANGE_CLOEXEC
...
Change-Id: I157fe280c9298d969bbe0a32d08843f8103d542c
This commit is contained in:
31 files changed
+374
-83
No files matched your search
@@ -416,3 +416,5 @@
|
||||
399 common io_pgetevents sys_io_pgetevents
|
||||
424 common pidfd_send_signal sys_pidfd_send_signal
|
||||
434 common pidfd_open sys_pidfd_open
|
||||
436 common close_range sys_close_range
|
||||
441 common epoll_pwait2 sys_epoll_pwait2
|
||||
@@ -122,6 +122,7 @@ CONFIG_XFRM_INTERFACE=y
|
||||
CONFIG_XFRM_MIGRATE=y
|
||||
CONFIG_XFRM_STATISTICS=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_XDP_SOCKETS=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
|
||||
@@ -122,6 +122,7 @@ CONFIG_XFRM_INTERFACE=y
|
||||
CONFIG_XFRM_MIGRATE=y
|
||||
CONFIG_XFRM_STATISTICS=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_XDP_SOCKETS=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
|
||||
@@ -120,6 +120,7 @@ CONFIG_XFRM_INTERFACE=y
|
||||
CONFIG_XFRM_MIGRATE=y
|
||||
CONFIG_XFRM_STATISTICS=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_XDP_SOCKETS=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5)
|
||||
#define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800)
|
||||
|
||||
#define __NR_compat_syscalls 435
|
||||
#define __NR_compat_syscalls 442
|
||||
#endif
|
||||
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
|
||||
@@ -823,6 +823,10 @@ __SYSCALL(__NR_rseq, sys_rseq)
|
||||
__SYSCALL(__NR_pidfd_send_signal, sys_pidfd_send_signal)
|
||||
#define __NR_pidfd_open 434
|
||||
__SYSCALL(__NR_pidfd_open, sys_pidfd_open)
|
||||
#define __NR_close_range 436
|
||||
__SYSCALL(__NR_close_range, sys_close_range)
|
||||
#define __NR_epoll_pwait2 441
|
||||
__SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2)
|
||||
|
||||
/*
|
||||
* Please add new compat syscalls above this comment and update
|
||||
|
||||
@@ -393,3 +393,5 @@
|
||||
383 common rseq sys_rseq compat_sys_rseq
|
||||
424 common pidfd_send_signal sys_pidfd_send_signal sys_pidfd_send_signal
|
||||
434 common pidfd_open sys_pidfd_open sys_pidfd_open
|
||||
436 common close_range sys_close_range sys_close_range
|
||||
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
|
||||
@@ -400,3 +400,5 @@
|
||||
386 i386 rseq sys_rseq __ia32_sys_rseq
|
||||
424 i386 pidfd_send_signal sys_pidfd_send_signal __ia32_sys_pidfd_send_signal
|
||||
434 i386 pidfd_open sys_pidfd_open __ia32_sys_pidfd_open
|
||||
436 i386 close_range sys_close_range
|
||||
441 i386 epoll_pwait2 sys_epoll_pwait2 __ia32_sys_epoll_pwait2
|
||||
@@ -341,6 +341,8 @@
|
||||
332 common statx sys_statx
|
||||
424 common pidfd_send_signal sys_pidfd_send_signal
|
||||
434 common pidfd_open sys_pidfd_open
|
||||
436 common close_range sys_close_range
|
||||
441 common epoll_pwait2 sys_epoll_pwait2
|
||||
|
||||
#
|
||||
# x32-specific system call numbers start at 512 to avoid cache impact
|
||||
|
||||
@@ -1572,8 +1572,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)
|
||||
INIT_WORK(&mhi_cntrl->st_worker, mhi_pm_st_worker);
|
||||
init_waitqueue_head(&mhi_cntrl->state_event);
|
||||
|
||||
mhi_cntrl->wq = alloc_ordered_workqueue("mhi_w",
|
||||
WQ_MEM_RECLAIM | WQ_HIGHPRI);
|
||||
mhi_cntrl->wq = alloc_ordered_workqueue("mhi_w", WQ_HIGHPRI);
|
||||
if (!mhi_cntrl->wq)
|
||||
goto error_alloc_cmd;
|
||||
|
||||
|
||||
@@ -480,7 +480,7 @@ static int hfi_process_session_cvp_msg(u32 device_id,
|
||||
struct cvp_session_msg *sess_msg;
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
struct msm_cvp_core *core;
|
||||
void *session_id;
|
||||
unsigned int session_id;
|
||||
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "%s: invalid param\n", __func__);
|
||||
@@ -489,9 +489,9 @@ static int hfi_process_session_cvp_msg(u32 device_id,
|
||||
dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size);
|
||||
return -E2BIG;
|
||||
}
|
||||
session_id = (void *)(uintptr_t)get_msg_session_id(pkt);
|
||||
session_id = get_msg_session_id(pkt);
|
||||
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||
inst = cvp_get_inst_from_id(core, (unsigned int)session_id);
|
||||
inst = cvp_get_inst_from_id(core, session_id);
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: invalid session\n", __func__);
|
||||
|
||||
@@ -4794,7 +4794,7 @@ static int qpnp_qg_probe(struct platform_device *pdev)
|
||||
chip->batt_age_level = -EINVAL;
|
||||
chip->qg_charge_counter = -EINVAL;
|
||||
|
||||
chip->qg_version = (u8)of_device_get_match_data(&pdev->dev);
|
||||
chip->qg_version = (enum qg_version)of_device_get_match_data(&pdev->dev);
|
||||
|
||||
switch (chip->qg_version) {
|
||||
case QG_LITE:
|
||||
|
||||
@@ -2101,7 +2101,7 @@ static int smb1390_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, chip);
|
||||
chip->cp_role = (int)of_device_get_match_data(chip->dev);
|
||||
chip->cp_role = (int)(unsigned long)of_device_get_match_data(chip->dev);
|
||||
switch (chip->cp_role) {
|
||||
case CP_MASTER:
|
||||
rc = smb1390_master_probe(chip);
|
||||
|
||||
@@ -2732,7 +2732,7 @@ static int smb1398_probe(struct platform_device *pdev)
|
||||
chip->disabled = true;
|
||||
platform_set_drvdata(pdev, chip);
|
||||
|
||||
chip->div2_cp_role = (int)of_device_get_match_data(chip->dev);
|
||||
chip->div2_cp_role = (int)(unsigned long)of_device_get_match_data(chip->dev);
|
||||
switch (chip->div2_cp_role) {
|
||||
case DIV2_CP_MASTER:
|
||||
case SMB1394_DIV2_CP_PRY:
|
||||
|
||||
+101
-27
@@ -1713,15 +1713,25 @@ static int ep_send_events(struct eventpoll *ep,
|
||||
return esed.res;
|
||||
}
|
||||
|
||||
static inline struct timespec64 ep_set_mstimeout(long ms)
|
||||
static struct timespec64 *ep_timeout_to_timespec(struct timespec64 *to, long ms)
|
||||
{
|
||||
struct timespec64 now, ts = {
|
||||
.tv_sec = ms / MSEC_PER_SEC,
|
||||
.tv_nsec = NSEC_PER_MSEC * (ms % MSEC_PER_SEC),
|
||||
};
|
||||
struct timespec64 now;
|
||||
|
||||
if (ms < 0)
|
||||
return NULL;
|
||||
|
||||
if (!ms) {
|
||||
to->tv_sec = 0;
|
||||
to->tv_nsec = 0;
|
||||
return to;
|
||||
}
|
||||
|
||||
to->tv_sec = ms / MSEC_PER_SEC;
|
||||
to->tv_nsec = NSEC_PER_MSEC * (ms % MSEC_PER_SEC);
|
||||
|
||||
ktime_get_ts64(&now);
|
||||
return timespec64_add_safe(now, ts);
|
||||
*to = timespec64_add_safe(now, *to);
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1733,8 +1743,8 @@ static inline struct timespec64 ep_set_mstimeout(long ms)
|
||||
* stored.
|
||||
* @maxevents: Size (in terms of number of events) of the caller event buffer.
|
||||
* @timeout: Maximum timeout for the ready events fetch operation, in
|
||||
* milliseconds. If the @timeout is zero, the function will not block,
|
||||
* while if the @timeout is less than zero, the function will block
|
||||
* timespec. If the timeout is zero, the function will not block,
|
||||
* while if the @timeout ptr is NULL, the function will block
|
||||
* until at least one event has been retrieved (or an error
|
||||
* occurred).
|
||||
*
|
||||
@@ -1742,7 +1752,7 @@ static inline struct timespec64 ep_set_mstimeout(long ms)
|
||||
* error code, in case of error.
|
||||
*/
|
||||
static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
|
||||
int maxevents, long timeout)
|
||||
int maxevents, struct timespec64 *timeout)
|
||||
{
|
||||
int res = 0, eavail, timed_out = 0;
|
||||
u64 slack = 0;
|
||||
@@ -1751,13 +1761,11 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
|
||||
|
||||
lockdep_assert_irqs_enabled();
|
||||
|
||||
if (timeout > 0) {
|
||||
struct timespec64 end_time = ep_set_mstimeout(timeout);
|
||||
|
||||
slack = select_estimate_accuracy(&end_time);
|
||||
if (timeout && (timeout->tv_sec | timeout->tv_nsec)) {
|
||||
slack = select_estimate_accuracy(timeout);
|
||||
to = &expires;
|
||||
*to = timespec64_to_ktime(end_time);
|
||||
} else if (timeout == 0) {
|
||||
*to = timespec64_to_ktime(*timeout);
|
||||
} else if (timeout) {
|
||||
/*
|
||||
* Avoid the unnecessary trip to the wait queue loop, if the
|
||||
* caller specified a non blocking operation.
|
||||
@@ -2155,7 +2163,7 @@ error_return:
|
||||
* part of the user space epoll_wait(2).
|
||||
*/
|
||||
static int do_epoll_wait(int epfd, struct epoll_event __user *events,
|
||||
int maxevents, int timeout)
|
||||
int maxevents, struct timespec64 *to)
|
||||
{
|
||||
int error;
|
||||
struct fd f;
|
||||
@@ -2189,7 +2197,7 @@ static int do_epoll_wait(int epfd, struct epoll_event __user *events,
|
||||
ep = f.file->private_data;
|
||||
|
||||
/* Time to fish for events ... */
|
||||
error = ep_poll(ep, events, maxevents, timeout);
|
||||
error = ep_poll(ep, events, maxevents, to);
|
||||
|
||||
error_fput:
|
||||
fdput(f);
|
||||
@@ -2199,16 +2207,19 @@ error_fput:
|
||||
SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,
|
||||
int, maxevents, int, timeout)
|
||||
{
|
||||
return do_epoll_wait(epfd, events, maxevents, timeout);
|
||||
struct timespec64 to;
|
||||
|
||||
return do_epoll_wait(epfd, events, maxevents,
|
||||
ep_timeout_to_timespec(&to, timeout));
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the event wait interface for the eventpoll file. It is the kernel
|
||||
* part of the user space epoll_pwait(2).
|
||||
*/
|
||||
SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
|
||||
int, maxevents, int, timeout, const sigset_t __user *, sigmask,
|
||||
size_t, sigsetsize)
|
||||
static int do_epoll_pwait(int epfd, struct epoll_event __user *events,
|
||||
int maxevents, struct timespec64 *to,
|
||||
const sigset_t __user *sigmask, size_t sigsetsize)
|
||||
{
|
||||
int error;
|
||||
sigset_t ksigmask, sigsaved;
|
||||
@@ -2226,7 +2237,7 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
|
||||
set_current_blocked(&ksigmask);
|
||||
}
|
||||
|
||||
error = do_epoll_wait(epfd, events, maxevents, timeout);
|
||||
error = do_epoll_wait(epfd, events, maxevents, to);
|
||||
|
||||
/*
|
||||
* If we changed the signal mask, we need to restore the original one.
|
||||
@@ -2246,12 +2257,40 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
|
||||
return error;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
|
||||
int, maxevents, int, timeout, const sigset_t __user *, sigmask,
|
||||
size_t, sigsetsize)
|
||||
{
|
||||
struct timespec64 to;
|
||||
|
||||
return do_epoll_pwait(epfd, events, maxevents,
|
||||
ep_timeout_to_timespec(&to, timeout),
|
||||
sigmask, sigsetsize);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE6(epoll_pwait2, int, epfd, struct epoll_event __user *, events,
|
||||
int, maxevents, const struct __kernel_timespec __user *, timeout,
|
||||
const sigset_t __user *, sigmask, size_t, sigsetsize)
|
||||
{
|
||||
struct timespec64 ts, *to = NULL;
|
||||
|
||||
if (timeout) {
|
||||
if (get_timespec64(&ts, timeout))
|
||||
return -EFAULT;
|
||||
to = &ts;
|
||||
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return do_epoll_pwait(epfd, events, maxevents, to,
|
||||
sigmask, sigsetsize);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
|
||||
struct epoll_event __user *, events,
|
||||
int, maxevents, int, timeout,
|
||||
const compat_sigset_t __user *, sigmask,
|
||||
compat_size_t, sigsetsize)
|
||||
static int do_compat_epoll_pwait(int epfd, struct epoll_event __user *events,
|
||||
int maxevents, struct timespec64 *timeout,
|
||||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize)
|
||||
{
|
||||
long err;
|
||||
sigset_t ksigmask, sigsaved;
|
||||
@@ -2288,6 +2327,41 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
|
||||
struct epoll_event __user *, events,
|
||||
int, maxevents, int, timeout,
|
||||
const compat_sigset_t __user *, sigmask,
|
||||
compat_size_t, sigsetsize)
|
||||
{
|
||||
struct timespec64 to;
|
||||
|
||||
return do_compat_epoll_pwait(epfd, events, maxevents,
|
||||
ep_timeout_to_timespec(&to, timeout),
|
||||
sigmask, sigsetsize);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(epoll_pwait2, int, epfd,
|
||||
struct epoll_event __user *, events,
|
||||
int, maxevents,
|
||||
const struct __kernel_timespec __user *, timeout,
|
||||
const compat_sigset_t __user *, sigmask,
|
||||
compat_size_t, sigsetsize)
|
||||
{
|
||||
struct timespec64 ts, *to = NULL;
|
||||
|
||||
if (timeout) {
|
||||
if (get_timespec64(&ts, timeout))
|
||||
return -EFAULT;
|
||||
to = &ts;
|
||||
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return do_compat_epoll_pwait(epfd, events, maxevents, to,
|
||||
sigmask, sigsetsize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int __init eventpoll_init(void)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -18,6 +19,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/close_range.h>
|
||||
|
||||
unsigned int sysctl_nr_open __read_mostly = 1024*1024;
|
||||
unsigned int sysctl_nr_open_min = BITS_PER_LONG;
|
||||
@@ -84,6 +86,14 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
|
||||
* 'unsigned long' in some places, but simply because that is how the Linux
|
||||
* kernel bitmaps are defined to work: they are not "bits in an array of bytes",
|
||||
* they are very much "bits in an array of unsigned long".
|
||||
*
|
||||
* The ALIGN(nr, BITS_PER_LONG) here is for clarity: since we just multiplied
|
||||
* by that "1024/sizeof(ptr)" before, we already know there are sufficient
|
||||
* clear low bits. Clang seems to realize that, gcc ends up being confused.
|
||||
*
|
||||
* On a 128-bit machine, the ALIGN() would actually matter. In the meantime,
|
||||
* let's consider it documentation (and maybe a test-case for gcc to improve
|
||||
* its code generation ;)
|
||||
*/
|
||||
static struct fdtable *alloc_fdtable(unsigned int slots_wanted)
|
||||
{
|
||||
@@ -272,36 +282,45 @@ static inline void __clear_open_fd(unsigned int fd, struct fdtable *fdt)
|
||||
__clear_bit(fd / BITS_PER_LONG, fdt->full_fds_bits);
|
||||
}
|
||||
|
||||
static unsigned int count_open_files(struct fdtable *fdt)
|
||||
/*
|
||||
* Note that a sane fdtable size always has to be a multiple of
|
||||
* BITS_PER_LONG, since we have bitmaps that are sized by this.
|
||||
*
|
||||
* punch_hole is optional - when close_range() is asked to unshare
|
||||
* and close, we don't need to copy descriptors in that range, so
|
||||
* a smaller cloned descriptor table might suffice if the last
|
||||
* currently opened descriptor falls into that range.
|
||||
*/
|
||||
static unsigned int sane_fdtable_size(struct fdtable *fdt, struct fd_range *punch_hole)
|
||||
{
|
||||
unsigned int size = fdt->max_fds;
|
||||
unsigned int i;
|
||||
unsigned int last = find_last_bit(fdt->open_fds, fdt->max_fds);
|
||||
|
||||
/* Find the last open fd */
|
||||
for (i = size / BITS_PER_LONG; i > 0; ) {
|
||||
if (fdt->open_fds[--i])
|
||||
break;
|
||||
if (last == fdt->max_fds)
|
||||
return NR_OPEN_DEFAULT;
|
||||
if (punch_hole && punch_hole->to >= last && punch_hole->from <= last) {
|
||||
last = find_last_bit(fdt->open_fds, punch_hole->from);
|
||||
if (last == punch_hole->from)
|
||||
return NR_OPEN_DEFAULT;
|
||||
}
|
||||
i = (i + 1) * BITS_PER_LONG;
|
||||
return i;
|
||||
return ALIGN(last + 1, BITS_PER_LONG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new files structure and copy contents from the
|
||||
* passed in files structure.
|
||||
* errorp will be valid only when the returned files_struct is NULL.
|
||||
* Allocate a new descriptor table and copy contents from the passed in
|
||||
* instance. Returns a pointer to cloned table on success, ERR_PTR()
|
||||
* on failure. For 'punch_hole' see sane_fdtable_size().
|
||||
*/
|
||||
struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
|
||||
struct files_struct *dup_fd(struct files_struct *oldf, struct fd_range *punch_hole)
|
||||
{
|
||||
struct files_struct *newf;
|
||||
struct file **old_fds, **new_fds;
|
||||
unsigned int open_files, i;
|
||||
struct fdtable *old_fdt, *new_fdt;
|
||||
int error;
|
||||
|
||||
*errorp = -ENOMEM;
|
||||
newf = kmem_cache_alloc(files_cachep, GFP_KERNEL);
|
||||
if (!newf)
|
||||
goto out;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
atomic_set(&newf->count, 1);
|
||||
|
||||
@@ -318,7 +337,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
|
||||
|
||||
spin_lock(&oldf->file_lock);
|
||||
old_fdt = files_fdtable(oldf);
|
||||
open_files = count_open_files(old_fdt);
|
||||
open_files = sane_fdtable_size(old_fdt, punch_hole);
|
||||
|
||||
/*
|
||||
* Check whether we need to allocate a larger fd array and fd set.
|
||||
@@ -331,7 +350,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
|
||||
|
||||
new_fdt = alloc_fdtable(open_files);
|
||||
if (IS_ERR(new_fdt)) {
|
||||
*errorp = PTR_ERR(new_fdt);
|
||||
error = PTR_ERR(new_fdt);
|
||||
goto out_release;
|
||||
}
|
||||
|
||||
@@ -342,7 +361,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
|
||||
*/
|
||||
spin_lock(&oldf->file_lock);
|
||||
old_fdt = files_fdtable(oldf);
|
||||
open_files = count_open_files(old_fdt);
|
||||
open_files = sane_fdtable_size(old_fdt, punch_hole);
|
||||
}
|
||||
|
||||
copy_fd_bitmaps(new_fdt, old_fdt, open_files / BITS_PER_LONG);
|
||||
@@ -376,8 +395,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
|
||||
|
||||
out_release:
|
||||
kmem_cache_free(files_cachep, newf);
|
||||
out:
|
||||
return NULL;
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
static struct fdtable *close_files(struct files_struct * files)
|
||||
@@ -630,12 +648,9 @@ void fd_install(unsigned int fd, struct file *file)
|
||||
|
||||
EXPORT_SYMBOL(fd_install);
|
||||
|
||||
/*
|
||||
* The same warnings as for __alloc_fd()/__fd_install() apply here...
|
||||
*/
|
||||
int __close_fd(struct files_struct *files, unsigned fd)
|
||||
static struct file *pick_file(struct files_struct *files, unsigned fd)
|
||||
{
|
||||
struct file *file;
|
||||
struct file *file = NULL;
|
||||
struct fdtable *fdt;
|
||||
|
||||
spin_lock(&files->file_lock);
|
||||
@@ -648,15 +663,129 @@ int __close_fd(struct files_struct *files, unsigned fd)
|
||||
goto out_unlock;
|
||||
rcu_assign_pointer(fdt->fd[fd], NULL);
|
||||
__put_unused_fd(files, fd);
|
||||
spin_unlock(&files->file_lock);
|
||||
return filp_close(file, files);
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&files->file_lock);
|
||||
return -EBADF;
|
||||
return file;
|
||||
}
|
||||
|
||||
/*
|
||||
* The same warnings as for __alloc_fd()/__fd_install() apply here...
|
||||
*/
|
||||
int __close_fd(struct files_struct *files, unsigned fd)
|
||||
{
|
||||
struct file *file;
|
||||
|
||||
file = pick_file(files, fd);
|
||||
if (!file)
|
||||
return -EBADF;
|
||||
|
||||
return filp_close(file, files);
|
||||
}
|
||||
EXPORT_SYMBOL(__close_fd); /* for ksys_close() */
|
||||
|
||||
/**
|
||||
* last_fd - return last valid index into fd table
|
||||
* @cur_fds: files struct
|
||||
*
|
||||
* Context: Either rcu read lock or files_lock must be held.
|
||||
*
|
||||
* Returns: Last valid index into fdtable.
|
||||
*/
|
||||
static inline unsigned last_fd(struct fdtable *fdt)
|
||||
{
|
||||
return fdt->max_fds - 1;
|
||||
}
|
||||
|
||||
static inline void __range_cloexec(struct files_struct *cur_fds,
|
||||
unsigned int fd, unsigned int max_fd)
|
||||
{
|
||||
struct fdtable *fdt;
|
||||
|
||||
/* make sure we're using the correct maximum value */
|
||||
spin_lock(&cur_fds->file_lock);
|
||||
fdt = files_fdtable(cur_fds);
|
||||
max_fd = min(last_fd(fdt), max_fd);
|
||||
if (fd <= max_fd)
|
||||
bitmap_set(fdt->close_on_exec, fd, max_fd - fd + 1);
|
||||
spin_unlock(&cur_fds->file_lock);
|
||||
}
|
||||
|
||||
static inline void __range_close(struct files_struct *cur_fds, unsigned int fd,
|
||||
unsigned int max_fd)
|
||||
{
|
||||
while (fd <= max_fd) {
|
||||
struct file *file;
|
||||
|
||||
file = pick_file(cur_fds, fd++);
|
||||
if (!file)
|
||||
continue;
|
||||
|
||||
filp_close(file, cur_fds);
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __close_range() - Close all file descriptors in a given range.
|
||||
*
|
||||
* @fd: starting file descriptor to close
|
||||
* @max_fd: last file descriptor to close
|
||||
*
|
||||
* This closes a range of file descriptors. All file descriptors
|
||||
* from @fd up to and including @max_fd are closed.
|
||||
*/
|
||||
int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
|
||||
{
|
||||
struct task_struct *me = current;
|
||||
struct files_struct *cur_fds = me->files, *fds = NULL;
|
||||
|
||||
if (flags & ~(CLOSE_RANGE_UNSHARE | CLOSE_RANGE_CLOEXEC))
|
||||
return -EINVAL;
|
||||
|
||||
if (fd > max_fd)
|
||||
return -EINVAL;
|
||||
|
||||
if ((flags & CLOSE_RANGE_UNSHARE) && atomic_read(&cur_fds->count) > 1) {
|
||||
struct fd_range range = {fd, max_fd}, *punch_hole = ⦥
|
||||
|
||||
/*
|
||||
* If the caller requested all fds to be made cloexec we always
|
||||
* copy all of the file descriptors since they still want to
|
||||
* use them.
|
||||
*/
|
||||
if (flags & CLOSE_RANGE_CLOEXEC)
|
||||
punch_hole = NULL;
|
||||
|
||||
fds = dup_fd(cur_fds, punch_hole);
|
||||
if (IS_ERR(fds))
|
||||
return PTR_ERR(fds);
|
||||
/*
|
||||
* We used to share our file descriptor table, and have now
|
||||
* created a private one, make sure we're using it below.
|
||||
*/
|
||||
swap(cur_fds, fds);
|
||||
}
|
||||
|
||||
if (flags & CLOSE_RANGE_CLOEXEC)
|
||||
__range_cloexec(cur_fds, fd, max_fd);
|
||||
else
|
||||
__range_close(cur_fds, fd, max_fd);
|
||||
|
||||
if (fds) {
|
||||
/*
|
||||
* We're done closing the files we were supposed to. Time to install
|
||||
* the new file descriptor table and drop the old one.
|
||||
*/
|
||||
task_lock(me);
|
||||
me->files = cur_fds;
|
||||
task_unlock(me);
|
||||
put_files_struct(fds);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_close_on_exec(struct files_struct *files)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
@@ -1213,6 +1213,23 @@ SYSCALL_DEFINE1(close, unsigned int, fd)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* close_range() - Close all file descriptors in a given range.
|
||||
*
|
||||
* @fd: starting file descriptor to close
|
||||
* @max_fd: last file descriptor to close
|
||||
* @flags: reserved for future extensions
|
||||
*
|
||||
* This closes a range of file descriptors. All file descriptors
|
||||
* from @fd up to and including @max_fd are closed.
|
||||
* Currently, errors to close a given file descriptor are ignored.
|
||||
*/
|
||||
SYSCALL_DEFINE3(close_range, unsigned int, fd, unsigned int, max_fd,
|
||||
unsigned int, flags)
|
||||
{
|
||||
return __close_range(fd, max_fd, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine simulates a hangup on the tty, to arrange that users
|
||||
* are given clean terminals at login time.
|
||||
|
||||
@@ -568,6 +568,12 @@ asmlinkage long compat_sys_epoll_pwait(int epfd,
|
||||
int maxevents, int timeout,
|
||||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize);
|
||||
asmlinkage long compat_sys_epoll_pwait2(int epfd,
|
||||
struct epoll_event __user *events,
|
||||
int maxevents,
|
||||
const struct __kernel_timespec __user *timeout,
|
||||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize);
|
||||
|
||||
/* fs/fcntl.c */
|
||||
asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
|
||||
|
||||
@@ -109,7 +109,10 @@ struct files_struct *get_files_struct(struct task_struct *);
|
||||
void put_files_struct(struct files_struct *fs);
|
||||
void reset_files_struct(struct files_struct *);
|
||||
int unshare_files(struct files_struct **);
|
||||
struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy;
|
||||
struct fd_range {
|
||||
unsigned int from, to;
|
||||
};
|
||||
struct files_struct *dup_fd(struct files_struct *, struct fd_range *) __latent_entropy;
|
||||
void do_close_on_exec(struct files_struct *);
|
||||
int iterate_fd(struct files_struct *, unsigned,
|
||||
int (*)(const void *, struct file *, unsigned),
|
||||
@@ -121,6 +124,7 @@ extern void __fd_install(struct files_struct *files,
|
||||
unsigned int fd, struct file *file);
|
||||
extern int __close_fd(struct files_struct *files,
|
||||
unsigned int fd);
|
||||
extern int __close_range(unsigned int fd, unsigned int max_fd, unsigned int flags);
|
||||
|
||||
extern struct kmem_cache *files_cachep;
|
||||
|
||||
|
||||
@@ -599,6 +599,9 @@ struct netdev_queue {
|
||||
|
||||
/* Subordinate device that the queue has been assigned to */
|
||||
struct net_device *sb_dev;
|
||||
#ifdef CONFIG_XDP_SOCKETS
|
||||
struct xdp_umem *umem;
|
||||
#endif
|
||||
/*
|
||||
* write-mostly part
|
||||
*/
|
||||
@@ -736,6 +739,9 @@ struct netdev_rx_queue {
|
||||
struct kobject kobj;
|
||||
struct net_device *dev;
|
||||
struct xdp_rxq_info xdp_rxq;
|
||||
#ifdef CONFIG_XDP_SOCKETS
|
||||
struct xdp_umem *umem;
|
||||
#endif
|
||||
|
||||
ANDROID_KABI_RESERVE(1);
|
||||
ANDROID_KABI_RESERVE(2);
|
||||
|
||||
@@ -346,6 +346,11 @@ asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
|
||||
int maxevents, int timeout,
|
||||
const sigset_t __user *sigmask,
|
||||
size_t sigsetsize);
|
||||
asmlinkage long sys_epoll_pwait2(int epfd, struct epoll_event __user *events,
|
||||
int maxevents,
|
||||
const struct __kernel_timespec __user *timeout,
|
||||
const sigset_t __user *sigmask,
|
||||
size_t sigsetsize);
|
||||
|
||||
/* fs/fcntl.c */
|
||||
asmlinkage long sys_dup(unsigned int fildes);
|
||||
@@ -423,6 +428,8 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group);
|
||||
asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
|
||||
umode_t mode);
|
||||
asmlinkage long sys_close(unsigned int fd);
|
||||
asmlinkage long sys_close_range(unsigned int fd, unsigned int max_fd,
|
||||
unsigned int flags);
|
||||
asmlinkage long sys_vhangup(void);
|
||||
|
||||
/* fs/pipe.c */
|
||||
|
||||
@@ -740,9 +740,13 @@ __SYSCALL(__NR_rseq, sys_rseq)
|
||||
__SYSCALL(__NR_pidfd_send_signal, sys_pidfd_send_signal)
|
||||
#define __NR_pidfd_open 434
|
||||
__SYSCALL(__NR_pidfd_open, sys_pidfd_open)
|
||||
#define __NR_close_range 436
|
||||
__SYSCALL(__NR_close_range, sys_close_range)
|
||||
#define __NR_epoll_pwait2 441
|
||||
__SC_COMP(__NR_epoll_pwait2, sys_epoll_pwait2, compat_sys_epoll_pwait2)
|
||||
|
||||
#undef __NR_syscalls
|
||||
#define __NR_syscalls 435
|
||||
#define __NR_syscalls 442
|
||||
|
||||
/*
|
||||
* 32 bit systems traditionally used different
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _UAPI_LINUX_CLOSE_RANGE_H
|
||||
#define _UAPI_LINUX_CLOSE_RANGE_H
|
||||
|
||||
/* Unshare the file descriptor table before closing file descriptors. */
|
||||
#define CLOSE_RANGE_UNSHARE (1U << 1)
|
||||
|
||||
/* Set the FD_CLOEXEC bit instead of closing the file descriptor. */
|
||||
#define CLOSE_RANGE_CLOEXEC (1U << 2)
|
||||
|
||||
#endif /* _UAPI_LINUX_CLOSE_RANGE_H */
|
||||
|
||||
@@ -6482,6 +6482,7 @@ void cgroup_sk_clone(struct sock_cgroup_data *skcd)
|
||||
* Don't use cgroup_get_live().
|
||||
*/
|
||||
cgroup_get(sock_cgroup_ptr(skcd));
|
||||
cgroup_bpf_get(sock_cgroup_ptr(skcd));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-13
@@ -1399,28 +1399,25 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
|
||||
static int copy_files(unsigned long clone_flags, struct task_struct *tsk)
|
||||
{
|
||||
struct files_struct *oldf, *newf;
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* A background process may not have any files ...
|
||||
*/
|
||||
oldf = current->files;
|
||||
if (!oldf)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
if (clone_flags & CLONE_FILES) {
|
||||
atomic_inc(&oldf->count);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
newf = dup_fd(oldf, &error);
|
||||
if (!newf)
|
||||
goto out;
|
||||
newf = dup_fd(oldf, NULL);
|
||||
if (IS_ERR(newf))
|
||||
return PTR_ERR(newf);
|
||||
|
||||
tsk->files = newf;
|
||||
error = 0;
|
||||
out:
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
|
||||
@@ -2616,13 +2613,13 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
|
||||
static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp)
|
||||
{
|
||||
struct files_struct *fd = current->files;
|
||||
int error = 0;
|
||||
|
||||
if ((unshare_flags & CLONE_FILES) &&
|
||||
(fd && atomic_read(&fd->count) > 1)) {
|
||||
*new_fdp = dup_fd(fd, &error);
|
||||
if (!*new_fdp)
|
||||
return error;
|
||||
fd = dup_fd(fd, NULL);
|
||||
if (IS_ERR(fd))
|
||||
return PTR_ERR(fd);
|
||||
*new_fdp = fd;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -63,6 +63,8 @@ COND_SYSCALL(epoll_create1);
|
||||
COND_SYSCALL(epoll_ctl);
|
||||
COND_SYSCALL(epoll_pwait);
|
||||
COND_SYSCALL_COMPAT(epoll_pwait);
|
||||
COND_SYSCALL(epoll_pwait2);
|
||||
COND_SYSCALL_COMPAT(epoll_pwait2);
|
||||
|
||||
/* fs/fcntl.c */
|
||||
|
||||
|
||||
@@ -74,8 +74,6 @@ KBUILD_CFLAGS += $(call cc-disable-warning, uninitialized)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-int-cast)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, void-pointer-to-int-cast)
|
||||
KBUILD_CFLAGS += -Wno-enum-compare-conditional
|
||||
KBUILD_CFLAGS += -Wno-enum-enum-conversion
|
||||
endif
|
||||
|
||||
@@ -1342,7 +1342,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl)
|
||||
|
||||
ctrl->catalog->fec_config(ctrl->catalog, false);
|
||||
dp_ctrl_configure_source_link_params(ctrl, false);
|
||||
ctrl->catalog->reset(ctrl->catalog);
|
||||
dp_ctrl_state_ctrl(ctrl, 0);
|
||||
|
||||
/* Make sure DP is disabled before clk disable */
|
||||
wmb();
|
||||
|
||||
@@ -2715,6 +2715,7 @@ static irqreturn_t dsi_ctrl_isr(int irq, void *ptr)
|
||||
static int _dsi_ctrl_setup_isr(struct dsi_ctrl *dsi_ctrl)
|
||||
{
|
||||
int irq_num, rc;
|
||||
uint32_t intr_idx;
|
||||
|
||||
if (!dsi_ctrl)
|
||||
return -EINVAL;
|
||||
@@ -2726,6 +2727,22 @@ static int _dsi_ctrl_setup_isr(struct dsi_ctrl *dsi_ctrl)
|
||||
init_completion(&dsi_ctrl->irq_info.cmd_frame_done);
|
||||
init_completion(&dsi_ctrl->irq_info.bta_done);
|
||||
|
||||
/* If there is unbalanced refcount for any interrupt, irq_stat_mask
|
||||
* does not get clear during suspend. On resume, enable irq is not
|
||||
* called leading to ctrl ISR permanently disabled. This is a defensive
|
||||
* check to recover from such scenario.
|
||||
*/
|
||||
for (intr_idx = DSI_SINT_CMD_MODE_DMA_DONE;
|
||||
intr_idx < DSI_STATUS_INTERRUPT_COUNT; intr_idx++) {
|
||||
if (dsi_ctrl->irq_info.irq_stat_refcount[intr_idx]) {
|
||||
DSI_CTRL_ERR(dsi_ctrl,
|
||||
"refcount mismatch: intr_idx %d\n",
|
||||
intr_idx);
|
||||
dsi_ctrl->irq_info.irq_stat_refcount[intr_idx] = 0;
|
||||
}
|
||||
}
|
||||
dsi_ctrl->irq_info.irq_stat_mask = 0x0;
|
||||
|
||||
irq_num = platform_get_irq(dsi_ctrl->pdev, 0);
|
||||
if (irq_num < 0) {
|
||||
DSI_CTRL_ERR(dsi_ctrl, "Failed to get IRQ number, %d\n",
|
||||
@@ -2760,6 +2777,7 @@ static void _dsi_ctrl_destroy_isr(struct dsi_ctrl *dsi_ctrl)
|
||||
devm_free_irq(&dsi_ctrl->pdev->dev,
|
||||
dsi_ctrl->irq_info.irq_num, dsi_ctrl);
|
||||
dsi_ctrl->irq_info.irq_num = -1;
|
||||
dsi_ctrl->irq_info.irq_stat_mask = 0x0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -525,12 +525,14 @@ static int _sde_encoder_phys_cmd_handle_ppdone_timeout(
|
||||
pending_kickoff_cnt);
|
||||
|
||||
SDE_EVT32(DRMID(phys_enc->parent), SDE_EVTLOG_FATAL);
|
||||
mutex_lock(phys_enc->vblank_ctl_lock);
|
||||
sde_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR);
|
||||
if (sde_kms_is_secure_session_inprogress(phys_enc->sde_kms))
|
||||
SDE_DBG_DUMP("secure", "all", "dbg_bus");
|
||||
else
|
||||
SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus");
|
||||
sde_encoder_helper_register_irq(phys_enc, INTR_IDX_RDPTR);
|
||||
mutex_unlock(phys_enc->vblank_ctl_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1278,7 +1278,7 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
|
||||
sde_encoder_virt_reset(encoder);
|
||||
}
|
||||
|
||||
SDE_ATRACE_END("sde_ksm_wait_for_commit_done");
|
||||
SDE_ATRACE_END("sde_kms_wait_for_commit_done");
|
||||
}
|
||||
|
||||
static void sde_kms_prepare_fence(struct msm_kms *kms,
|
||||
|
||||
Reference in new issue
Block a user