From: Yu Kuai yukuai3@huawei.com
hulk inclusion category: bugfix bugzilla: 30213 CVE: CVE-2019-19770
---------------------------
The UAF in blktrace was fixed by a different approch from mainline, thus revert our solution and backport related patches.
Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Yufen Yu yuyufen@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- block/blk-sysfs.c | 49 ----------------------------------------------- 1 file changed, 49 deletions(-)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index ce84526ed51dd..2d905a8b14730 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -11,7 +11,6 @@ #include <linux/blktrace_api.h> #include <linux/blk-mq.h> #include <linux/blk-cgroup.h> -#include <linux/debugfs.h> #include <linux/atomic.h>
#include "blk.h" @@ -960,53 +959,6 @@ int blk_register_queue(struct gendisk *disk) } EXPORT_SYMBOL_GPL(blk_register_queue);
-#ifdef CONFIG_DEBUG_FS -void blk_rename_debugfs_dir(struct dentry **old) -{ - static atomic_t i = ATOMIC_INIT(0); - struct dentry *new; - char name[DNAME_INLINE_LEN]; - u32 index = atomic_fetch_inc(&i); - - snprintf(name, sizeof(name), "ready_to_remove_%u", index); - new = debugfs_lookup(name, blk_debugfs_root); - if (WARN_ON(new)) { - dput(new); - return; - } - new = debugfs_rename(blk_debugfs_root, *old, blk_debugfs_root, name); - if (WARN_ON(!new)) - return; - *old = new; -} - -/* - * blk_prepare_release_queue - rename q->debugfs_dir and q->blk_trace->dir - * @q: request_queue of which the dir to be renamed belong to. - * - * Because the final release of request_queue is in a workqueue, the - * cleanup might not been finished yet while the same device start to - * create. It's not correct if q->debugfs_dir still exist while trying - * to create a new one. - */ -static void blk_prepare_release_queue(struct request_queue *q) -{ -#ifdef CONFIG_BLK_DEBUG_FS - if (!IS_ERR_OR_NULL(q->debugfs_dir)) - blk_rename_debugfs_dir(&q->debugfs_dir); - -#endif -#ifdef CONFIG_BLK_DEV_IO_TRACE - mutex_lock(&q->blk_trace_mutex); - if (q->blk_trace && !IS_ERR_OR_NULL(q->blk_trace->dir)) - blk_rename_debugfs_dir(&q->blk_trace->dir); - mutex_unlock(&q->blk_trace_mutex); -#endif -} -#else -#define blk_prepare_release_queue(q) do { } while (0) -#endif - /** * blk_unregister_queue - counterpart of blk_register_queue() * @disk: Disk of which the request queue should be unregistered from sysfs. @@ -1031,7 +983,6 @@ void blk_unregister_queue(struct gendisk *disk) * concurrent elv_iosched_store() calls. */ mutex_lock(&q->sysfs_lock); - blk_prepare_release_queue(q);
blk_queue_flag_clear(QUEUE_FLAG_REGISTERED, q);
From: Luis Chamberlain mcgrof@kernel.org
mainline inclusion from mainline-v5.9-rc1 commit bad8e64fb19d3a0de5e564d9a7271c31bd684369 category: bugfix bugzilla: 30213 CVE: CVE-2019-19770
---------------------------
On commit 6ac93117ab00 ("blktrace: use existing disk debugfs directory") merged on v4.12 Omar fixed the original blktrace code for request-based drivers (multiqueue). This however left in place a possible crash, if you happen to abuse blktrace while racing to remove / add a device.
We used to use asynchronous removal of the request_queue, and with that the issue was easier to reproduce. Now that we have reverted to synchronous removal of the request_queue, the issue is still possible to reproduce, its however just a bit more difficult.
We essentially run two instances of break-blktrace which add/remove a loop device, and setup a blktrace and just never tear the blktrace down. We do this twice in parallel. This is easily reproduced with the script run_0004.sh from break-blktrace [0].
We can end up with two types of panics each reflecting where we race, one a failed blktrace setup:
[ 252.426751] debugfs: Directory 'loop0' with parent 'block' already present! [ 252.432265] BUG: kernel NULL pointer dereference, address: 00000000000000a0 [ 252.436592] #PF: supervisor write access in kernel mode [ 252.439822] #PF: error_code(0x0002) - not-present page [ 252.442967] PGD 0 P4D 0 [ 252.444656] Oops: 0002 [#1] SMP NOPTI [ 252.446972] CPU: 10 PID: 1153 Comm: break-blktrace Tainted: G E 5.7.0-rc2-next-20200420+ #164 [ 252.452673] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014 [ 252.456343] RIP: 0010:down_write+0x15/0x40 [ 252.458146] Code: eb ca e8 ae 22 8d ff cc cc cc cc cc cc cc cc cc cc cc cc cc cc 0f 1f 44 00 00 55 48 89 fd e8 52 db ff ff 31 c0 ba 01 00 00 00 <f0> 48 0f b1 55 00 75 0f 48 8b 04 25 c0 8b 01 00 48 89 45 08 5d [ 252.463638] RSP: 0018:ffffa626415abcc8 EFLAGS: 00010246 [ 252.464950] RAX: 0000000000000000 RBX: ffff958c25f0f5c0 RCX: ffffff8100000000 [ 252.466727] RDX: 0000000000000001 RSI: ffffff8100000000 RDI: 00000000000000a0 [ 252.468482] RBP: 00000000000000a0 R08: 0000000000000000 R09: 0000000000000001 [ 252.470014] R10: 0000000000000000 R11: ffff958d1f9227ff R12: 0000000000000000 [ 252.471473] R13: ffff958c25ea5380 R14: ffffffff8cce15f1 R15: 00000000000000a0 [ 252.473346] FS: 00007f2e69dee540(0000) GS:ffff958c2fc80000(0000) knlGS:0000000000000000 [ 252.475225] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 252.476267] CR2: 00000000000000a0 CR3: 0000000427d10004 CR4: 0000000000360ee0 [ 252.477526] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 252.478776] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 252.479866] Call Trace: [ 252.480322] simple_recursive_removal+0x4e/0x2e0 [ 252.481078] ? debugfs_remove+0x60/0x60 [ 252.481725] ? relay_destroy_buf+0x77/0xb0 [ 252.482662] debugfs_remove+0x40/0x60 [ 252.483518] blk_remove_buf_file_callback+0x5/0x10 [ 252.484328] relay_close_buf+0x2e/0x60 [ 252.484930] relay_open+0x1ce/0x2c0 [ 252.485520] do_blk_trace_setup+0x14f/0x2b0 [ 252.486187] __blk_trace_setup+0x54/0xb0 [ 252.486803] blk_trace_ioctl+0x90/0x140 [ 252.487423] ? do_sys_openat2+0x1ab/0x2d0 [ 252.488053] blkdev_ioctl+0x4d/0x260 [ 252.488636] block_ioctl+0x39/0x40 [ 252.489139] ksys_ioctl+0x87/0xc0 [ 252.489675] __x64_sys_ioctl+0x16/0x20 [ 252.490380] do_syscall_64+0x52/0x180 [ 252.491032] entry_SYSCALL_64_after_hwframe+0x44/0xa9
And the other on the device removal:
[ 128.528940] debugfs: Directory 'loop0' with parent 'block' already present! [ 128.615325] BUG: kernel NULL pointer dereference, address: 00000000000000a0 [ 128.619537] #PF: supervisor write access in kernel mode [ 128.622700] #PF: error_code(0x0002) - not-present page [ 128.625842] PGD 0 P4D 0 [ 128.627585] Oops: 0002 [#1] SMP NOPTI [ 128.629871] CPU: 12 PID: 544 Comm: break-blktrace Tainted: G E 5.7.0-rc2-next-20200420+ #164 [ 128.635595] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014 [ 128.640471] RIP: 0010:down_write+0x15/0x40 [ 128.643041] Code: eb ca e8 ae 22 8d ff cc cc cc cc cc cc cc cc cc cc cc cc cc cc 0f 1f 44 00 00 55 48 89 fd e8 52 db ff ff 31 c0 ba 01 00 00 00 <f0> 48 0f b1 55 00 75 0f 65 48 8b 04 25 c0 8b 01 00 48 89 45 08 5d [ 128.650180] RSP: 0018:ffffa9c3c05ebd78 EFLAGS: 00010246 [ 128.651820] RAX: 0000000000000000 RBX: ffff8ae9a6370240 RCX: ffffff8100000000 [ 128.653942] RDX: 0000000000000001 RSI: ffffff8100000000 RDI: 00000000000000a0 [ 128.655720] RBP: 00000000000000a0 R08: 0000000000000002 R09: ffff8ae9afd2d3d0 [ 128.657400] R10: 0000000000000056 R11: 0000000000000000 R12: 0000000000000000 [ 128.659099] R13: 0000000000000000 R14: 0000000000000003 R15: 00000000000000a0 [ 128.660500] FS: 00007febfd995540(0000) GS:ffff8ae9afd00000(0000) knlGS:0000000000000000 [ 128.662204] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 128.663426] CR2: 00000000000000a0 CR3: 0000000420042003 CR4: 0000000000360ee0 [ 128.664776] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 128.666022] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 128.667282] Call Trace: [ 128.667801] simple_recursive_removal+0x4e/0x2e0 [ 128.668663] ? debugfs_remove+0x60/0x60 [ 128.669368] debugfs_remove+0x40/0x60 [ 128.669985] blk_trace_free+0xd/0x50 [ 128.670593] __blk_trace_remove+0x27/0x40 [ 128.671274] blk_trace_shutdown+0x30/0x40 [ 128.671935] blk_release_queue+0x95/0xf0 [ 128.672589] kobject_put+0xa5/0x1b0 [ 128.673188] disk_release+0xa2/0xc0 [ 128.673786] device_release+0x28/0x80 [ 128.674376] kobject_put+0xa5/0x1b0 [ 128.674915] loop_remove+0x39/0x50 [loop] [ 128.675511] loop_control_ioctl+0x113/0x130 [loop] [ 128.676199] ksys_ioctl+0x87/0xc0 [ 128.676708] __x64_sys_ioctl+0x16/0x20 [ 128.677274] do_syscall_64+0x52/0x180 [ 128.677823] entry_SYSCALL_64_after_hwframe+0x44/0xa9
The common theme here is:
debugfs: Directory 'loop0' with parent 'block' already present
This crash happens because of how blktrace uses the debugfs directory where it places its files. Upon init we always create the same directory which would be needed by blktrace but we only do this for make_request drivers (multiqueue) block drivers. When you race a removal of these devices with a blktrace setup you end up in a situation where the make_request recursive debugfs removal will sweep away the blktrace files and then later blktrace will also try to remove individual dentries which are already NULL. The inverse is also possible and hence the two types of use after frees.
We don't create the block debugfs directory on init for these types of block devices:
* request-based block driver block devices * every possible partition * scsi-generic
And so, this race should in theory only be possible with make_request drivers.
We can fix the UAF by simply re-using the debugfs directory for make_request drivers (multiqueue) and only creating the ephemeral directory for the other type of block devices. The new clarifications on relying on the q->blk_trace_mutex *and* also checking for q->blk_trace *prior* to processing a blktrace ensures the debugfs directories are only created if no possible directory name clashes are possible.
This goes tested with:
o nvme partitions o ISCSI with tgt, and blktracing against scsi-generic with: o block o tape o cdrom o media changer o blktests
This patch is part of the work which disputes the severity of CVE-2019-19770 which shows this issue is not a core debugfs issue, but a misuse of debugfs within blktace.
Fixes: 6ac93117ab00 ("blktrace: use existing disk debugfs directory") Reported-by: syzbot+603294af2d01acfdd6da@syzkaller.appspotmail.com Signed-off-by: Luis Chamberlain mcgrof@kernel.org Reviewed-by: Christoph Hellwig hch@lst.de Cc: Bart Van Assche bvanassche@acm.org Cc: Omar Sandoval osandov@fb.com Cc: Hannes Reinecke hare@suse.com Cc: Nicolai Stange nstange@suse.de Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Michal Hocko mhocko@kernel.org Cc: "Martin K. Petersen" martin.petersen@oracle.com Cc: "James E.J. Bottomley" jejb@linux.ibm.com Cc: yu kuai yukuai3@huawei.com Signed-off-by: Jens Axboe axboe@kernel.dk
Conflict: kernel/trace/blktrace.c use 'q->mq_ops' instead of 'queue_is_mq(q)' Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Yufen Yu yuyufen@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- kernel/trace/blktrace.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 01be274c32a56..04ec425b44f45 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -521,10 +521,18 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, if (!bt->msg_data) goto err;
- ret = -ENOENT; - - dir = debugfs_lookup(buts->name, blk_debugfs_root); - if (!dir) +#ifdef CONFIG_BLK_DEBUG_FS + /* + * When tracing whole make_request drivers (multiqueue) block devices, + * reuse the existing debugfs directory created by the block layer on + * init. For request-based block devices, all partitions block devices, + * and scsi-generic block devices we create a temporary new debugfs + * directory that will be removed once the trace ends. + */ + if (q->mq_ops && bdev && bdev == bdev->bd_contains) + dir = q->debugfs_dir; + else +#endif bt->dir = dir = debugfs_create_dir(buts->name, blk_debugfs_root); if (!dir) goto err; @@ -571,8 +579,6 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
ret = 0; err: - if (dir && !bt->dir) - dput(dir); if (ret) blk_trace_free(bt); return ret;
From: Luis Chamberlain mcgrof@kernel.org
mainline inclusion from mainline-v5.9-rc1 commit b431ef837e3374da0db8ff6683170359aaa0859c category: bugfix bugzilla: 30213 CVE: CVE-2019-19770
---------------------------
We make an assumption that a debugfs directory exists, but since this can fail ensure it exists before allowing blktrace setup to complete. Otherwise we end up stuffing blktrace files on the debugfs root directory. In the worst case scenario this *in theory* can create an eventual panic *iff* in the future a similarly named file is created prior on the debugfs root directory. This theoretical crash can happen due to a recursive removal followed by a specific dentry removal.
This doesn't fix any known crash, however I have seen the files go into the main debugfs root directory in cases where the debugfs directory was not created due to other internal bugs with blktrace now fixed.
blktrace is also completely useless without this directory, so this ensures to userspace we only setup blktrace if the kernel can stuff files where they are supposed to go into.
debugfs directory creations typically aren't checked for, and we have maintainers doing sweep removals of these checks, but since we need this check to ensure proper userspace blktrace functionality we make sure to annotate the justification for the check.
Signed-off-by: Luis Chamberlain mcgrof@kernel.org Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Jens Axboe axboe@kernel.dk
Conflict: kernel/trace/blktrace.c Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Yufen Yu yuyufen@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- kernel/trace/blktrace.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 04ec425b44f45..da0ee8cc15a72 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -534,8 +534,18 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, else #endif bt->dir = dir = debugfs_create_dir(buts->name, blk_debugfs_root); - if (!dir) + + /* + * As blktrace relies on debugfs for its interface the debugfs directory + * is required, contrary to the usual mantra of not checking for debugfs + * files or directories. + */ + if (IS_ERR_OR_NULL(dir)) { + pr_warn("debugfs_dir not present for %s so skipping\n", + buts->name); + ret = -ENOENT; goto err; + }
bt->dev = dev; atomic_set(&bt->dropped, 0);
From: Wen Yang wenyang@linux.alibaba.com
mainline inclusion from mainline-v5.6 commit 4cbbc3a0eeed675449b1a4d080008927121f3da3 category: bugfix bugzilla: 32422 CVE: NA
------------------------
While unlikely the divisor in scale64_check_overflow() could be >= 32bit in scale64_check_overflow(). do_div() truncates the divisor to 32bit at least on 32bit platforms.
Use div64_u64() instead to avoid the truncation to 32-bit.
[ tglx: Massaged changelog ]
Signed-off-by: Wen Yang wenyang@linux.alibaba.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lkml.kernel.org/r/20200120100523.45656-1-wenyang@linux.alibaba.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- kernel/time/timekeeping.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index d3b375591e615..64aa492f79422 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1005,9 +1005,8 @@ static int scale64_check_overflow(u64 mult, u64 div, u64 *base) ((int)sizeof(u64)*8 - fls64(mult) < fls64(rem))) return -EOVERFLOW; tmp *= mult; - rem *= mult;
- do_div(rem, div); + rem = div64_u64(rem * mult, div); *base = tmp + rem; return 0; }
From: Guojia Liao liaoguojia@huawei.com
driver inclusion category: bugfix bugzilla: NA CVE: NA
-------------------------------------
We consider that the uniqueness of the MAC address configuration should be guaranteed by the user. So the restriction on the configuration of duplicate MAC addresses is removed in patch "remove the limitation of MAC address duplicate configuration".
What happens if a duplicate MAC address is still configured?
If the MAC address A is configured to vport A and then vport B. The MAC address of vport A in the hardware becomes invalid. If the address of vport A is changed to MAC address B, the driver needs to delete the MAC address A of vport A. Due to the MAC address A of vport A has become invalid in the hardware entry, so "-ENOENT" is returned. In this case, the "used_umv_size" value recorded in driver is not updated. As a result, the MAC entry status of the software is inconsistent with that of the hardware.
Therefore, the driver updates the umv size even if the MAC entry cannot be found. Ensure that the software and hardware status is consistent.
Signed-off-by: Guojia Liao liaoguojia@huawei.com Reviewed-by: Peng Li lipeng321@huawei.com Reviewed-by: Weiwei Deng dengweiwei@huawei.com Reviewed-by: Zhaohui Zhong zhongzhaohui@huawei.com Reviewed-by: Junxin Chen chenjunxin1@huawei.com Signed-off-by: Shengzui You youshengzui@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 823f161766aa4..24b86d704e038 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -7586,12 +7586,11 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport, hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hclge_prepare_mac_addr(&req, addr, false); ret = hclge_remove_mac_vlan_tbl(vport, &req); - if (!ret) { + if (!ret || ret == -ENOENT) { mutex_lock(&hdev->vport_lock); hclge_update_umv_space(vport, true); mutex_unlock(&hdev->vport_lock); - } else if (ret == -ENOENT) { - ret = 0; + return 0; }
return ret;
From: Guojia Liao liaoguojia@huawei.com
driver inclusion category: bugfix bugzilla: NA CVE: NA
-------------------------------------
This patch adds support of dumping MAC umv counter in debugfs, which will be helpful for debugging.
Signed-off-by: Guojia Liao liaoguojia@huawei.com Reviewed-by: Peng Li lipeng321@huawei.com Reviewed-by: Weiwei Deng dengweiwei@huawei.com Reviewed-by: Zhaohui Zhong zhongzhaohui@huawei.com Reviewed-by: Junxin Chen chenjunxin1@huawei.com Signed-off-by: Shengzui You youshengzui@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- .../ethernet/hisilicon/hns3/hns3_debugfs.c | 1 + .../hisilicon/hns3/hns3pf/hclge_debugfs.c | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index 9f4a849107598..98f2142c41bbd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -265,6 +265,7 @@ static void hns3_dbg_help(struct hnae3_handle *h) dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); dev_info(&h->pdev->dev, "dump uc mac list <func id>\n"); dev_info(&h->pdev->dev, "dump mc mac list <func id>\n"); + dev_info(&h->pdev->dev, "dump umv info <func id>\n"); dev_info(&h->pdev->dev, "dump vlan filter <func id>\n");
memset(printf_buf, 0, HNS3_DBG_BUF_LEN); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index 78f13dd77cf1d..fd86a34f36df8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -1615,6 +1615,49 @@ static int hclge_dbg_dump_mac_list(struct hclge_dev *hdev, const char *cmd_buf, return 0; }
+static void hclge_dbg_dump_umv_info(struct hclge_dev *hdev, const char *cmd_buf) +{ + struct hclge_vport *vport; + u16 share_umv_size; + u16 priv_umv_size; + u16 used_umv_num; + u32 vf_id; + int ret; + + ret = kstrtouint(cmd_buf, 0, &vf_id); + if (ret < 0) { + dev_err(&hdev->pdev->dev, + "failed to dump umv info: bad command string, ret = %d\n", + ret); + return; + } + + if (vf_id >= hdev->num_alloc_vport) { + dev_err(&hdev->pdev->dev, + "vf id(%u) is out of range(0-%u)\n", vf_id, + hdev->num_alloc_vport - 1); + return; + } + + vport = &hdev->vport[vf_id]; + mutex_lock(&hdev->vport_lock); + priv_umv_size = hdev->priv_umv_size; + share_umv_size = hdev->share_umv_size; + used_umv_num = vport->used_umv_num; + mutex_unlock(&hdev->vport_lock); + + dev_info(&hdev->pdev->dev, "num_alloc_vport : %u\n", + hdev->num_alloc_vport); + dev_info(&hdev->pdev->dev, "max_umv_size : %u\n", + hdev->max_umv_size); + dev_info(&hdev->pdev->dev, "wanted_umv_size : %u\n", + hdev->wanted_umv_size); + dev_info(&hdev->pdev->dev, "priv_umv_size : %u\n", priv_umv_size); + dev_info(&hdev->pdev->dev, "share_umv_size : %u\n", share_umv_size); + dev_info(&hdev->pdev->dev, "vport(%u) used_umv_num : %u\n", + vf_id, used_umv_num); +} + static void hclge_dbg_dump_vlan_filter(struct hclge_dev *hdev, const char *cmd_buf) { @@ -1672,6 +1715,7 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) #define DUMP_REG "dump reg" #define DUMP_LOOPBACK "dump loopback" #define DUMP_VLAN_FILTER "dump vlan filter" +#define DUMP_UMV_INFO "dump umv info"
struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -1725,6 +1769,9 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) strlen(DUMP_VLAN_FILTER)) == 0) { hclge_dbg_dump_vlan_filter(hdev, &cmd_buf[sizeof(DUMP_VLAN_FILTER)]); + } else if (strncmp(cmd_buf, DUMP_UMV_INFO, + strlen(DUMP_UMV_INFO)) == 0) { + hclge_dbg_dump_umv_info(hdev, &cmd_buf[sizeof(DUMP_UMV_INFO)]); } else { dev_info(&hdev->pdev->dev, "unknown command\n"); return -EINVAL;
From: Shengzui You youshengzui@huawei.com
driver inclusion category: bugfix bugzilla: NA CVE: NA
-----------------------------
This patch is used to update driver version to 1.9.38.6.
Signed-off-by: Shengzui You youshengzui@huawei.com Reviewed-by: Weiwei Deng dengweiwei@huawei.com Reviewed-by: Zhaohui Zhong zhongzhaohui@huawei.com Reviewed-by: Junxin Chen chenjunxin1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 6613dc0440f9c..cb2e6334e5d75 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -30,7 +30,7 @@ #include <linux/pci.h> #include <linux/types.h>
-#define HNAE3_MOD_VERSION "1.9.38.5" +#define HNAE3_MOD_VERSION "1.9.38.6"
#define HNAE3_MIN_VECTOR_NUM 2 /* first one for misc, another for IO */
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h b/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h index fb6987cf04d44..fa14f75702d1a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h @@ -4,7 +4,7 @@ #ifndef __HNS3_CAE_VERSION_H__ #define __HNS3_CAE_VERSION_H__
-#define HNS3_CAE_MOD_VERSION "1.9.38.5" +#define HNS3_CAE_MOD_VERSION "1.9.38.6"
#define CMT_ID_LEN 8 #define RESV_LEN 3 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index 77618fa9f8a84..d05a7e0c4cad2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -8,7 +8,7 @@
#include "hnae3.h"
-#define HNS3_MOD_VERSION "1.9.38.5" +#define HNS3_MOD_VERSION "1.9.38.6"
extern char hns3_driver_version[];
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 0460a78002d30..6bd9c215af9a3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -12,7 +12,7 @@ #include "hclge_cmd.h" #include "hnae3.h"
-#define HCLGE_MOD_VERSION "1.9.38.5" +#define HCLGE_MOD_VERSION "1.9.38.6" #define HCLGE_DRIVER_NAME "hclge"
#define HCLGE_MAX_PF_NUM 8 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index 094e436c98d4c..b91ff73c503b9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -10,7 +10,7 @@ #include "hclgevf_cmd.h" #include "hnae3.h"
-#define HCLGEVF_MOD_VERSION "1.9.38.5" +#define HCLGEVF_MOD_VERSION "1.9.38.6" #define HCLGEVF_DRIVER_NAME "hclgevf"
#define HCLGEVF_MAX_VLAN_ID 4095
hulk inclusion category: feature bugzilla: NA CVE: NA ---------------------------
This feature may be conflict with pointer authentication (PAC) feature from ARMv8.3 Extensions, revert it temporarily.
Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- Documentation/arm64/ilp32.txt | 52 --- arch/Kconfig | 15 - arch/arc/Kconfig | 1 - arch/arc/include/uapi/asm/unistd.h | 1 - arch/arm/Kconfig | 1 - arch/arm64/Kconfig | 17 +- arch/arm64/Makefile | 3 - arch/arm64/configs/euleros_defconfig | 2 - arch/arm64/configs/hulk_defconfig | 2 - arch/arm64/configs/openeuler_defconfig | 2 - arch/arm64/configs/storage_ci_defconfig | 2 - arch/arm64/configs/syzkaller_defconfig | 2 - arch/arm64/include/asm/compat.h | 19 +- arch/arm64/include/asm/elf.h | 36 +- arch/arm64/include/asm/fpsimd.h | 2 +- arch/arm64/include/asm/ftrace.h | 2 +- arch/arm64/include/asm/hwcap.h | 8 +- arch/arm64/include/asm/is_compat.h | 78 ---- arch/arm64/include/asm/memory.h | 4 - arch/arm64/include/asm/processor.h | 13 +- arch/arm64/include/asm/ptrace.h | 12 +- arch/arm64/include/asm/seccomp.h | 2 +- arch/arm64/include/asm/signal32.h | 19 +- arch/arm64/include/asm/signal32_common.h | 13 - arch/arm64/include/asm/signal_common.h | 303 --------------- arch/arm64/include/asm/signal_ilp32.h | 23 -- arch/arm64/include/asm/syscall.h | 10 +- arch/arm64/include/asm/thread_info.h | 4 +- arch/arm64/include/asm/unistd.h | 6 +- arch/arm64/include/asm/vdso.h | 6 - arch/arm64/include/uapi/asm/bitsperlong.h | 9 +- arch/arm64/include/uapi/asm/unistd.h | 13 - arch/arm64/kernel/Makefile | 8 +- arch/arm64/kernel/armv8_deprecated.c | 6 +- arch/arm64/kernel/asm-offsets.c | 9 +- arch/arm64/kernel/binfmt_elf32.c | 35 -- arch/arm64/kernel/binfmt_ilp32.c | 87 ----- arch/arm64/kernel/cpufeature.c | 28 +- arch/arm64/kernel/cpuinfo.c | 18 +- arch/arm64/kernel/debug-monitors.c | 4 +- arch/arm64/kernel/entry.S | 6 +- arch/arm64/kernel/head.S | 2 +- arch/arm64/kernel/hw_breakpoint.c | 8 +- arch/arm64/kernel/perf_callchain.c | 28 +- arch/arm64/kernel/perf_regs.c | 4 +- arch/arm64/kernel/process.c | 13 +- arch/arm64/kernel/ptrace.c | 38 +- arch/arm64/kernel/signal.c | 348 ++++++++++++++---- arch/arm64/kernel/signal32.c | 111 +++--- arch/arm64/kernel/signal32_common.c | 37 -- arch/arm64/kernel/signal_ilp32.c | 67 ---- arch/arm64/kernel/sys32.c | 104 +++++- arch/arm64/kernel/sys32_common.c | 106 ------ arch/arm64/kernel/sys_compat.c | 12 +- arch/arm64/kernel/sys_ilp32.c | 75 ---- arch/arm64/kernel/syscall.c | 37 +- arch/arm64/kernel/traps.c | 3 +- arch/arm64/kernel/vdso-ilp32/.gitignore | 2 - arch/arm64/kernel/vdso-ilp32/Makefile | 89 ----- arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S | 22 -- arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 84 ----- arch/arm64/kernel/vdso.c | 62 +--- arch/arm64/kernel/vdso/gettimeofday.c | 6 - arch/arm64/kernel/vdso/vdso.S | 6 +- arch/arm64/mm/mmap.c | 2 +- arch/c6x/include/uapi/asm/unistd.h | 1 - arch/h8300/Kconfig | 1 - arch/h8300/include/uapi/asm/unistd.h | 1 - arch/hexagon/Kconfig | 1 - arch/hexagon/include/uapi/asm/unistd.h | 1 - arch/m68k/Kconfig | 1 - arch/microblaze/Kconfig | 1 - arch/mips/Kconfig | 1 - arch/nds32/Kconfig | 1 - arch/nds32/include/uapi/asm/unistd.h | 1 - arch/nios2/Kconfig | 1 - arch/nios2/include/uapi/asm/unistd.h | 1 - arch/openrisc/Kconfig | 1 - arch/openrisc/include/uapi/asm/unistd.h | 1 - arch/parisc/Kconfig | 1 - arch/powerpc/Kconfig | 1 - arch/riscv/Kconfig | 1 - arch/riscv/include/asm/unistd.h | 1 - arch/sh/Kconfig | 1 - arch/sparc/Kconfig | 1 - arch/unicore32/Kconfig | 1 - arch/unicore32/include/uapi/asm/unistd.h | 1 - arch/x86/Kconfig | 1 - arch/x86/um/Kconfig | 1 - arch/xtensa/Kconfig | 1 - drivers/clocksource/arm_arch_timer.c | 4 +- include/linux/fcntl.h | 2 +- include/linux/sched.h | 1 - include/linux/thread_bits.h | 87 ----- include/linux/thread_info.h | 75 +++- include/uapi/asm-generic/unistd.h | 10 +- kernel/ptrace.c | 47 +-- scripts/checksyscalls.sh | 5 - 98 files changed, 726 insertions(+), 1679 deletions(-) delete mode 100644 Documentation/arm64/ilp32.txt delete mode 100644 arch/arm64/include/asm/is_compat.h delete mode 100644 arch/arm64/include/asm/signal32_common.h delete mode 100644 arch/arm64/include/asm/signal_common.h delete mode 100644 arch/arm64/include/asm/signal_ilp32.h delete mode 100644 arch/arm64/kernel/binfmt_elf32.c delete mode 100644 arch/arm64/kernel/binfmt_ilp32.c delete mode 100644 arch/arm64/kernel/signal32_common.c delete mode 100644 arch/arm64/kernel/signal_ilp32.c delete mode 100644 arch/arm64/kernel/sys32_common.c delete mode 100644 arch/arm64/kernel/sys_ilp32.c delete mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore delete mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile delete mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S delete mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S delete mode 100644 include/linux/thread_bits.h
diff --git a/Documentation/arm64/ilp32.txt b/Documentation/arm64/ilp32.txt deleted file mode 100644 index 5f01a61c92af5..0000000000000 --- a/Documentation/arm64/ilp32.txt +++ /dev/null @@ -1,52 +0,0 @@ -ILP32 AARCH64 SYSCALL ABI -========================= - -This document describes the ILP32 syscall ABI and where it differs -from the generic compat linux syscall interface. - -ILP32 is acronym for memory model which stands for "Integers, Longs and -Pointers are 32-bit". The main purpose of ILP32 in Linux kernel is providing -compatibility with 32-bit legacy code. Also, ILP32 binaries look better in some -performance tests. ARM has AN490 document which coves ILP32 details for ARM64 -platform: -http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0490a/ar01s01... - -AARCH64/ILP32 userspace may pass garbage in the top halve of w0-w7 registers -(syscall arguments). So top 32 bits are zeroed for them. - -Comparing to AARCH32, AARCH64/ILP32 has 64-bit length of following types: -ino_t is u64 type. -off_t is s64 type. -blkcnt_t is s64 type. -fsblkcnt_t is u64 type. -fsfilcnt_t is u64 type. -rlim_t is u64 type. - -AARCH64/ILP32 ABI uses standard syscall table which can be found at -include/uapi/asm-generic/unistd.h, with the exceptions listed below. - -Syscalls which pass 64-bit values are handled by the code shared from -AARCH32 and pass that value as a pair. Following syscalls are affected: -fadvise64_64() -fallocate() -ftruncate64() -pread64() -pwrite64() -readahead() -sync_file_range() -truncate64() - -ptrace() syscall is handled by compat version. - -shmat() syscall is handled by non-compat handler as aarch64/ilp32 has no -limitation on 4-pages alignment for shared memory. - -statfs() and fstatfs() take the size of struct statfs as an argument. -It is calculated differently in kernel and user spaces. So AARCH32 handlers -are taken to handle it. - -struct rt_sigframe is redefined and contains struct compat_siginfo, -as compat syscalls expect, and struct ilp32_ucontext, to handle -AARCH64 register set and 32-bit userspace register representation. - -elf_gregset_t is taken from lp64 to handle registers properly. diff --git a/arch/Kconfig b/arch/Kconfig index 52aa86aa8bad1..d3d70369bf9c4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -276,21 +276,6 @@ config ARCH_THREAD_STACK_ALLOCATOR config ARCH_WANTS_DYNAMIC_TASK_STRUCT bool
-config ARCH_32BIT_OFF_T - bool - depends on !64BIT - help - All new 32-bit architectures should have 64-bit off_t type on - userspace side which corresponds to the loff_t kernel type. This - is the requirement for modern ABIs. Some existing architectures - already have 32-bit off_t. This option is enabled for all such - architectures explicitly. Namely: arc, arm, blackfin, cris, frv, - h8300, hexagon, m32r, m68k, metag, microblaze, mips32, mn10300, - nios2, openrisc, parisc32, powerpc32, score, sh, sparc, tile32, - unicore32, x86_32 and xtensa. This is the complete list. Any - new 32-bit architecture should declare 64-bit off_t type on user - side and so should not enable this option. - config HAVE_REGS_AND_STACK_ACCESS_API bool help diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 8dcf0820111c2..0cce54182cc57 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -14,7 +14,6 @@ config ARC select ARCH_HAS_SYNC_DMA_FOR_DEVICE select ARCH_HAS_SG_CHAIN select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC - select ARCH_32BIT_OFF_T select BUILDTIME_EXTABLE_SORT select CLONE_BACKWARDS select COMMON_CLK diff --git a/arch/arc/include/uapi/asm/unistd.h b/arch/arc/include/uapi/asm/unistd.h index 660dbb2e799cb..517178b1daef3 100644 --- a/arch/arc/include/uapi/asm/unistd.h +++ b/arch/arc/include/uapi/asm/unistd.h @@ -17,7 +17,6 @@ #define _UAPI_ASM_ARC_UNISTD_H
#define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_CLONE #define __ARCH_WANT_SYS_VFORK diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 58852a1d004bf..407bf532a5486 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -2,7 +2,6 @@ config ARM bool default y - select ARCH_32BIT_OFF_T select ARCH_CLOCKSOURCE_DATA select ARCH_DISCARD_MEMBLOCK if !HAVE_ARCH_PFN_VALID && !KEXEC select ARCH_HAS_DEBUG_VIRTUAL if MMU diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index d444e1bdbc7e3..6fb5cc4fd6079 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -447,7 +447,7 @@ config ARM64_ERRATUM_834220
config ARM64_ERRATUM_845719 bool "Cortex-A53: 845719: a load might read incorrect data" - depends on AARCH32_EL0 + depends on COMPAT default y help This option adds an alternative code sequence to work around ARM @@ -1042,7 +1042,7 @@ config ARM64_SSBD
menuconfig ARMV8_DEPRECATED bool "Emulate deprecated/obsolete ARMv8 instructions" - depends on AARCH32_EL0 + depends on COMPAT depends on SYSCTL help Legacy software support may require certain instructions @@ -1493,13 +1493,9 @@ config DMI endmenu
config COMPAT - def_bool y - depends on AARCH32_EL0 || ARM64_ILP32 - -config AARCH32_EL0 bool "Kernel support for 32-bit EL0" - def_bool y depends on ARM64_4K_PAGES || EXPERT + select COMPAT_BINFMT_ELF if BINFMT_ELF select HAVE_UID16 select OLD_SIGSUSPEND3 select COMPAT_OLD_SIGACTION @@ -1515,13 +1511,6 @@ config AARCH32_EL0
If you want to execute 32-bit userspace applications, say Y.
-config ARM64_ILP32 - bool "Kernel support for ILP32" - help - This option enables support for AArch64 ILP32 user space. ILP32 - is an ABI where long and pointers are 32bits but it uses the AARCH64 - instruction set. - config SYSVIPC_COMPAT def_bool y depends on COMPAT && SYSVIPC diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index e20e8c082448e..9a5e281412116 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -158,9 +158,6 @@ ifeq ($(KBUILD_EXTMOD),) prepare: vdso_prepare vdso_prepare: prepare0 $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h -ifeq ($(CONFIG_ARM64_ILP32), y) - $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso-ilp32 include/generated/vdso-ilp32-offsets.h -endif endif
define archhelp diff --git a/arch/arm64/configs/euleros_defconfig b/arch/arm64/configs/euleros_defconfig index af6fb5732ee68..673dcb491a5ac 100644 --- a/arch/arm64/configs/euleros_defconfig +++ b/arch/arm64/configs/euleros_defconfig @@ -484,8 +484,6 @@ CONFIG_EFI_STUB=y CONFIG_EFI=y CONFIG_DMI=y CONFIG_COMPAT=y -CONFIG_AARCH32_EL0=y -CONFIG_ARM64_ILP32=y CONFIG_SYSVIPC_COMPAT=y
# diff --git a/arch/arm64/configs/hulk_defconfig b/arch/arm64/configs/hulk_defconfig index b5325f18054f3..9bcbc79bef166 100644 --- a/arch/arm64/configs/hulk_defconfig +++ b/arch/arm64/configs/hulk_defconfig @@ -490,8 +490,6 @@ CONFIG_EFI_STUB=y CONFIG_EFI=y CONFIG_DMI=y CONFIG_COMPAT=y -CONFIG_AARCH32_EL0=y -CONFIG_ARM64_ILP32=y CONFIG_SYSVIPC_COMPAT=y
# diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 9f2d1475cfa64..201d26100ce94 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -487,8 +487,6 @@ CONFIG_EFI_STUB=y CONFIG_EFI=y CONFIG_DMI=y CONFIG_COMPAT=y -CONFIG_AARCH32_EL0=y -# CONFIG_ARM64_ILP32 is not set CONFIG_SYSVIPC_COMPAT=y
# diff --git a/arch/arm64/configs/storage_ci_defconfig b/arch/arm64/configs/storage_ci_defconfig index 2be19309f0ff5..a9d33d58de703 100644 --- a/arch/arm64/configs/storage_ci_defconfig +++ b/arch/arm64/configs/storage_ci_defconfig @@ -467,8 +467,6 @@ CONFIG_EFI_STUB=y CONFIG_EFI=y CONFIG_DMI=y CONFIG_COMPAT=y -CONFIG_AARCH32_EL0=y -# CONFIG_ARM64_ILP32 is not set CONFIG_SYSVIPC_COMPAT=y
# diff --git a/arch/arm64/configs/syzkaller_defconfig b/arch/arm64/configs/syzkaller_defconfig index bc52e7eaabb5b..781bfd1c366fc 100644 --- a/arch/arm64/configs/syzkaller_defconfig +++ b/arch/arm64/configs/syzkaller_defconfig @@ -481,8 +481,6 @@ CONFIG_EFI_STUB=y CONFIG_EFI=y CONFIG_DMI=y CONFIG_COMPAT=y -CONFIG_AARCH32_EL0=y -CONFIG_ARM64_ILP32=y CONFIG_SYSVIPC_COMPAT=y
# diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h index b924cddb5014f..cee28a05ee98f 100644 --- a/arch/arm64/include/asm/compat.h +++ b/arch/arm64/include/asm/compat.h @@ -25,8 +25,6 @@ #include <linux/sched.h> #include <linux/sched/task_stack.h>
-#include <asm/is_compat.h> - #define COMPAT_USER_HZ 100 #ifdef __AARCH64EB__ #define COMPAT_UTS_MACHINE "armv8b\0\0" @@ -226,6 +224,23 @@ struct compat_shmid64_ds { compat_ulong_t __unused5; };
+static inline int is_compat_task(void) +{ + return test_thread_flag(TIF_32BIT); +} + +static inline int is_compat_thread(struct thread_info *thread) +{ + return test_ti_thread_flag(thread, TIF_32BIT); +} + +#else /* !CONFIG_COMPAT */ + +static inline int is_compat_thread(struct thread_info *thread) +{ + return 0; +} + #endif /* CONFIG_COMPAT */ #endif /* __KERNEL__ */ #endif /* __ASM_COMPAT_H */ diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 35c551c7df178..433b9554c6a19 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -16,10 +16,6 @@ #ifndef __ASM_ELF_H #define __ASM_ELF_H
-#ifndef __ASSEMBLY__ -#include <linux/compat.h> -#endif - #include <asm/hwcap.h>
/* @@ -146,7 +142,6 @@ typedef struct user_fpsimd_state elf_fpregset_t;
#define SET_PERSONALITY(ex) \ ({ \ - clear_thread_flag(TIF_32BIT_AARCH64); \ clear_thread_flag(TIF_32BIT); \ current->personality &= ~READ_IMPLIES_EXEC; \ }) @@ -174,9 +169,13 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp);
/* 1GB of VA */ -#define STACK_RND_MASK (is_compat_task() ? \ +#ifdef CONFIG_COMPAT +#define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \ 0x7ff >> (PAGE_SHIFT - 12) : \ 0x3ffff >> (PAGE_SHIFT - 12)) +#else +#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12)) +#endif
#ifdef __AARCH64EB__ #define COMPAT_ELF_PLATFORM ("v8b") @@ -188,16 +187,35 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */ #define COMPAT_ELF_ET_DYN_BASE 0x000400000UL -#endif /*CONFIG_COMPAT */
-#ifdef CONFIG_AARCH32_EL0 /* AArch32 registers. */ #define COMPAT_ELF_NGREG 18 typedef unsigned int compat_elf_greg_t; typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; + +/* AArch32 EABI. */ +#define EF_ARM_EABI_MASK 0xff000000 +#define compat_elf_check_arch(x) (system_supports_32bit_el0() && \ + ((x)->e_machine == EM_ARM) && \ + ((x)->e_flags & EF_ARM_EABI_MASK)) + +#define compat_start_thread compat_start_thread +/* + * Unlike the native SET_PERSONALITY macro, the compat version maintains + * READ_IMPLIES_EXEC across an execve() since this is the behaviour on + * arch/arm/. + */ +#define COMPAT_SET_PERSONALITY(ex) \ +({ \ + set_thread_flag(TIF_32BIT); \ + }) +#define COMPAT_ARCH_DLINFO extern int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp); -#endif /* CONFIG_AARCH32_EL0 */ +#define compat_arch_setup_additional_pages \ + aarch32_setup_vectors_page + +#endif /* CONFIG_COMPAT */
#endif /* !__ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 097c8d4966b1c..dd1ad3950ef5d 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -29,7 +29,7 @@ #include <linux/init.h> #include <linux/stddef.h>
-#if defined(__KERNEL__) && defined(CONFIG_AARCH32_EL0) +#if defined(__KERNEL__) && defined(CONFIG_COMPAT) /* Masks for extracting the FPSR and FPCR from the FPSCR */ #define VFP_FPSCR_STAT_MASK 0xf800009f #define VFP_FPSCR_CTRL_MASK 0x07f79f00 diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h index ce4934ccbb496..fac54fb050d00 100644 --- a/arch/arm64/include/asm/ftrace.h +++ b/arch/arm64/include/asm/ftrace.h @@ -54,7 +54,7 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs) { - return is_a32_compat_task(); + return is_compat_task(); }
#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index 428b745b53860..400b80b49595d 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -46,13 +46,15 @@ */ #define ELF_HWCAP (elf_hwcap)
-#ifdef CONFIG_AARCH32_EL0 -extern unsigned int a32_elf_hwcap, a32_elf_hwcap2; +#ifdef CONFIG_COMPAT +#define COMPAT_ELF_HWCAP (compat_elf_hwcap) +#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2) +extern unsigned int compat_elf_hwcap, compat_elf_hwcap2; #endif
enum { CAP_HWCAP = 1, -#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT CAP_COMPAT_HWCAP, CAP_COMPAT_HWCAP2, #endif diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h deleted file mode 100644 index 484c01def030c..0000000000000 --- a/arch/arm64/include/asm/is_compat.h +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ - -#ifndef __ASM_IS_COMPAT_H -#define __ASM_IS_COMPAT_H -#ifndef __ASSEMBLY__ - -#include <linux/thread_bits.h> - -#ifdef CONFIG_AARCH32_EL0 - -static inline int is_a32_compat_task(void) -{ - return test_thread_flag(TIF_32BIT); -} - -static inline int is_a32_compat_thread(struct thread_info *thread) -{ - return test_ti_thread_flag(thread, TIF_32BIT); -} - -#else - -static inline int is_a32_compat_task(void) - -{ - return 0; -} - -static inline int is_a32_compat_thread(struct thread_info *thread) -{ - return 0; -} - -#endif /* CONFIG_AARCH32_EL0 */ - -#ifdef CONFIG_ARM64_ILP32 - -static inline int is_ilp32_compat_task(void) -{ - return test_thread_flag(TIF_32BIT_AARCH64); -} - -static inline int is_ilp32_compat_thread(struct thread_info *thread) -{ - return test_ti_thread_flag(thread, TIF_32BIT_AARCH64); -} - -#else - -static inline int is_ilp32_compat_task(void) -{ - return 0; -} - -static inline int is_ilp32_compat_thread(struct thread_info *thread) -{ - return 0; -} - -#endif /* CONFIG_ARM64_ILP32 */ - -#ifdef CONFIG_COMPAT - -static inline int is_compat_task(void) -{ - return is_a32_compat_task() || is_ilp32_compat_task(); -} - -#endif /* CONFIG_COMPAT */ - -static inline int is_compat_thread(struct thread_info *thread) -{ - return is_a32_compat_thread(thread) || is_ilp32_compat_thread(thread); -} - - -#endif /* !__ASSEMBLY__ */ -#endif /* __ASM_IS_COMPAT_H */ diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index fc13895cfc79b..09bba86224b07 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -192,12 +192,10 @@ extern u64 kimage_vaddr; /* the offset between the kernel virtual and physical mappings */ extern u64 kimage_voffset;
-#ifndef __ILP32__ static inline unsigned long kaslr_offset(void) { return kimage_vaddr - KIMAGE_VADDR; } -#endif
/* * Allow all memory at the discovery stage. We will clip it later. @@ -257,7 +255,6 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); #define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page))) #define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys)))
-#ifndef __ILP32__ /* * Note: Drivers should NOT use these. They are the wrong * translation for translating DMA addresses. Use the driver @@ -274,7 +271,6 @@ static inline void *phys_to_virt(phys_addr_t x) { return (void *)(__phys_to_virt(x)); } -#endif
/* * Drivers should NOT use these either. diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index e66293afd6f3d..926981d4e0489 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -50,7 +50,6 @@
#include <asm/alternative.h> #include <asm/cpufeature.h> -#include <asm/is_compat.h> #include <asm/hw_breakpoint.h> #include <asm/lse.h> #include <asm/pgtable-hwdef.h> @@ -72,9 +71,9 @@ #else #define TASK_SIZE_32 (UL(0x100000000) - PAGE_SIZE) #endif /* CONFIG_ARM64_64K_PAGES */ -#define TASK_SIZE (is_compat_task() ? \ +#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ TASK_SIZE_32 : TASK_SIZE_64) -#define TASK_SIZE_OF(tsk) (is_compat_thread(tsk) ? \ +#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT) ? \ TASK_SIZE_32 : TASK_SIZE_64) #else #define TASK_SIZE TASK_SIZE_64 @@ -85,7 +84,7 @@ #define STACK_TOP_MAX TASK_SIZE_64 #ifdef CONFIG_COMPAT #define AARCH32_VECTORS_BASE 0xffff0000 -#define STACK_TOP (is_compat_task() ? \ +#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ AARCH32_VECTORS_BASE : STACK_TOP_MAX) #else #define STACK_TOP STACK_TOP_MAX @@ -162,11 +161,11 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset, *size = sizeof_field(struct thread_struct, uw); }
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT #define task_user_tls(t) \ ({ \ unsigned long *__tls; \ - if (is_a32_compat_thread(task_thread_info(t))) \ + if (is_compat_thread(task_thread_info(t))) \ __tls = &(t)->thread.uw.tp2_value; \ else \ __tls = &(t)->thread.uw.tp_value; \ @@ -215,7 +214,7 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc, regs->sp = sp; }
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) { diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index bf6497c757acf..046ee6e1545b4 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -207,17 +207,17 @@ static inline void forget_syscall(struct pt_regs *regs)
#define arch_has_single_step() (1)
-#ifdef CONFIG_AARCH32_EL0 -#define a32_thumb_mode(regs) \ +#ifdef CONFIG_COMPAT +#define compat_thumb_mode(regs) \ (((regs)->pstate & PSR_AA32_T_BIT)) #else -#define a32_thumb_mode(regs) (0) +#define compat_thumb_mode(regs) (0) #endif
#define user_mode(regs) \ (((regs)->pstate & PSR_MODE_MASK) == PSR_MODE_EL0t)
-#define a32_user_mode(regs) \ +#define compat_user_mode(regs) \ (((regs)->pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) == \ (PSR_MODE32_BIT | PSR_MODE_EL0t))
@@ -236,10 +236,10 @@ static inline void forget_syscall(struct pt_regs *regs) (!((regs)->pstate & PSR_F_BIT))
#define GET_USP(regs) \ - (!a32_user_mode(regs) ? (regs)->sp : (regs)->compat_sp) + (!compat_user_mode(regs) ? (regs)->sp : (regs)->compat_sp)
#define SET_USP(ptregs, value) \ - (!a32_user_mode(regs) ? ((regs)->sp = value) : ((regs)->compat_sp = value)) + (!compat_user_mode(regs) ? ((regs)->sp = value) : ((regs)->compat_sp = value))
extern int regs_query_register_offset(const char *name); extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, diff --git a/arch/arm64/include/asm/seccomp.h b/arch/arm64/include/asm/seccomp.h index 00ef0bf632305..c76fac9796290 100644 --- a/arch/arm64/include/asm/seccomp.h +++ b/arch/arm64/include/asm/seccomp.h @@ -13,7 +13,7 @@
#include <asm/unistd.h>
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT #define __NR_seccomp_read_32 __NR_compat_read #define __NR_seccomp_write_32 __NR_compat_write #define __NR_seccomp_exit_32 __NR_compat_exit diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h index 92f48828b13a1..81abea0b76508 100644 --- a/arch/arm64/include/asm/signal32.h +++ b/arch/arm64/include/asm/signal32.h @@ -17,37 +17,34 @@ #define __ASM_SIGNAL32_H
#ifdef __KERNEL__ - -#ifdef CONFIG_AARCH32_EL0 - +#ifdef CONFIG_COMPAT #include <linux/compat.h>
#define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500
-int a32_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, +int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs); - -int a32_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, +int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs);
-void a32_setup_restart_syscall(struct pt_regs *regs); +void compat_setup_restart_syscall(struct pt_regs *regs); #else
-static inline int a32_setup_frame(int usid, struct ksignal *ksig, +static inline int compat_setup_frame(int usid, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { return -ENOSYS; }
-static inline int a32_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, +static inline int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { return -ENOSYS; }
-static inline void a32_setup_restart_syscall(struct pt_regs *regs) +static inline void compat_setup_restart_syscall(struct pt_regs *regs) { } -#endif /* CONFIG_AARCH32_EL0 */ +#endif /* CONFIG_COMPAT */ #endif /* __KERNEL__ */ #endif /* __ASM_SIGNAL32_H */ diff --git a/arch/arm64/include/asm/signal32_common.h b/arch/arm64/include/asm/signal32_common.h deleted file mode 100644 index 10bcdf6b8b4c2..0000000000000 --- a/arch/arm64/include/asm/signal32_common.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ - -#ifndef __ASM_SIGNAL32_COMMON_H -#define __ASM_SIGNAL32_COMMON_H - -#ifdef CONFIG_COMPAT - -int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set); -int get_sigset_t(sigset_t *set, const compat_sigset_t __user *uset); - -#endif /* CONFIG_COMPAT*/ - -#endif /* __ASM_SIGNAL32_COMMON_H */ diff --git a/arch/arm64/include/asm/signal_common.h b/arch/arm64/include/asm/signal_common.h deleted file mode 100644 index 4045faab34b4c..0000000000000 --- a/arch/arm64/include/asm/signal_common.h +++ /dev/null @@ -1,303 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ - -/* - * Copyright (C) 1995-2009 Russell King - * Copyright (C) 2012 ARM Ltd. - * Copyright (C) 2018 Cavium Networks. - */ - -#ifndef __ASM_SIGNAL_COMMON_H -#define __ASM_SIGNAL_COMMON_H - -#include <linux/uaccess.h> -#include <asm/fpsimd.h> -#include <asm/traps.h> - -#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) -#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) -#define SIGCONTEXT_RESERVED_SIZE sizeof(((struct sigcontext *)0)->__reserved) -#define RT_SIGFRAME_RESERVED_OFFSET \ - offsetof(struct rt_sigframe, uc.uc_mcontext.__reserved) - -/* - * Sanity limit on the approximate maximum size of signal frame we'll - * try to generate. Stack alignment padding and the frame record are - * not taken into account. This limit is not a guarantee and is - * NOT ABI. - */ -#define SIGFRAME_MAXSZ SZ_64K - -struct rt_sigframe_user_layout { - void __user *sigframe; - struct frame_record __user *next_frame; - - unsigned long size; /* size of allocated sigframe data */ - unsigned long limit; /* largest allowed size */ - - unsigned long fpsimd_offset; - unsigned long esr_offset; - unsigned long sve_offset; - unsigned long extra_offset; - unsigned long end_offset; -}; - -struct user_ctxs { - struct fpsimd_context __user *fpsimd; - struct sve_context __user *sve; -}; - -struct frame_record { - u64 fp; - u64 lr; -}; - -void __user *apply_user_offset(struct rt_sigframe_user_layout const *user, - unsigned long offset); - -int setup_sigframe_layout(struct rt_sigframe_user_layout *user, bool add_all); -int setup_extra_context(char __user *sfp, unsigned long sf_size, - char __user *exprap); -int __parse_user_sigcontext(struct user_ctxs *user, - struct sigcontext __user const *sc, - void __user const *sigframe_base); -#define parse_user_sigcontext(user, sf) \ - __parse_user_sigcontext(user, &(sf)->uc.uc_mcontext, sf) - -int preserve_fpsimd_context(struct fpsimd_context __user *ctx); -int restore_fpsimd_context(struct fpsimd_context __user *ctx); - -#ifdef CONFIG_ARM64_SVE -int preserve_sve_context(struct sve_context __user *ctx); -int restore_sve_fpsimd_context(struct user_ctxs *user); -#else /* ! CONFIG_ARM64_SVE */ - -/* Turn any non-optimised out attempts to use these into a link error: */ -extern int preserve_sve_context(void __user *ctx); -extern int restore_sve_fpsimd_context(struct user_ctxs *user); - -#endif /* ! CONFIG_ARM64_SVE */ - -int sigframe_alloc(struct rt_sigframe_user_layout *user, - unsigned long *offset, size_t size); -int sigframe_alloc_end(struct rt_sigframe_user_layout *user); - -void __setup_return(struct pt_regs *regs, struct k_sigaction *ka, - struct rt_sigframe_user_layout *user, int usig); - -static void init_user_layout(struct rt_sigframe_user_layout *user) -{ - memset(user, 0, sizeof(*user)); - user->size = RT_SIGFRAME_RESERVED_OFFSET; - - user->limit = user->size + SIGCONTEXT_RESERVED_SIZE; - - user->limit -= TERMINATOR_SIZE; - user->limit -= EXTRA_CONTEXT_SIZE; - /* Reserve space for extension and terminator ^ */ -} - -static size_t sigframe_size(struct rt_sigframe_user_layout const *user) -{ - return round_up(max(user->size, sizeof(struct rt_sigframe)), 16); -} - -static int get_sigframe(struct rt_sigframe_user_layout *user, - struct ksignal *ksig, struct pt_regs *regs) -{ - unsigned long sp, sp_top; - int err; - - init_user_layout(user); - err = setup_sigframe_layout(user, false); - if (err) - return err; - - sp = sp_top = sigsp(regs->sp, ksig); - - sp = round_down(sp - sizeof(struct frame_record), 16); - user->next_frame = (struct frame_record __user *)sp; - - sp = round_down(sp, 16) - sigframe_size(user); - user->sigframe = (void __user *)sp; - - /* - * Check that we can actually write to the signal frame. - */ - if (!access_ok(user->sigframe, sp_top - sp)) - return -EFAULT; - - return 0; -} - -static int restore_sigframe(struct pt_regs *regs, - struct rt_sigframe __user *sf) -{ - sigset_t set; - int i, err; - struct user_ctxs user; - - err = get_sigset(&set, &sf->uc.uc_sigmask); - if (err == 0) - set_current_blocked(&set); - - for (i = 0; i < 31; i++) - __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], - err); - __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); - __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); - __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); - - /* - * Avoid sys_rt_sigreturn() restarting. - */ - forget_syscall(regs); - - err |= !valid_user_regs(®s->user_regs, current); - if (err == 0) - err = parse_user_sigcontext(&user, sf); - - if (err == 0) { - if (!user.fpsimd) - return -EINVAL; - - if (user.sve) { - if (!system_supports_sve()) - return -EINVAL; - - err = restore_sve_fpsimd_context(&user); - } else { - err = restore_fpsimd_context(user.fpsimd); - } - } - - return err; -} - -static int setup_sigframe(struct rt_sigframe_user_layout *user, - struct pt_regs *regs, sigset_t *set) -{ - int i, err = 0; - struct rt_sigframe __user *sf = user->sigframe; - - /* set up the stack frame for unwinding */ - __put_user_error(regs->regs[29], &user->next_frame->fp, err); - __put_user_error(regs->regs[30], &user->next_frame->lr, err); - - for (i = 0; i < 31; i++) - __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], - err); - __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); - __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); - __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); - - __put_user_error(current->thread.fault_address, - &sf->uc.uc_mcontext.fault_address, err); - - err |= put_sigset(set, &sf->uc.uc_sigmask); - - if (err == 0) { - struct fpsimd_context __user *fpsimd_ctx = - apply_user_offset(user, user->fpsimd_offset); - err |= preserve_fpsimd_context(fpsimd_ctx); - } - - /* fault information, if valid */ - if (err == 0 && user->esr_offset) { - struct esr_context __user *esr_ctx = - apply_user_offset(user, user->esr_offset); - - __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); - __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); - __put_user_error(current->thread.fault_code, - &esr_ctx->esr, err); - } - - /* Scalable Vector Extension state, if present */ - if (system_supports_sve() && err == 0 && user->sve_offset) { - struct sve_context __user *sve_ctx = - apply_user_offset(user, user->sve_offset); - err |= preserve_sve_context(sve_ctx); - } - - if (err == 0 && user->extra_offset) - setup_extra_context((char __user *)user->sigframe, user->size, - (char __user *)apply_user_offset(user, - user->extra_offset)); - - /* set the "end" magic */ - if (err == 0) { - struct _aarch64_ctx __user *end = - apply_user_offset(user, user->end_offset); - - __put_user_error(0, &end->magic, err); - __put_user_error(0, &end->size, err); - } - - return err; -} - -static long __sys_rt_sigreturn(struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - - /* Always make any pending restarted system calls return -EINTR */ - current->restart_block.fn = do_no_restart_syscall; - - /* - * Since we stacked the signal on a 128-bit boundary, then 'sp' should - * be word aligned here. - */ - if (regs->sp & 15) - goto badframe; - - frame = (struct rt_sigframe __user *)regs->sp; - - if (!access_ok(frame, sizeof(*frame))) - goto badframe; - - if (restore_sigframe(regs, frame)) - goto badframe; - - if (restore_altstack(&frame->uc.uc_stack)) - goto badframe; - - return regs->regs[0]; - -badframe: - arm64_notify_segfault(regs->sp); - return 0; -} - -static int __setup_rt_frame(int usig, struct ksignal *ksig, - sigset_t *set, struct pt_regs *regs) -{ - struct rt_sigframe_user_layout user; - struct rt_sigframe __user *frame; - int err = 0; - - fpsimd_signal_preserve_current_state(); - - if (get_sigframe(&user, ksig, regs)) - return 1; - - frame = user.sigframe; - - __put_user_error(0, &frame->uc.uc_flags, err); - __put_user_error((typeof(frame->uc.uc_link)) 0, - &frame->uc.uc_link, err); - - err |= __save_altstack(&frame->uc.uc_stack, regs->sp); - err |= setup_sigframe(&user, regs, set); - if (err == 0) { - setup_return(regs, &ksig->ka, &user, usig); - if (ksig->ka.sa.sa_flags & SA_SIGINFO) { - err |= copy_siginfo_to_user(&frame->info, &ksig->info); - regs->regs[1] = (unsigned long)&frame->info; - regs->regs[2] = (unsigned long)&frame->uc; - } - } - - return err; -} - -#endif /* __ASM_SIGNAL_COMMON_H */ diff --git a/arch/arm64/include/asm/signal_ilp32.h b/arch/arm64/include/asm/signal_ilp32.h deleted file mode 100644 index 7ee97c1336056..0000000000000 --- a/arch/arm64/include/asm/signal_ilp32.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ - -#ifndef __ASM_SIGNAL_ILP32_H -#define __ASM_SIGNAL_ILP32_H - -#ifdef CONFIG_ARM64_ILP32 - -#include <linux/compat.h> - -int ilp32_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, - struct pt_regs *regs); - -#else - -static inline int ilp32_setup_rt_frame(int usig, struct ksignal *ksig, - sigset_t *set, struct pt_regs *regs) -{ - return -ENOSYS; -} - -#endif /* CONFIG_ARM64_ILP32 */ - -#endif /* __ASM_SIGNAL_ILP32_H */ diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h index 7ffed9d85f0ae..615376030abad 100644 --- a/arch/arm64/include/asm/syscall.h +++ b/arch/arm64/include/asm/syscall.h @@ -24,12 +24,8 @@ typedef long (*syscall_fn_t)(const struct pt_regs *regs);
extern const syscall_fn_t sys_call_table[];
-#ifdef CONFIG_AARCH32_EL0 -extern const syscall_fn_t a32_sys_call_table[]; -#endif - -#ifdef CONFIG_ARM64_ILP32 -extern const syscall_fn_t ilp32_sys_call_table[]; +#ifdef CONFIG_COMPAT +extern const syscall_fn_t compat_sys_call_table[]; #endif
static inline int syscall_get_nr(struct task_struct *task, @@ -133,7 +129,7 @@ static inline void syscall_set_arguments(struct task_struct *task, */ static inline int syscall_get_arch(void) { - if (is_a32_compat_task()) + if (is_compat_task()) return AUDIT_ARCH_ARM;
return AUDIT_ARCH_AARCH64; diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 01f063a81d648..802a7d10ab821 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -88,11 +88,10 @@ void arch_release_task_struct(struct task_struct *tsk); #define TIF_FREEZE 19 #define TIF_RESTORE_SIGMASK 20 #define TIF_SINGLESTEP 21 -#define TIF_32BIT 22 /* AARCH32 process */ +#define TIF_32BIT 22 /* 32bit process */ #define TIF_SVE 23 /* Scalable Vector Extension in use */ #define TIF_SVE_VL_INHERIT 24 /* Inherit sve_vl_onexec across exec */ #define TIF_SSBD 25 /* Wants SSB mitigation */ -#define TIF_32BIT_AARCH64 26 /* 32 bit process on AArch64(ILP32) */
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -109,7 +108,6 @@ void arch_release_task_struct(struct task_struct *tsk); #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_SVE (1 << TIF_SVE) -#define _TIF_32BIT_AARCH64 (1 << TIF_32BIT_AARCH64) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index f3401de12dc9d..d52051879ffe2 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -13,16 +13,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ - #ifdef CONFIG_COMPAT #define __ARCH_WANT_COMPAT_STAT64 -#define __ARCH_WANT_SYS_LLSEEK -#endif - -#ifdef CONFIG_AARCH32_EL0 #define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK #define __ARCH_WANT_SYS_NICE #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h index 33a4e10014aad..839ce0031bd58 100644 --- a/arch/arm64/include/asm/vdso.h +++ b/arch/arm64/include/asm/vdso.h @@ -29,12 +29,6 @@
#include <generated/vdso-offsets.h>
-#ifdef CONFIG_ARM64_ILP32 -#include <generated/vdso-ilp32-offsets.h> -#else -#define vdso_offset_sigtramp_ilp32 ({ BUILD_BUG(); 0; }) -#endif - #define VDSO_SYMBOL(base, name) \ ({ \ (void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \ diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h index 9a05a9659e761..485d60bee26ca 100644 --- a/arch/arm64/include/uapi/asm/bitsperlong.h +++ b/arch/arm64/include/uapi/asm/bitsperlong.h @@ -17,14 +17,7 @@ #ifndef __ASM_BITSPERLONG_H #define __ASM_BITSPERLONG_H
-#if defined(__LP64__) -/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */ -# define __BITS_PER_LONG 64 -#elif defined(__ILP32__) -# define __BITS_PER_LONG 32 -#else -# error "Neither LP64 nor ILP32: unsupported ABI in asm/bitsperlong.h" -#endif +#define __BITS_PER_LONG 64
#include <asm-generic/bitsperlong.h>
diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h index 80f1cb4ae2e13..5072cbd15c829 100644 --- a/arch/arm64/include/uapi/asm/unistd.h +++ b/arch/arm64/include/uapi/asm/unistd.h @@ -15,19 +15,6 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */
-/* - * Use AARCH32 interface for sys_sync_file_range() as it passes 64-bit arguments. - */ -#if defined(__ILP32__) || defined(__SYSCALL_COMPAT) -#define __ARCH_WANT_SYNC_FILE_RANGE2 -#endif - -/* - * AARCH64/ILP32 is introduced after next syscalls were deprecated. - */ -#if !(defined(__ILP32__) || defined(__SYSCALL_COMPAT)) #define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_SET_GET_RLIMIT -#endif
#include <asm-generic/unistd.h> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 1c9e374821f67..d9237117da97c 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -27,11 +27,8 @@ OBJCOPYFLAGS := --prefix-symbols=__efistub_ $(obj)/%.stub.o: $(obj)/%.o FORCE $(call if_changed,objcopy)
-arm64-obj-$(CONFIG_AARCH32_EL0) += sys32.o kuser32.o signal32.o \ - sys_compat.o binfmt_elf32.o -arm64-obj-$(CONFIG_ARM64_ILP32) += binfmt_ilp32.o sys_ilp32.o \ - signal_ilp32.o -arm64-obj-$(CONFIG_COMPAT) += sys32_common.o signal32_common.o +arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ + sys_compat.o arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o @@ -68,7 +65,6 @@ arm64-obj-$(CONFIG_MPAM) += mpam.o mpam_ctrlmon.o mpam_mon.o arm64-obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
obj-y += $(arm64-obj-y) vdso/ probes/ -obj-$(CONFIG_ARM64_ILP32) += vdso-ilp32/ obj-m += $(arm64-obj-m) head-y := head.o extra-y += $(head-y) vmlinux.lds diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index 4cd5f244323b8..c14b3a508c8a5 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -559,7 +559,7 @@ static int setend_set_hw_mode(bool enable) return 0; }
-static int __a32_setend_handler(struct pt_regs *regs, u32 big_endian) +static int compat_setend_handler(struct pt_regs *regs, u32 big_endian) { char *insn;
@@ -582,14 +582,14 @@ static int __a32_setend_handler(struct pt_regs *regs, u32 big_endian)
static int a32_setend_handler(struct pt_regs *regs, u32 instr) { - int rc = __a32_setend_handler(regs, (instr >> 9) & 1); + int rc = compat_setend_handler(regs, (instr >> 9) & 1); arm64_skip_faulting_instruction(regs, 4); return rc; }
static int t16_setend_handler(struct pt_regs *regs, u32 instr) { - int rc = __a32_setend_handler(regs, (instr >> 3) & 1); + int rc = compat_setend_handler(regs, (instr >> 3) & 1); arm64_skip_faulting_instruction(regs, 2); return rc; } diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 6e1847fb44115..f7776492164be 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -70,7 +70,7 @@ int main(void) DEFINE(S_X28, offsetof(struct pt_regs, regs[28])); DEFINE(S_LR, offsetof(struct pt_regs, regs[30])); DEFINE(S_SP, offsetof(struct pt_regs, sp)); -#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT DEFINE(S_COMPAT_SP, offsetof(struct pt_regs, compat_sp)); #endif DEFINE(S_PSTATE, offsetof(struct pt_regs, pstate)); @@ -129,13 +129,6 @@ int main(void) DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec)); DEFINE(TSPEC_TV_NSEC, offsetof(struct timespec, tv_nsec)); BLANK(); -#ifdef CONFIG_COMPAT - DEFINE(COMPAT_TVAL_TV_SEC, offsetof(struct compat_timeval, tv_sec)); - DEFINE(COMPAT_TVAL_TV_USEC, offsetof(struct compat_timeval, tv_usec)); - DEFINE(COMPAT_TSPEC_TV_SEC, offsetof(struct compat_timespec, tv_sec)); - DEFINE(COMPAT_TSPEC_TV_NSEC, offsetof(struct compat_timespec, tv_nsec)); - BLANK(); -#endif DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest)); DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime)); BLANK(); diff --git a/arch/arm64/kernel/binfmt_elf32.c b/arch/arm64/kernel/binfmt_elf32.c deleted file mode 100644 index 2b49d2a40d8bd..0000000000000 --- a/arch/arm64/kernel/binfmt_elf32.c +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ - -/* - * Support for AArch32 Linux ELF binaries. - */ - -/* AArch32 EABI. */ -#define EF_ARM_EABI_MASK 0xff000000 - -#define compat_start_thread compat_start_thread -/* - * Unlike the native SET_PERSONALITY macro, the compat version inherits - * READ_IMPLIES_EXEC across a fork() since this is the behaviour on - * arch/arm/. - */ -#define COMPAT_SET_PERSONALITY(ex) \ -({ \ - clear_thread_flag(TIF_32BIT_AARCH64); \ - set_thread_flag(TIF_32BIT); \ -}) - -#define COMPAT_ARCH_DLINFO -#define COMPAT_ELF_HWCAP (a32_elf_hwcap) -#define COMPAT_ELF_HWCAP2 (a32_elf_hwcap2) - -#define compat_arch_setup_additional_pages \ - aarch32_setup_vectors_page - -/* AArch32 EABI. */ -#define compat_elf_check_arch(x) (system_supports_32bit_el0() && \ - ((x)->e_machine == EM_ARM) && \ - ((x)->e_flags & EF_ARM_EABI_MASK)) - - -#include "../../../fs/compat_binfmt_elf.c" diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c deleted file mode 100644 index 26b2477d190db..0000000000000 --- a/arch/arm64/kernel/binfmt_ilp32.c +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ - -/* - * Support for ILP32 Linux/aarch64 ELF binaries. - */ -#undef CONFIG_AARCH32_EL0 -#define compat_elf_gregset_t elf_gregset_t - -#include <linux/elfcore-compat.h> -#include <linux/time.h> - -#undef ELF_CLASS -#define ELF_CLASS ELFCLASS32 - -#undef elfhdr -#undef elf_phdr -#undef elf_shdr -#undef elf_note -#undef elf_addr_t -#define elfhdr elf32_hdr -#define elf_phdr elf32_phdr -#define elf_shdr elf32_shdr -#define elf_note elf32_note -#define elf_addr_t Elf32_Addr - -/* - * Some data types as stored in coredump. - */ -#define user_long_t compat_long_t -#define user_siginfo_t compat_siginfo_t -#define copy_siginfo_to_user copy_siginfo_to_user32 - -/* - * The machine-dependent core note format types are defined in elfcore-compat.h, - * which requires asm/elf.h to define compat_elf_gregset_t et al. - */ -#define elf_prstatus compat_elf_prstatus -#define elf_prpsinfo compat_elf_prpsinfo - -/* AARCH64 ILP32 EABI. */ -#undef elf_check_arch -#define elf_check_arch(x) (((x)->e_machine == EM_AARCH64) \ - && (x)->e_ident[EI_CLASS] == ELFCLASS32) - -#undef SET_PERSONALITY -#define SET_PERSONALITY(ex) \ -do { \ - set_bit(TIF_32BIT, ¤t->mm->context.flags); \ - set_thread_flag(TIF_32BIT_AARCH64); \ - clear_thread_flag(TIF_32BIT); \ -} while (0) - -#undef ARCH_DLINFO -#define ARCH_DLINFO \ -do { \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, \ - (elf_addr_t)(long)current->mm->context.vdso); \ -} while (0) - -#undef ELF_PLATFORM -#ifdef __AARCH64EB__ -#define ELF_PLATFORM ("aarch64_be:ilp32") -#else -#define ELF_PLATFORM ("aarch64:ilp32") -#endif - -#undef ELF_ET_DYN_BASE -#define ELF_ET_DYN_BASE COMPAT_ELF_ET_DYN_BASE - -#undef ELF_HWCAP -#undef ELF_HWCAP2 -#define ELF_HWCAP ((u32) elf_hwcap) -#define ELF_HWCAP2 ((u32) (elf_hwcap >> 32)) - -/* - * Rename a few of the symbols that binfmt_elf.c will define. - * These are all local so the names don't really matter, but it - * might make some debugging less confusing not to duplicate them. - */ -#define elf_format compat_elf_format -#define init_elf_binfmt init_compat_elf_binfmt -#define exit_elf_binfmt exit_compat_elf_binfmt - -#undef ns_to_timeval -#define ns_to_timeval ns_to_compat_timeval - -#include "../../../fs/binfmt_elf.c" diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index edd6682cc2f1b..8df58d0859e81 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -38,14 +38,14 @@ unsigned long elf_hwcap __read_mostly; EXPORT_SYMBOL_GPL(elf_hwcap);
-#ifdef CONFIG_AARCH32_EL0 -#define AARCH32_EL0_ELF_HWCAP_DEFAULT \ +#ifdef CONFIG_COMPAT +#define COMPAT_ELF_HWCAP_DEFAULT \ (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\ COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\ COMPAT_HWCAP_TLS|COMPAT_HWCAP_IDIV|\ COMPAT_HWCAP_LPAE) -unsigned int a32_elf_hwcap __read_mostly = AARCH32_EL0_ELF_HWCAP_DEFAULT; -unsigned int a32_elf_hwcap2 __read_mostly; +unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT; +unsigned int compat_elf_hwcap2 __read_mostly; #endif
DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); @@ -1706,8 +1706,8 @@ static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope) } #endif
-static const struct arm64_cpu_capabilities a32_elf_hwcaps[] = { -#ifdef CONFIG_AARCH32_EL0 +static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = { +#ifdef CONFIG_COMPAT HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON), HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4), /* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */ @@ -1728,12 +1728,12 @@ static void __init cap_set_elf_hwcap(const struct arm64_cpu_capabilities *cap) case CAP_HWCAP: elf_hwcap |= cap->hwcap; break; -#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT case CAP_COMPAT_HWCAP: - a32_elf_hwcap |= (u32)cap->hwcap; + compat_elf_hwcap |= (u32)cap->hwcap; break; case CAP_COMPAT_HWCAP2: - a32_elf_hwcap2 |= (u32)cap->hwcap; + compat_elf_hwcap2 |= (u32)cap->hwcap; break; #endif default: @@ -1751,12 +1751,12 @@ static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap) case CAP_HWCAP: rc = (elf_hwcap & cap->hwcap) != 0; break; -#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT case CAP_COMPAT_HWCAP: - rc = (a32_elf_hwcap & (u32)cap->hwcap) != 0; + rc = (compat_elf_hwcap & (u32)cap->hwcap) != 0; break; case CAP_COMPAT_HWCAP2: - rc = (a32_elf_hwcap2 & (u32)cap->hwcap) != 0; + rc = (compat_elf_hwcap2 & (u32)cap->hwcap) != 0; break; #endif default: @@ -2005,7 +2005,7 @@ static void verify_local_cpu_capabilities(void) verify_local_elf_hwcaps(arm64_elf_hwcaps);
if (system_supports_32bit_el0()) - verify_local_elf_hwcaps(a32_elf_hwcaps); + verify_local_elf_hwcaps(compat_elf_hwcaps);
if (system_supports_sve()) verify_sve_features(); @@ -2076,7 +2076,7 @@ void __init setup_cpu_features(void) setup_elf_hwcaps(arm64_elf_hwcaps);
if (system_supports_32bit_el0()) - setup_elf_hwcaps(a32_elf_hwcaps); + setup_elf_hwcaps(compat_elf_hwcaps);
if (system_uses_ttbr0_pan()) pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n"); diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index a11a66c1199dc..ca0685f339002 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -88,7 +88,7 @@ static const char *const hwcap_str[] = { NULL };
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT static const char *const compat_hwcap_str[] = { "swp", "half", @@ -123,12 +123,12 @@ static const char *const compat_hwcap2_str[] = { "crc32", NULL }; -#endif /* CONFIG_AARCH32_EL0 */ +#endif /* CONFIG_COMPAT */
static int c_show(struct seq_file *m, void *v) { int i, j; - bool aarch32 = personality(current->personality) == PER_LINUX32; + bool compat = personality(current->personality) == PER_LINUX32;
for_each_online_cpu(i) { struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i); @@ -140,7 +140,7 @@ static int c_show(struct seq_file *m, void *v) * "processor". Give glibc what it expects. */ seq_printf(m, "processor\t: %d\n", i); - if (aarch32) + if (compat) seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n", MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
@@ -155,16 +155,16 @@ static int c_show(struct seq_file *m, void *v) * software which does already (at least for 32-bit). */ seq_puts(m, "Features\t:"); - if (aarch32) { -#ifdef CONFIG_AARCH32_EL0 + if (compat) { +#ifdef CONFIG_COMPAT for (j = 0; compat_hwcap_str[j]; j++) - if (a32_elf_hwcap & (1 << j)) + if (compat_elf_hwcap & (1 << j)) seq_printf(m, " %s", compat_hwcap_str[j]);
for (j = 0; compat_hwcap2_str[j]; j++) - if (a32_elf_hwcap2 & (1 << j)) + if (compat_elf_hwcap2 & (1 << j)) seq_printf(m, " %s", compat_hwcap2_str[j]); -#endif /* CONFIG_AARCH32_EL0 */ +#endif /* CONFIG_COMPAT */ } else { for (j = 0; hwcap_str[j]; j++) if (elf_hwcap & (1 << j)) diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 34df37bab5d44..501e835c65007 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -343,10 +343,10 @@ int aarch32_break_handler(struct pt_regs *regs) bool bp = false; void __user *pc = (void __user *)instruction_pointer(regs);
- if (!a32_user_mode(regs)) + if (!compat_user_mode(regs)) return -EFAULT;
- if (a32_thumb_mode(regs)) { + if (compat_thumb_mode(regs)) { /* get 16-bit Thumb instruction */ __le16 instr; get_user(instr, (__le16 __user *)pc); diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 8c84c43dfcd72..54092ae9968ad 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -489,7 +489,7 @@ ENTRY(vectors) kernel_ventry 0, fiq_invalid // FIQ 64-bit EL0 kernel_ventry 0, error // Error 64-bit EL0
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT kernel_ventry 0, sync_compat, 32 // Synchronous 32-bit EL0 kernel_ventry 0, irq_compat, 32 // IRQ 32-bit EL0 kernel_ventry 0, fiq_invalid_compat, 32 // FIQ 32-bit EL0 @@ -558,7 +558,7 @@ el0_error_invalid: inv_entry 0, BAD_ERROR ENDPROC(el0_error_invalid)
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT el0_fiq_invalid_compat: inv_entry 0, BAD_FIQ, 32 ENDPROC(el0_fiq_invalid_compat) @@ -759,7 +759,7 @@ el0_sync: b.ge el0_dbg b el0_inv
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT .align 6 el0_sync_compat: kernel_entry 0, 32 diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 2c1f6e0e5c59b..d22ab8d9edc95 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -542,7 +542,7 @@ set_hcr: msr vpidr_el2, x0 msr vmpidr_el2, x1
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT msr hstr_el2, xzr // Disable CP15 traps to EL2 #endif
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c index bc83afe54134e..9f105fe58595d 100644 --- a/arch/arm64/kernel/hw_breakpoint.c +++ b/arch/arm64/kernel/hw_breakpoint.c @@ -168,7 +168,7 @@ enum hw_breakpoint_ops { HW_BREAKPOINT_RESTORE };
-static int is_a32_compat_bp(struct perf_event *bp) +static int is_compat_bp(struct perf_event *bp) { struct task_struct *tsk = bp->hw.target;
@@ -179,7 +179,7 @@ static int is_a32_compat_bp(struct perf_event *bp) * deprecated behaviour if we use unaligned watchpoints in * AArch64 state. */ - return tsk && is_a32_compat_thread(task_thread_info(tsk)); + return tsk && is_compat_thread(task_thread_info(tsk)); }
/** @@ -478,7 +478,7 @@ static int arch_build_bp_info(struct perf_event *bp, * Watchpoints can be of length 1, 2, 4 or 8 bytes. */ if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE) { - if (is_a32_compat_bp(bp)) { + if (is_compat_bp(bp)) { if (hw->ctrl.len != ARM_BREAKPOINT_LEN_2 && hw->ctrl.len != ARM_BREAKPOINT_LEN_4) return -EINVAL; @@ -536,7 +536,7 @@ int hw_breakpoint_arch_parse(struct perf_event *bp, * AArch32 tasks expect some simple alignment fixups, so emulate * that here. */ - if (is_a32_compat_bp(bp)) { + if (is_compat_bp(bp)) { if (hw->ctrl.len == ARM_BREAKPOINT_LEN_8) alignment_mask = 0x7; else diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c index edb86558290c5..742a45c787070 100644 --- a/arch/arm64/kernel/perf_callchain.c +++ b/arch/arm64/kernel/perf_callchain.c @@ -63,26 +63,26 @@ user_backtrace(struct frame_tail __user *tail, return buftail.fp; }
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT /* * The registers we're interested in are at the end of the variable * length saved register structure. The fp points at the end of this * structure so the address of this struct is: - * (struct a32_frame_tail *)(xxx->fp)-1 + * (struct compat_frame_tail *)(xxx->fp)-1 * * This code has been adapted from the ARM OProfile support. */ -struct a32_frame_tail { - compat_uptr_t fp; /* a (struct a32_frame_tail *) in compat mode */ +struct compat_frame_tail { + compat_uptr_t fp; /* a (struct compat_frame_tail *) in compat mode */ u32 sp; u32 lr; } __attribute__((packed));
-static struct a32_frame_tail __user * -compat_user_backtrace(struct a32_frame_tail __user *tail, +static struct compat_frame_tail __user * +compat_user_backtrace(struct compat_frame_tail __user *tail, struct perf_callchain_entry_ctx *entry) { - struct a32_frame_tail buftail; + struct compat_frame_tail buftail; unsigned long err;
/* Also check accessibility of one struct frame_tail beyond */ @@ -102,13 +102,13 @@ compat_user_backtrace(struct a32_frame_tail __user *tail, * Frame pointers should strictly progress back up the stack * (towards higher addresses). */ - if (tail + 1 >= (struct a32_frame_tail __user *) + if (tail + 1 >= (struct compat_frame_tail __user *) compat_ptr(buftail.fp)) return NULL;
- return (struct a32_frame_tail __user *)compat_ptr(buftail.fp) - 1; + return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1; } -#endif /* CONFIG_AARCH32_EL0 */ +#endif /* CONFIG_COMPAT */
void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) @@ -120,7 +120,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
perf_callchain_store(entry, regs->pc);
- if (!a32_user_mode(regs)) { + if (!compat_user_mode(regs)) { /* AARCH64 mode */ struct frame_tail __user *tail;
@@ -130,11 +130,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, tail && !((unsigned long)tail & 0xf)) tail = user_backtrace(tail, entry); } else { -#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT /* AARCH32 compat mode */ - struct a32_frame_tail __user *tail; + struct compat_frame_tail __user *tail;
- tail = (struct a32_frame_tail __user *)regs->compat_fp - 1; + tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
while ((entry->nr < entry->max_stack) && tail && !((unsigned long)tail & 0x3)) diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c index 3682cb13c1b7a..666b225aeb3ad 100644 --- a/arch/arm64/kernel/perf_regs.c +++ b/arch/arm64/kernel/perf_regs.c @@ -36,7 +36,7 @@ u64 perf_reg_value(struct pt_regs *regs, int idx) * At the time we make a sample, we don't know whether the consumer is * 32-bit or 64-bit, so we have to cater for both possibilities. */ - if (a32_user_mode(regs)) { + if (compat_user_mode(regs)) { if ((u32)idx == PERF_REG_ARM64_SP) return regs->compat_sp; if ((u32)idx == PERF_REG_ARM64_LR) @@ -66,7 +66,7 @@ int perf_reg_validate(u64 mask)
u64 perf_reg_abi(struct task_struct *task) { - if (is_a32_compat_thread(task_thread_info(task))) + if (is_compat_thread(task_thread_info(task))) return PERF_SAMPLE_REGS_ABI_32; else return PERF_SAMPLE_REGS_ABI_64; diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 1073b5620c67b..acf9a7b6ecec7 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -52,6 +52,7 @@
#include <asm/alternative.h> #include <asm/arch_gicv3.h> +#include <asm/compat.h> #include <asm/cacheflush.h> #include <asm/exec.h> #include <asm/fpsimd.h> @@ -224,7 +225,7 @@ static void print_pstate(struct pt_regs *regs) { u64 pstate = regs->pstate;
- if (a32_user_mode(regs)) { + if (compat_user_mode(regs)) { printk("pstate: %08llx (%c%c%c%c %c %s %s %c%c%c)\n", pstate, pstate & PSR_AA32_N_BIT ? 'N' : 'n', @@ -258,7 +259,7 @@ void __show_regs(struct pt_regs *regs) int i, top_reg; u64 lr, sp;
- if (a32_user_mode(regs)) { + if (compat_user_mode(regs)) { lr = regs->compat_lr; sp = regs->compat_sp; top_reg = 12; @@ -309,7 +310,7 @@ static void tls_thread_flush(void) { write_sysreg(0, tpidr_el0);
- if (is_a32_compat_task()) { + if (is_compat_task()) { current->thread.uw.tp_value = 0;
/* @@ -391,7 +392,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, *task_user_tls(p) = read_sysreg(tpidr_el0);
if (stack_start) { - if (is_a32_compat_thread(task_thread_info(p))) + if (is_compat_thread(task_thread_info(p))) childregs->compat_sp = stack_start; else childregs->sp = stack_start; @@ -435,7 +436,7 @@ static void tls_thread_switch(struct task_struct *next) { tls_preserve_current_state();
- if (is_a32_compat_thread(task_thread_info(next))) + if (is_compat_thread(task_thread_info(next))) write_sysreg(next->thread.uw.tp_value, tpidrro_el0); else if (!arm64_kernel_unmapped_at_el0()) write_sysreg(0, tpidrro_el0); @@ -481,7 +482,7 @@ static void ssbs_thread_switch(struct task_struct *next) test_tsk_thread_flag(next, TIF_SSBD)) return;
- if (a32_user_mode(regs)) + if (compat_user_mode(regs)) set_compat_ssbs_bit(regs); else if (user_mode(regs)) set_ssbs_bit(regs); diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 2b6b8f3fa9ec6..52b11e80ca698 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -41,6 +41,7 @@ #include <linux/tracehook.h> #include <linux/elf.h>
+#include <asm/compat.h> #include <asm/cpufeature.h> #include <asm/debug-monitors.h> #include <asm/fpsimd.h> @@ -190,8 +191,8 @@ static void ptrace_hbptriggered(struct perf_event *bp, info.si_code = TRAP_HWBKPT; info.si_addr = (void __user *)(bkpt->trigger);
-#ifdef CONFIG_AARCH32_EL0 - if (is_a32_compat_task()) { +#ifdef CONFIG_COMPAT + if (is_compat_task()) { int si_errno = 0; int i;
@@ -1245,10 +1246,6 @@ static const struct user_regset_view user_aarch64_view = { };
#ifdef CONFIG_COMPAT -#include <linux/compat.h> -#endif - -#ifdef CONFIG_AARCH32_EL0 enum compat_regset { REGSET_COMPAT_GPR, REGSET_COMPAT_VFP, @@ -1714,7 +1711,7 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num, } #endif /* CONFIG_HAVE_HW_BREAKPOINT */
-static long compat_a32_ptrace(struct task_struct *child, compat_long_t request, +long compat_arch_ptrace(struct task_struct *child, compat_long_t request, compat_ulong_t caddr, compat_ulong_t cdata) { unsigned long addr = caddr; @@ -1791,35 +1788,20 @@ static long compat_a32_ptrace(struct task_struct *child, compat_long_t request,
return ret; } - -#else -#define compat_a32_ptrace(child, request, caddr, cdata) (0) -#endif /* CONFIG_AARCH32_EL0 */ - -#ifdef CONFIG_COMPAT -long compat_arch_ptrace(struct task_struct *child, compat_long_t request, - compat_ulong_t caddr, compat_ulong_t cdata) -{ - if (is_a32_compat_task()) - return compat_a32_ptrace(child, request, caddr, cdata); - - /* ILP32 */ - return compat_ptrace_request(child, request, caddr, cdata); -} -#endif +#endif /* CONFIG_COMPAT */
const struct user_regset_view *task_user_regset_view(struct task_struct *task) { -#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT /* * Core dumping of 32-bit tasks or compat ptrace requests must use the * user_aarch32_view compatible with arm32. Native ptrace requests on * 32-bit children use an extended user_aarch32_ptrace_view to allow * access to the TLS register. */ - if (is_a32_compat_task()) + if (is_compat_task()) return &user_aarch32_view; - else if (is_a32_compat_thread(task_thread_info(task))) + else if (is_compat_thread(task_thread_info(task))) return &user_aarch32_ptrace_view; #endif return &user_aarch64_view; @@ -1846,7 +1828,7 @@ static void tracehook_report_syscall(struct pt_regs *regs, * A scratch register (ip(r12) on AArch32, x7 on AArch64) is * used to denote syscall entry/exit: */ - regno = (is_a32_compat_task() ? 12 : 7); + regno = (is_compat_task() ? 12 : 7); saved_reg = regs->regs[regno]; regs->regs[regno] = dir;
@@ -1977,7 +1959,7 @@ int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task) /* https://lore.kernel.org/lkml/20191118131525.GA4180@willie-the-truck */ user_regs_reset_single_step(regs, task);
- if (is_a32_compat_thread(task_thread_info(task))) + if (is_compat_thread(task_thread_info(task))) return valid_compat_regs(regs); else return valid_native_regs(regs); diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index a733bbb709a68..f8291666a45a6 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -44,10 +44,6 @@ #include <asm/traps.h> #include <asm/vdso.h> #include <asm/ras.h> -#include <asm/signal_ilp32.h> - -#define get_sigset(s, m) __copy_from_user(s, m, sizeof(*s)) -#define put_sigset(s, m) __copy_to_user(m, s, sizeof(*s))
/* * Do a signal return; undo the signal stack. These are aligned to 128-bit. @@ -56,12 +52,57 @@ struct rt_sigframe { struct siginfo info; struct ucontext uc; }; -struct rt_sigframe_user_layout;
-static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, - struct rt_sigframe_user_layout *user, int usig); +struct frame_record { + u64 fp; + u64 lr; +}; + +struct rt_sigframe_user_layout { + struct rt_sigframe __user *sigframe; + struct frame_record __user *next_frame; + + unsigned long size; /* size of allocated sigframe data */ + unsigned long limit; /* largest allowed size */ + + unsigned long fpsimd_offset; + unsigned long esr_offset; + unsigned long sve_offset; + unsigned long extra_offset; + unsigned long end_offset; +}; + +#define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16) +#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) +#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) + +static void init_user_layout(struct rt_sigframe_user_layout *user) +{ + const size_t reserved_size = + sizeof(user->sigframe->uc.uc_mcontext.__reserved); + + memset(user, 0, sizeof(*user)); + user->size = offsetof(struct rt_sigframe, uc.uc_mcontext.__reserved); + + user->limit = user->size + reserved_size; + + user->limit -= TERMINATOR_SIZE; + user->limit -= EXTRA_CONTEXT_SIZE; + /* Reserve space for extension and terminator ^ */ +}
-#include <asm/signal_common.h> +static size_t sigframe_size(struct rt_sigframe_user_layout const *user) +{ + return round_up(max(user->size, sizeof(struct rt_sigframe)), 16); +} + +/* + * Sanity limit on the approximate maximum size of signal frame we'll + * try to generate. Stack alignment padding and the frame record are + * not taken into account. This limit is not a guarantee and is + * NOT ABI. + */ +#define SIGFRAME_MAXSZ SZ_64K
static int __sigframe_alloc(struct rt_sigframe_user_layout *user, unsigned long *offset, size_t size, bool extend) @@ -106,14 +147,14 @@ static int __sigframe_alloc(struct rt_sigframe_user_layout *user, * signal frame. The offset from the signal frame base address to the * allocated block is assigned to *offset. */ -int sigframe_alloc(struct rt_sigframe_user_layout *user, +static int sigframe_alloc(struct rt_sigframe_user_layout *user, unsigned long *offset, size_t size) { return __sigframe_alloc(user, offset, size, true); }
/* Allocate the null terminator record and prevent further allocations */ -int sigframe_alloc_end(struct rt_sigframe_user_layout *user) +static int sigframe_alloc_end(struct rt_sigframe_user_layout *user) { int ret;
@@ -130,7 +171,7 @@ int sigframe_alloc_end(struct rt_sigframe_user_layout *user) return 0; }
-void __user *apply_user_offset( +static void __user *apply_user_offset( struct rt_sigframe_user_layout const *user, unsigned long offset) { char __user *base = (char __user *)user->sigframe; @@ -138,7 +179,7 @@ void __user *apply_user_offset( return base + offset; }
-int preserve_fpsimd_context(struct fpsimd_context __user *ctx) +static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) { struct user_fpsimd_state const *fpsimd = ¤t->thread.uw.fpsimd_state; @@ -156,7 +197,7 @@ int preserve_fpsimd_context(struct fpsimd_context __user *ctx) return err ? -EFAULT : 0; }
-int restore_fpsimd_context(struct fpsimd_context __user *ctx) +static int restore_fpsimd_context(struct fpsimd_context __user *ctx) { struct user_fpsimd_state fpsimd; __u32 magic, size; @@ -185,9 +226,15 @@ int restore_fpsimd_context(struct fpsimd_context __user *ctx) return err ? -EFAULT : 0; }
+ +struct user_ctxs { + struct fpsimd_context __user *fpsimd; + struct sve_context __user *sve; +}; + #ifdef CONFIG_ARM64_SVE
-int preserve_sve_context(struct sve_context __user *ctx) +static int preserve_sve_context(struct sve_context __user *ctx) { int err = 0; u16 reserved[ARRAY_SIZE(ctx->__reserved)]; @@ -219,7 +266,7 @@ int preserve_sve_context(struct sve_context __user *ctx) return err ? -EFAULT : 0; }
-int restore_sve_fpsimd_context(struct user_ctxs *user) +static int restore_sve_fpsimd_context(struct user_ctxs *user) { int err; unsigned int vq; @@ -282,18 +329,25 @@ int restore_sve_fpsimd_context(struct user_ctxs *user) return err ? -EFAULT : 0; }
+#else /* ! CONFIG_ARM64_SVE */ + +/* Turn any non-optimised out attempts to use these into a link error: */ +extern int preserve_sve_context(void __user *ctx); +extern int restore_sve_fpsimd_context(struct user_ctxs *user); + #endif /* ! CONFIG_ARM64_SVE */
-int __parse_user_sigcontext(struct user_ctxs *user, - struct sigcontext __user const *sc, - void __user const *sigframe_base) + +static int parse_user_sigframe(struct user_ctxs *user, + struct rt_sigframe __user *sf) { + struct sigcontext __user *const sc = &sf->uc.uc_mcontext; struct _aarch64_ctx __user *head; char __user *base = (char __user *)&sc->__reserved; size_t offset = 0; size_t limit = sizeof(sc->__reserved); bool have_extra_context = false; - char const __user *const sfp = (char const __user *)sigframe_base; + char const __user *const sfp = (char const __user *)sf;
user->fpsimd = NULL; user->sve = NULL; @@ -442,11 +496,81 @@ int __parse_user_sigcontext(struct user_ctxs *user, return -EINVAL; }
+static int restore_sigframe(struct pt_regs *regs, + struct rt_sigframe __user *sf) +{ + sigset_t set; + int i, err; + struct user_ctxs user; + + err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); + if (err == 0) + set_current_blocked(&set); + + for (i = 0; i < 31; i++) + __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], + err); + __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); + __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); + __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); + + /* + * Avoid sys_rt_sigreturn() restarting. + */ + forget_syscall(regs); + + err |= !valid_user_regs(®s->user_regs, current); + if (err == 0) + err = parse_user_sigframe(&user, sf); + + if (err == 0) { + if (!user.fpsimd) + return -EINVAL; + + if (user.sve) { + if (!system_supports_sve()) + return -EINVAL; + + err = restore_sve_fpsimd_context(&user); + } else { + err = restore_fpsimd_context(user.fpsimd); + } + } + + return err; +} + SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs = current_pt_regs(); + struct rt_sigframe __user *frame; + + /* Always make any pending restarted system calls return -EINTR */ + current->restart_block.fn = do_no_restart_syscall; + + /* + * Since we stacked the signal on a 128-bit boundary, then 'sp' should + * be word aligned here. + */ + if (regs->sp & 15) + goto badframe; + + frame = (struct rt_sigframe __user *)regs->sp; + + if (!access_ok(frame, sizeof (*frame))) + goto badframe;
- return __sys_rt_sigreturn(regs); + if (restore_sigframe(regs, frame)) + goto badframe; + + if (restore_altstack(&frame->uc.uc_stack)) + goto badframe; + + return regs->regs[0]; + +badframe: + arm64_notify_segfault(regs->sp); + return 0; }
/* @@ -456,7 +580,8 @@ SYSCALL_DEFINE0(rt_sigreturn) * this task; otherwise, generates a layout for the current state * of the task. */ -int setup_sigframe_layout(struct rt_sigframe_user_layout *user, bool add_all) +static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, + bool add_all) { int err;
@@ -494,49 +619,122 @@ int setup_sigframe_layout(struct rt_sigframe_user_layout *user, bool add_all) return sigframe_alloc_end(user); }
-int setup_extra_context(char __user *sfp, unsigned long sf_size, - char __user *extrap) +static int setup_sigframe(struct rt_sigframe_user_layout *user, + struct pt_regs *regs, sigset_t *set) { - int err = 0; - struct extra_context __user *extra; - struct _aarch64_ctx __user *end; - u64 extra_datap; - u32 extra_size; + int i, err = 0; + struct rt_sigframe __user *sf = user->sigframe;
- extra = (struct extra_context __user *)extrap; - extrap += EXTRA_CONTEXT_SIZE; + /* set up the stack frame for unwinding */ + __put_user_error(regs->regs[29], &user->next_frame->fp, err); + __put_user_error(regs->regs[30], &user->next_frame->lr, err);
- end = (struct _aarch64_ctx __user *)extrap; - extrap += TERMINATOR_SIZE; + for (i = 0; i < 31; i++) + __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], + err); + __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); + __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); + __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err);
- /* - * extra_datap is just written to the signal frame. - * The value gets cast back to a void __user * - * during sigreturn. - */ - extra_datap = (__force u64)extrap; - extra_size = sfp + round_up(sf_size, 16) - extrap; + __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); + + err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); + + if (err == 0) { + struct fpsimd_context __user *fpsimd_ctx = + apply_user_offset(user, user->fpsimd_offset); + err |= preserve_fpsimd_context(fpsimd_ctx); + } + + /* fault information, if valid */ + if (err == 0 && user->esr_offset) { + struct esr_context __user *esr_ctx = + apply_user_offset(user, user->esr_offset); + + __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); + __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); + __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); + } + + /* Scalable Vector Extension state, if present */ + if (system_supports_sve() && err == 0 && user->sve_offset) { + struct sve_context __user *sve_ctx = + apply_user_offset(user, user->sve_offset); + err |= preserve_sve_context(sve_ctx); + } + + if (err == 0 && user->extra_offset) { + char __user *sfp = (char __user *)user->sigframe; + char __user *userp = + apply_user_offset(user, user->extra_offset); + + struct extra_context __user *extra; + struct _aarch64_ctx __user *end; + u64 extra_datap; + u32 extra_size;
- __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); - __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); - __put_user_error(extra_datap, &extra->datap, err); - __put_user_error(extra_size, &extra->size, err); + extra = (struct extra_context __user *)userp; + userp += EXTRA_CONTEXT_SIZE;
- /* Add the terminator */ - __put_user_error(0, &end->magic, err); - __put_user_error(0, &end->size, err); + end = (struct _aarch64_ctx __user *)userp; + userp += TERMINATOR_SIZE; + + /* + * extra_datap is just written to the signal frame. + * The value gets cast back to a void __user * + * during sigreturn. + */ + extra_datap = (__force u64)userp; + extra_size = sfp + round_up(user->size, 16) - userp; + + __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); + __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); + __put_user_error(extra_datap, &extra->datap, err); + __put_user_error(extra_size, &extra->size, err); + + /* Add the terminator */ + __put_user_error(0, &end->magic, err); + __put_user_error(0, &end->size, err); + } + + /* set the "end" magic */ + if (err == 0) { + struct _aarch64_ctx __user *end = + apply_user_offset(user, user->end_offset); + + __put_user_error(0, &end->magic, err); + __put_user_error(0, &end->size, err); + }
return err; }
-void __setup_return(struct pt_regs *regs, struct k_sigaction *ka, - struct rt_sigframe_user_layout *user, int usig) +static int get_sigframe(struct rt_sigframe_user_layout *user, + struct ksignal *ksig, struct pt_regs *regs) { - regs->regs[0] = usig; - regs->sp = (unsigned long)user->sigframe; - regs->regs[29] = (unsigned long)&user->next_frame->fp; - regs->pc = (unsigned long)ka->sa.sa_handler; + unsigned long sp, sp_top; + int err; + + init_user_layout(user); + err = setup_sigframe_layout(user, false); + if (err) + return err; + + sp = sp_top = sigsp(regs->sp, ksig); + + sp = round_down(sp - sizeof(struct frame_record), 16); + user->next_frame = (struct frame_record __user *)sp; + + sp = round_down(sp, 16) - sigframe_size(user); + user->sigframe = (struct rt_sigframe __user *)sp;
+ /* + * Check that we can actually write to the signal frame. + */ + if (!access_ok(user->sigframe, sp_top - sp)) + return -EFAULT; + + return 0; }
static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, @@ -544,7 +742,10 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, { __sigrestore_t sigtramp;
- __setup_return(regs, ka, user, usig); + regs->regs[0] = usig; + regs->sp = (unsigned long)user->sigframe; + regs->regs[29] = (unsigned long)&user->next_frame->fp; + regs->pc = (unsigned long)ka->sa.sa_handler;
if (ka->sa.sa_flags & SA_RESTORER) sigtramp = ka->sa.sa_restorer; @@ -557,13 +758,38 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { - return __setup_rt_frame(usig, ksig, set, regs); + struct rt_sigframe_user_layout user; + struct rt_sigframe __user *frame; + int err = 0; + + fpsimd_signal_preserve_current_state(); + + if (get_sigframe(&user, ksig, regs)) + return 1; + + frame = user.sigframe; + + __put_user_error(0, &frame->uc.uc_flags, err); + __put_user_error(NULL, &frame->uc.uc_link, err); + + err |= __save_altstack(&frame->uc.uc_stack, regs->sp); + err |= setup_sigframe(&user, regs, set); + if (err == 0) { + setup_return(regs, &ksig->ka, &user, usig); + if (ksig->ka.sa.sa_flags & SA_SIGINFO) { + err |= copy_siginfo_to_user(&frame->info, &ksig->info); + regs->regs[1] = (unsigned long)&frame->info; + regs->regs[2] = (unsigned long)&frame->uc; + } + } + + return err; }
static void setup_restart_syscall(struct pt_regs *regs) { - if (is_a32_compat_task()) - a32_setup_restart_syscall(regs); + if (is_compat_task()) + compat_setup_restart_syscall(regs); else regs->regs[8] = __NR_restart_syscall; } @@ -582,13 +808,11 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) /* * Set up the stack frame */ - if (is_a32_compat_task()) { + if (is_compat_task()) { if (ksig->ka.sa.sa_flags & SA_SIGINFO) - ret = a32_setup_rt_frame(usig, ksig, oldset, regs); + ret = compat_setup_rt_frame(usig, ksig, oldset, regs); else - ret = a32_setup_frame(usig, ksig, oldset, regs); - } else if (is_ilp32_compat_task()) { - ret = ilp32_setup_rt_frame(usig, ksig, oldset, regs); + ret = compat_setup_frame(usig, ksig, oldset, regs); } else { ret = setup_rt_frame(usig, ksig, oldset, regs); } @@ -623,7 +847,7 @@ static void do_signal(struct pt_regs *regs) */ if (syscall) { continue_addr = regs->pc; - restart_addr = continue_addr - (a32_thumb_mode(regs) ? 2 : 4); + restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4); retval = regs->regs[0];
/* diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index 06c370cc2618f..cb7800acd19fb 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -27,11 +27,10 @@ #include <asm/fpsimd.h> #include <asm/signal32.h> #include <asm/traps.h> -#include <asm/signal32_common.h> #include <linux/uaccess.h> #include <asm/unistd.h>
-struct a32_sigcontext { +struct compat_sigcontext { /* We always set these two fields to 0 */ compat_ulong_t trap_no; compat_ulong_t error_code; @@ -57,17 +56,17 @@ struct a32_sigcontext { compat_ulong_t fault_address; };
-struct a32_ucontext { +struct compat_ucontext { compat_ulong_t uc_flags; compat_uptr_t uc_link; compat_stack_t uc_stack; - struct a32_sigcontext uc_mcontext; + struct compat_sigcontext uc_mcontext; compat_sigset_t uc_sigmask; int __unused[32 - (sizeof (compat_sigset_t) / sizeof (int))]; compat_ulong_t uc_regspace[128] __attribute__((__aligned__(8))); };
-struct a32_vfp_sigframe { +struct compat_vfp_sigframe { compat_ulong_t magic; compat_ulong_t size; struct compat_user_vfp { @@ -82,34 +81,56 @@ struct a32_vfp_sigframe { } __attribute__((__aligned__(8)));
#define VFP_MAGIC 0x56465001 -#define VFP_STORAGE_SIZE sizeof(struct a32_vfp_sigframe) +#define VFP_STORAGE_SIZE sizeof(struct compat_vfp_sigframe)
#define FSR_WRITE_SHIFT (11)
-struct a32_aux_sigframe { - struct a32_vfp_sigframe vfp; +struct compat_aux_sigframe { + struct compat_vfp_sigframe vfp;
/* Something that isn't a valid magic number for any coprocessor. */ unsigned long end_magic; } __attribute__((__aligned__(8)));
-struct a32_sigframe { - struct a32_ucontext uc; +struct compat_sigframe { + struct compat_ucontext uc; compat_ulong_t retcode[2]; };
-struct a32_rt_sigframe { +struct compat_rt_sigframe { struct compat_siginfo info; - struct a32_sigframe sig; + struct compat_sigframe sig; };
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) +{ + compat_sigset_t cset; + + cset.sig[0] = set->sig[0] & 0xffffffffull; + cset.sig[1] = set->sig[0] >> 32; + + return copy_to_user(uset, &cset, sizeof(*uset)); +} + +static inline int get_sigset_t(sigset_t *set, + const compat_sigset_t __user *uset) +{ + compat_sigset_t s32; + + if (copy_from_user(&s32, uset, sizeof(*uset))) + return -EFAULT; + + set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); + return 0; +} + /* * VFP save/restore code. * * We have to be careful with endianness, since the fpsimd context-switch - * code operates on 128-bit (Q) register values whereas the a32 ABI + * code operates on 128-bit (Q) register values whereas the compat ABI * uses an array of 64-bit (D) registers. Consequently, we need to swap * the two halves of each Q register when running on a big-endian CPU. */ @@ -126,7 +147,7 @@ union __fpsimd_vreg { }; };
-static int a32_preserve_vfp_context(struct a32_vfp_sigframe __user *frame) +static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) { struct user_fpsimd_state const *fpsimd = ¤t->thread.uw.fpsimd_state; @@ -176,7 +197,7 @@ static int a32_preserve_vfp_context(struct a32_vfp_sigframe __user *frame) return err ? -EFAULT : 0; }
-static int a32_restore_vfp_context(struct a32_vfp_sigframe __user *frame) +static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame) { struct user_fpsimd_state fpsimd; compat_ulong_t magic = VFP_MAGIC; @@ -216,12 +237,12 @@ static int a32_restore_vfp_context(struct a32_vfp_sigframe __user *frame) return err ? -EFAULT : 0; }
-static int a32_restore_sigframe(struct pt_regs *regs, - struct a32_sigframe __user *sf) +static int compat_restore_sigframe(struct pt_regs *regs, + struct compat_sigframe __user *sf) { int err; sigset_t set; - struct a32_aux_sigframe __user *aux; + struct compat_aux_sigframe __user *aux; unsigned long psr;
err = get_sigset_t(&set, &sf->uc.uc_sigmask); @@ -257,9 +278,9 @@ static int a32_restore_sigframe(struct pt_regs *regs,
err |= !valid_user_regs(®s->user_regs, current);
- aux = (struct a32_aux_sigframe __user *) sf->uc.uc_regspace; + aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace; if (err == 0) - err |= a32_restore_vfp_context(&aux->vfp); + err |= compat_restore_vfp_context(&aux->vfp);
return err; } @@ -267,7 +288,7 @@ static int a32_restore_sigframe(struct pt_regs *regs, COMPAT_SYSCALL_DEFINE0(sigreturn) { struct pt_regs *regs = current_pt_regs(); - struct a32_sigframe __user *frame; + struct compat_sigframe __user *frame;
/* Always make any pending restarted system calls return -EINTR */ current->restart_block.fn = do_no_restart_syscall; @@ -280,12 +301,12 @@ COMPAT_SYSCALL_DEFINE0(sigreturn) if (regs->compat_sp & 7) goto badframe;
- frame = (struct a32_sigframe __user *)regs->compat_sp; + frame = (struct compat_sigframe __user *)regs->compat_sp;
if (!access_ok(frame, sizeof (*frame))) goto badframe;
- if (a32_restore_sigframe(regs, frame)) + if (compat_restore_sigframe(regs, frame)) goto badframe;
return regs->regs[0]; @@ -298,7 +319,7 @@ COMPAT_SYSCALL_DEFINE0(sigreturn) COMPAT_SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs = current_pt_regs(); - struct a32_rt_sigframe __user *frame; + struct compat_rt_sigframe __user *frame;
/* Always make any pending restarted system calls return -EINTR */ current->restart_block.fn = do_no_restart_syscall; @@ -311,12 +332,12 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) if (regs->compat_sp & 7) goto badframe;
- frame = (struct a32_rt_sigframe __user *)regs->compat_sp; + frame = (struct compat_rt_sigframe __user *)regs->compat_sp;
if (!access_ok(frame, sizeof (*frame))) goto badframe;
- if (a32_restore_sigframe(regs, &frame->sig)) + if (compat_restore_sigframe(regs, &frame->sig)) goto badframe;
if (compat_restore_altstack(&frame->sig.uc.uc_stack)) @@ -329,7 +350,7 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) return 0; }
-static void __user *a32_get_sigframe(struct ksignal *ksig, +static void __user *compat_get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize) { @@ -350,7 +371,7 @@ static void __user *a32_get_sigframe(struct ksignal *ksig, return frame; }
-static void a32_setup_return(struct pt_regs *regs, struct k_sigaction *ka, +static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka, compat_ulong_t __user *rc, void __user *frame, int usig) { @@ -394,10 +415,10 @@ static void a32_setup_return(struct pt_regs *regs, struct k_sigaction *ka, regs->pstate = spsr; }
-static int a32_setup_sigframe(struct a32_sigframe __user *sf, +static int compat_setup_sigframe(struct compat_sigframe __user *sf, struct pt_regs *regs, sigset_t *set) { - struct a32_aux_sigframe __user *aux; + struct compat_aux_sigframe __user *aux; unsigned long psr = pstate_to_compat_psr(regs->pstate); int err = 0;
@@ -420,7 +441,7 @@ static int a32_setup_sigframe(struct a32_sigframe __user *sf, __put_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err); - /* set the aarch32 FSR WnR */ + /* set the compat FSR WnR */ __put_user_error(!!(current->thread.fault_code & ESR_ELx_WNR) << FSR_WRITE_SHIFT, &sf->uc.uc_mcontext.error_code, err); __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); @@ -428,25 +449,25 @@ static int a32_setup_sigframe(struct a32_sigframe __user *sf,
err |= put_sigset_t(&sf->uc.uc_sigmask, set);
- aux = (struct a32_aux_sigframe __user *) sf->uc.uc_regspace; + aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
if (err == 0) - err |= a32_preserve_vfp_context(&aux->vfp); + err |= compat_preserve_vfp_context(&aux->vfp); __put_user_error(0, &aux->end_magic, err);
return err; }
/* - * aarch32-bit signal handling routines called from signal.c + * 32-bit signal handling routines called from signal.c */ -int a32_setup_rt_frame(int usig, struct ksignal *ksig, +int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { - struct a32_rt_sigframe __user *frame; + struct compat_rt_sigframe __user *frame; int err = 0;
- frame = a32_get_sigframe(ksig, regs, sizeof(*frame)); + frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
if (!frame) return 1; @@ -458,10 +479,10 @@ int a32_setup_rt_frame(int usig, struct ksignal *ksig,
err |= __compat_save_altstack(&frame->sig.uc.uc_stack, regs->compat_sp);
- err |= a32_setup_sigframe(&frame->sig, regs, set); + err |= compat_setup_sigframe(&frame->sig, regs, set);
if (err == 0) { - a32_setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig); + compat_setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig); regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info; regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc; } @@ -469,27 +490,27 @@ int a32_setup_rt_frame(int usig, struct ksignal *ksig, return err; }
-int a32_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, +int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { - struct a32_sigframe __user *frame; + struct compat_sigframe __user *frame; int err = 0;
- frame = a32_get_sigframe(ksig, regs, sizeof(*frame)); + frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
if (!frame) return 1;
__put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err);
- err |= a32_setup_sigframe(frame, regs, set); + err |= compat_setup_sigframe(frame, regs, set); if (err == 0) - a32_setup_return(regs, &ksig->ka, frame->retcode, frame, usig); + compat_setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
return err; }
-void a32_setup_restart_syscall(struct pt_regs *regs) +void compat_setup_restart_syscall(struct pt_regs *regs) { regs->regs[7] = __NR_compat_restart_syscall; } diff --git a/arch/arm64/kernel/signal32_common.c b/arch/arm64/kernel/signal32_common.c deleted file mode 100644 index 21995fc4e0b44..0000000000000 --- a/arch/arm64/kernel/signal32_common.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ - -/* - * Based on arch/arm/kernel/signal.c - * - * Copyright (C) 1995-2009 Russell King - * Copyright (C) 2012 ARM Ltd. - * Modified by Will Deacon will.deacon@arm.com - */ - -#include <linux/compat.h> -#include <linux/signal.h> -#include <linux/uaccess.h> - -#include <asm/signal32_common.h> -#include <asm/unistd.h> - -int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) -{ - compat_sigset_t cset; - - cset.sig[0] = set->sig[0] & 0xffffffffull; - cset.sig[1] = set->sig[0] >> 32; - - return copy_to_user(uset, &cset, sizeof(*uset)); -} - -int get_sigset_t(sigset_t *set, const compat_sigset_t __user *uset) -{ - compat_sigset_t s32; - - if (copy_from_user(&s32, uset, sizeof(*uset))) - return -EFAULT; - - set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); - return 0; -} diff --git a/arch/arm64/kernel/signal_ilp32.c b/arch/arm64/kernel/signal_ilp32.c deleted file mode 100644 index 6e84c8669a608..0000000000000 --- a/arch/arm64/kernel/signal_ilp32.c +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ - -/* - * Copyright (C) 1995-2009 Russell King - * Copyright (C) 2012 ARM Ltd. - * Copyright (C) 2018 Cavium Networks. - * Yury Norov ynorov@caviumnetworks.com - */ - -#include <linux/compat.h> -#include <linux/signal.h> -#include <linux/syscalls.h> - -#include <asm/fpsimd.h> -#include <asm/unistd.h> -#include <asm/ucontext.h> -#include <asm/vdso.h> - -#include <asm/signal_ilp32.h> -#include <asm/signal32_common.h> - -#define get_sigset(s, m) get_sigset_t(s, m) -#define put_sigset(s, m) put_sigset_t(m, s) - -#define restore_altstack(stack) compat_restore_altstack(stack) -#define __save_altstack(stack, sp) __compat_save_altstack(stack, sp) -#define copy_siginfo_to_user(frame_info, ksig_info) \ - copy_siginfo_to_user32(frame_info, ksig_info) - -#define setup_return(regs, ka, user_layout, usig) \ -{ \ - __setup_return(regs, ka, user_layout, usig); \ - regs->regs[30] = \ - (unsigned long)VDSO_SYMBOL(current->mm->context.vdso, \ - sigtramp_ilp32); \ -} - -struct ilp32_ucontext { - u32 uc_flags; - u32 uc_link; - compat_stack_t uc_stack; - compat_sigset_t uc_sigmask; - /* glibc uses a 1024-bit sigset_t */ - __u8 __unused[1024 / 8 - sizeof(compat_sigset_t)]; - /* last for future expansion */ - struct sigcontext uc_mcontext; -}; - -struct rt_sigframe { - struct compat_siginfo info; - struct ilp32_ucontext uc; -}; - -#include <asm/signal_common.h> - -COMPAT_SYSCALL_DEFINE0(ilp32_rt_sigreturn) -{ - struct pt_regs *regs = current_pt_regs(); - - return __sys_rt_sigreturn(regs); -} - -int ilp32_setup_rt_frame(int usig, struct ksignal *ksig, - sigset_t *set, struct pt_regs *regs) -{ - return __setup_rt_frame(usig, ksig, set, regs); -} diff --git a/arch/arm64/kernel/sys32.c b/arch/arm64/kernel/sys32.c index 8e99938a1c2b4..3c80a40c1c9d6 100644 --- a/arch/arm64/kernel/sys32.c +++ b/arch/arm64/kernel/sys32.c @@ -31,6 +31,108 @@ asmlinkage long compat_sys_sigreturn(void); asmlinkage long compat_sys_rt_sigreturn(void);
+COMPAT_SYSCALL_DEFINE3(aarch32_statfs64, const char __user *, pathname, + compat_size_t, sz, struct compat_statfs64 __user *, buf) +{ + /* + * 32-bit ARM applies an OABI compatibility fixup to statfs64 and + * fstatfs64 regardless of whether OABI is in use, and therefore + * arbitrary binaries may rely upon it, so we must do the same. + * For more details, see commit: + * + * 713c481519f19df9 ("[ARM] 3108/2: old ABI compat: statfs64 and + * fstatfs64") + */ + if (sz == 88) + sz = 84; + + return kcompat_sys_statfs64(pathname, sz, buf); +} + +COMPAT_SYSCALL_DEFINE3(aarch32_fstatfs64, unsigned int, fd, compat_size_t, sz, + struct compat_statfs64 __user *, buf) +{ + /* see aarch32_statfs64 */ + if (sz == 88) + sz = 84; + + return kcompat_sys_fstatfs64(fd, sz, buf); +} + +/* + * Note: off_4k is always in units of 4K. If we can't do the + * requested offset because it is not page-aligned, we return -EINVAL. + */ +COMPAT_SYSCALL_DEFINE6(aarch32_mmap2, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, off_4k) +{ + if (off_4k & (~PAGE_MASK >> 12)) + return -EINVAL; + + off_4k >>= (PAGE_SHIFT - 12); + + return ksys_mmap_pgoff(addr, len, prot, flags, fd, off_4k); +} + +#ifdef CONFIG_CPU_BIG_ENDIAN +#define arg_u32p(name) u32, name##_hi, u32, name##_lo +#else +#define arg_u32p(name) u32, name##_lo, u32, name##_hi +#endif + +#define arg_u64(name) (((u64)name##_hi << 32) | name##_lo) + +COMPAT_SYSCALL_DEFINE6(aarch32_pread64, unsigned int, fd, char __user *, buf, + size_t, count, u32, __pad, arg_u32p(pos)) +{ + return ksys_pread64(fd, buf, count, arg_u64(pos)); +} + +COMPAT_SYSCALL_DEFINE6(aarch32_pwrite64, unsigned int, fd, + const char __user *, buf, size_t, count, u32, __pad, + arg_u32p(pos)) +{ + return ksys_pwrite64(fd, buf, count, arg_u64(pos)); +} + +COMPAT_SYSCALL_DEFINE4(aarch32_truncate64, const char __user *, pathname, + u32, __pad, arg_u32p(length)) +{ + return ksys_truncate(pathname, arg_u64(length)); +} + +COMPAT_SYSCALL_DEFINE4(aarch32_ftruncate64, unsigned int, fd, u32, __pad, + arg_u32p(length)) +{ + return ksys_ftruncate(fd, arg_u64(length)); +} + +COMPAT_SYSCALL_DEFINE5(aarch32_readahead, int, fd, u32, __pad, + arg_u32p(offset), size_t, count) +{ + return ksys_readahead(fd, arg_u64(offset), count); +} + +COMPAT_SYSCALL_DEFINE6(aarch32_fadvise64_64, int, fd, int, advice, + arg_u32p(offset), arg_u32p(len)) +{ + return ksys_fadvise64_64(fd, arg_u64(offset), arg_u64(len), advice); +} + +COMPAT_SYSCALL_DEFINE6(aarch32_sync_file_range2, int, fd, unsigned int, flags, + arg_u32p(offset), arg_u32p(nbytes)) +{ + return ksys_sync_file_range(fd, arg_u64(offset), arg_u64(nbytes), + flags); +} + +COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode, + arg_u32p(offset), arg_u32p(len)) +{ + return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len)); +} + #undef __SYSCALL #define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *); #include <asm/unistd32.h> @@ -38,7 +140,7 @@ asmlinkage long compat_sys_rt_sigreturn(void); #undef __SYSCALL #define __SYSCALL(nr, sym) [nr] = __arm64_##sym,
-const syscall_fn_t a32_sys_call_table[__NR_compat_syscalls] = { +const syscall_fn_t compat_sys_call_table[__NR_compat_syscalls] = { [0 ... __NR_compat_syscalls - 1] = __arm64_sys_ni_syscall, #include <asm/unistd32.h> }; diff --git a/arch/arm64/kernel/sys32_common.c b/arch/arm64/kernel/sys32_common.c deleted file mode 100644 index 453cc62741132..0000000000000 --- a/arch/arm64/kernel/sys32_common.c +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ - -#include <linux/compat.h> -#include <linux/syscalls.h> - -COMPAT_SYSCALL_DEFINE3(aarch32_statfs64, const char __user *, pathname, - compat_size_t, sz, struct compat_statfs64 __user *, buf) -{ - /* - * 32-bit ARM applies an OABI compatibility fixup to statfs64 and - * fstatfs64 regardless of whether OABI is in use, and therefore - * arbitrary binaries may rely upon it, so we must do the same. - * For more details, see commit: - * - * 713c481519f19df9 ("[ARM] 3108/2: old ABI compat: statfs64 and - * fstatfs64") - */ - if (sz == 88) - sz = 84; - - return kcompat_sys_statfs64(pathname, sz, buf); -} - -COMPAT_SYSCALL_DEFINE3(aarch32_fstatfs64, unsigned int, fd, compat_size_t, sz, - struct compat_statfs64 __user *, buf) -{ - /* see aarch32_statfs64 */ - if (sz == 88) - sz = 84; - - return kcompat_sys_fstatfs64(fd, sz, buf); -} - -/* - * Note: off_4k is always in units of 4K. If we can't do the - * requested offset because it is not page-aligned, we return -EINVAL. - */ -COMPAT_SYSCALL_DEFINE6(aarch32_mmap2, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, - unsigned long, fd, unsigned long, off_4k) -{ - if (off_4k & (~PAGE_MASK >> 12)) - return -EINVAL; - - off_4k >>= (PAGE_SHIFT - 12); - - return ksys_mmap_pgoff(addr, len, prot, flags, fd, off_4k); -} - -#ifdef CONFIG_CPU_BIG_ENDIAN -#define arg_u32p(name) u32, name##_hi, u32, name##_lo -#else -#define arg_u32p(name) u32, name##_lo, u32, name##_hi -#endif - -#define arg_u64(name) (((u64)name##_hi << 32) | name##_lo) - -COMPAT_SYSCALL_DEFINE6(aarch32_pread64, unsigned int, fd, char __user *, buf, - size_t, count, u32, __pad, arg_u32p(pos)) -{ - return ksys_pread64(fd, buf, count, arg_u64(pos)); -} - -COMPAT_SYSCALL_DEFINE6(aarch32_pwrite64, unsigned int, fd, - const char __user *, buf, size_t, count, u32, __pad, - arg_u32p(pos)) -{ - return ksys_pwrite64(fd, buf, count, arg_u64(pos)); -} - -COMPAT_SYSCALL_DEFINE4(aarch32_truncate64, const char __user *, pathname, - u32, __pad, arg_u32p(length)) -{ - return ksys_truncate(pathname, arg_u64(length)); -} - -COMPAT_SYSCALL_DEFINE4(aarch32_ftruncate64, unsigned int, fd, u32, __pad, - arg_u32p(length)) -{ - return ksys_ftruncate(fd, arg_u64(length)); -} - -COMPAT_SYSCALL_DEFINE5(aarch32_readahead, int, fd, u32, __pad, - arg_u32p(offset), size_t, count) -{ - return ksys_readahead(fd, arg_u64(offset), count); -} - -COMPAT_SYSCALL_DEFINE6(aarch32_fadvise64_64, int, fd, int, advice, - arg_u32p(offset), arg_u32p(len)) -{ - return ksys_fadvise64_64(fd, arg_u64(offset), arg_u64(len), advice); -} - -COMPAT_SYSCALL_DEFINE6(aarch32_sync_file_range2, int, fd, unsigned int, flags, - arg_u32p(offset), arg_u32p(nbytes)) -{ - return ksys_sync_file_range(fd, arg_u64(offset), arg_u64(nbytes), - flags); -} - -COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode, - arg_u32p(offset), arg_u32p(len)) -{ - return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len)); -} diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index c07ecb5332346..1e40a38017df5 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c @@ -33,7 +33,7 @@ #include <asm/unistd.h>
static long -__do_a32_cache_op(unsigned long start, unsigned long end) +__do_compat_cache_op(unsigned long start, unsigned long end) { long ret;
@@ -64,7 +64,7 @@ __do_a32_cache_op(unsigned long start, unsigned long end) }
static inline long -do_a32_cache_op(unsigned long start, unsigned long end, int flags) +do_compat_cache_op(unsigned long start, unsigned long end, int flags) { if (end < start || flags) return -EINVAL; @@ -72,12 +72,12 @@ do_a32_cache_op(unsigned long start, unsigned long end, int flags) if (!access_ok((const void __user *)start, end - start)) return -EFAULT;
- return __do_a32_cache_op(start, end); + return __do_compat_cache_op(start, end); } /* * Handle all unrecognised system calls. */ -long a32_arm_syscall(struct pt_regs *regs, int scno) +long compat_arm_syscall(struct pt_regs *regs, int scno) { siginfo_t info;
@@ -97,7 +97,7 @@ long a32_arm_syscall(struct pt_regs *regs, int scno) * the specified region). */ case __ARM_NR_compat_cacheflush: - return do_a32_cache_op(regs->regs[0], regs->regs[1], regs->regs[2]); + return do_compat_cache_op(regs->regs[0], regs->regs[1], regs->regs[2]);
case __ARM_NR_compat_set_tls: current->thread.uw.tp_value = regs->regs[0]; @@ -127,7 +127,7 @@ long a32_arm_syscall(struct pt_regs *regs, int scno) info.si_errno = 0; info.si_code = ILL_ILLTRP; info.si_addr = (void __user *)instruction_pointer(regs) - - (a32_thumb_mode(regs) ? 2 : 4); + (compat_thumb_mode(regs) ? 2 : 4);
arm64_notify_die("Oops - bad compat syscall(2)", regs, &info, scno); return 0; diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c deleted file mode 100644 index ce82c297da3b7..0000000000000 --- a/arch/arm64/kernel/sys_ilp32.c +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ - -/* - * AArch64- ILP32 specific system calls implementation - * Copyright (C) 2018 Marvell. - */ - -#define __SYSCALL_COMPAT - -#include <linux/compat.h> -#include <linux/compiler.h> -#include <linux/syscalls.h> - -#include <asm/syscall.h> - -/* - * AARCH32 requires 4-page alignment for shared memory, - * but AARCH64 - only 1 page. This is the only difference - * between compat and native sys_shmat(). So ILP32 just pick - * AARCH64 version. - */ -#define __arm64_compat_sys_shmat __arm64_sys_shmat - -/* - * ILP32 needs special handling for some ptrace requests. - */ -#define __arm64_sys_ptrace __arm64_compat_sys_ptrace - -/* - * Using AARCH32 interface for syscalls that take 64-bit - * parameters in registers. - */ -#define __arm64_compat_sys_fadvise64_64 __arm64_compat_sys_aarch32_fadvise64_64 -#define __arm64_compat_sys_fallocate __arm64_compat_sys_aarch32_fallocate -#define __arm64_compat_sys_ftruncate64 __arm64_compat_sys_aarch32_ftruncate64 -#define __arm64_compat_sys_pread64 __arm64_compat_sys_aarch32_pread64 -#define __arm64_compat_sys_pwrite64 __arm64_compat_sys_aarch32_pwrite64 -#define __arm64_compat_sys_readahead __arm64_compat_sys_aarch32_readahead -#define __arm64_compat_sys_sync_file_range2 __arm64_compat_sys_aarch32_sync_file_range2 -#define __arm64_compat_sys_truncate64 __arm64_compat_sys_aarch32_truncate64 -#define __arm64_sys_mmap2 __arm64_compat_sys_aarch32_mmap2 - -/* - * Using AARCH32 interface for syscalls that take the size of - * struct statfs as an argument, as it's calculated differently - * in kernel and user spaces. - */ -#define __arm64_compat_sys_fstatfs64 __arm64_compat_sys_aarch32_fstatfs64 -#define __arm64_compat_sys_statfs64 __arm64_compat_sys_aarch32_statfs64 - -/* - * Using custom wrapper for rt_sigreturn() to handle custom - * struct rt_sigframe. - */ -#define __arm64_compat_sys_rt_sigreturn __arm64_compat_sys_ilp32_rt_sigreturn - -/* - * Wrappers to pass the pt_regs argument. - */ -#define sys_personality sys_arm64_personality - -asmlinkage long sys_ni_syscall(const struct pt_regs *); -#define __arm64_sys_ni_syscall sys_ni_syscall - -#undef __SYSCALL -#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *); -#include <asm/unistd.h> - -#undef __SYSCALL -#define __SYSCALL(nr, sym) [nr] = (syscall_fn_t)__arm64_##sym, - -const syscall_fn_t ilp32_sys_call_table[__NR_syscalls] = { - [0 ... __NR_syscalls - 1] = (syscall_fn_t)sys_ni_syscall, -#include <asm/unistd.h> -}; diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 20b6ebbd79d67..1457a0ba83dbc 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -14,15 +14,15 @@ #include <asm/thread_info.h> #include <asm/unistd.h>
-long a32_arm_syscall(struct pt_regs *regs, int scno); +long compat_arm_syscall(struct pt_regs *regs, int scno); long sys_ni_syscall(void);
static long do_ni_syscall(struct pt_regs *regs, int scno) { -#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT long ret; - if (is_a32_compat_task()) { - ret = a32_arm_syscall(regs, scno); + if (is_compat_task()) { + ret = compat_arm_syscall(regs, scno); if (ret != -ENOSYS) return ret; } @@ -157,39 +157,16 @@ static inline void sve_user_discard(void) sve_user_disable(); }
-#ifdef CONFIG_ARM64_ILP32 -static inline void delouse_pt_regs(struct pt_regs *regs) -{ - regs->regs[0] &= UINT_MAX; - regs->regs[1] &= UINT_MAX; - regs->regs[2] &= UINT_MAX; - regs->regs[3] &= UINT_MAX; - regs->regs[4] &= UINT_MAX; - regs->regs[5] &= UINT_MAX; - regs->regs[6] &= UINT_MAX; - regs->regs[7] &= UINT_MAX; -} -#endif - asmlinkage void el0_svc_handler(struct pt_regs *regs) { - const syscall_fn_t *t = sys_call_table; - -#ifdef CONFIG_ARM64_ILP32 - if (is_ilp32_compat_task()) { - t = ilp32_sys_call_table; - delouse_pt_regs(regs); - } -#endif - sve_user_discard(); - el0_svc_common(regs, regs->regs[8], __NR_syscalls, t); + el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table); }
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT asmlinkage void el0_svc_compat_handler(struct pt_regs *regs) { el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls, - a32_sys_call_table); + compat_sys_call_table); } #endif diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 90f12890d9399..1b7e4fdade298 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -18,7 +18,6 @@ */
#include <linux/bug.h> -#include <linux/compat.h> #include <linux/signal.h> #include <linux/personality.h> #include <linux/kallsyms.h> @@ -319,7 +318,7 @@ static int call_undef_hook(struct pt_regs *regs) if (probe_kernel_address((__force __le32 *)pc, instr_le)) goto exit; instr = le32_to_cpu(instr_le); - } else if (a32_thumb_mode(regs)) { + } else if (compat_thumb_mode(regs)) { /* 16-bit Thumb instruction */ __le16 instr_le; if (get_user(instr_le, (__le16 __user *)pc)) diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore deleted file mode 100644 index 61806c3fd68b0..0000000000000 --- a/arch/arm64/kernel/vdso-ilp32/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -vdso-ilp32.lds -vdso-ilp32-offsets.h diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile deleted file mode 100644 index fc6cff94e9c29..0000000000000 --- a/arch/arm64/kernel/vdso-ilp32/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ - -# -# Building a vDSO image for AArch64. -# -# Author: Will Deacon will.deacon@arm.com -# Heavily based on the vDSO Makefiles for other archs. -# - -obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o - -# Build rules -targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg -obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso)) - -ccflags-y := -shared -fno-common -fno-builtin -fno-stack-protector -ccflags-y += -DDISABLE_BRANCH_PROFILING -ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \ - $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) - -# Force -O2 to avoid libgcc dependencies -CFLAGS_REMOVE_gettimeofday-ilp32.o = -pg -Os -CFLAGS_gettimeofday-ilp32.o = -O2 -mcmodel=tiny -mabi=ilp32 - -# Disable gcov profiling for VDSO code -GCOV_PROFILE := n - -# Workaround for bare-metal (ELF) toolchains that neglect to pass -shared -# down to collect2, resulting in silent corruption of the vDSO image. -ccflags-y += -Wl,-shared - -obj-y += vdso-ilp32.o -extra-y += vdso-ilp32.lds -CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32 - -# Force dependency (incbin is bad) -$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so - -# Link rule for the .so file, .lds has to be first -$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso) - $(call if_changed,vdso-ilp32ld) - -# Strip rule for the .so file -$(obj)/%.so: OBJCOPYFLAGS := -S -$(obj)/%.so: $(obj)/%.so.dbg FORCE - $(call if_changed,objcopy) - -# Generate VDSO offsets using helper script -gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh -quiet_cmd_vdsosym = VDSOSYM $@ -define cmd_vdsosym - $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ -endef - -include/generated/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE - $(call if_changed,vdsosym) - -# Assembly rules for the .S files -#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S) -# $(call if_changed_dep,vdso-ilp32as) - -$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.c - $(call if_changed_dep,vdso-ilp32cc) - -$(obj)/note-ilp32.o: $(src)/../vdso/note.S - $(call if_changed_dep,vdso-ilp32as) - -# This one should be fine because ILP32 uses the same generic -# __NR_rt_sigreturn syscall number. -$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S - $(call if_changed_dep,vdso-ilp32as) - -# Actual build commands -quiet_cmd_vdso-ilp32ld = VDSOILP32L $@ - cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32 -Wl,-n -Wl,-T $^ -o $@ -quiet_cmd_vdso-ilp32as = VDSOILP32C $@ - cmd_vdso-ilp32cc= $(CC) $(c_flags) -mabi=ilp32 -c -o $@ $< -quiet_cmd_vdso-ilp32as = VDSOILP32A $@ - cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $< - -# Install commands for the unstripped file -quiet_cmd_vdso_install = INSTALL $@ - cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ - -vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg - @mkdir -p $(MODLIB)/vdso - $(call cmd,vdso_install) - -vdso_install: vdso-ilp32.so diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S deleted file mode 100644 index dee65ab796626..0000000000000 --- a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ - -/* - * Copyright (C) 2012 ARM Limited - * Author: Will Deacon will.deacon@arm.com - */ - -#include <linux/init.h> -#include <linux/linkage.h> -#include <linux/const.h> -#include <asm/page.h> - - __PAGE_ALIGNED_DATA - - .globl vdso_ilp32_start, vdso_ilp32_end - .balign PAGE_SIZE -vdso_ilp32_start: - .incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so" - .balign PAGE_SIZE -vdso_ilp32_end: - - .previous diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S deleted file mode 100644 index 9f14666feef72..0000000000000 --- a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ - -/* - * GNU linker script for the VDSO library. - * - * Copyright (C) 2012 ARM Limited - * Author: Will Deacon will.deacon@arm.com - * Heavily based on the vDSO linker scripts for other archs. - */ - -#include <linux/const.h> -#include <asm/page.h> -#include <asm/vdso.h> - -SECTIONS -{ - PROVIDE(_vdso_data = . - PAGE_SIZE); - . = VDSO_LBASE + SIZEOF_HEADERS; - - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - .note : { *(.note.*) } :text :note - - . = ALIGN(16); - - .text : { *(.text*) } :text =0xd503201f - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - - .dynamic : { *(.dynamic) } :text :dynamic - - .rodata : { *(.rodata*) } :text - - _end = .; - PROVIDE(end = .); - - /DISCARD/ : { - *(.note.GNU-stack) - *(.data .data.* .gnu.linkonce.d.* .sdata*) - *(.bss .sbss .dynbss .dynsbss) - } -} - -/* - * We must supply the ELF program headers explicitly to get just one - * PT_LOAD segment, and set the flags explicitly to make segments read-only. - */ -PHDRS -{ - text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - note PT_NOTE FLAGS(4); /* PF_R */ - eh_frame_hdr PT_GNU_EH_FRAME; -} - -/* - * This controls what symbols we export from the DSO. - */ -VERSION -{ - LINUX_4.12 { - global: - __kernel_rt_sigreturn; - __kernel_gettimeofday; - __kernel_clock_gettime; - __kernel_clock_getres; - local: *; - }; -} - -/* - * Make the sigreturn code visible to the kernel. - */ -VDSO_sigtramp_ilp32 = __kernel_rt_sigreturn; diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 65252f0dd24c1..fc72138b5c257 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -37,13 +37,8 @@ #include <asm/vdso.h> #include <asm/vdso_datapage.h>
-extern char vdso_lp64_start[], vdso_lp64_end[]; -static unsigned long vdso_lp64_pages __ro_after_init; - -#ifdef CONFIG_ARM64_ILP32 -extern char vdso_ilp32_start[], vdso_ilp32_end[]; -static unsigned long vdso_ilp32_pages __ro_after_init; -#endif +extern char vdso_start[], vdso_end[]; +static unsigned long vdso_pages __ro_after_init;
/* * The vDSO data page. @@ -54,7 +49,7 @@ static union { } vdso_data_store __page_aligned_data; struct vdso_data *vdso_data = &vdso_data_store.data;
-#ifdef CONFIG_AARCH32_EL0 +#ifdef CONFIG_COMPAT /* * Create and map the vectors page for AArch32 tasks. */ @@ -113,13 +108,13 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
return PTR_ERR_OR_ZERO(ret); } -#endif /* CONFIG_AARCH32_EL0 */ +#endif /* CONFIG_COMPAT */
static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma) { unsigned long new_size = new_vma->vm_end - new_vma->vm_start; - unsigned long vdso_size = vdso_lp64_end - vdso_lp64_start; + unsigned long vdso_size = vdso_end - vdso_start;
if (vdso_size != new_size) return -EINVAL; @@ -129,7 +124,7 @@ static int vdso_mremap(const struct vm_special_mapping *sm, return 0; }
-static struct vm_special_mapping vdso_lp64_spec[2] __ro_after_init = { +static struct vm_special_mapping vdso_spec[2] __ro_after_init = { { .name = "[vvar]", }, @@ -139,23 +134,9 @@ static struct vm_special_mapping vdso_lp64_spec[2] __ro_after_init = { }, };
-#ifdef CONFIG_ARM64_ILP32 -static struct vm_special_mapping vdso_ilp32_spec[2] __ro_after_init = { - { - .name = "[vvar]", - }, - { - .name = "[vdso]", - }, -}; -#endif - -static int __init vdso_init(char *vdso_start, char *vdso_end, - unsigned long *vdso_pagesp, - struct vm_special_mapping *vdso_spec) +static int __init vdso_init(void) { int i; - unsigned long vdso_pages; struct page **vdso_pagelist; unsigned long pfn;
@@ -165,7 +146,6 @@ static int __init vdso_init(char *vdso_start, char *vdso_end, }
vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; - *vdso_pagesp = vdso_pages;
/* Allocate the vDSO pagelist, plus a page for the data. */ vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *), @@ -188,22 +168,7 @@ static int __init vdso_init(char *vdso_start, char *vdso_end,
return 0; } - -static int __init vdso_lp64_init(void) -{ - return vdso_init(vdso_lp64_start, vdso_lp64_end, - &vdso_lp64_pages, vdso_lp64_spec); -} -arch_initcall(vdso_lp64_init); - -#ifdef CONFIG_ARM64_ILP32 -static int __init vdso_ilp32_init(void) -{ - return vdso_init(vdso_ilp32_start, vdso_ilp32_end, - &vdso_ilp32_pages, vdso_ilp32_spec); -} -arch_initcall(vdso_ilp32_init); -#endif +arch_initcall(vdso_init);
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) @@ -211,17 +176,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, struct mm_struct *mm = current->mm; unsigned long vdso_base, vdso_text_len, vdso_mapping_len; void *ret; - unsigned long pages = vdso_lp64_pages; - struct vm_special_mapping *vdso_spec = vdso_lp64_spec; - -#ifdef CONFIG_ARM64_ILP32 - if (is_ilp32_compat_task()) { - pages = vdso_ilp32_pages; - vdso_spec = vdso_ilp32_spec; - } -#endif
- vdso_text_len = pages << PAGE_SHIFT; + vdso_text_len = vdso_pages << PAGE_SHIFT; /* Be sure to map the data page */ vdso_mapping_len = vdso_text_len + PAGE_SIZE;
diff --git a/arch/arm64/kernel/vdso/gettimeofday.c b/arch/arm64/kernel/vdso/gettimeofday.c index 3140ffb5e89de..2e28ff5bb1e2f 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.c +++ b/arch/arm64/kernel/vdso/gettimeofday.c @@ -26,12 +26,6 @@ #include <linux/math64.h> #include <linux/time.h> #include <linux/kernel.h> - -#ifdef __ILP32__ -#undef BITS_PER_LONG -#define BITS_PER_LONG 32 -#endif - #include <linux/hrtimer.h>
extern struct vdso_data _vdso_data; diff --git a/arch/arm64/kernel/vdso/vdso.S b/arch/arm64/kernel/vdso/vdso.S index a40ae24854308..82379a70ef03f 100644 --- a/arch/arm64/kernel/vdso/vdso.S +++ b/arch/arm64/kernel/vdso/vdso.S @@ -21,12 +21,12 @@ #include <linux/const.h> #include <asm/page.h>
- .globl vdso_lp64_start, vdso_lp64_end + .globl vdso_start, vdso_end .section .rodata .balign PAGE_SIZE -vdso_lp64_start: +vdso_start: .incbin "arch/arm64/kernel/vdso/vdso.so" .balign PAGE_SIZE -vdso_lp64_end: +vdso_end:
.previous diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index 2ad9110f44130..f25859a1c5fab 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -54,7 +54,7 @@ unsigned long arch_mmap_rnd(void) unsigned long rnd;
#ifdef CONFIG_COMPAT - if (is_compat_task()) + if (test_thread_flag(TIF_32BIT)) rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1); else #endif diff --git a/arch/c6x/include/uapi/asm/unistd.h b/arch/c6x/include/uapi/asm/unistd.h index df40dc128ba92..0d2daf7f9809c 100644 --- a/arch/c6x/include/uapi/asm/unistd.h +++ b/arch/c6x/include/uapi/asm/unistd.h @@ -16,7 +16,6 @@ */
#define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_SYS_CLONE
/* Use the standard ABI for syscalls. */ diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 4b0b4d4c947fa..0b334b671e90c 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 config H8300 def_bool y - select ARCH_32BIT_OFF_T select GENERIC_ATOMIC64 select HAVE_UID16 select VIRT_TO_BUS diff --git a/arch/h8300/include/uapi/asm/unistd.h b/arch/h8300/include/uapi/asm/unistd.h index 2f98394b77d4f..7dd20ef7625ad 100644 --- a/arch/h8300/include/uapi/asm/unistd.h +++ b/arch/h8300/include/uapi/asm/unistd.h @@ -1,6 +1,5 @@ #define __ARCH_NOMMU
#define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_SET_GET_RLIMIT
#include <asm-generic/unistd.h> diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 1c7a4582c3ce5..89a4b22f34d9b 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -4,7 +4,6 @@ comment "Linux Kernel Configuration for Hexagon"
config HEXAGON def_bool y - select ARCH_32BIT_OFF_T select ARCH_NO_PREEMPT select HAVE_OPROFILE # Other pending projects/to-do items. diff --git a/arch/hexagon/include/uapi/asm/unistd.h b/arch/hexagon/include/uapi/asm/unistd.h index c9eb56ed57448..ea181e79162e7 100644 --- a/arch/hexagon/include/uapi/asm/unistd.h +++ b/arch/hexagon/include/uapi/asm/unistd.h @@ -29,7 +29,6 @@
#define sys_mmap2 sys_mmap_pgoff #define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_CLONE #define __ARCH_WANT_SYS_VFORK diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index bfcf1fa1497db..070553791e977 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -2,7 +2,6 @@ config M68K bool default y - select ARCH_32BIT_OFF_T select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA select ARCH_MIGHT_HAVE_PC_PARPORT if ISA select ARCH_NO_COHERENT_DMA_MMAP if !MMU diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 6432b66209dea..ace5c5bf18361 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -1,6 +1,5 @@ config MICROBLAZE def_bool y - select ARCH_32BIT_OFF_T select ARCH_NO_SWAP select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_SYNC_DMA_FOR_CPU diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 60d5914c6e8d9..a830a9701e501 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2,7 +2,6 @@ config MIPS bool default y - select ARCH_32BIT_OFF_T if !64BIT select ARCH_BINFMT_ELF_STATE select ARCH_CLOCKSOURCE_DATA select ARCH_DISCARD_MEMBLOCK diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig index 0cd422345d49b..7068f341133d7 100644 --- a/arch/nds32/Kconfig +++ b/arch/nds32/Kconfig @@ -31,7 +31,6 @@ config NDS32 select HAVE_DEBUG_KMEMLEAK select HAVE_MEMBLOCK select HAVE_REGS_AND_STACK_ACCESS_API - select ARCH_32BIT_OFF_T select IRQ_DOMAIN select LOCKDEP_SUPPORT select MODULES_USE_ELF_RELA diff --git a/arch/nds32/include/uapi/asm/unistd.h b/arch/nds32/include/uapi/asm/unistd.h index 539dd4eaa5c08..6e95901cabe3c 100644 --- a/arch/nds32/include/uapi/asm/unistd.h +++ b/arch/nds32/include/uapi/asm/unistd.h @@ -2,7 +2,6 @@ // Copyright (C) 2005-2017 Andes Technology Corporation
#define __ARCH_WANT_SYNC_FILE_RANGE2 -#define __ARCH_WANT_SET_GET_RLIMIT
/* Use the standard ABI for syscalls */ #include <asm-generic/unistd.h> diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index 4ccd84aa5c902..f4ad1138e6b90 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 config NIOS2 def_bool y - select ARCH_32BIT_OFF_T select ARCH_HAS_SYNC_DMA_FOR_CPU select ARCH_HAS_SYNC_DMA_FOR_DEVICE select ARCH_NO_SWAP diff --git a/arch/nios2/include/uapi/asm/unistd.h b/arch/nios2/include/uapi/asm/unistd.h index aa4e90e008855..b6bdae04bc84c 100644 --- a/arch/nios2/include/uapi/asm/unistd.h +++ b/arch/nios2/include/uapi/asm/unistd.h @@ -19,7 +19,6 @@ #define sys_mmap2 sys_mmap_pgoff
#define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_SET_GET_RLIMIT
/* Use the standard ABI for syscalls */ #include <asm-generic/unistd.h> diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 078b06c61f0a9..e0081e7348271 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -6,7 +6,6 @@
config OPENRISC def_bool y - select ARCH_32BIT_OFF_T select ARCH_HAS_SYNC_DMA_FOR_DEVICE select DMA_NONCOHERENT_OPS select OF diff --git a/arch/openrisc/include/uapi/asm/unistd.h b/arch/openrisc/include/uapi/asm/unistd.h index 017d57d62b045..11c5a58ab3336 100644 --- a/arch/openrisc/include/uapi/asm/unistd.h +++ b/arch/openrisc/include/uapi/asm/unistd.h @@ -20,7 +20,6 @@ #define sys_mmap2 sys_mmap_pgoff
#define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_SYS_FORK #define __ARCH_WANT_SYS_CLONE
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 4e445d3f08741..8e6d83f79e72b 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 config PARISC def_bool y - select ARCH_32BIT_OFF_T if !64BIT select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_IDE select HAVE_OPROFILE diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8968013d87766..71ecadbe2ecbd 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -128,7 +128,6 @@ config PPC # # Please keep this list sorted alphabetically. # - select ARCH_32BIT_OFF_T if PPC32 select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_DMA_SET_COHERENT_MASK select ARCH_HAS_ELF_RANDOMIZE diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 1efa59f493cca..a344980287a51 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -11,7 +11,6 @@ config 32BIT
config RISCV def_bool y - select ARCH_32BIT_OFF_T if !64BIT # even on 32-bit, physical (and DMA) addresses are > 32-bits select PHYS_ADDR_T_64BIT select OF diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h index 1b164c6cbba1d..0caea01d5ccab 100644 --- a/arch/riscv/include/asm/unistd.h +++ b/arch/riscv/include/asm/unistd.h @@ -17,6 +17,5 @@ */
#define __ARCH_WANT_SYS_CLONE -#define __ARCH_WANT_SET_GET_RLIMIT #include <uapi/asm/unistd.h> #include <uapi/asm/syscalls.h> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 79f9e9d2b01f6..1fb7b6d72bafc 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -61,7 +61,6 @@ config SUPERH
config SUPERH32 def_bool "$(ARCH)" = "sh" - select ARCH_32BIT_OFF_T select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_IOREMAP_PROT if MMU && !X2TLB diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 453988f1a1f17..e6f2a38d2e61e 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -50,7 +50,6 @@ config SPARC
config SPARC32 def_bool !64BIT - select ARCH_32BIT_OFF_T select ARCH_HAS_SYNC_DMA_FOR_CPU select DMA_NONCOHERENT_OPS select GENERIC_ATOMIC64 diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 981bf646bf8a1..60eae744d8fd0 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 config UNICORE32 def_bool y - select ARCH_32BIT_OFF_T select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h index 0314f78943755..65856eaab163e 100644 --- a/arch/unicore32/include/uapi/asm/unistd.h +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -12,7 +12,6 @@ */
#define __ARCH_WANT_RENAMEAT -#define __ARCH_WANT_SET_GET_RLIMIT
/* Use the standard ABI for syscalls. */ #include <asm-generic/unistd.h> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index bc152a96776da..343a83caebb7a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -46,7 +46,6 @@ config X86 select ACPI_LEGACY_TABLES_LOOKUP if ACPI select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI select ANON_INODES - select ARCH_32BIT_OFF_T if X86_32 select ARCH_CLOCKSOURCE_DATA select ARCH_DISCARD_MEMBLOCK select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig index a9e80e44178c7..494eeb51e4e18 100644 --- a/arch/x86/um/Kconfig +++ b/arch/x86/um/Kconfig @@ -16,7 +16,6 @@ config 64BIT
config X86_32 def_bool !64BIT - select ARCH_32BIT_OFF_T select ARCH_WANT_IPC_PARSE_VERSION select MODULES_USE_ELF_REL select CLONE_BACKWARDS diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 74145aa292b8a..b9ad83a0ee5db 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -4,7 +4,6 @@ config ZONE_DMA
config XTENSA def_bool y - select ARCH_32BIT_OFF_T select ARCH_HAS_SG_CHAIN select ARCH_HAS_SYNC_DMA_FOR_CPU select ARCH_HAS_SYNC_DMA_FOR_DEVICE diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index a9869c2e0d92d..486e51605e683 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -821,8 +821,8 @@ static void arch_timer_evtstrm_enable(int divider) | ARCH_TIMER_VIRT_EVT_EN; arch_timer_set_cntkctl(cntkctl); elf_hwcap |= HWCAP_EVTSTRM; -#ifdef CONFIG_AARCH32_EL0 - a32_elf_hwcap |= COMPAT_HWCAP_EVTSTRM; +#ifdef CONFIG_COMPAT + compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM; #endif cpumask_set_cpu(smp_processor_id(), &evtstrm_available); } diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h index d019df946cb24..27dc7a60693e1 100644 --- a/include/linux/fcntl.h +++ b/include/linux/fcntl.h @@ -12,7 +12,7 @@ O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
#ifndef force_o_largefile -#define force_o_largefile() (!IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T)) +#define force_o_largefile() (BITS_PER_LONG != 32) #endif
#if BITS_PER_LONG == 32 diff --git a/include/linux/sched.h b/include/linux/sched.h index 8f17d3f55b954..9c1810252dd04 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -28,7 +28,6 @@ #include <linux/mm_types_task.h> #include <linux/task_io_accounting.h> #include <linux/rseq.h> -#include <linux/thread_bits.h>
/* task_struct member predeclarations (sorted alphabetically): */ struct audit_context; diff --git a/include/linux/thread_bits.h b/include/linux/thread_bits.h deleted file mode 100644 index e362abc4b8d59..0000000000000 --- a/include/linux/thread_bits.h +++ /dev/null @@ -1,87 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ - -/* Common low-level thread bits accessors */ - -#ifndef _LINUX_THREAD_BITS_H -#define _LINUX_THREAD_BITS_H - -#ifndef __ASSEMBLY__ - -/* - * For per-arch arch_within_stack_frames() implementations, defined in - * asm/thread_info.h. - */ -enum { - BAD_STACK = -1, - NOT_STACK = 0, - GOOD_FRAME, - GOOD_STACK, -}; - -#include <linux/bitops.h> -#include <asm/thread_info.h> - -#ifdef CONFIG_THREAD_INFO_IN_TASK -/* - * For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the - * definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels, - * including <asm/current.h> can cause a circular dependency on some platforms. - */ -#include <asm/current.h> -#define current_thread_info() ((struct thread_info *)current) -#endif - -/* - * flag set/clear/test wrappers - * - pass TIF_xxxx constants to these functions - */ - -static inline void set_ti_thread_flag(struct thread_info *ti, int flag) -{ - set_bit(flag, (unsigned long *)&ti->flags); -} - -static inline void clear_ti_thread_flag(struct thread_info *ti, int flag) -{ - clear_bit(flag, (unsigned long *)&ti->flags); -} - -static inline void update_ti_thread_flag(struct thread_info *ti, int flag, - bool value) -{ - if (value) - set_ti_thread_flag(ti, flag); - else - clear_ti_thread_flag(ti, flag); -} - -static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag) -{ - return test_and_set_bit(flag, (unsigned long *)&ti->flags); -} - -static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag) -{ - return test_and_clear_bit(flag, (unsigned long *)&ti->flags); -} - -static inline int test_ti_thread_flag(struct thread_info *ti, int flag) -{ - return test_bit(flag, (unsigned long *)&ti->flags); -} - -#define set_thread_flag(flag) \ - set_ti_thread_flag(current_thread_info(), flag) -#define clear_thread_flag(flag) \ - clear_ti_thread_flag(current_thread_info(), flag) -#define update_thread_flag(flag, value) \ - update_ti_thread_flag(current_thread_info(), flag, value) -#define test_and_set_thread_flag(flag) \ - test_and_set_ti_thread_flag(current_thread_info(), flag) -#define test_and_clear_thread_flag(flag) \ - test_and_clear_ti_thread_flag(current_thread_info(), flag) -#define test_thread_flag(flag) \ - test_ti_thread_flag(current_thread_info(), flag) - -#endif /* !__ASSEMBLY__ */ -#endif /* _LINUX_THREAD_BITS_H */ diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 06ca9c157980b..8d8821b3689a2 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -11,9 +11,30 @@ #include <linux/types.h> #include <linux/bug.h> #include <linux/restart_block.h> -#include <linux/thread_bits.h> + +#ifdef CONFIG_THREAD_INFO_IN_TASK +/* + * For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the + * definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels, + * including <asm/current.h> can cause a circular dependency on some platforms. + */ +#include <asm/current.h> +#define current_thread_info() ((struct thread_info *)current) +#endif
#include <linux/bitops.h> + +/* + * For per-arch arch_within_stack_frames() implementations, defined in + * asm/thread_info.h. + */ +enum { + BAD_STACK = -1, + NOT_STACK = 0, + GOOD_FRAME, + GOOD_STACK, +}; + #include <asm/thread_info.h>
#ifdef __KERNEL__ @@ -24,6 +45,58 @@
#define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
+/* + * flag set/clear/test wrappers + * - pass TIF_xxxx constants to these functions + */ + +static inline void set_ti_thread_flag(struct thread_info *ti, int flag) +{ + set_bit(flag, (unsigned long *)&ti->flags); +} + +static inline void clear_ti_thread_flag(struct thread_info *ti, int flag) +{ + clear_bit(flag, (unsigned long *)&ti->flags); +} + +static inline void update_ti_thread_flag(struct thread_info *ti, int flag, + bool value) +{ + if (value) + set_ti_thread_flag(ti, flag); + else + clear_ti_thread_flag(ti, flag); +} + +static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag) +{ + return test_and_set_bit(flag, (unsigned long *)&ti->flags); +} + +static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag) +{ + return test_and_clear_bit(flag, (unsigned long *)&ti->flags); +} + +static inline int test_ti_thread_flag(struct thread_info *ti, int flag) +{ + return test_bit(flag, (unsigned long *)&ti->flags); +} + +#define set_thread_flag(flag) \ + set_ti_thread_flag(current_thread_info(), flag) +#define clear_thread_flag(flag) \ + clear_ti_thread_flag(current_thread_info(), flag) +#define update_thread_flag(flag, value) \ + update_ti_thread_flag(current_thread_info(), flag, value) +#define test_and_set_thread_flag(flag) \ + test_and_set_ti_thread_flag(current_thread_info(), flag) +#define test_and_clear_thread_flag(flag) \ + test_and_clear_ti_thread_flag(current_thread_info(), flag) +#define test_thread_flag(flag) \ + test_ti_thread_flag(current_thread_info(), flag) + #define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED)
#ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index b538ed1be4eb9..df4bedb9b01c2 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -179,7 +179,7 @@ __SYSCALL(__NR_fchownat, sys_fchownat) #define __NR_fchown 55 __SYSCALL(__NR_fchown, sys_fchown) #define __NR_openat 56 -__SYSCALL(__NR_openat, sys_openat) +__SC_COMP(__NR_openat, sys_openat, compat_sys_openat) #define __NR_close 57 __SYSCALL(__NR_close, sys_close) #define __NR_vhangup 58 @@ -465,15 +465,10 @@ __SYSCALL(__NR_uname, sys_newuname) __SYSCALL(__NR_sethostname, sys_sethostname) #define __NR_setdomainname 162 __SYSCALL(__NR_setdomainname, sys_setdomainname) - -#ifdef __ARCH_WANT_SET_GET_RLIMIT -/* getrlimit and setrlimit are superseded with prlimit64 */ #define __NR_getrlimit 163 __SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit) #define __NR_setrlimit 164 __SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit) -#endif - #define __NR_getrusage 165 __SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage) #define __NR_umask 166 @@ -681,7 +676,8 @@ __SYSCALL(__NR_fanotify_mark, sys_fanotify_mark) #define __NR_name_to_handle_at 264 __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) #define __NR_open_by_handle_at 265 -__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at) +__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \ + compat_sys_open_by_handle_at) #define __NR_clock_adjtime 266 __SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime) #define __NR_syncfs 267 diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 7edf242e5d3bf..9f0505f39f002 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -900,22 +900,6 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type, EXPORT_SYMBOL_GPL(task_user_regset_view); #endif
-static int ptrace_setsigmask(struct task_struct *child, sigset_t *new_set) -{ - sigdelsetmask(new_set, sigmask(SIGKILL)|sigmask(SIGSTOP)); - - /* - * Every thread does recalc_sigpending() after resume, so - * retarget_shared_pending() and recalc_sigpending() are not - * called here. - */ - spin_lock_irq(&child->sighand->siglock); - child->blocked = *new_set; - spin_unlock_irq(&child->sighand->siglock); - - return 0; -} - int ptrace_request(struct task_struct *child, long request, unsigned long addr, unsigned long data) { @@ -995,10 +979,20 @@ int ptrace_request(struct task_struct *child, long request, break; }
- ret = ptrace_setsigmask(child, &new_set); + sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP)); + + /* + * Every thread does recalc_sigpending() after resume, so + * retarget_shared_pending() and recalc_sigpending() are not + * called here. + */ + spin_lock_irq(&child->sighand->siglock); + child->blocked = new_set; + spin_unlock_irq(&child->sighand->siglock);
clear_tsk_restore_sigmask(child);
+ ret = 0; break; }
@@ -1217,7 +1211,6 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, { compat_ulong_t __user *datap = compat_ptr(data); compat_ulong_t word; - sigset_t new_set; siginfo_t siginfo; int ret;
@@ -1258,24 +1251,6 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, else ret = ptrace_setsiginfo(child, &siginfo); break; - case PTRACE_GETSIGMASK: - if (addr != sizeof(compat_sigset_t)) - return -EINVAL; - - ret = put_compat_sigset((compat_sigset_t __user *) datap, - &child->blocked, sizeof(compat_sigset_t)); - break; - case PTRACE_SETSIGMASK: - if (addr != sizeof(compat_sigset_t)) - return -EINVAL; - - ret = get_compat_sigset(&new_set, - (compat_sigset_t __user *) datap); - if (ret) - break; - - ret = ptrace_setsigmask(child, &new_set); - break; #ifdef CONFIG_HAVE_ARCH_TRACEHOOK case PTRACE_GETREGSET: case PTRACE_SETREGSET: diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 5717766c5b4a2..ee3dfb5be6cd1 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -38,11 +38,6 @@ cat << EOF #define __IGNORE_lstat64 /* fstatat64 */ #endif
-#ifndef __ARCH_WANT_SET_GET_RLIMIT -#define __IGNORE_getrlimit /* getrlimit */ -#define __IGNORE_setrlimit /* setrlimit */ -#endif - /* Missing flags argument */ #define __IGNORE_renameat /* renameat2 */