Kernel
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- 51 participants
- 18727 discussions

[PATCH openEuler-1.0-LTS] dhugetlb: isolate hwpoison hugepage when release
by Yongqiang Liu 23 Feb '23
by Yongqiang Liu 23 Feb '23
23 Feb '23
From: Liu Shixin <liushixin2(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/I6GSKP
CVE: NA
--------------------------------
For a hwpoison hugetlb page, the page will be freed firstly. If succeed, it
will be dissolved and released to buddy system, then isolate the hwpoison page.
For a hwpoison hugepage belong to dynamic hugetlb, we isolate the hugepage
without dissolve it. Add a check in free_huge_page_to_dhugetlb_pool() to
isolate the hwpoison hugepage directly. And keep HUGETLB_PAGE_DTOR after free
to ensure the PageHuge() check return true in dissolve_free_huge_page().
Fixes: 0f0535e57da("dhugetlb: skip dissolve hugepage belonging to dynamic hugetlb")
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/hugetlb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ed89df6fc5de..9f974270c84d 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1348,8 +1348,9 @@ static void free_huge_page_to_dhugetlb_pool(struct page *page,
}
spin_lock(&hpool->lock);
+ if (PageHWPoison(page))
+ goto out;
ClearPagePool(page);
- set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
if (!hstate_is_gigantic(h)) {
list_add(&page->lru, &hpool->dhugetlb_2M_freelists);
hpool->free_reserved_2M++;
@@ -1375,6 +1376,7 @@ static void free_huge_page_to_dhugetlb_pool(struct page *page,
trace_dhugetlb_alloc_free(hpool, page, hpool->free_reserved_1G,
DHUGETLB_FREE_1G);
}
+out:
spin_unlock(&hpool->lock);
dhugetlb_pool_put(hpool);
}
--
2.25.1
1
0

[PATCH openEuler-5.10-LTS-SP1 01/29] media: vivid: fix compose size exceed boundary
by Jialin Zhang 22 Feb '23
by Jialin Zhang 22 Feb '23
22 Feb '23
From: Liu Shixin <liushixin2(a)huawei.com>
stable inclusion
from stable-v5.10.163
commit f9d19f3a044ca651b0be52a4bf951ffe74259b9f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6CIF8
CVE: CVE-2023-0615
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 94a7ad9283464b75b12516c5512541d467cefcf8 ]
syzkaller found a bug:
BUG: unable to handle page fault for address: ffffc9000a3b1000
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
PGD 100000067 P4D 100000067 PUD 10015f067 PMD 1121ca067 PTE 0
Oops: 0002 [#1] PREEMPT SMP
CPU: 0 PID: 23489 Comm: vivid-000-vid-c Not tainted 6.1.0-rc1+ #512
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
RIP: 0010:memcpy_erms+0x6/0x10
[...]
Call Trace:
<TASK>
? tpg_fill_plane_buffer+0x856/0x15b0
vivid_fillbuff+0x8ac/0x1110
vivid_thread_vid_cap_tick+0x361/0xc90
vivid_thread_vid_cap+0x21a/0x3a0
kthread+0x143/0x180
ret_from_fork+0x1f/0x30
</TASK>
This is because we forget to check boundary after adjust compose->height
int V4L2_SEL_TGT_CROP case. Add v4l2_rect_map_inside() to fix this problem
for this case.
Fixes: ef834f7836ec ("[media] vivid: add the video capture and output parts")
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco(a)xs4all.nl>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Wang Hai <wanghai38(a)huawei.com>
Signed-off-by: Longlong Xia <xialonglong1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
drivers/media/test-drivers/vivid/vivid-vid-cap.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
index eadf28ab1e39..eeb0aeb62f79 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -953,6 +953,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
if (dev->has_compose_cap) {
v4l2_rect_set_min_size(compose, &min_rect);
v4l2_rect_set_max_size(compose, &max_rect);
+ v4l2_rect_map_inside(compose, &fmt);
}
dev->fmt_cap_rect = fmt;
tpg_s_buf_height(&dev->tpg, fmt.height);
--
2.25.1
1
28

[PATCH openEuler-5.10-LTS 01/18] media: vivid: fix compose size exceed boundary
by Jialin Zhang 22 Feb '23
by Jialin Zhang 22 Feb '23
22 Feb '23
From: Liu Shixin <liushixin2(a)huawei.com>
stable inclusion
from stable-v5.10.163
commit f9d19f3a044ca651b0be52a4bf951ffe74259b9f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6CIF8
CVE: CVE-2023-0615
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 94a7ad9283464b75b12516c5512541d467cefcf8 ]
syzkaller found a bug:
BUG: unable to handle page fault for address: ffffc9000a3b1000
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
PGD 100000067 P4D 100000067 PUD 10015f067 PMD 1121ca067 PTE 0
Oops: 0002 [#1] PREEMPT SMP
CPU: 0 PID: 23489 Comm: vivid-000-vid-c Not tainted 6.1.0-rc1+ #512
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
RIP: 0010:memcpy_erms+0x6/0x10
[...]
Call Trace:
<TASK>
? tpg_fill_plane_buffer+0x856/0x15b0
vivid_fillbuff+0x8ac/0x1110
vivid_thread_vid_cap_tick+0x361/0xc90
vivid_thread_vid_cap+0x21a/0x3a0
kthread+0x143/0x180
ret_from_fork+0x1f/0x30
</TASK>
This is because we forget to check boundary after adjust compose->height
int V4L2_SEL_TGT_CROP case. Add v4l2_rect_map_inside() to fix this problem
for this case.
Fixes: ef834f7836ec ("[media] vivid: add the video capture and output parts")
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco(a)xs4all.nl>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Wang Hai <wanghai38(a)huawei.com>
Signed-off-by: Longlong Xia <xialonglong1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
drivers/media/test-drivers/vivid/vivid-vid-cap.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
index eadf28ab1e39..eeb0aeb62f79 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -953,6 +953,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
if (dev->has_compose_cap) {
v4l2_rect_set_min_size(compose, &min_rect);
v4l2_rect_set_max_size(compose, &max_rect);
+ v4l2_rect_map_inside(compose, &fmt);
}
dev->fmt_cap_rect = fmt;
tpg_s_buf_height(&dev->tpg, fmt.height);
--
2.25.1
1
17

[PATCH openEuler-5.10-LTS 01/18] media: vivid: fix compose size exceed boundary
by Jialin Zhang 22 Feb '23
by Jialin Zhang 22 Feb '23
22 Feb '23
From: Liu Shixin <liushixin2(a)huawei.com>
stable inclusion
from stable-v5.10.163
commit f9d19f3a044ca651b0be52a4bf951ffe74259b9f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6CIF8
CVE: CVE-2023-0615
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 94a7ad9283464b75b12516c5512541d467cefcf8 ]
syzkaller found a bug:
BUG: unable to handle page fault for address: ffffc9000a3b1000
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
PGD 100000067 P4D 100000067 PUD 10015f067 PMD 1121ca067 PTE 0
Oops: 0002 [#1] PREEMPT SMP
CPU: 0 PID: 23489 Comm: vivid-000-vid-c Not tainted 6.1.0-rc1+ #512
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
RIP: 0010:memcpy_erms+0x6/0x10
[...]
Call Trace:
<TASK>
? tpg_fill_plane_buffer+0x856/0x15b0
vivid_fillbuff+0x8ac/0x1110
vivid_thread_vid_cap_tick+0x361/0xc90
vivid_thread_vid_cap+0x21a/0x3a0
kthread+0x143/0x180
ret_from_fork+0x1f/0x30
</TASK>
This is because we forget to check boundary after adjust compose->height
int V4L2_SEL_TGT_CROP case. Add v4l2_rect_map_inside() to fix this problem
for this case.
Fixes: ef834f7836ec ("[media] vivid: add the video capture and output parts")
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco(a)xs4all.nl>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Wang Hai <wanghai38(a)huawei.com>
Signed-off-by: Longlong Xia <xialonglong1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
drivers/media/test-drivers/vivid/vivid-vid-cap.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
index eadf28ab1e39..eeb0aeb62f79 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -953,6 +953,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
if (dev->has_compose_cap) {
v4l2_rect_set_min_size(compose, &min_rect);
v4l2_rect_set_max_size(compose, &max_rect);
+ v4l2_rect_map_inside(compose, &fmt);
}
dev->fmt_cap_rect = fmt;
tpg_s_buf_height(&dev->tpg, fmt.height);
--
2.25.1
1
17

[PATCH openEuler-5.10-LTS-SP1 01/29] media: vivid: fix compose size exceed boundary
by Jialin Zhang 22 Feb '23
by Jialin Zhang 22 Feb '23
22 Feb '23
From: Liu Shixin <liushixin2(a)huawei.com>
stable inclusion
from stable-v5.10.163
commit f9d19f3a044ca651b0be52a4bf951ffe74259b9f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6CIF8
CVE: CVE-2023-0615
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 94a7ad9283464b75b12516c5512541d467cefcf8 ]
syzkaller found a bug:
BUG: unable to handle page fault for address: ffffc9000a3b1000
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
PGD 100000067 P4D 100000067 PUD 10015f067 PMD 1121ca067 PTE 0
Oops: 0002 [#1] PREEMPT SMP
CPU: 0 PID: 23489 Comm: vivid-000-vid-c Not tainted 6.1.0-rc1+ #512
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
RIP: 0010:memcpy_erms+0x6/0x10
[...]
Call Trace:
<TASK>
? tpg_fill_plane_buffer+0x856/0x15b0
vivid_fillbuff+0x8ac/0x1110
vivid_thread_vid_cap_tick+0x361/0xc90
vivid_thread_vid_cap+0x21a/0x3a0
kthread+0x143/0x180
ret_from_fork+0x1f/0x30
</TASK>
This is because we forget to check boundary after adjust compose->height
int V4L2_SEL_TGT_CROP case. Add v4l2_rect_map_inside() to fix this problem
for this case.
Fixes: ef834f7836ec ("[media] vivid: add the video capture and output parts")
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco(a)xs4all.nl>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Wang Hai <wanghai38(a)huawei.com>
Signed-off-by: Longlong Xia <xialonglong1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
drivers/media/test-drivers/vivid/vivid-vid-cap.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
index eadf28ab1e39..eeb0aeb62f79 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -953,6 +953,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
if (dev->has_compose_cap) {
v4l2_rect_set_min_size(compose, &min_rect);
v4l2_rect_set_max_size(compose, &max_rect);
+ v4l2_rect_map_inside(compose, &fmt);
}
dev->fmt_cap_rect = fmt;
tpg_s_buf_height(&dev->tpg, fmt.height);
--
2.25.1
1
28

[PATCH openEuler-1.0-LTS] mm/sharepool: Fix null-pointer-deference in sp_free_area
by Yongqiang Liu 22 Feb '23
by Yongqiang Liu 22 Feb '23
22 Feb '23
From: Wang Wensheng <wangwensheng4(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6G76L
CVE: NA
----------------------------------------------
When a process is deleted from a group, the process does not apply for
memory from the shared group. Otherwise, the UAF problem occurs. We checked
this, but it didn't do a good job of preventing sp_alloc and del_task
concurrency. The process applies for memory after passing the check, which
violates our requirements and causes problems. The solution is to place the
checked code in the critical area to ensure that no memory can be allocated
after the check is passed.
[ T7596] Unable to handle kernel NULL pointer dereference at virtual
address 0000000000000098
[ T7596] Mem abort info:
[ T7596] ESR = 0x96000004
[ T7596] EC = 0x25: DABT (current EL), IL = 32 bits
[ T7596] SET = 0, FnV = 0
[ T7596] EA = 0, S1PTW = 0
[ T7596] Data abort info:
[ T7596] ISV = 0, ISS = 0x00000004
[ T7596] CM = 0, WnR = 0
[ T7596] user pgtable: 4k pages, 48-bit VAs, pgdp=00000001040a3000
[ T7596] [0000000000000098] pgd=0000000000000000, p4d=0000000000000000
[ T7596] Internal error: Oops: 96000004 [#1] SMP
[ T7596] Modules linked in: sharepool_dev(OE) [last unloaded: demo]
[ T7596] CPU: 1 PID: 7596 Comm: test_sp_group_d Tainted: G OE 5.10.0+ #8
[ T7596] Hardware name: linux,dummy-virt (DT)
[ T7596] pstate: 20000005 (nzCv daif -PAN -UAO -TCO BTYPE=--)
[ T7596] pc : sp_free_area+0x34/0x120
[ T7596] lr : sp_free_area+0x30/0x120
[ T7596] sp : ffff80001c6a3b20
[ T7596] x29: ffff80001c6a3b20 x28: 0000000000000009
[ T7596] x27: 0000000000000000 x26: ffff800011c49d20
[ T7596] x25: ffff0000c227f6c0 x24: 0000000000000008
[ T7596] x23: ffff0000c0cf0ce8 x22: 0000000000000001
[ T7596] x21: ffff0000c4082b30 x20: 0000000000000000
[ T7596] x19: ffff0000c4082b00 x18: 0000000000000000
[ T7596] x17: 0000000000000000 x16: 0000000000000000
[ T7596] x15: 0000000000000000 x14: 0000000000000000
[ T7596] x13: 0000000000000000 x12: ffff0005fffe12c0
[ T7596] x11: 0000000000000008 x10: ffff0005fffe12c0
[ T7596] x9 : ffff8000103eb690 x8 : 0000000000000001
[ T7596] x7 : 0000000000210d00 x6 : 0000000000000000
[ T7596] x5 : ffff8000123edea0 x4 : 0000000000000030
[ T7596] x3 : ffffeff000000000 x2 : 0000eff000000000
[ T7596] x1 : 0000e80000000000 x0 : 0000000000000000
[ T7596] Call trace:
[ T7596] sp_free_area+0x34/0x120
[ T7596] __sp_area_drop_locked+0x3c/0x60
[ T7596] sp_area_drop+0x80/0xbc
[ T7596] remove_vma+0x54/0x70
[ T7596] exit_mmap+0x114/0x1d0
[ T7596] mmput+0x90/0x1ec
[ T7596] exit_mm+0x1d0/0x2f0
[ T7596] do_exit+0x180/0x400
[ T7596] do_group_exit+0x40/0x114
[ T7596] get_signal+0x1e8/0x720
[ T7596] do_signal+0x11c/0x1e4
[ T7596] do_notify_resume+0x15c/0x250
[ T7596] work_pending+0xc/0x6d8
[ T7596] Code: f9400001 f9402c00 97fff0e5 aa0003f4 (f9404c00)
[ T7596] ---[ end trace 3c8368d77e758ebd ]---
Signed-off-by: Wang Wensheng <wangwensheng4(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/share_pool.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/mm/share_pool.c b/mm/share_pool.c
index 5d8344fe805a..a136c70b7588 100644
--- a/mm/share_pool.c
+++ b/mm/share_pool.c
@@ -1712,14 +1712,6 @@ int mg_sp_group_del_task(int pid, int spg_id)
ret = -EINVAL;
goto out;
}
-
- if (!list_empty(&spg->spa_list)) {
- up_write(&sp_group_sem);
- pr_err_ratelimited("spa is not empty");
- ret = -EINVAL;
- goto out;
- }
-
ret = get_task(pid, &tsk);
if (ret) {
up_write(&sp_group_sem);
@@ -1743,6 +1735,15 @@ int mg_sp_group_del_task(int pid, int spg_id)
}
down_write(&spg->rw_lock);
+
+ if (!list_empty(&spg->spa_list)) {
+ up_write(&spg->rw_lock);
+ up_write(&sp_group_sem);
+ pr_err_ratelimited("spa is not empty");
+ ret = -EINVAL;
+ goto out_put_mm;
+ }
+
if (list_is_singular(&spg->procs))
is_alive = spg->is_alive = false;
spg->proc_num--;
--
2.25.1
1
0
您好!
Kernel SIG 邀请您参加 2023-02-24 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler Kernel SIG双周例会
会议内容:
欢迎您参加Kernel SIG双周例会,当前议题:
1. 进展update
2. 议题征集中
欢迎大家积极申报议题(新增议题可以直接回复邮件,或录入会议看板)
会议链接:https://us06web.zoom.us/j/82111503728?pwd=TWRGa2REc0V2ZmlGZ2ZreUF1OXA3dz09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2023-02-24 14:00,
The subject of the conference is openEuler Kernel SIG双周例会,
Summary:
欢迎您参加Kernel SIG双周例会,当前议题:
1. 进展update
2. 议题征集中
欢迎大家积极申报议题(新增议题可以直接回复邮件,或录入会议看板)
You can join the meeting at https://us06web.zoom.us/j/82111503728?pwd=TWRGa2REc0V2ZmlGZ2ZreUF1OXA3dz09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0
您好!
sig-Intel-Arch SIG 邀请您参加 2023-02-21 10:00 召开的Zoom会议
会议主题:Intel Arch SIG 例会
会议内容:
1. Intel几个复杂特性的支持计划
2. QEMU和kernel选型对未来lntel平台支持
和release安排讨论
3. openEuler在SPR上的用户诉求和反馈
会议链接:https://us06web.zoom.us/j/87058792984?pwd=UFlzSzA4OHNyMEIvRkpCdWFwdEdRQT09
会议纪要:https://etherpad.openeuler.org/p/sig-Intel-Arch-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler sig-Intel-Arch SIG invites you to attend the Zoom conference will be held at 2023-02-21 10:00,
The subject of the conference is Intel Arch SIG 例会,
Summary:
1. Intel几个复杂特性的支持计划
2. QEMU和kernel选型对未来lntel平台支持
和release安排讨论
3. openEuler在SPR上的用户诉求和反馈
You can join the meeting at https://us06web.zoom.us/j/87058792984?pwd=UFlzSzA4OHNyMEIvRkpCdWFwdEdRQT09.
Add topics at https://etherpad.openeuler.org/p/sig-Intel-Arch-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0
kernel-leave(a)openeuler.org
Best Regards
嵌入式软件开发部 杨国锋
珠海一微半导体股份有限公司 / Amicro Semiconductor Co., Ltd.
横琴总部中心:珠海市横琴新区ICC横琴国际商务中心2座27楼
香洲研发中心:香洲区红山路26号阳光大厦13楼
深圳办公中心:深圳市南山区国家工程实验室大楼A座1102室
电话:0756-2666456
邮编:519000
Phone:18814181955
E-Mail:guofeng.yang(a)amicro.com.cn
This email may contain confidential and/or privileged information from Amicro,and is intended solely for the attention and use of the person(s) named above. If you are not the intended recipient (or have received this email in error), please notify the sender immediately and destroy this email. Any unauthorized copying, disclosure or distribution of the material in this email is strictly forbidden. The content provided in this email can not be guaranteed and assured to be accurate, appropriate for all, and complete by Amicro, and Amicro can not be held responsible forany error or negligence derived therefrom.
(此电子邮件包含来自一微半导体的信息,而且是机密的或者专用的信息。这些信息是供所有以上列出的个人或者团体使用的。如果您不是此邮件的预期收件人,请勿阅读、复制、转发或存储此邮件。如果已误收此邮件,请通知发件人。本公司不担保本电子邮件中信息的准确性、适当性或完整性,并且对此产生的任何错误或疏忽不承担任何责任.)
1
0

[PATCH openEuler-1.0-LTS 1/5] mm/memcg_memfs_info: fix potential oom_lock recursion deadlock
by Yongqiang Liu 16 Feb '23
by Yongqiang Liu 16 Feb '23
16 Feb '23
From: Liu Shixin <liushixin2(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6AXGS
CVE: NA
--------------------------------
syzbot is reporting GFP_KERNEL allocation with oom_lock held when
reporting memcg OOM [1]. If this allocation triggers the global OOM
situation then the system can livelock because the GFP_KERNEL
allocation with oom_lock held cannot trigger the global OOM killer
because __alloc_pages_may_oom() fails to hold oom_lock.
The problem mentioned above has been fixed by patch[2]. The is the same
problem in memcg_memfs_info feature too. Refer to the patch[2], fix it by
removing the allocation from mem_cgroup_print_memfs_info() completely,
and pass static buffer when calling from memcg OOM path.
Link: https://syzkaller.appspot.com/bug?extid=2d2aeadc6ce1e1f11d45 [1]
Link: https://lkml.kernel.org/r/86afb39f-8c65-bec2-6cfc-c5e3cd600c0b@I-love.SAKUR… [2]
Fixes: 6b1d4d3a3713 ("mm/memcg_memfs_info: show files that having pages charged in mem_cgroup")
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
include/linux/memcg_memfs_info.h | 4 +++-
mm/memcg_memfs_info.c | 20 ++++++++++----------
mm/memcontrol.c | 3 ++-
3 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/include/linux/memcg_memfs_info.h b/include/linux/memcg_memfs_info.h
index 658a91e22bd7..b5e3709baa9e 100644
--- a/include/linux/memcg_memfs_info.h
+++ b/include/linux/memcg_memfs_info.h
@@ -6,11 +6,13 @@
#include <linux/seq_file.h>
#ifdef CONFIG_MEMCG_MEMFS_INFO
-void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, struct seq_file *m);
+void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, char *pathbuf,
+ struct seq_file *m);
int mem_cgroup_memfs_files_show(struct seq_file *m, void *v);
void mem_cgroup_memfs_info_init(void);
#else
static inline void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg,
+ char *pathbuf,
struct seq_file *m)
{
}
diff --git a/mm/memcg_memfs_info.c b/mm/memcg_memfs_info.c
index 346175026cae..632e03da673b 100644
--- a/mm/memcg_memfs_info.c
+++ b/mm/memcg_memfs_info.c
@@ -162,7 +162,8 @@ static void memfs_show_files_in_mem_cgroup(struct super_block *sb, void *data)
mntput(pfc->vfsmnt);
}
-void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, struct seq_file *m)
+void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, char *pathbuf,
+ struct seq_file *m)
{
struct print_files_control pfc = {
.memcg = memcg,
@@ -170,17 +171,11 @@ void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, struct seq_file *m)
.max_print_files = memfs_max_print_files,
.size_threshold = memfs_size_threshold,
};
- char *pathbuf;
int i;
if (!memfs_enable || !memcg)
return;
- pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
- if (!pathbuf) {
- SEQ_printf(m, "Show memfs failed due to OOM\n");
- return;
- }
pfc.pathbuf = pathbuf;
pfc.pathbuf_size = PATH_MAX;
@@ -197,15 +192,20 @@ void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, struct seq_file *m)
SEQ_printf(m, "total files: %lu, total memory-size: %lukB\n",
pfc.total_print_files, pfc.total_files_size >> 10);
}
-
- kfree(pfc.pathbuf);
}
int mem_cgroup_memfs_files_show(struct seq_file *m, void *v)
{
struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
+ char *pathbuf;
- mem_cgroup_print_memfs_info(memcg, m);
+ pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+ if (!pathbuf) {
+ SEQ_printf(m, "Show memfs abort: failed to allocate memory\n");
+ return 0;
+ }
+ mem_cgroup_print_memfs_info(memcg, pathbuf, m);
+ kfree(pathbuf);
return 0;
}
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index bdc90e6fc082..fd40fef49e45 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1490,6 +1490,7 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
{
struct mem_cgroup *iter;
unsigned int i;
+ static char pathbuf[PATH_MAX];
pr_info("memory: usage %llukB, limit %llukB, failcnt %lu\n",
K((u64)page_counter_read(&memcg->memory)),
@@ -1522,7 +1523,7 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
pr_cont("\n");
}
- mem_cgroup_print_memfs_info(memcg, NULL);
+ mem_cgroup_print_memfs_info(memcg, pathbuf, NULL);
}
/*
--
2.25.1
1
4

[PATCH openEuler-5.10-LTS-SP1 001/263] KVM: PPC: Book3S HV: Context tracking exit guest context before enabling irqs
by Jialin Zhang 15 Feb '23
by Jialin Zhang 15 Feb '23
15 Feb '23
From: Nicholas Piggin <npiggin(a)gmail.com>
stable inclusion
from stable-v5.10.145
commit 6bae47548188ae957578e6d92d4b8753dec435e4
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6D0VF
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 112665286d08c87e66d699e7cba43c1497ad165f ]
Interrupts that occur in kernel mode expect that context tracking
is set to kernel. Enabling local irqs before context tracking
switches from guest to host means interrupts can come in and trigger
warnings about wrong context, and possibly worse.
Signed-off-by: Nicholas Piggin <npiggin(a)gmail.com>
Signed-off-by: Michael Ellerman <mpe(a)ellerman.id.au>
Link: https://lore.kernel.org/r/20210130130852.2952424-3-npiggin@gmail.com
Stable-dep-of: 235cee162459 ("KVM: PPC: Tick accounting should defer vtime accounting 'til after IRQ handling")
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
Reviewed-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
arch/powerpc/kvm/book3s_hv.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 38b7a3491aac..d6c4e27f7ed9 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -3399,8 +3399,9 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
kvmppc_set_host_core(pcpu);
+ guest_exit_irqoff();
+
local_irq_enable();
- guest_exit();
/* Let secondaries go back to the offline loop */
for (i = 0; i < controlled_threads; ++i) {
@@ -4235,8 +4236,9 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
kvmppc_set_host_core(pcpu);
+ guest_exit_irqoff();
+
local_irq_enable();
- guest_exit();
cpumask_clear_cpu(pcpu, &kvm->arch.cpu_in_guest);
--
2.25.1
1
262

[PATCH openEuler-1.0-LTS 1/2] net: bridge: mcast: add and enforce startup query interval minimum
by Yongqiang Liu 15 Feb '23
by Yongqiang Liu 15 Feb '23
15 Feb '23
From: Nikolay Aleksandrov <nikolay(a)nvidia.com>
mainline inclusion
from mainline-v5.16-rc8
commit f83a112bd91a494cdee671aec74e777470fb4a07
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6DKZJ
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
As reported[1] if startup query interval is set too low in combination with
large number of startup queries and we have multiple bridges or even a
single bridge with multiple querier vlans configured we can crash the
machine. Add a 1 second minimum which must be enforced by overwriting the
value if set lower (i.e. without returning an error) to avoid breaking
user-space. If that happens a log message is emitted to let the admin know
that the startup interval has been set to the minimum. It doesn't make
sense to make the startup interval lower than the normal query interval
so use the same value of 1 second. The issue has been present since these
intervals could be user-controlled.
[1] https://lore.kernel.org/netdev/e8b9ce41-57b9-b6e2-a46a-ff9c791cf0ba@gmail.c…
Fixes: d902eee43f19 ("bridge: Add multicast count/interval sysfs entries")
Reported-by: Eric Dumazet <eric.dumazet(a)gmail.com>
Signed-off-by: Nikolay Aleksandrov <nikolay(a)nvidia.com>
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Conflicts:
net/bridge/br_multicast.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/bridge/br_sysfs_br.c
Signed-off-by: Zhengchao Shao <shaozhengchao(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
net/bridge/br_multicast.c | 16 ++++++++++++++++
net/bridge/br_netlink.c | 2 +-
net/bridge/br_private.h | 5 +++++
net/bridge/br_sysfs_br.c | 2 +-
4 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 3504c3acd38f..ed67a43efdef 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -2351,6 +2351,22 @@ int br_multicast_set_mld_version(struct net_bridge *br, unsigned long val)
}
#endif
+void br_multicast_set_startup_query_intvl(struct net_bridge *br,
+ unsigned long val)
+{
+ unsigned long intvl_jiffies = clock_t_to_jiffies(val);
+
+ if (intvl_jiffies < BR_MULTICAST_STARTUP_QUERY_INTVL_MIN) {
+ br_info(br,
+ "trying to set multicast startup query interval below minimum, setting to %lu (%ums)\n",
+ jiffies_to_clock_t(BR_MULTICAST_STARTUP_QUERY_INTVL_MIN),
+ jiffies_to_msecs(BR_MULTICAST_STARTUP_QUERY_INTVL_MIN));
+ intvl_jiffies = BR_MULTICAST_STARTUP_QUERY_INTVL_MIN;
+ }
+
+ br->multicast_startup_query_interval = intvl_jiffies;
+}
+
/**
* br_multicast_list_adjacent - Returns snooped multicast addresses
* @dev: The bridge port adjacent to which to retrieve addresses
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index c00cb376263a..b3bcfb77077a 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -1237,7 +1237,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
if (data[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]) {
u64 val = nla_get_u64(data[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]);
- br->multicast_startup_query_interval = clock_t_to_jiffies(val);
+ br_multicast_set_startup_query_intvl(br, val);
}
if (data[IFLA_BR_MCAST_STATS_ENABLED]) {
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 23fed55942fa..877fbc65a2fe 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -31,6 +31,9 @@
#define BR_PORT_BITS 10
#define BR_MAX_PORTS (1<<BR_PORT_BITS)
+#define BR_MULTICAST_QUERY_INTVL_MIN msecs_to_jiffies(1000)
+#define BR_MULTICAST_STARTUP_QUERY_INTVL_MIN BR_MULTICAST_QUERY_INTVL_MIN
+
#define BR_VERSION "2.3"
/* Control of forwarding link local multicast */
@@ -1200,4 +1203,6 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
u16 vid, struct net_bridge_port *p, struct nd_msg *msg);
struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m);
+void br_multicast_set_startup_query_intvl(struct net_bridge *br,
+ unsigned long val);
#endif
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 0318a69888d4..bfbffc5088ac 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -618,7 +618,7 @@ static ssize_t multicast_startup_query_interval_show(
static int set_startup_query_interval(struct net_bridge *br, unsigned long val)
{
- br->multicast_startup_query_interval = clock_t_to_jiffies(val);
+ br_multicast_set_startup_query_intvl(br, val);
return 0;
}
--
2.25.1
1
1

[PATCH openEuler-5.10-LTS 1/6] cifs: sanitize multiple delimiters in prepath
by Jialin Zhang 14 Feb '23
by Jialin Zhang 14 Feb '23
14 Feb '23
From: Thiago Rafael Becker <trbecker(a)gmail.com>
mainline inclusion
from mainline-v5.16-rc6
commit a31080899d5fdafcccf7f39dd214a814a2c82626
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6D6RL
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
mount.cifs can pass a device with multiple delimiters in it. This will
cause rename(2) to fail with ENOENT.
V2:
- Make sanitize_path more readable.
- Fix multiple delimiters between UNC and prepath.
- Avoid a memory leak if a bad user starts putting a lot of delimiters
in the path on purpose.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=2031200
Fixes: 24e0a1eff9e2 ("cifs: switch to new mount api")
Cc: stable(a)vger.kernel.org # 5.11+
Acked-by: Ronnie Sahlberg <lsahlber(a)redhat.com>
Signed-off-by: Thiago Rafael Becker <trbecker(a)gmail.com>
Signed-off-by: Steve French <stfrench(a)microsoft.com>
conflicts:
fs/cifs/fs_context.c
Signed-off-by: ZhaoLong Wang <wangzhaolong1(a)huawei.com>
Reviewed-by: Zhang Xiaoxu <zhangxiaoxu5(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
fs/cifs/connect.c | 38 +++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 7f5d173760cf..0a2eced46e35 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1316,6 +1316,42 @@ static int get_option_gid(substring_t args[], kgid_t *result)
return 0;
}
+/*
+ * Remove duplicate path delimiters. Windows is supposed to do that
+ * but there are some bugs that prevent rename from working if there are
+ * multiple delimiters.
+ *
+ * Returns a sanitized duplicate of @path. The caller is responsible for
+ * cleaning up the original.
+ */
+#define IS_DELIM(c) ((c) == '/' || (c) == '\\')
+static char *sanitize_path(char *path)
+{
+ char *cursor1 = path, *cursor2 = path;
+
+ /* skip all prepended delimiters */
+ while (IS_DELIM(*cursor1))
+ cursor1++;
+
+ /* copy the first letter */
+ *cursor2 = *cursor1;
+
+ /* copy the remainder... */
+ while (*(cursor1++)) {
+ /* ... skipping all duplicated delimiters */
+ if (IS_DELIM(*cursor1) && IS_DELIM(*cursor2))
+ continue;
+ *(++cursor2) = *cursor1;
+ }
+
+ /* if the last character is a delimiter, skip it */
+ if (IS_DELIM(*(cursor2 - 1)))
+ cursor2--;
+
+ *(cursor2) = '\0';
+ return kstrdup(path, GFP_KERNEL);
+}
+
/*
* Parse a devname into substrings and populate the vol->UNC and vol->prepath
* fields with the result. Returns 0 on success and an error otherwise.
@@ -1364,7 +1400,7 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)
if (!*pos)
return 0;
- vol->prepath = kstrdup(pos, GFP_KERNEL);
+ vol->prepath = sanitize_path(pos);
if (!vol->prepath)
return -ENOMEM;
--
2.25.1
1
5

[PATCH openEuler-5.10-LTS-SP1 1/8] bpf, sockmap: Fix sk->sk_forward_alloc warn_on in sk_stream_kill_queues
by Jialin Zhang 14 Feb '23
by Jialin Zhang 14 Feb '23
14 Feb '23
From: Wang Yufen <wangyufen(a)huawei.com>
mainline inclusion
from mainline-v6.0-rc1
commit d8616ee2affcff37c5d315310da557a694a3303d
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6BRTY
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
During TCP sockmap redirect pressure test, the following warning is triggered:
WARNING: CPU: 3 PID: 2145 at net/core/stream.c:205 sk_stream_kill_queues+0xbc/0xd0
CPU: 3 PID: 2145 Comm: iperf Kdump: loaded Tainted: G W 5.10.0+ #9
Call Trace:
inet_csk_destroy_sock+0x55/0x110
inet_csk_listen_stop+0xbb/0x380
tcp_close+0x41b/0x480
inet_release+0x42/0x80
__sock_release+0x3d/0xa0
sock_close+0x11/0x20
__fput+0x9d/0x240
task_work_run+0x62/0x90
exit_to_user_mode_prepare+0x110/0x120
syscall_exit_to_user_mode+0x27/0x190
entry_SYSCALL_64_after_hwframe+0x44/0xa9
The reason we observed is that:
When the listener is closing, a connection may have completed the three-way
handshake but not accepted, and the client has sent some packets. The child
sks in accept queue release by inet_child_forget()->inet_csk_destroy_sock(),
but psocks of child sks have not released.
To fix, add sock_map_destroy to release psocks.
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
Signed-off-by: Daniel Borkmann <daniel(a)iogearbox.net>
Signed-off-by: Andrii Nakryiko <andrii(a)kernel.org>
Acked-by: Jakub Sitnicki <jakub(a)cloudflare.com>
Acked-by: John Fastabend <john.fastabend(a)gmail.com>
Link: https://lore.kernel.org/bpf/20220524075311.649153-1-wangyufen@huawei.com
Signed-off-by: Liu Jian <liujian56(a)huawei.com>
Conflicts:
include/linux/bpf.h
Reviewed-by: Wang Yufen <wangyufen(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
include/linux/bpf.h | 1 +
include/linux/skmsg.h | 1 +
net/core/skmsg.c | 1 +
net/core/sock_map.c | 23 +++++++++++++++++++++++
net/ipv4/tcp_bpf.c | 1 +
5 files changed, 27 insertions(+)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 8d95f4c66275..79fb7c1be8fd 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1845,6 +1845,7 @@ static inline bool bpf_map_is_dev_bound(struct bpf_map *map)
struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr);
void bpf_map_offload_map_free(struct bpf_map *map);
+void sock_map_destroy(struct sock *sk);
#else
static inline int bpf_prog_offload_init(struct bpf_prog *prog,
union bpf_attr *attr)
diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
index 1899a1c8421c..a83885c5bb86 100644
--- a/include/linux/skmsg.h
+++ b/include/linux/skmsg.h
@@ -105,6 +105,7 @@ struct sk_psock {
spinlock_t link_lock;
refcount_t refcnt;
void (*saved_unhash)(struct sock *sk);
+ void (*saved_destroy)(struct sock *sk);
void (*saved_close)(struct sock *sk, long timeout);
void (*saved_write_space)(struct sock *sk);
struct proto *sk_proto;
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 622d93d56953..925863fab5bd 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -616,6 +616,7 @@ struct sk_psock *sk_psock_init(struct sock *sk, int node)
psock->eval = __SK_NONE;
psock->sk_proto = prot;
psock->saved_unhash = prot->unhash;
+ psock->saved_destroy = prot->destroy;
psock->saved_close = prot->close;
psock->saved_write_space = sk->sk_write_space;
diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index 28e518da4bcb..85df06298c98 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -1560,6 +1560,29 @@ void sock_map_unhash(struct sock *sk)
saved_unhash(sk);
}
+void sock_map_destroy(struct sock *sk)
+{
+ void (*saved_destroy)(struct sock *sk);
+ struct sk_psock *psock;
+
+ rcu_read_lock();
+ psock = sk_psock_get(sk);
+ if (unlikely(!psock)) {
+ rcu_read_unlock();
+ if (sk->sk_prot->destroy)
+ sk->sk_prot->destroy(sk);
+ return;
+ }
+
+ saved_destroy = psock->saved_destroy;
+ sock_map_remove_links(sk, psock);
+ rcu_read_unlock();
+ sk_psock_stop(psock, true);
+ sk_psock_put(sk, psock);
+ saved_destroy(sk);
+}
+EXPORT_SYMBOL_GPL(sock_map_destroy);
+
void sock_map_close(struct sock *sk, long timeout)
{
void (*saved_close)(struct sock *sk, long timeout);
diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
index afeaf35194de..1a8f129fb309 100644
--- a/net/ipv4/tcp_bpf.c
+++ b/net/ipv4/tcp_bpf.c
@@ -577,6 +577,7 @@ static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS],
struct proto *base)
{
prot[TCP_BPF_BASE] = *base;
+ prot[TCP_BPF_BASE].destroy = sock_map_destroy;
prot[TCP_BPF_BASE].close = sock_map_close;
prot[TCP_BPF_BASE].recvmsg = tcp_bpf_recvmsg;
prot[TCP_BPF_BASE].stream_memory_read = tcp_bpf_stream_read;
--
2.25.1
1
7

14 Feb '23
From: Rodrigo Branco <bsdaemon(a)google.com>
stable inclusion
from stable-v4.19.270
commit 940ede60d74d2fc7291b96cb38072d705333c8e0
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6CU98
CVE: CVE-2023-0045
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=…
--------------------------------
commit a664ec9158eeddd75121d39c9a0758016097fa96 upstream.
We missed the window between the TIF flag update and the next reschedule.
Signed-off-by: Rodrigo Branco <bsdaemon(a)google.com>
Reviewed-by: Borislav Petkov (AMD) <bp(a)alien8.de>
Signed-off-by: Ingo Molnar <mingo(a)kernel.org>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yuyao Lin <linyuyao1(a)huawei.com>
Reviewed-by: Wei Li <liwei391(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
arch/x86/kernel/cpu/bugs.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 3ba948bbd77d..d4d114d62e2e 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -1547,6 +1547,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
if (ctrl == PR_SPEC_FORCE_DISABLE)
task_set_spec_ib_force_disable(task);
task_update_spec_tif(task);
+ if (task == current)
+ indirect_branch_prediction_barrier();
break;
default:
return -ERANGE;
--
2.25.1
1
1
driver inclusion
category:feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6DRLU
CVE: NA
When using the old PCI_FUNC method to obtain the vf id, if the number
of vf big than 8, the obtained id number will be wrong, and the new
method needs to be used to correct it.
Signed-off-by: Longfang Liu <liulongfang(a)huawei.com>
Signed-off-by: JiangShui Yang <yangjiangshui(a)h-partners.com>
---
.../hisilicon/migration/acc_vf_migration.c | 17 ++++++++++--
.../hisilicon/migration/acc_vf_migration.h | 26 +++++++++++++++++++
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/hisilicon/migration/acc_vf_migration.c b/drivers/crypto/hisilicon/migration/acc_vf_migration.c
index 920f19916fea..7c5fc4eb02ac 100644
--- a/drivers/crypto/hisilicon/migration/acc_vf_migration.c
+++ b/drivers/crypto/hisilicon/migration/acc_vf_migration.c
@@ -1610,6 +1610,19 @@ static int acc_vf_dev_init(struct pci_dev *pdev, struct hisi_qm *pf_qm,
return -ENOMEM;
}
+static int hisi_acc_get_vf_id(struct pci_dev *dev)
+{
+ struct pci_dev *pf;
+
+ if (!dev->is_virtfn)
+ return -EINVAL;
+
+ pf = pci_physfn(dev);
+ return (((dev->bus->number << 8) + dev->devfn) -
+ ((pf->bus->number << 8) + pf->devfn + pf->sriov->offset)) /
+ pf->sriov->stride;
+}
+
static void *acc_vf_probe(struct pci_dev *pdev)
{
struct acc_vf_migration *acc_vf_dev;
@@ -1635,7 +1648,7 @@ static void *acc_vf_probe(struct pci_dev *pdev)
return ERR_PTR(-EINVAL);
}
- vf_id = PCI_FUNC(vf_dev->devfn);
+ vf_id = hisi_acc_get_vf_id(vf_dev);
if (vf_id < 0) {
dev_info(&pdev->dev, "vf device: %s, vf id: %d\n",
pf_qm->dev_name, vf_id);
@@ -1652,7 +1665,7 @@ static void *acc_vf_probe(struct pci_dev *pdev)
return ERR_PTR(-ENOMEM);
}
- acc_vf_dev->vf_id = vf_id;
+ acc_vf_dev->vf_id = vf_id + 1;
acc_vf_dev->vf_vendor = pdev->vendor;
acc_vf_dev->vf_device = pdev->device;
acc_vf_dev->pf_dev = pf_dev;
diff --git a/drivers/crypto/hisilicon/migration/acc_vf_migration.h b/drivers/crypto/hisilicon/migration/acc_vf_migration.h
index 2f459eecb8f0..8b38b9943d35 100644
--- a/drivers/crypto/hisilicon/migration/acc_vf_migration.h
+++ b/drivers/crypto/hisilicon/migration/acc_vf_migration.h
@@ -215,6 +215,32 @@ struct acc_vf_region_ops {
struct vfio_info_cap *caps);
};
+/* Single Root I/O Virtualization */
+struct pci_sriov {
+ int pos; /* Capability position */
+ int nres; /* Number of resources */
+ u32 cap; /* SR-IOV Capabilities */
+ u16 ctrl; /* SR-IOV Control */
+ u16 total_VFs; /* Total VFs associated with the PF */
+ u16 initial_VFs; /* Initial VFs associated with the PF */
+ u16 num_VFs; /* Number of VFs available */
+ u16 offset; /* First VF Routing ID offset */
+ u16 stride; /* Following VF stride */
+ u16 vf_device; /* VF device ID */
+ u32 pgsz; /* Page size for BAR alignment */
+ u8 link; /* Function Dependency Link */
+ u8 max_VF_buses; /* Max buses consumed by VFs */
+ u16 driver_max_VFs; /* Max num VFs driver supports */
+ struct pci_dev *dev; /* Lowest numbered PF */
+ struct pci_dev *self; /* This PF */
+ u32 class; /* VF device */
+ u8 hdr_type; /* VF header type */
+ u16 subsystem_vendor; /* VF subsystem vendor */
+ u16 subsystem_device; /* VF subsystem device */
+ resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
+ bool drivers_autoprobe; /* Auto probing of VFs by driver */
+};
+
struct acc_vf_region {
u32 type;
u32 subtype;
--
2.33.0
1
0
您好!
sig-Intel-Arch SIG 邀请您参加 2023-02-21 10:00 召开的Zoom会议
会议主题:Intel Arch SIG 例会
会议内容:
1. Intel几个复杂特性的支持计划
2. QEMU和kernel选型对未来lntel平台支持
和release安排讨论
3. openEuler在SPR上的用户诉求和反馈
会议链接:https://us06web.zoom.us/j/87058792984?pwd=UFlzSzA4OHNyMEIvRkpCdWFwdEdRQT09
会议纪要:https://etherpad.openeuler.org/p/sig-Intel-Arch-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler sig-Intel-Arch SIG invites you to attend the Zoom conference will be held at 2023-02-21 10:00,
The subject of the conference is Intel Arch SIG 例会,
Summary:
1. Intel几个复杂特性的支持计划
2. QEMU和kernel选型对未来lntel平台支持
和release安排讨论
3. openEuler在SPR上的用户诉求和反馈
You can join the meeting at https://us06web.zoom.us/j/87058792984?pwd=UFlzSzA4OHNyMEIvRkpCdWFwdEdRQT09.
Add topics at https://etherpad.openeuler.org/p/sig-Intel-Arch-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0
Sorry! The Zoom meeting will be held at 2023-02-20 10:00 scheduled by openEuler sig-Intel-Arch SIG has been cancelled.
1
0
您好!
sig-Intel-Arch SIG 邀请您参加 2023-02-20 10:00 召开的Zoom会议
会议主题:Intel Arch SIG 例会
会议内容:
1. Intel几个复杂特性的支持计划
2. QEMU和kernel选型对未来lntel平台支持
和release安排讨论
3. openEuler在SPR上的用户诉求和反馈
会议链接:https://us06web.zoom.us/j/87427026722?pwd=eE9lQXBNck9KS0kzek9Da2VYV2VRdz09
会议纪要:https://etherpad.openeuler.org/p/sig-Intel-Arch-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler sig-Intel-Arch SIG invites you to attend the Zoom conference will be held at 2023-02-20 10:00,
The subject of the conference is Intel Arch SIG 例会,
Summary:
1. Intel几个复杂特性的支持计划
2. QEMU和kernel选型对未来lntel平台支持
和release安排讨论
3. openEuler在SPR上的用户诉求和反馈
You can join the meeting at https://us06web.zoom.us/j/87427026722?pwd=eE9lQXBNck9KS0kzek9Da2VYV2VRdz09.
Add topics at https://etherpad.openeuler.org/p/sig-Intel-Arch-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0

[PATCH openEuler-1.0-LTS] media: vivid: fix compose size exceed boundary
by Yongqiang Liu 13 Feb '23
by Yongqiang Liu 13 Feb '23
13 Feb '23
From: Liu Shixin <liushixin2(a)huawei.com>
stable inclusion
from stable-v4.19.270
commit 9c7fba9503b826f0c061d136f8f0c9f953ed18b9
category: bugfix
bugzilla: https://gitee.com/src-openeuler/risc-v-kernel/issues/I6CIGU
CVE: CVE-2023-0615
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 94a7ad9283464b75b12516c5512541d467cefcf8 ]
syzkaller found a bug:
BUG: unable to handle page fault for address: ffffc9000a3b1000
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
PGD 100000067 P4D 100000067 PUD 10015f067 PMD 1121ca067 PTE 0
Oops: 0002 [#1] PREEMPT SMP
CPU: 0 PID: 23489 Comm: vivid-000-vid-c Not tainted 6.1.0-rc1+ #512
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
RIP: 0010:memcpy_erms+0x6/0x10
[...]
Call Trace:
<TASK>
? tpg_fill_plane_buffer+0x856/0x15b0
vivid_fillbuff+0x8ac/0x1110
vivid_thread_vid_cap_tick+0x361/0xc90
vivid_thread_vid_cap+0x21a/0x3a0
kthread+0x143/0x180
ret_from_fork+0x1f/0x30
</TASK>
This is because we forget to check boundary after adjust compose->height
int V4L2_SEL_TGT_CROP case. Add v4l2_rect_map_inside() to fix this problem
for this case.
Fixes: ef834f7836ec ("[media] vivid: add the video capture and output parts")
Signed-off-by: Liu Shixin <liushixin2(a)huawei.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco(a)xs4all.nl>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Longlong Xia <xialonglong1(a)huawei.com>
Reviewed-by: Nanyong Sun <sunnanyong(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/media/platform/vivid/vivid-vid-cap.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index c58ae489f39c..9eaac497ec34 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -915,6 +915,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
if (dev->has_compose_cap) {
v4l2_rect_set_min_size(compose, &min_rect);
v4l2_rect_set_max_size(compose, &max_rect);
+ v4l2_rect_map_inside(compose, &fmt);
}
dev->fmt_cap_rect = fmt;
tpg_s_buf_height(&dev->tpg, fmt.height);
--
2.25.1
1
0

[PATCH openEuler-5.10-LTS-SP1 01/87] NFSD: Fix verifier returned in stable WRITEs
by Jialin Zhang 13 Feb '23
by Jialin Zhang 13 Feb '23
13 Feb '23
From: Chuck Lever <chuck.lever(a)oracle.com>
stable inclusion
from stable-v5.10.143
commit d3d885507b52b28f54770a42d650251876d433a3
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6D0U6
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit f11ad7aa653130b71e2e89bed207f387718216d5 upstream.
RFC 8881 explains the purpose of the write verifier this way:
> The final portion of the result is the field writeverf. This field
> is the write verifier and is a cookie that the client can use to
> determine whether a server has changed instance state (e.g., server
> restart) between a call to WRITE and a subsequent call to either
> WRITE or COMMIT.
But then it says:
> This cookie MUST be unchanged during a single instance of the
> NFSv4.1 server and MUST be unique between instances of the NFSv4.1
> server. If the cookie changes, then the client MUST assume that
> any data written with an UNSTABLE4 value for committed and an old
> writeverf in the reply has been lost and will need to be
> recovered.
RFC 1813 has similar language for NFSv3. NFSv2 does not have a write
verifier since it doesn't implement the COMMIT procedure.
Since commit 19e0663ff9bc ("nfsd: Ensure sampling of the write
verifier is atomic with the write"), the Linux NFS server has
returned a boot-time-based verifier for UNSTABLE WRITEs, but a zero
verifier for FILE_SYNC and DATA_SYNC WRITEs. FILE_SYNC and DATA_SYNC
WRITEs are not followed up with a COMMIT, so there's no need for
clients to compare verifiers for stable writes.
However, by returning a different verifier for stable and unstable
writes, the above commit puts the Linux NFS server a step farther
out of compliance with the first MUST above. At least one NFS client
(FreeBSD) noticed the difference, making this a potential
regression.
[Removed down_write to fix the conflict in the cherry-pick. The
down_write functionality was no longer needed there. Upstream commit
555dbf1a9aac6d3150c8b52fa35f768a692f4eeb titled nfsd: Replace use of
rwsem with errseq_t removed those and replace it with new functionality
that was more scalable. This commit is already backported onto 5.10 and
so removing down_write ensures consistency with that change. Tested by
compiling and booting successfully. - kochera]
Reported-by: Rick Macklem <rmacklem(a)uoguelph.ca>
Link: https://lore.kernel.org/linux-nfs/YQXPR0101MB096857EEACF04A6DF1FC6D9BDD749@…
Fixes: 19e0663ff9bc ("nfsd: Ensure sampling of the write verifier is atomic with the write")
Signed-off-by: Chuck Lever <chuck.lever(a)oracle.com>
Signed-off-by: Michael Kochera <kochera(a)google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
Reviewed-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
fs/nfsd/vfs.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index c852bb5ff212..a4ae1fcd2ab1 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1014,6 +1014,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
iov_iter_kvec(&iter, WRITE, vec, vlen, *cnt);
since = READ_ONCE(file->f_wb_err);
if (flags & RWF_SYNC) {
+ if (verf)
+ nfsd_copy_boot_verifier(verf,
+ net_generic(SVC_NET(rqstp),
+ nfsd_net_id));
host_err = vfs_iter_write(file, &iter, &pos, flags);
if (host_err < 0)
nfsd_reset_boot_verifier(net_generic(SVC_NET(rqstp),
--
2.25.1
1
86
您好!
Kernel SIG 邀请您参加 2023-02-10 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler Kernel SIG双周例会
会议内容:
欢迎您参加年后第一次Kernel SIG 双周例会:
1. 进展update
2. 议题征集中
欢迎大家积极申报议题(新增议题可以直接回复邮件,或录入会议看板)
会议链接:https://us06web.zoom.us/j/89146789515?pwd=NVN5RmdCSFh2Y1g4SXUwK2NCRnFEZz09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2023-02-10 14:00,
The subject of the conference is openEuler Kernel SIG双周例会,
Summary:
欢迎您参加年后第一次Kernel SIG 双周例会:
1. 进展update
2. 议题征集中
欢迎大家积极申报议题(新增议题可以直接回复邮件,或录入会议看板)
You can join the meeting at https://us06web.zoom.us/j/89146789515?pwd=NVN5RmdCSFh2Y1g4SXUwK2NCRnFEZz09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
4
3

[PATCH openEuler-5.10-LTS 1/5] crypto: hisilicon/qm - add functions for releasing resources
by Zheng Zengkai 09 Feb '23
by Zheng Zengkai 09 Feb '23
09 Feb '23
From: Weili Qian <qianweili(a)huawei.com>
mainline inclusion
from mainline-v6.0-rc1
commit bf081d6fa8e9
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6DRLU
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
----------------------------------------------------------------------
The resources allocated by hisi_qm_memory_init() are released by
hisi_qm_uninit(). Add hisi_qm_memory_uninit() to release resources,
no functional change.
conficts:
drivers/crypto/hisilicon/qm.c
Signed-off-by: Weili Qian <qianweili(a)huawei.com>
Signed-off-by: JiangShui Yang <yangjiangshui(a)h-partners.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
---
drivers/crypto/hisilicon/qm.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 57de083e8967..ef09e45bdc3e 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -3480,6 +3480,21 @@ static void hisi_qm_pci_uninit(struct hisi_qm *qm)
pci_disable_device(pdev);
}
+static void hisi_qm_memory_uninit(struct hisi_qm *qm)
+{
+ struct device *dev = &qm->pdev->dev;
+
+ hisi_qp_memory_uninit(qm, qm->qp_num);
+ if (qm->qdma.va) {
+ hisi_qm_cache_wb(qm);
+ dma_free_coherent(dev, qm->qdma.size,
+ qm->qdma.va, qm->qdma.dma);
+ }
+
+ idr_destroy(&qm->qp_idr);
+ kfree(qm->factor);
+}
+
/**
* hisi_qm_uninit() - Uninitialize qm.
* @qm: The qm needed uninit.
@@ -3488,26 +3503,15 @@ static void hisi_qm_pci_uninit(struct hisi_qm *qm)
*/
void hisi_qm_uninit(struct hisi_qm *qm)
{
- struct pci_dev *pdev = qm->pdev;
- struct device *dev = &pdev->dev;
-
qm_cmd_uninit(qm);
- kfree(qm->factor);
- down_write(&qm->qps_lock);
+ down_write(&qm->qps_lock);
if (!qm_avail_state(qm, QM_CLOSE)) {
up_write(&qm->qps_lock);
return;
}
- hisi_qp_memory_uninit(qm, qm->qp_num);
- idr_destroy(&qm->qp_idr);
-
- if (qm->qdma.va) {
- hisi_qm_cache_wb(qm);
- dma_free_coherent(dev, qm->qdma.size,
- qm->qdma.va, qm->qdma.dma);
- }
+ hisi_qm_memory_uninit(qm);
up_write(&qm->qps_lock);
hisi_qm_set_state(qm, VF_NOT_READY);
--
2.20.1
1
4
Chen Zhongjin (1):
perf: Fix possible memleak in pmu_dev_alloc()
Christian Brauner (1):
pnode: terminate at peers of source
Chuck Lever (1):
SUNRPC: Don't leak netobj memory when gss_read_proxy_verf() fails
Dan Carpenter (2):
bonding: uninitialized variable in bond_miimon_inspect()
ipmi: fix use after free in _ipmi_destroy_user()
Enzo Matsumiya (1):
cifs: do not include page data when checking signature
Eric Dumazet (1):
net: stream: purge sk_error_queue in sk_stream_kill_queues()
Greg Kroah-Hartman (1):
prlimit: do_prlimit needs to have a speculation check
Huaxin Lu (1):
ima: Fix a potential NULL pointer access in
ima_restore_measurement_list
Isaac J. Manjarres (1):
driver core: Fix bus_type.match() error handling in __driver_attach()
Jakub Kicinski (2):
bpf: pull before calling skb_postpull_rcsum()
net: stream: don't purge sk_error_queue in sk_stream_kill_queues()
Jan Kara (2):
mbcache: automatically delete entries from cache on freeing
ext4: fix deadlock due to mbcache entry corruption
Jann Horn (2):
mm/khugepaged: fix GUP-fast interaction by sending IPI
mm/khugepaged: invoke MMU notifiers in shmem/file collapse paths
Jiamei Xie (1):
serial: amba-pl011: avoid SBSA UART accessing DMACR register
Jiang Li (1):
md/raid1: stop mdx_raid1 thread when raid1 array run failed
Li Zetao (1):
ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage()
Mark Rutland (1):
arm64: cmpxchg_double*: hazard against entire exchange variable
Michael S. Tsirkin (1):
PCI: Fix pci_device_is_present() for VFs by checking PF
Mikulas Patocka (1):
md: fix a crash in mempool_free
Paolo Abeni (1):
net/ulp: prevent ULP without clone op from entering the LISTEN status
Rafael J. Wysocki (1):
ACPICA: Fix error code path in acpi_ds_call_control_method()
Sascha Hauer (1):
PCI/sysfs: Fix double free in error path
Schspa Shi (1):
mrp: introduce active flags to prevent UAF when applicant uninit
Stanislav Fomichev (1):
bpf: make sure skb->len != 0 when redirecting to a tunneling device
Stephen Boyd (1):
pstore: Avoid kcore oops by vmap()ing with VM_IOREMAP
Subash Abhinov Kasiviswanathan (1):
skbuff: Account for tail adjustment during pull operations
Ulf Hansson (1):
cpuidle: dt: Return the correct numbers of parsed idle states
Volker Lendecke (1):
cifs: Fix uninitialized memory read for smb311 posix symlink create
Wang ShaoBo (1):
SUNRPC: Fix missing release socket in rpc_sockname()
Wang Weiyang (1):
device_cgroup: Roll back to original exceptions after copy failure
Wang Yufen (2):
pstore/ram: Fix error return code in ramoops_probe()
binfmt: Fix error return code in load_elf_fdpic_binary()
Xiu Jianfeng (1):
ima: Fix misuse of dereference of pointer in
template_desc_init_fields()
Yang Jihong (1):
blktrace: Fix output non-blktrace event when blk_classic option
enabled
Yang Shi (1):
mm: gup: fix the fast GUP race against THP collapse
Yang Yingliang (2):
class: fix possible memory leak in __class_register()
chardev: fix error handling in cdev_device_add()
Ye Bin (1):
blk-mq: fix possible memleak when register 'hctx' failed
Yuan Can (1):
perf: arm_dsu: Fix hotplug callback leak in dsu_pmu_init()
Zhang Tianci (1):
ovl: Use ovl mounter's fsuid and fsgid in ovl_link()
Zhang Yiqun (1):
crypto: tcrypt - Fix multibuffer skcipher speed test mem leak
Zhang Yuchen (2):
ipmi: fix memleak when unload ipmi driver
ipmi: fix long wait in unload when IPMI disconnect
ZhangPeng (1):
pinctrl: pinconf-generic: add missing of_node_put()
delisun (1):
serial: pl011: Do not clear RX FIFO & RX interrupt in unthrottle.
minoura makoto (1):
SUNRPC: ensure the matching upcall is in-flight upon downcall
arch/arm64/include/asm/atomic_ll_sc.h | 2 +-
arch/arm64/include/asm/atomic_lse.h | 2 +-
block/blk-mq-sysfs.c | 11 ++-
crypto/tcrypt.c | 9 --
drivers/acpi/acpica/dsmethod.c | 10 ++-
drivers/acpi/acpica/utcopy.c | 7 --
drivers/base/class.c | 5 ++
drivers/base/dd.c | 8 +-
drivers/char/ipmi/ipmi_msghandler.c | 12 ++-
drivers/char/ipmi/ipmi_si_intf.c | 27 ++++--
drivers/cpuidle/dt_idle_states.c | 2 +-
drivers/md/md.c | 9 +-
drivers/md/raid1.c | 1 +
drivers/net/bonding/bond_main.c | 2 +-
drivers/pci/pci-sysfs.c | 13 ++-
drivers/pci/pci.c | 2 +
drivers/perf/arm_dsu_pmu.c | 6 +-
drivers/pinctrl/pinconf-generic.c | 4 +-
drivers/tty/serial/amba-pl011.c | 14 ++-
fs/binfmt_elf_fdpic.c | 5 +-
fs/char_dev.c | 2 +-
fs/cifs/link.c | 1 +
fs/cifs/smb2pdu.c | 15 ++--
fs/ext4/xattr.c | 4 +-
fs/mbcache.c | 118 ++++++++++----------------
fs/overlayfs/dir.c | 46 ++++++----
fs/pnode.c | 2 +-
fs/pstore/ram.c | 2 +
fs/pstore/ram_core.c | 6 +-
include/asm-generic/tlb.h | 6 ++
include/linux/mbcache.h | 33 ++++---
include/linux/sunrpc/rpc_pipe_fs.h | 5 ++
include/net/mrp.h | 1 +
kernel/events/core.c | 8 +-
kernel/sys.c | 2 +
kernel/trace/blktrace.c | 3 +-
mm/gup.c | 34 ++++++--
mm/khugepaged.c | 34 ++++++--
mm/memory.c | 1 +
mm/mmu_gather.c | 5 ++
net/802/mrp.c | 18 ++--
net/core/filter.c | 11 ++-
net/core/skbuff.c | 3 +
net/core/stream.c | 7 +-
net/ipv4/inet_connection_sock.c | 16 +++-
net/sunrpc/auth_gss/auth_gss.c | 19 ++++-
net/sunrpc/auth_gss/svcauth_gss.c | 4 +-
net/sunrpc/clnt.c | 2 +-
security/device_cgroup.c | 33 ++++++-
security/integrity/ima/ima_template.c | 9 +-
50 files changed, 406 insertions(+), 195 deletions(-)
--
2.25.1
1
49
Ard Biesheuvel (1):
crypto: tcrypt - avoid signed overflow in byte count
Guenter Roeck (1):
lib/list_debug.c: Detect uninitialized lists
Guoqing Jiang (1):
md: protect md_unregister_thread from reentrancy
Konstantin Khlebnikov (1):
sched/rt: Optimize checking group RT scheduler constraints
Sean Christopherson (1):
hugetlbfs: fix off-by-one error in hugetlb_vmdelete_list()
crypto/tcrypt.c | 20 ++++++++++----------
drivers/md/md.c | 15 ++++++++++-----
fs/hugetlbfs/inode.c | 7 ++++---
kernel/sched/rt.c | 24 +++++++++++-------------
lib/list_debug.c | 12 ++++++++++--
5 files changed, 45 insertions(+), 33 deletions(-)
--
2.25.1
1
5

[PATCH openEuler-1.0-LTS] mm: sharepool: fix hugepage_rsvd count increase error
by Yongqiang Liu 09 Feb '23
by Yongqiang Liu 09 Feb '23
09 Feb '23
From: Guo Mengqi <guomengqi3(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RO2H
CVE: NA
--------------------------------
When nr_hugepages is configured, sharepool allocates hugepages first
from hugetlb pool, then from buddy system if the pool had been used up.
Current page release function treat the buddy system hugepages as
hugetlb pages, which caused HugePages_Rsvd to increase improperly.
Add a check in page release function:
if the page is temporary, do not call hugetlb_unreserve_pages.
Signed-off-by: Guo Mengqi <guomengqi3(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/hugetlbfs/inode.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index f29d6d2fb052..d70c8aaf5acc 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -448,6 +448,14 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end)
}
}
+static inline bool PageHugeTemporary(struct page *page)
+{
+ if (!PageHuge(page))
+ return false;
+
+ return (unsigned long)page[2].mapping == -1U;
+}
+
/*
* remove_inode_hugepages handles two distinct cases: truncation and hole
* punch. There are subtle differences in operation for each case.
@@ -532,11 +540,17 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
*/
VM_BUG_ON(PagePrivate(page));
remove_huge_page(page);
- freed++;
- if (!truncate_op) {
- if (unlikely(hugetlb_unreserve_pages(inode,
+ /*
+ * if the page is from buddy system, do not add to freed.
+ * because freed is used for hugetlbfs reservation accounting.
+ */
+ if (!PageHugeTemporary(page)) {
+ freed++;
+ if (!truncate_op) {
+ if (unlikely(hugetlb_unreserve_pages(inode,
index, index + 1, 1)))
hugetlb_fix_reserve_counts(inode);
+ }
}
unlock_page(page);
--
2.25.1
1
0

[PATCH openEuler-5.10-LTS 1/5] crypto: hisilicon/qm - add functions for releasing resources
by Zheng Zengkai 09 Feb '23
by Zheng Zengkai 09 Feb '23
09 Feb '23
From: Weili Qian <qianweili(a)huawei.com>
mainline inclusion
from mainline-v6.0-rc1
commit bf081d6fa8e9
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6DRLU
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
----------------------------------------------------------------------
The resources allocated by hisi_qm_memory_init() are released by
hisi_qm_uninit(). Add hisi_qm_memory_uninit() to release resources,
no functional change.
conficts:
drivers/crypto/hisilicon/qm.c
Signed-off-by: Weili Qian <qianweili(a)huawei.com>
Signed-off-by: JiangShui Yang <yangjiangshui(a)h-partners.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
---
drivers/crypto/hisilicon/qm.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 57de083e8967..ef09e45bdc3e 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -3480,6 +3480,21 @@ static void hisi_qm_pci_uninit(struct hisi_qm *qm)
pci_disable_device(pdev);
}
+static void hisi_qm_memory_uninit(struct hisi_qm *qm)
+{
+ struct device *dev = &qm->pdev->dev;
+
+ hisi_qp_memory_uninit(qm, qm->qp_num);
+ if (qm->qdma.va) {
+ hisi_qm_cache_wb(qm);
+ dma_free_coherent(dev, qm->qdma.size,
+ qm->qdma.va, qm->qdma.dma);
+ }
+
+ idr_destroy(&qm->qp_idr);
+ kfree(qm->factor);
+}
+
/**
* hisi_qm_uninit() - Uninitialize qm.
* @qm: The qm needed uninit.
@@ -3488,26 +3503,15 @@ static void hisi_qm_pci_uninit(struct hisi_qm *qm)
*/
void hisi_qm_uninit(struct hisi_qm *qm)
{
- struct pci_dev *pdev = qm->pdev;
- struct device *dev = &pdev->dev;
-
qm_cmd_uninit(qm);
- kfree(qm->factor);
- down_write(&qm->qps_lock);
+ down_write(&qm->qps_lock);
if (!qm_avail_state(qm, QM_CLOSE)) {
up_write(&qm->qps_lock);
return;
}
- hisi_qp_memory_uninit(qm, qm->qp_num);
- idr_destroy(&qm->qp_idr);
-
- if (qm->qdma.va) {
- hisi_qm_cache_wb(qm);
- dma_free_coherent(dev, qm->qdma.size,
- qm->qdma.va, qm->qdma.dma);
- }
+ hisi_qm_memory_uninit(qm);
up_write(&qm->qps_lock);
hisi_qm_set_state(qm, VF_NOT_READY);
--
2.20.1
1
4

[PATCH openEuler-1.0-LTS 1/3] irqchip/gic-v3-its: introduce CONFIG_GENERIC_PENDING_IRQ
by Yongqiang Liu 09 Feb '23
by Yongqiang Liu 09 Feb '23
09 Feb '23
From: Yipeng Zou <zouyipeng(a)huawei.com>
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6BO2R
CVE: NA
--------------------------------
Now, There is some issues about LPI migration on ARM SMP platform.
For example, NIC device generates MSI and sends LPI to CPU0 via ITS,
meanwhile irqbalance running on CPU1 set irq affinty of NIC to CPU1,
the next interrupt will be sent to CPU2, due to the state of irq is
still in progress, kernel does not end up performing irq handler on
CPU2, which results in some userland service timeouts, the sequence
of events is shown as follows:
NIC CPU0 CPU1
Generate IRQ#1 READ_IAR
Lock irq_desc
Set IRQD_IN_PROGRESS
Unlock irq_desc
Lock irq_desc
Change LPI Affinity
Unlock irq_desc
Call irq_handler
Generate IRQ#2
READ_IAR
Lock irq_desc
Check IRQD_IN_PROGRESS
Unlock irq_desc
Return from interrupt#2
Lock irq_desc
Clear IRQD_IN_PROGRESS
Unlock irq_desc
return from interrupt#1
For this scenario, We can enable CONFIG_GENERIC_PENDING_IRQ to avoid this.
The CONFIG_GENERIC_PENDING_IRQ will delay all action that modify LPI
affinity until the next interrupt eoi handler.
Signed-off-by: Yipeng Zou <zouyipeng(a)huawei.com>
Reviewed-by: Liao Chang <liaochang1(a)huawei.com>
Reviewed-by: Zhang Jianhua <chris.zjh(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/irqchip/irq-gic-v3-its.c | 8 +++++++-
kernel/irq/Kconfig | 4 +++-
kernel/irq/migration.c | 2 ++
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 15a0292e8e61..7a0adf67761e 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1162,6 +1162,12 @@ static void its_unmask_irq(struct irq_data *d)
lpi_update_config(d, 0, LPI_PROP_ENABLED);
}
+static void its_irq_chip_eoi(struct irq_data *d)
+{
+ irq_move_irq(d);
+ irq_chip_eoi_parent(d);
+}
+
static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
bool force)
{
@@ -1485,7 +1491,7 @@ static struct irq_chip its_irq_chip = {
.name = "ITS",
.irq_mask = its_mask_irq,
.irq_unmask = its_unmask_irq,
- .irq_eoi = irq_chip_eoi_parent,
+ .irq_eoi = its_irq_chip_eoi,
.irq_set_affinity = its_set_affinity,
.irq_compose_msi_msg = its_irq_compose_msi_msg,
.irq_set_irqchip_state = its_irq_set_irqchip_state,
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 14a85d0161ea..eebbced84e44 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -32,7 +32,9 @@ config GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
# Support for delayed migration from interrupt context
config GENERIC_PENDING_IRQ
- bool
+ bool "Support for delayed migration from interrupt context"
+ depends on SMP
+ default n
# Support for generic irq migrating off cpu before the cpu is offline.
config GENERIC_IRQ_MIGRATION
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index def48589ea48..bcb61ee69c20 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -117,3 +117,5 @@ void __irq_move_irq(struct irq_data *idata)
if (!masked)
idata->chip->irq_unmask(idata);
}
+
+void __weak irq_force_complete_move(struct irq_desc *desc) { }
--
2.25.1
1
2

[PATCH openEuler-1.0-LTS 1/3] jbd2: Fix data missing when reusing bh which is ready to be checkpointed
by Yongqiang Liu 09 Feb '23
by Yongqiang Liu 09 Feb '23
09 Feb '23
From: Zhihao Cheng <chengzhihao1(a)huawei.com>
maillist inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6C5HV
CVE: NA
Reference: https://lore.kernel.org/lkml/20230110015327.1181863-1-chengzhihao1@huawei.c…
--------------------------------
Following process will make data lost and could lead to a filesystem
corrupted problem:
1. jh(bh) is inserted into T1->t_checkpoint_list, bh is dirty, and
jh->b_transaction = NULL
2. T1 is added into journal->j_checkpoint_transactions.
3. Get bh prepare to write while doing checkpoing:
PA PB
do_get_write_access jbd2_log_do_checkpoint
spin_lock(&jh->b_state_lock)
if (buffer_dirty(bh))
clear_buffer_dirty(bh) // clear buffer dirty
set_buffer_jbddirty(bh)
transaction =
journal->j_checkpoint_transactions
jh = transaction->t_checkpoint_list
if (!buffer_dirty(bh))
__jbd2_journal_remove_checkpoint(jh)
// bh won't be flushed
jbd2_cleanup_journal_tail
__jbd2_journal_file_buffer(jh, transaction, BJ_Reserved)
4. Aborting journal/Power-cut before writing latest bh on journal area.
In this way we get a corrupted filesystem with bh's data lost.
Fix it by moving the clearing of buffer_dirty bit just before the call
to __jbd2_journal_file_buffer(), both bit clearing and jh->b_transaction
assignment are under journal->j_list_lock locked, so that
jbd2_log_do_checkpoint() will wait until jh's new transaction fininshed
even bh is currently not dirty. And journal_shrink_one_cp_list() won't
remove jh from checkpoint list if the buffer head is reused in
do_get_write_access().
Fetch a reproducer in [Link].
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216898
Cc: <stable(a)kernel.org>
Signed-off-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Signed-off-by: zhanchengbin <zhanchengbin1(a)huawei.com>
Suggested-by: Jan Kara <jack(a)suse.cz>
Conflicts:
fs/jbd2/transaction.c
[ 464170647b5648bb8("jbd2: Make state lock a spinlock") is not
applied. ]
Signed-off-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Reviewed-by: Yang Erkun <yangerkun(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/jbd2/transaction.c | 50 +++++++++++++++++++++++++------------------
1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 3b31bd1f7b77..149190c2ac89 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -935,36 +935,28 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
* ie. locked but not dirty) or tune2fs (which may actually have
* the buffer dirtied, ugh.) */
- if (buffer_dirty(bh)) {
+ if (buffer_dirty(bh) && jh->b_transaction) {
+ warn_dirty_buffer(bh);
/*
- * First question: is this buffer already part of the current
- * transaction or the existing committing transaction?
- */
- if (jh->b_transaction) {
- J_ASSERT_JH(jh,
- jh->b_transaction == transaction ||
- jh->b_transaction ==
- journal->j_committing_transaction);
- if (jh->b_next_transaction)
- J_ASSERT_JH(jh, jh->b_next_transaction ==
- transaction);
- warn_dirty_buffer(bh);
- }
- /*
- * In any case we need to clean the dirty flag and we must
- * do it under the buffer lock to be sure we don't race
- * with running write-out.
+ * We need to clean the dirty flag and we must do it under the
+ * buffer lock to be sure we don't race with running write-out.
*/
JBUFFER_TRACE(jh, "Journalling dirty buffer");
clear_buffer_dirty(bh);
+ /*
+ * The buffer is going to be added to BJ_Reserved list now and
+ * nothing guarantees jbd2_journal_dirty_metadata() will be
+ * ever called for it. So we need to set jbddirty bit here to
+ * make sure the buffer is dirtied and written out when the
+ * journaling machinery is done with it.
+ */
set_buffer_jbddirty(bh);
}
- unlock_buffer(bh);
-
error = -EROFS;
if (is_handle_aborted(handle)) {
jbd_unlock_bh_state(bh);
+ unlock_buffer(bh);
goto out;
}
error = 0;
@@ -974,8 +966,10 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
* b_next_transaction points to it
*/
if (jh->b_transaction == transaction ||
- jh->b_next_transaction == transaction)
+ jh->b_next_transaction == transaction) {
+ unlock_buffer(bh);
goto done;
+ }
/*
* this is the first time this transaction is touching this buffer,
@@ -999,10 +993,24 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
*/
smp_wmb();
spin_lock(&journal->j_list_lock);
+ if (test_clear_buffer_dirty(bh)) {
+ /*
+ * Execute buffer dirty clearing and jh->b_transaction
+ * assignment under journal->j_list_lock locked to
+ * prevent bh being removed from checkpoint list if
+ * the buffer is in an intermediate state (not dirty
+ * and jh->b_transaction is NULL).
+ */
+ JBUFFER_TRACE(jh, "Journalling dirty buffer");
+ set_buffer_jbddirty(bh);
+ }
__jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
spin_unlock(&journal->j_list_lock);
+ unlock_buffer(bh);
goto done;
}
+ unlock_buffer(bh);
+
/*
* If there is already a copy-out version of this buffer, then we don't
* need to make another one
--
2.25.1
1
2

[PATCH openEuler-1.0-LTS] x86/unwind: Fix orc entry for paravirt {save,restore}_fl
by Yongqiang Liu 08 Feb '23
by Yongqiang Liu 08 Feb '23
08 Feb '23
From: Chen Zhongjin <chenzhongjin(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 187818, https://gitee.com/openeuler/kernel/issues/I6DK3O
CVE: NA
--------------------------------
When CONFIG_PARAVIRT is enabled, the code of {save,restore}_fl is
defined as:
ff 14 25 00 00 00 00 callq *0x0
which will be patched to call the xen paravirt function, or native
implementation, in 'paravirt_patch_64.c':
pushfq; popq %rax // for native_save_fl
pushq %rdi; popfq // for native_restore_fl
The orc metadata is generated with insn 'callq', so it can become
inconsistent with the real insn 'push;pop'.
This makes stacktrace on the 'pop' insn fail and incorrect stacktrace
result can be returned.
To prevent reliable stacktrace broken, check the insns when unwind
pt_regs stack frame:
When there are 'push;pop' combination and both insns don't change orc
entry, it means the stack state is inconsistent with orc on pop.
Add one slot to sp_offset for on original orc entry to get the correct
orc entry.
Signed-off-by: Chen Zhongjin <chenzhongjin(a)huawei.com>
Reviewed-by: Xu Kuohai <xukuohai(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
arch/x86/kernel/unwind_orc.c | 43 ++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
index 0402bc0b5851..ec4a14e4f639 100644
--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -138,6 +138,34 @@ static struct orc_entry null_orc_entry = {
.type = ORC_TYPE_CALL
};
+#ifdef CONFIG_PARAVIRT
+static bool check_paravirt(struct unwind_state *state, struct orc_entry *orc)
+{
+ u8 *ip = (u8 *)state->ip;
+
+ /*
+ * In paravirt_patch_64.c, patched paravirt opcode should be:
+ * pushfq; popq %rax // 0x9c 0x58
+ * pushq %rdi; popfq // 0x57 0x9d
+ *
+ * Error unwinding only happens when:
+ * 1. In irq or preempt context.
+ * 2. Current insn is popq, and it doesn't change orc.
+ * 3. Last insn doesn't change orc, checking it first to
+ * promise ip - 1 is valid.
+ * 4. Last byte fits pushf.
+ */
+ if (state->regs && orc->type == ORC_TYPE_CALL &&
+ (ip[0] == 0x58 || ip[0] == 0x9d) &&
+ orc == orc_find((unsigned long)(ip + 1)) &&
+ orc == orc_find((unsigned long)(ip - 1)) &&
+ (ip[-1] == 0x9c || ip[-1] == 0x57))
+ return true;
+
+ return false;
+}
+#endif
+
static struct orc_entry *orc_find(unsigned long ip)
{
static struct orc_entry *orc;
@@ -415,6 +443,9 @@ bool unwind_next_frame(struct unwind_state *state)
enum stack_type prev_type = state->stack_info.type;
struct orc_entry *orc;
bool indirect = false;
+#ifdef CONFIG_PARAVIRT
+ struct orc_entry para_orc;
+#endif
if (unwind_done(state))
return false;
@@ -436,6 +467,18 @@ bool unwind_next_frame(struct unwind_state *state)
if (!orc)
goto err;
+#ifdef CONFIG_PARAVIRT
+ /*
+ * When hitting paravirt POP insn, the orc entry should add
+ * one slot for PUSH insn.
+ */
+ if (!state->error && check_paravirt(state, orc)) {
+ para_orc = *orc;
+ para_orc.sp_offset += sizeof(long);
+ orc = ¶_orc;
+ }
+#endif
+
/* End-of-stack check for kernel threads: */
if (orc->sp_reg == ORC_REG_UNDEFINED) {
if (!orc->end)
--
2.25.1
1
0

[PATCH openEuler-1.0-LTS 1/2] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry
by Yongqiang Liu 07 Feb '23
by Yongqiang Liu 07 Feb '23
07 Feb '23
From: Zheng Wang <zyytlz.wz(a)163.com>
mainline inclusion
from mainline-v6.2-rc3
commit 4a61648af68f5ba4884f0e3b494ee1cabc4b6620
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5XXFF
CVE: CVE-2022-3707
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
If intel_gvt_dma_map_guest_page failed, it will call
ppgtt_invalidate_spt, which will finally free the spt.
But the caller function ppgtt_populate_spt_by_guest_entry
does not notice that, it will free spt again in its error
path.
Fix this by canceling the mapping of DMA address and freeing sub_spt.
Besides, leave the handle of spt destroy to caller function instead
of callee function when error occurs.
Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support")
Signed-off-by: Zheng Wang <zyytlz.wz(a)163.com>
Reviewed-by: Zhenyu Wang <zhenyuw(a)linux.intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw(a)linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20221229165641.1192455-1-zyytl…
conflicts:
drivers/gpu/drm/i915/gvt/gtt.c
Signed-off-by: Wang ShaoBo <bobo.shaobowang(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Wei Li <liwei391(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/gpu/drm/i915/gvt/gtt.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 40b32b4d1d98..afbc648befec 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1155,10 +1155,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
for_each_shadow_entry(sub_spt, &sub_se, sub_index) {
ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu,
start_gfn + sub_index, PAGE_SIZE, &dma_addr);
- if (ret) {
- ppgtt_invalidate_spt(spt);
- return ret;
- }
+ if (ret)
+ goto err;
sub_se.val64 = se->val64;
/* Copy the PAT field from PDE. */
@@ -1177,6 +1175,17 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
ops->set_pfn(se, sub_spt->shadow_page.mfn);
ppgtt_set_shadow_entry(spt, se, index);
return 0;
+err:
+ /* Cancel the existing addess mappings of DMA addr. */
+ for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) {
+ gvt_vdbg_mm("invalidate 4K entry\n");
+ ppgtt_invalidate_pte(sub_spt, &sub_se);
+ }
+ /* Release the new allocated spt. */
+ trace_spt_change(sub_spt->vgpu->id, "release", sub_spt,
+ sub_spt->guest_page.gfn, sub_spt->shadow_page.type);
+ ppgtt_free_spt(sub_spt);
+ return ret;
}
static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
--
2.25.1
1
1

07 Feb '23
From: Dave Chinner <dchinner(a)redhat.com>
mainline inclusion
from mainline-v5.19-rc1
commit c230a4a85bcdbfc1a7415deec6caf04e8fca1301
category: bugfix
bugzilla: 187372, https://gitee.com/openeuler/kernel/issues/I5K0OM
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
Ever since we added shadown format buffers to the log items, log
items need to handle the item being released with shadow buffers
attached. Due to the fact this requirement was added at the same
time we added new rmap/reflink intents, we missed the cleanup of
those items.
In theory, this means shadow buffers can be leaked in a very small
window when a shutdown is initiated. Testing with KASAN shows this
leak does not happen in practice - we haven't identified a single
leak in several years of shutdown testing since ~v4.8 kernels.
However, the intent whiteout cleanup mechanism results in every
cancelled intent in exactly the same state as this tiny race window
creates and so if intents down clean up shadow buffers on final
release we will leak the shadow buffer for just about every intent
we create.
Hence we start with this patch to close this condition off and
ensure that when whiteouts start to be used we don't leak lots of
memory.
Signed-off-by: Dave Chinner <dchinner(a)redhat.com>
Reviewed-by: Darrick J. Wong <djwong(a)kernel.org>
Reviewed-by: Allison Henderson <allison.henderson(a)oracle.com>
Signed-off-by: Dave Chinner <david(a)fromorbit.com>
conflicts:
fs/xfs/xfs_bmap_item.c
fs/xfs/xfs_icreate_item.c
fs/xfs/xfs_refcount_item.c
fs/xfs/xfs_rmap_item.c
Signed-off-by: Li Nan <linan122(a)huawei.com>
Reviewed-by: Yang Erkun <yangerkun(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
fs/xfs/xfs_bmap_item.c | 2 ++
fs/xfs/xfs_icreate_item.c | 1 +
fs/xfs/xfs_refcount_item.c | 2 ++
fs/xfs/xfs_rmap_item.c | 2 ++
4 files changed, 7 insertions(+)
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index 44ec0f2d5253..e6de8081451f 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -40,6 +40,7 @@ STATIC void
xfs_bui_item_free(
struct xfs_bui_log_item *buip)
{
+ kmem_free(buip->bui_item.li_lv_shadow);
kmem_cache_free(xfs_bui_zone, buip);
}
@@ -199,6 +200,7 @@ xfs_bud_item_release(
struct xfs_bud_log_item *budp = BUD_ITEM(lip);
xfs_bui_release(budp->bud_buip);
+ kmem_free(budp->bud_item.li_lv_shadow);
kmem_cache_free(xfs_bud_zone, budp);
}
diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c
index 9b3994b9c716..aa8c7c261d24 100644
--- a/fs/xfs/xfs_icreate_item.c
+++ b/fs/xfs/xfs_icreate_item.c
@@ -63,6 +63,7 @@ STATIC void
xfs_icreate_item_release(
struct xfs_log_item *lip)
{
+ kmem_free(ICR_ITEM(lip)->ic_item.li_lv_shadow);
kmem_cache_free(xfs_icreate_zone, ICR_ITEM(lip));
}
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
index 0dee316283a9..9f4ff45c7a93 100644
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -35,6 +35,7 @@ STATIC void
xfs_cui_item_free(
struct xfs_cui_log_item *cuip)
{
+ kmem_free(cuip->cui_item.li_lv_shadow);
if (cuip->cui_format.cui_nextents > XFS_CUI_MAX_FAST_EXTENTS)
kmem_free(cuip);
else
@@ -204,6 +205,7 @@ xfs_cud_item_release(
struct xfs_cud_log_item *cudp = CUD_ITEM(lip);
xfs_cui_release(cudp->cud_cuip);
+ kmem_free(cudp->cud_item.li_lv_shadow);
kmem_cache_free(xfs_cud_zone, cudp);
}
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index 20905953fe76..b5447ac7cb9b 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -35,6 +35,7 @@ STATIC void
xfs_rui_item_free(
struct xfs_rui_log_item *ruip)
{
+ kmem_free(ruip->rui_item.li_lv_shadow);
if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS)
kmem_free(ruip);
else
@@ -227,6 +228,7 @@ xfs_rud_item_release(
struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
xfs_rui_release(rudp->rud_ruip);
+ kmem_free(rudp->rud_item.li_lv_shadow);
kmem_cache_free(xfs_rud_zone, rudp);
}
--
2.25.1
1
9

07 Feb '23
From: Dave Chinner <dchinner(a)redhat.com>
mainline inclusion
from mainline-v5.19-rc1
commit c230a4a85bcdbfc1a7415deec6caf04e8fca1301
category: bugfix
bugzilla: 187372, https://gitee.com/openeuler/kernel/issues/I5K0OM
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
Ever since we added shadown format buffers to the log items, log
items need to handle the item being released with shadow buffers
attached. Due to the fact this requirement was added at the same
time we added new rmap/reflink intents, we missed the cleanup of
those items.
In theory, this means shadow buffers can be leaked in a very small
window when a shutdown is initiated. Testing with KASAN shows this
leak does not happen in practice - we haven't identified a single
leak in several years of shutdown testing since ~v4.8 kernels.
However, the intent whiteout cleanup mechanism results in every
cancelled intent in exactly the same state as this tiny race window
creates and so if intents down clean up shadow buffers on final
release we will leak the shadow buffer for just about every intent
we create.
Hence we start with this patch to close this condition off and
ensure that when whiteouts start to be used we don't leak lots of
memory.
Signed-off-by: Dave Chinner <dchinner(a)redhat.com>
Reviewed-by: Darrick J. Wong <djwong(a)kernel.org>
Reviewed-by: Allison Henderson <allison.henderson(a)oracle.com>
Signed-off-by: Dave Chinner <david(a)fromorbit.com>
conflicts:
fs/xfs/xfs_bmap_item.c
fs/xfs/xfs_icreate_item.c
fs/xfs/xfs_refcount_item.c
fs/xfs/xfs_rmap_item.c
Signed-off-by: Li Nan <linan122(a)huawei.com>
Reviewed-by: Yang Erkun <yangerkun(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
fs/xfs/xfs_bmap_item.c | 2 ++
fs/xfs/xfs_icreate_item.c | 1 +
fs/xfs/xfs_refcount_item.c | 2 ++
fs/xfs/xfs_rmap_item.c | 2 ++
4 files changed, 7 insertions(+)
diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index 44ec0f2d5253..e6de8081451f 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -40,6 +40,7 @@ STATIC void
xfs_bui_item_free(
struct xfs_bui_log_item *buip)
{
+ kmem_free(buip->bui_item.li_lv_shadow);
kmem_cache_free(xfs_bui_zone, buip);
}
@@ -199,6 +200,7 @@ xfs_bud_item_release(
struct xfs_bud_log_item *budp = BUD_ITEM(lip);
xfs_bui_release(budp->bud_buip);
+ kmem_free(budp->bud_item.li_lv_shadow);
kmem_cache_free(xfs_bud_zone, budp);
}
diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c
index 9b3994b9c716..aa8c7c261d24 100644
--- a/fs/xfs/xfs_icreate_item.c
+++ b/fs/xfs/xfs_icreate_item.c
@@ -63,6 +63,7 @@ STATIC void
xfs_icreate_item_release(
struct xfs_log_item *lip)
{
+ kmem_free(ICR_ITEM(lip)->ic_item.li_lv_shadow);
kmem_cache_free(xfs_icreate_zone, ICR_ITEM(lip));
}
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
index 0dee316283a9..9f4ff45c7a93 100644
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -35,6 +35,7 @@ STATIC void
xfs_cui_item_free(
struct xfs_cui_log_item *cuip)
{
+ kmem_free(cuip->cui_item.li_lv_shadow);
if (cuip->cui_format.cui_nextents > XFS_CUI_MAX_FAST_EXTENTS)
kmem_free(cuip);
else
@@ -204,6 +205,7 @@ xfs_cud_item_release(
struct xfs_cud_log_item *cudp = CUD_ITEM(lip);
xfs_cui_release(cudp->cud_cuip);
+ kmem_free(cudp->cud_item.li_lv_shadow);
kmem_cache_free(xfs_cud_zone, cudp);
}
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index 20905953fe76..b5447ac7cb9b 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -35,6 +35,7 @@ STATIC void
xfs_rui_item_free(
struct xfs_rui_log_item *ruip)
{
+ kmem_free(ruip->rui_item.li_lv_shadow);
if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS)
kmem_free(ruip);
else
@@ -227,6 +228,7 @@ xfs_rud_item_release(
struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
xfs_rui_release(rudp->rud_ruip);
+ kmem_free(rudp->rud_item.li_lv_shadow);
kmem_cache_free(xfs_rud_zone, rudp);
}
--
2.25.1
1
19

[PATCH openEuler-5.10-LTS-SP1 01/74] drm/msm/dsi: fix the inconsistent indenting
by Jialin Zhang 07 Feb '23
by Jialin Zhang 07 Feb '23
07 Feb '23
From: sunliming <sunliming(a)kylinos.cn>
stable inclusion
from stable-v5.10.142
commit 631fbefd877721d15c4f525cc71e851e0e588c8e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6CSFH
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 2f25a1fb4ec516c5ad67afd754334b491b9f09a5 ]
Fix the inconsistent indenting in function msm_dsi_dphy_timing_calc_v3().
Fix the following smatch warnings:
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c:350 msm_dsi_dphy_timing_calc_v3() warn: inconsistent indenting
Fixes: f1fa7ff44056 ("drm/msm/dsi: implement auto PHY timing calculator for 10nm PHY")
Reported-by: kernel test robot <lkp(a)intel.com>
Signed-off-by: sunliming <sunliming(a)kylinos.cn>
Reviewed-by: Abhinav Kumar <quic_abhinavk(a)quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/494662/
Link: https://lore.kernel.org/r/20220719015622.646718-1-sunliming@kylinos.cn
Signed-off-by: Abhinav Kumar <quic_abhinavk(a)quicinc.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
Reviewed-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index e07986ab52c2..2e0be85ec394 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -345,7 +345,7 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
} else {
timing->shared_timings.clk_pre =
linear_inter(tmax, tmin, pcnt2, 0, false);
- timing->shared_timings.clk_pre_inc_by_2 = 0;
+ timing->shared_timings.clk_pre_inc_by_2 = 0;
}
timing->ta_go = 3;
--
2.25.1
1
73

[PATCH openEuler-1.0-LTS 1/2] block: don't allow a disk link holder to itself
by Yongqiang Liu 07 Feb '23
by Yongqiang Liu 07 Feb '23
07 Feb '23
From: Yu Kuai <yukuai3(a)huawei.com>
mainline inclusion
from mainline-v6.2-rc1
commit 077a4033541fc96fb0a955985aab7d1f353da831
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6B4N7
CVE: NA
--------------------------------
After creating a dm device, then user can reload such dm with itself,
and dead loop will be triggered because dm keep looking up to itself.
Test procedures:
1) dmsetup create test --table "xxx sda", assume dm-0 is created
2) dmsetup suspend test
3) dmsetup reload test --table "xxx dm-0"
4) dmsetup resume test
Test result:
BUG: TASK stack guard page was hit at 00000000736a261f (stack is 000000008d12c88d..00000000c8dd82d5)
stack guard page: 0000 [#1] PREEMPT SMP
CPU: 29 PID: 946 Comm: systemd-udevd Not tainted 6.1.0-rc3-next-20221101-00006-g17640ca3b0ee #1295
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014
RIP: 0010:dm_prepare_ioctl+0xf/0x1e0
Code: da 48 83 05 4a 7c 99 0b 01 41 89 c4 eb cd e8 b8 1f 40 00 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 57 48 83 05 a1 5a 99 0b 01 <41> 56 49 89 d6 41 55 4c 8d af 90 02 00 00 9
RSP: 0018:ffffc90002090000 EFLAGS: 00010206
RAX: ffff8881049d6800 RBX: ffff88817e589000 RCX: 0000000000000000
RDX: ffffc90002090010 RSI: ffffc9000209001c RDI: ffff88817e589000
RBP: 00000000484a101d R08: 0000000000000000 R09: 0000000000000007
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000005331
R13: 0000000000005331 R14: 0000000000000000 R15: 0000000000000000
FS: 00007fddf9609200(0000) GS:ffff889fbfd40000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffc9000208fff8 CR3: 0000000179043000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
dm_blk_ioctl+0x50/0x1c0
? dm_prepare_ioctl+0xe0/0x1e0
dm_blk_ioctl+0x88/0x1c0
dm_blk_ioctl+0x88/0x1c0
......(a lot of same lines)
dm_blk_ioctl+0x88/0x1c0
dm_blk_ioctl+0x88/0x1c0
blkdev_ioctl+0x184/0x3e0
__x64_sys_ioctl+0xa3/0x110
do_syscall_64+0x35/0x80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fddf7306577
Code: b3 66 90 48 8b 05 11 89 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e1 88 8
RSP: 002b:00007ffd0b2ec318 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00005634ef478320 RCX: 00007fddf7306577
RDX: 0000000000000000 RSI: 0000000000005331 RDI: 0000000000000007
RBP: 0000000000000007 R08: 00005634ef4843e0 R09: 0000000000000080
R10: 00007fddf75cfb38 R11: 0000000000000246 R12: 00000000030d4000
R13: 0000000000000000 R14: 0000000000000000 R15: 00005634ef48b800
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:dm_prepare_ioctl+0xf/0x1e0
Code: da 48 83 05 4a 7c 99 0b 01 41 89 c4 eb cd e8 b8 1f 40 00 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 57 48 83 05 a1 5a 99 0b 01 <41> 56 49 89 d6 41 55 4c 8d af 90 02 00 00 9
RSP: 0018:ffffc90002090000 EFLAGS: 00010206
RAX: ffff8881049d6800 RBX: ffff88817e589000 RCX: 0000000000000000
RDX: ffffc90002090010 RSI: ffffc9000209001c RDI: ffff88817e589000
RBP: 00000000484a101d R08: 0000000000000000 R09: 0000000000000007
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000005331
R13: 0000000000005331 R14: 0000000000000000 R15: 0000000000000000
FS: 00007fddf9609200(0000) GS:ffff889fbfd40000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffc9000208fff8 CR3: 0000000179043000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Kernel panic - not syncing: Fatal exception in interrupt
Kernel Offset: disabled
---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
Fix the problem by forbidding a disk to create link to itself.
Signed-off-by: Yu Kuai <yukuai3(a)huawei.com>
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Link: https://lore.kernel.org/r/20221115141054.1051801-11-yukuai1@huaweicloud.com
Signed-off-by: Jens Axboe <axboe(a)kernel.dk>
Signed-off-by: Li Lingfeng <lilingfeng3(a)huawei.com>
Reviewed-by: Yang Erkun <yangerkun(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/block_dev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 2680092c022d..6ba91b97753f 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1305,6 +1305,8 @@ int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk)
struct bd_holder_disk *holder;
int ret = 0;
+ if (bdev->bd_disk == disk)
+ return -EINVAL;
/*
* bdev could be deleted beneath us which would implicitly destroy
* the holder directory. Hold on to it.
--
2.25.1
1
1

[PATCH openEuler-1.0-LTS 1/3] ipv6: raw: Deduct extension header length in rawv6_push_pending_frames
by Yongqiang Liu 06 Feb '23
by Yongqiang Liu 06 Feb '23
06 Feb '23
From: Herbert Xu <herbert(a)gondor.apana.org.au>
stable inclusion
from stable-v4.19.270
commit f487d636e49bc1fdfbd8105bc1ab159164e2d8bd
category: bugfix
bugzilla: 188291, https://gitee.com/src-openeuler/kernel/issues/I6B1V2
CVE: CVE-2023-0394
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=…
--------------------------------
commit cb3e9864cdbe35ff6378966660edbcbac955fe17 upstream.
The total cork length created by ip6_append_data includes extension
headers, so we must exclude them when comparing them against the
IPV6_CHECKSUM offset which does not include extension headers.
Reported-by: Kyle Zeng <zengyhkyle(a)gmail.com>
Fixes: 357b40a18b04 ("[IPV6]: IPV6_CHECKSUM socket option can corrupt kernel memory")
Signed-off-by: Herbert Xu <herbert(a)gondor.apana.org.au>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Lu Wei <luwei32(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
net/ipv6/raw.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 412d4f60a408..8ce6414edd88 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -543,6 +543,7 @@ static int rawv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
struct raw6_sock *rp)
{
+ struct ipv6_txoptions *opt;
struct sk_buff *skb;
int err = 0;
int offset;
@@ -560,6 +561,9 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
offset = rp->offset;
total_len = inet_sk(sk)->cork.base.length;
+ opt = inet6_sk(sk)->cork.opt;
+ total_len -= opt ? opt->opt_flen : 0;
+
if (offset >= total_len - 1) {
err = -EINVAL;
ip6_flush_pending_frames(sk);
--
2.25.1
1
2

[openEuler-5.10 1/4] SUNRPC: Clean up the handling of page padding in rpc_prepare_reply_pages()
by Zheng Zengkai 06 Feb '23
by Zheng Zengkai 06 Feb '23
06 Feb '23
From: Trond Myklebust <trond.myklebust(a)hammerspace.com>
mainline inclusion
from mainline-v5.11-rc1
commit 9ed5af268e88f6e5b65376be98d652b37cb20d7b
bugzilla: https://gitee.com/openeuler/kernel/issues/I6D0MJ
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
rpc_prepare_reply_pages() currently expects the 'hdrsize' argument to
contain the length of the data that we expect to want placed in the head
kvec plus a count of 1 word of padding that is placed after the page data.
This is very confusing when trying to read the code, and sometimes leads
to callers adding an arbitrary value of '1' just in order to satisfy the
requirement (whether or not the page data actually needs such padding).
This patch aims to clarify the code by changing the 'hdrsize' argument
to remove that 1 word of padding. This means we need to subtract the
padding from all the existing callers.
Fixes: 02ef04e432ba ("NFS: Account for XDR pad of buf->pages")
Signed-off-by: Trond Myklebust <trond.myklebust(a)hammerspace.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
fs/nfs/nfs2xdr.c | 19 ++++++++++---------
fs/nfs/nfs3xdr.c | 29 ++++++++++++++++-------------
fs/nfs/nfs4xdr.c | 36 +++++++++++++++++++-----------------
net/sunrpc/clnt.c | 5 +----
net/sunrpc/xdr.c | 3 ---
5 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 5e6453e9b307..3d5ba43f44bb 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -34,6 +34,7 @@
* Declare the space requirements for NFS arguments and replies as
* number of 32bit-words
*/
+#define NFS_pagepad_sz (1) /* Page padding */
#define NFS_fhandle_sz (8)
#define NFS_sattr_sz (8)
#define NFS_filename_sz (1+(NFS2_MAXNAMLEN>>2))
@@ -56,11 +57,11 @@
#define NFS_attrstat_sz (1+NFS_fattr_sz)
#define NFS_diropres_sz (1+NFS_fhandle_sz+NFS_fattr_sz)
-#define NFS_readlinkres_sz (2+1)
-#define NFS_readres_sz (1+NFS_fattr_sz+1+1)
+#define NFS_readlinkres_sz (2+NFS_pagepad_sz)
+#define NFS_readres_sz (1+NFS_fattr_sz+1+NFS_pagepad_sz)
#define NFS_writeres_sz (NFS_attrstat_sz)
#define NFS_stat_sz (1)
-#define NFS_readdirres_sz (1+1)
+#define NFS_readdirres_sz (1+NFS_pagepad_sz)
#define NFS_statfsres_sz (1+NFS_info_sz)
static int nfs_stat_to_errno(enum nfs_stat);
@@ -592,8 +593,8 @@ static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
const struct nfs_readlinkargs *args = data;
encode_fhandle(xdr, args->fh);
- rpc_prepare_reply_pages(req, args->pages, args->pgbase,
- args->pglen, NFS_readlinkres_sz);
+ rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->pglen,
+ NFS_readlinkres_sz - NFS_pagepad_sz);
}
/*
@@ -628,8 +629,8 @@ static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
const struct nfs_pgio_args *args = data;
encode_readargs(xdr, args);
- rpc_prepare_reply_pages(req, args->pages, args->pgbase,
- args->count, NFS_readres_sz);
+ rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->count,
+ NFS_readres_sz - NFS_pagepad_sz);
req->rq_rcv_buf.flags |= XDRBUF_READ;
}
@@ -786,8 +787,8 @@ static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
const struct nfs_readdirargs *args = data;
encode_readdirargs(xdr, args);
- rpc_prepare_reply_pages(req, args->pages, 0,
- args->count, NFS_readdirres_sz);
+ rpc_prepare_reply_pages(req, args->pages, 0, args->count,
+ NFS_readdirres_sz - NFS_pagepad_sz);
}
/*
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index b5a9379b1450..2c0cad7c51d6 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -33,6 +33,7 @@
* Declare the space requirements for NFS arguments and replies as
* number of 32bit-words
*/
+#define NFS3_pagepad_sz (1) /* Page padding */
#define NFS3_fhandle_sz (1+16)
#define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */
#define NFS3_post_op_fh_sz (1+NFS3_fh_sz)
@@ -70,13 +71,13 @@
#define NFS3_removeres_sz (NFS3_setattrres_sz)
#define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
#define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
-#define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1+1)
-#define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3+1)
+#define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1+NFS3_pagepad_sz)
+#define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3+NFS3_pagepad_sz)
#define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4)
#define NFS3_createres_sz (1+NFS3_post_op_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
#define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz))
#define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
-#define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2+1)
+#define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2+NFS3_pagepad_sz)
#define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13)
#define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12)
#define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
@@ -86,7 +87,8 @@
#define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \
XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
#define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \
- XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)+1)
+ XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)+\
+ NFS3_pagepad_sz)
#define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
static int nfs3_stat_to_errno(enum nfs_stat);
@@ -910,8 +912,8 @@ static void nfs3_xdr_enc_readlink3args(struct rpc_rqst *req,
const struct nfs3_readlinkargs *args = data;
encode_nfs_fh3(xdr, args->fh);
- rpc_prepare_reply_pages(req, args->pages, args->pgbase,
- args->pglen, NFS3_readlinkres_sz);
+ rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->pglen,
+ NFS3_readlinkres_sz - NFS3_pagepad_sz);
}
/*
@@ -940,7 +942,8 @@ static void nfs3_xdr_enc_read3args(struct rpc_rqst *req,
const void *data)
{
const struct nfs_pgio_args *args = data;
- unsigned int replen = args->replen ? args->replen : NFS3_readres_sz;
+ unsigned int replen = args->replen ? args->replen :
+ NFS3_readres_sz - NFS3_pagepad_sz;
encode_read3args(xdr, args);
rpc_prepare_reply_pages(req, args->pages, args->pgbase,
@@ -1240,8 +1243,8 @@ static void nfs3_xdr_enc_readdir3args(struct rpc_rqst *req,
const struct nfs3_readdirargs *args = data;
encode_readdir3args(xdr, args);
- rpc_prepare_reply_pages(req, args->pages, 0,
- args->count, NFS3_readdirres_sz);
+ rpc_prepare_reply_pages(req, args->pages, 0, args->count,
+ NFS3_readdirres_sz - NFS3_pagepad_sz);
}
/*
@@ -1282,8 +1285,8 @@ static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req,
const struct nfs3_readdirargs *args = data;
encode_readdirplus3args(xdr, args);
- rpc_prepare_reply_pages(req, args->pages, 0,
- args->count, NFS3_readdirres_sz);
+ rpc_prepare_reply_pages(req, args->pages, 0, args->count,
+ NFS3_readdirres_sz - NFS3_pagepad_sz);
}
/*
@@ -1329,7 +1332,7 @@ static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req,
if (args->mask & (NFS_ACL | NFS_DFACL)) {
rpc_prepare_reply_pages(req, args->pages, 0,
NFSACL_MAXPAGES << PAGE_SHIFT,
- ACL3_getaclres_sz);
+ ACL3_getaclres_sz - NFS3_pagepad_sz);
req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
}
}
@@ -1649,7 +1652,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
result->op_status = status;
if (status != NFS3_OK)
goto out_status;
- result->replen = 4 + ((xdr_stream_pos(xdr) - pos) >> 2);
+ result->replen = 3 + ((xdr_stream_pos(xdr) - pos) >> 2);
error = decode_read3resok(xdr, result);
out:
return error;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index e2f0e3446e22..f64b28d5bc22 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -84,6 +84,7 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
/* lock,open owner id:
* we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2)
*/
+#define pagepad_maxsz (1)
#define open_owner_id_maxsz (1 + 2 + 1 + 1 + 2)
#define lock_owner_id_maxsz (1 + 1 + 4)
#define decode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
@@ -215,14 +216,14 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
nfs4_fattr_bitmap_maxsz)
#define encode_read_maxsz (op_encode_hdr_maxsz + \
encode_stateid_maxsz + 3)
-#define decode_read_maxsz (op_decode_hdr_maxsz + 2 + 1)
+#define decode_read_maxsz (op_decode_hdr_maxsz + 2 + pagepad_maxsz)
#define encode_readdir_maxsz (op_encode_hdr_maxsz + \
2 + encode_verifier_maxsz + 5 + \
nfs4_label_maxsz)
#define decode_readdir_maxsz (op_decode_hdr_maxsz + \
- decode_verifier_maxsz + 1)
+ decode_verifier_maxsz + pagepad_maxsz)
#define encode_readlink_maxsz (op_encode_hdr_maxsz)
-#define decode_readlink_maxsz (op_decode_hdr_maxsz + 1 + 1)
+#define decode_readlink_maxsz (op_decode_hdr_maxsz + 1 + pagepad_maxsz)
#define encode_write_maxsz (op_encode_hdr_maxsz + \
encode_stateid_maxsz + 4)
#define decode_write_maxsz (op_decode_hdr_maxsz + \
@@ -284,14 +285,14 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
#define decode_delegreturn_maxsz (op_decode_hdr_maxsz)
#define encode_getacl_maxsz (encode_getattr_maxsz)
#define decode_getacl_maxsz (op_decode_hdr_maxsz + \
- nfs4_fattr_bitmap_maxsz + 1 + 1)
+ nfs4_fattr_bitmap_maxsz + 1 + pagepad_maxsz)
#define encode_setacl_maxsz (op_encode_hdr_maxsz + \
encode_stateid_maxsz + 3)
#define decode_setacl_maxsz (decode_setattr_maxsz)
#define encode_fs_locations_maxsz \
(encode_getattr_maxsz)
#define decode_fs_locations_maxsz \
- (1)
+ (pagepad_maxsz)
#define encode_secinfo_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz)
#define decode_secinfo_maxsz (op_decode_hdr_maxsz + 1 + ((NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN)) / 4))
@@ -393,12 +394,13 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
/* devaddr4 payload is read into page */ \
1 /* notification bitmap length */ + \
1 /* notification bitmap, word 0 */ + \
- 1 /* possible XDR padding */)
+ pagepad_maxsz /* possible XDR padding */)
#define encode_layoutget_maxsz (op_encode_hdr_maxsz + 10 + \
encode_stateid_maxsz)
#define decode_layoutget_maxsz (op_decode_hdr_maxsz + 8 + \
decode_stateid_maxsz + \
- XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE) + 1)
+ XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE) + \
+ pagepad_maxsz)
#define encode_layoutcommit_maxsz (op_encode_hdr_maxsz + \
2 /* offset */ + \
2 /* length */ + \
@@ -2342,7 +2344,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_layoutget(xdr, args->lg_args, &hdr);
rpc_prepare_reply_pages(req, args->lg_args->layout.pages, 0,
args->lg_args->layout.pglen,
- hdr.replen);
+ hdr.replen - pagepad_maxsz);
}
encode_nops(&hdr);
}
@@ -2388,7 +2390,7 @@ static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req,
encode_layoutget(xdr, args->lg_args, &hdr);
rpc_prepare_reply_pages(req, args->lg_args->layout.pages, 0,
args->lg_args->layout.pglen,
- hdr.replen);
+ hdr.replen - pagepad_maxsz);
}
encode_nops(&hdr);
}
@@ -2499,7 +2501,7 @@ static void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_readlink(xdr, args, req, &hdr);
rpc_prepare_reply_pages(req, args->pages, args->pgbase,
- args->pglen, hdr.replen);
+ args->pglen, hdr.replen - pagepad_maxsz);
encode_nops(&hdr);
}
@@ -2520,7 +2522,7 @@ static void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_readdir(xdr, args, req, &hdr);
rpc_prepare_reply_pages(req, args->pages, args->pgbase,
- args->count, hdr.replen);
+ args->count, hdr.replen - pagepad_maxsz);
encode_nops(&hdr);
}
@@ -2541,7 +2543,7 @@ static void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_read(xdr, args, &hdr);
rpc_prepare_reply_pages(req, args->pages, args->pgbase,
- args->count, hdr.replen);
+ args->count, hdr.replen - pagepad_maxsz);
req->rq_rcv_buf.flags |= XDRBUF_READ;
encode_nops(&hdr);
}
@@ -2588,7 +2590,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
ARRAY_SIZE(nfs4_acl_bitmap), &hdr);
rpc_prepare_reply_pages(req, args->acl_pages, 0,
- args->acl_len, replen + 1);
+ args->acl_len, replen);
encode_nops(&hdr);
}
@@ -2810,7 +2812,7 @@ static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req,
}
rpc_prepare_reply_pages(req, (struct page **)&args->page, 0,
- PAGE_SIZE, replen + 1);
+ PAGE_SIZE, replen);
encode_nops(&hdr);
}
@@ -3014,14 +3016,14 @@ static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req,
encode_compound_hdr(xdr, req, &hdr);
encode_sequence(xdr, &args->seq_args, &hdr);
- replen = hdr.replen + op_decode_hdr_maxsz;
+ replen = hdr.replen + op_decode_hdr_maxsz + 2;
encode_getdeviceinfo(xdr, args, &hdr);
/* set up reply kvec. device_addr4 opaque data is read into the
* pages */
rpc_prepare_reply_pages(req, args->pdev->pages, args->pdev->pgbase,
- args->pdev->pglen, replen + 2 + 1);
+ args->pdev->pglen, replen);
encode_nops(&hdr);
}
@@ -3043,7 +3045,7 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req,
encode_layoutget(xdr, args, &hdr);
rpc_prepare_reply_pages(req, args->layout.pages, 0,
- args->layout.pglen, hdr.replen);
+ args->layout.pglen, hdr.replen - pagepad_maxsz);
encode_nops(&hdr);
}
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 78c6648af782..88a4dff14666 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1251,10 +1251,7 @@ void rpc_prepare_reply_pages(struct rpc_rqst *req, struct page **pages,
unsigned int base, unsigned int len,
unsigned int hdrsize)
{
- /* Subtract one to force an extra word of buffer space for the
- * payload's XDR pad to fall into the rcv_buf's tail iovec.
- */
- hdrsize += RPC_REPHDRSIZE + req->rq_cred->cr_auth->au_ralign - 1;
+ hdrsize += RPC_REPHDRSIZE + req->rq_cred->cr_auth->au_ralign;
xdr_inline_pages(&req->rq_rcv_buf, hdrsize << 2, pages, base, len);
trace_rpc_xdr_reply_pages(req->rq_task, &req->rq_rcv_buf);
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index d84bb5037bb5..b1684b19b6d5 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -193,9 +193,6 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
tail->iov_base = buf + offset;
tail->iov_len = buflen - offset;
- if ((xdr->page_len & 3) == 0)
- tail->iov_len -= sizeof(__be32);
-
xdr->buflen += len;
}
EXPORT_SYMBOL_GPL(xdr_inline_pages);
--
2.20.1
1
3

06 Feb '23
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6BSMN
-----------------------------------------------------------------------
For ROH distributed scenario, EID is allocated by DHCP mode.
Driver needs to convert the origin MAC address to EID format,
and updates the destination MAC, chaddr and client id(if exists)
when transmit DHCP packets. Meantime, the chaddr field should
follow the source mac address, in order to make the dhcp
server reply to the right client. For the payload of
dhcp packet changed, so the checksum of L4 should be
calculated too.
Signed-off-by: Jian Shen <shenjian15(a)huawei.com>
Signed-off-by: Ke Chen <chenke54(a)huawei.com>
---
.../net/ethernet/hisilicon/hns3/hns3_enet.c | 172 +++++++++++++++++-
.../net/ethernet/hisilicon/hns3/hns3_enet.h | 50 +++++
.../hisilicon/hns3/hns3pf/hclge_main.c | 9 +
3 files changed, 226 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index cf79cd69c766..460f9d217a18 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1165,6 +1165,142 @@ static void hns3_tx_spare_reclaim_cb(struct hns3_enet_ring *ring,
}
}
+static struct hns3_dhcp_packet *hns3_get_dhcp_packet(struct sk_buff *skb,
+ int *dhcp_len)
+{
+ struct hns3_dhcp_packet *dhcp;
+ union l4_hdr_info l4;
+ int l4_payload_len;
+
+ l4.hdr = skb_transport_header(skb);
+ if (l4.udp->dest != htons(HNS3_DHCP_CLIENT_PORT) ||
+ l4.udp->source != htons(HNS3_DHCP_SERVER_PORT))
+ return NULL;
+
+ dhcp = (struct hns3_dhcp_packet *)(l4.hdr + sizeof(struct udphdr));
+ l4_payload_len = ntohs(l4.udp->len) - sizeof(struct udphdr);
+ if (l4_payload_len < offsetof(struct hns3_dhcp_packet, options) ||
+ dhcp->hlen != ETH_ALEN ||
+ dhcp->cookie != htonl(HNS3_DHCP_MAGIC))
+ return NULL;
+
+ *dhcp_len = l4_payload_len;
+ return dhcp;
+}
+
+static u8 *hns3_dhcp_option_scan(struct hns3_dhcp_packet *packet,
+ struct hns3_dhcp_opt_state *opt_state)
+{
+ int opt_len;
+ u8 *cur_opt;
+
+ /* option bytes: [code][len][data0~data[len-1]] */
+ while (opt_state->rem > 0) {
+ switch (opt_state->opt_ptr[DHCP_OPT_CODE]) {
+ /* option padding and end have no len and data byte. */
+ case DHCP_OPT_PADDING:
+ opt_state->rem--;
+ opt_state->opt_ptr++;
+ break;
+ case DHCP_OPT_END:
+ if (DHCP_OVERLOAD_USE_FILE(opt_state->overload_flag)) {
+ opt_state->overload_flag |=
+ DHCP_OVERLOAD_FILE_USED;
+ opt_state->opt_ptr = packet->file;
+ opt_state->rem = sizeof(packet->file);
+ break;
+ }
+ if (DHCP_OVERLOAD_USE_SNAME(opt_state->overload_flag)) {
+ opt_state->overload_flag |=
+ DHCP_OVERLOAD_SNAME_USED;
+ opt_state->opt_ptr = packet->sname;
+ opt_state->rem = sizeof(packet->sname);
+ break;
+ }
+ return NULL;
+ default:
+ if (opt_state->rem <= DHCP_OPT_LEN)
+ return NULL;
+ /* opt_len includes code, len and data bytes */
+ opt_len = opt_state->opt_ptr[DHCP_OPT_LEN] +
+ DHCP_OPT_DATA;
+ cur_opt = opt_state->opt_ptr;
+ if (opt_state->rem < opt_len)
+ return NULL;
+
+ opt_state->opt_ptr += opt_len;
+ opt_state->rem -= opt_len;
+ if (cur_opt[DHCP_OPT_CODE] == DHCP_OPT_OVERLOAD) {
+ opt_state->overload_flag |=
+ cur_opt[DHCP_OPT_DATA];
+ break;
+ }
+ return cur_opt;
+ }
+ }
+
+ return NULL;
+}
+
+static void hns3_dhcp_update_option61(struct hns3_nic_priv *priv,
+ struct hns3_dhcp_packet *packet,
+ int dhcp_len)
+{
+ struct hns3_dhcp_opt_state opt_state;
+ u8 *cur_opt;
+
+ opt_state.opt_ptr = packet->options;
+ opt_state.rem = dhcp_len - offsetof(struct hns3_dhcp_packet, options);
+ opt_state.overload_flag = 0;
+
+ cur_opt = hns3_dhcp_option_scan(packet, &opt_state);
+ while (cur_opt) {
+ if (cur_opt[DHCP_OPT_CODE] != DHCP_OPT_CLIENT_ID) {
+ cur_opt = hns3_dhcp_option_scan(packet, &opt_state);
+ continue;
+ }
+ if (cur_opt[DHCP_OPT_LEN] > ETH_ALEN)
+ ether_addr_copy(&cur_opt[DHCP_CLIENT_ID_MAC_OFT],
+ priv->roh_perm_mac);
+ break;
+ }
+}
+
+static void hns3_dhcp_cal_l4_csum(struct sk_buff *skb)
+{
+ union l3_hdr_info l3;
+ union l4_hdr_info l4;
+ __wsum csum = 0;
+ int offset;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ return;
+
+ l3.hdr = skb_network_header(skb);
+ l4.hdr = skb_transport_header(skb);
+ offset = skb_transport_offset(skb);
+ l4.udp->check = 0;
+ csum = csum_partial(l4.udp, ntohs(l4.udp->len), 0);
+ l4.udp->check = csum_tcpudp_magic(l3.v4->saddr, l3.v4->daddr,
+ skb->len - offset, IPPROTO_UDP, csum);
+}
+
+static void hns3_dhcp_packet_convert(struct hns3_nic_priv *priv,
+ struct sk_buff *skb,
+ struct hns3_dhcp_packet *dhcp,
+ int dhcp_len)
+{
+ struct ethhdr *l2hdr = eth_hdr(skb);
+
+ if (!dhcp)
+ return;
+
+ ether_addr_copy(dhcp->chaddr, l2hdr->h_source);
+ hns3_dhcp_update_option61(priv, dhcp, dhcp_len);
+ /* for l4 payload changed, need to re-calculate the csum */
+ hns3_dhcp_cal_l4_csum(skb);
+}
+
static int hns3_set_tso(struct sk_buff *skb, u32 *paylen_fdop_ol4cs,
u16 *mss, u32 *type_cs_vlan_tso, u32 *send_bytes)
{
@@ -1716,7 +1852,20 @@ static int hns3_handle_csum_partial(struct hns3_enet_ring *ring,
return 0;
}
-static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
+static bool hns3_roh_check_udpv4(struct sk_buff *skb)
+{
+ union l3_hdr_info l3;
+
+ l3.hdr = skb_network_header(skb);
+ if (skb->protocol != htons(ETH_P_IP) ||
+ l3.v4->version != IP_VERSION_IPV4)
+ return false;
+
+ return l3.v4->protocol == IPPROTO_UDP;
+}
+
+static int hns3_fill_skb_desc(struct hns3_nic_priv *priv,
+ struct hns3_enet_ring *ring,
struct sk_buff *skb, struct hns3_desc *desc,
struct hns3_desc_cb *desc_cb)
{
@@ -1741,6 +1890,14 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
hnae3_set_field(param.paylen_fdop_ol4cs, HNS3_TXD_FD_OP_M,
HNS3_TXD_FD_OP_S, fd_op);
+ if (hns3_roh_check_udpv4(skb)) {
+ struct hns3_dhcp_packet *dhcp;
+ int dhcp_len;
+
+ dhcp = hns3_get_dhcp_packet(skb, &dhcp_len);
+ hns3_dhcp_packet_convert(priv, skb, dhcp, dhcp_len);
+ }
+
/* Set txbd */
desc->tx.ol_type_vlan_len_msec =
cpu_to_le32(param.ol_type_vlan_len_msec);
@@ -2338,15 +2495,16 @@ static int hns3_handle_desc_filling(struct hns3_enet_ring *ring,
return hns3_fill_skb_to_desc(ring, skb, DESC_TYPE_SKB);
}
-static int hns3_handle_skb_desc(struct hns3_enet_ring *ring,
+static int hns3_handle_skb_desc(struct hns3_nic_priv *priv,
+ struct hns3_enet_ring *ring,
struct sk_buff *skb,
struct hns3_desc_cb *desc_cb,
int next_to_use_head)
{
int ret;
- ret = hns3_fill_skb_desc(ring, skb, &ring->desc[ring->next_to_use],
- desc_cb);
+ ret = hns3_fill_skb_desc(priv, ring, skb,
+ &ring->desc[ring->next_to_use], desc_cb);
if (unlikely(ret < 0))
goto fill_err;
@@ -2395,7 +2553,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
goto out_err_tx_ok;
}
- ret = hns3_handle_skb_desc(ring, skb, desc_cb, ring->next_to_use);
+ ret = hns3_handle_skb_desc(priv, ring, skb, desc_cb, ring->next_to_use);
if (unlikely(ret <= 0))
goto out_err_tx_ok;
@@ -5226,6 +5384,9 @@ static int hns3_init_mac_addr(struct net_device *netdev)
return 0;
}
+ if (is_zero_ether_addr(priv->roh_perm_mac))
+ ether_addr_copy(priv->roh_perm_mac, netdev->dev_addr);
+
if (h->ae_algo->ops->set_mac_addr)
ret = h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr, true);
@@ -5377,6 +5538,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
priv->tx_timeout_count = 0;
priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num;
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
+ eth_zero_addr(priv->roh_perm_mac);
handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index ccfd38b0028e..85c352fff83b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -604,6 +604,56 @@ struct hns3_nic_priv {
struct hns3_enet_coalesce rx_coal;
u32 tx_copybreak;
u32 rx_copybreak;
+ u8 roh_perm_mac[ETH_ALEN];
+};
+
+#define HNS3_DHCP_SERVER_PORT 68
+#define HNS3_DHCP_CLIENT_PORT 67
+#define HNS3_DHCP_MAGIC 0x63825363
+#define DHCP_OPT_CODE 0
+#define DHCP_OPT_LEN 1
+#define DHCP_OPT_DATA 2
+#define DHCP_CLIENT_ID_LEN 7
+#define DHCP_CLIENT_ID_MAC_OFT 3
+#define DHCP_OVERLOAD_FILE 0x1
+#define DHCP_OVERLOAD_SNAME 0x2
+#define DHCP_OVERLOAD_FILE_USED 0x101
+#define DHCP_OVERLOAD_SNAME_USED 0x202
+#define DHCP_OVERLOAD_USE_FILE(x) \
+ (((x) & DHCP_OVERLOAD_FILE_USED) == DHCP_OVERLOAD_FILE)
+#define DHCP_OVERLOAD_USE_SNAME(x) \
+ (((x) & DHCP_OVERLOAD_SNAME_USED) == DHCP_OVERLOAD_SNAME)
+
+enum DHCP_OPTION_CODES {
+ DHCP_OPT_PADDING = 0,
+ DHCP_OPT_OVERLOAD = 52,
+ DHCP_OPT_CLIENT_ID = 61,
+ DHCP_OPT_END = 255
+};
+
+struct hns3_dhcp_packet {
+ u8 op;
+ u8 htype;
+ u8 hlen;
+ u8 hops;
+ u32 xid;
+ u16 secs;
+ u16 flags;
+ u32 ciaddr;
+ u32 yiaddr;
+ u32 siaddr_nip;
+ u32 gateway_nip;
+ u8 chaddr[16]; /* link-layer client hardware address (MAC) */
+ u8 sname[64];
+ u8 file[128];
+ u32 cookie; /* DHCP magic bytes: 0x63825363 */
+ u8 options[312];
+};
+
+struct hns3_dhcp_opt_state {
+ u8 *opt_ptr; /* refer to current option item */
+ int rem; /* remain bytes in options */
+ u32 overload_flag; /* whether use file and sname field as options */
};
union l3_hdr_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index eea17548416b..5c8a821aa61a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2866,12 +2866,21 @@ static void hclge_get_fec(struct hnae3_handle *handle, u8 *fec_ability,
if (fec_mode)
*fec_mode = mac->fec_mode;
}
+
+static void hclge_roh_convert_mac_addr(struct hclge_dev *hdev)
+{
+#define HCLGE_ROH_EID_MASK_BYTE 3
+
+ memset(hdev->hw.mac.mac_addr, 0, HCLGE_ROH_EID_MASK_BYTE);
+}
+
static int hclge_mac_init(struct hclge_dev *hdev)
{
struct hclge_mac *mac = &hdev->hw.mac;
int ret;
hclge_mac_type_init(hdev);
+ hclge_roh_convert_mac_addr(hdev);
hdev->support_sfp_query = true;
hdev->hw.mac.duplex = HCLGE_MAC_FULL;
--
2.30.0
1
0

06 Feb '23
From: Sebastian Andrzej Siewior <bigeasy(a)linutronix.de>
stable inclusion
from stable-v5.10.142
commit d71a1c9fce184718d1b3a51a9e8a6e31cbbb45ce
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6D0ZE
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
-------------------------------------------------
commit 278d3ba61563ceed3cb248383ced19e14ec7bc1f upstream.
On 32bit-UP u64_stats_fetch_begin() disables only preemption. If the
reader is in preemptible context and the writer side
(u64_stats_update_begin*()) runs in an interrupt context (IRQ or
softirq) then the writer can update the stats during the read operation.
This update remains undetected.
Use u64_stats_fetch_begin_irq() to ensure the stats fetch on 32bit-UP
are not interrupted by a writer. 32bit-SMP remains unaffected by this
change.
Cc: "David S. Miller" <davem(a)davemloft.net>
Cc: Catherine Sullivan <csully(a)google.com>
Cc: David Awogbemila <awogbemila(a)google.com>
Cc: Dimitris Michailidis <dmichail(a)fungible.com>
Cc: Eric Dumazet <edumazet(a)google.com>
Cc: Hans Ulli Kroll <ulli.kroll(a)googlemail.com>
Cc: Jakub Kicinski <kuba(a)kernel.org>
Cc: Jeroen de Borst <jeroendb(a)google.com>
Cc: Johannes Berg <johannes(a)sipsolutions.net>
Cc: Linus Walleij <linus.walleij(a)linaro.org>
Cc: Paolo Abeni <pabeni(a)redhat.com>
Cc: Simon Horman <simon.horman(a)corigine.com>
Cc: linux-arm-kernel(a)lists.infradead.org
Cc: linux-wireless(a)vger.kernel.org
Cc: netdev(a)vger.kernel.org
Cc: oss-drivers(a)corigine.com
Cc: stable(a)vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy(a)linutronix.de>
Reviewed-by: Simon Horman <simon.horman(a)corigine.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
(cherry picked from commit d71a1c9fce184718d1b3a51a9e8a6e31cbbb45ce)
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
Conflicts:
drivers/net/ethernet/huawei/hinic/hinic_rx.c
drivers/net/ethernet/huawei/hinic/hinic_tx.c
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
---
drivers/net/ethernet/cortina/gemini.c | 24 +++++++++++-----------
drivers/net/ethernet/google/gve/gve_ethtool.c | 16 +++++++--------
drivers/net/ethernet/google/gve/gve_main.c | 12 +++++------
drivers/net/ethernet/huawei/hinic/hinic_rx.c | 4 ++--
drivers/net/ethernet/huawei/hinic/hinic_tx.c | 4 ++--
.../net/ethernet/netronome/nfp/nfp_net_common.c | 8 ++++----
.../net/ethernet/netronome/nfp/nfp_net_ethtool.c | 8 ++++----
drivers/net/netdevsim/netdev.c | 4 ++--
net/mac80211/sta_info.c | 8 ++++----
net/mpls/af_mpls.c | 4 ++--
10 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 3685878..b22ea40 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1920,7 +1920,7 @@ static void gmac_get_stats64(struct net_device *netdev,
/* Racing with RX NAPI */
do {
- start = u64_stats_fetch_begin(&port->rx_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp);
stats->rx_packets = port->stats.rx_packets;
stats->rx_bytes = port->stats.rx_bytes;
@@ -1932,11 +1932,11 @@ static void gmac_get_stats64(struct net_device *netdev,
stats->rx_crc_errors = port->stats.rx_crc_errors;
stats->rx_frame_errors = port->stats.rx_frame_errors;
- } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start));
/* Racing with MIB and TX completion interrupts */
do {
- start = u64_stats_fetch_begin(&port->ir_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp);
stats->tx_errors = port->stats.tx_errors;
stats->tx_packets = port->stats.tx_packets;
@@ -1946,15 +1946,15 @@ static void gmac_get_stats64(struct net_device *netdev,
stats->rx_missed_errors = port->stats.rx_missed_errors;
stats->rx_fifo_errors = port->stats.rx_fifo_errors;
- } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start));
/* Racing with hard_start_xmit */
do {
- start = u64_stats_fetch_begin(&port->tx_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp);
stats->tx_dropped = port->stats.tx_dropped;
- } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start));
stats->rx_dropped += stats->rx_missed_errors;
}
@@ -2032,18 +2032,18 @@ static void gmac_get_ethtool_stats(struct net_device *netdev,
/* Racing with MIB interrupt */
do {
p = values;
- start = u64_stats_fetch_begin(&port->ir_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp);
for (i = 0; i < RX_STATS_NUM; i++)
*p++ = port->hw_stats[i];
- } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start));
values = p;
/* Racing with RX NAPI */
do {
p = values;
- start = u64_stats_fetch_begin(&port->rx_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp);
for (i = 0; i < RX_STATUS_NUM; i++)
*p++ = port->rx_stats[i];
@@ -2051,13 +2051,13 @@ static void gmac_get_ethtool_stats(struct net_device *netdev,
*p++ = port->rx_csum_stats[i];
*p++ = port->rx_napi_exits;
- } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start));
values = p;
/* Racing with TX start_xmit */
do {
p = values;
- start = u64_stats_fetch_begin(&port->tx_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp);
for (i = 0; i < TX_MAX_FRAGS; i++) {
*values++ = port->tx_frag_stats[i];
@@ -2066,7 +2066,7 @@ static void gmac_get_ethtool_stats(struct net_device *netdev,
*values++ = port->tx_frags_linearized;
*values++ = port->tx_hw_csummed;
- } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start));
}
static int gmac_get_ksettings(struct net_device *netdev,
diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c
index 66f9b37..80a8c0c 100644
--- a/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -172,14 +172,14 @@ static int gve_get_sset_count(struct net_device *netdev, int sset)
struct gve_rx_ring *rx = &priv->rx[ring];
start =
- u64_stats_fetch_begin(&priv->rx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
tmp_rx_pkts = rx->rpackets;
tmp_rx_bytes = rx->rbytes;
tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail;
tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
tmp_rx_desc_err_dropped_pkt =
rx->rx_desc_err_dropped_pkt;
- } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
start));
rx_pkts += tmp_rx_pkts;
rx_bytes += tmp_rx_bytes;
@@ -193,10 +193,10 @@ static int gve_get_sset_count(struct net_device *netdev, int sset)
if (priv->tx) {
do {
start =
- u64_stats_fetch_begin(&priv->tx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
tmp_tx_pkts = priv->tx[ring].pkt_done;
tmp_tx_bytes = priv->tx[ring].bytes_done;
- } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
start));
tx_pkts += tmp_tx_pkts;
tx_bytes += tmp_tx_bytes;
@@ -254,13 +254,13 @@ static int gve_get_sset_count(struct net_device *netdev, int sset)
data[i++] = rx->cnt;
do {
start =
- u64_stats_fetch_begin(&priv->rx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
tmp_rx_bytes = rx->rbytes;
tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail;
tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
tmp_rx_desc_err_dropped_pkt =
rx->rx_desc_err_dropped_pkt;
- } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
start));
data[i++] = tmp_rx_bytes;
/* rx dropped packets */
@@ -313,9 +313,9 @@ static int gve_get_sset_count(struct net_device *netdev, int sset)
data[i++] = tx->done;
do {
start =
- u64_stats_fetch_begin(&priv->tx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
tmp_tx_bytes = tx->bytes_done;
- } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
start));
data[i++] = tmp_tx_bytes;
data[i++] = tx->wake_queue;
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 6cb75bb..f0c1e6c8 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -40,10 +40,10 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) {
do {
start =
- u64_stats_fetch_begin(&priv->rx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
packets = priv->rx[ring].rpackets;
bytes = priv->rx[ring].rbytes;
- } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
start));
s->rx_packets += packets;
s->rx_bytes += bytes;
@@ -53,10 +53,10 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) {
do {
start =
- u64_stats_fetch_begin(&priv->tx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
packets = priv->tx[ring].pkt_done;
bytes = priv->tx[ring].bytes_done;
- } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
start));
s->tx_packets += packets;
s->tx_bytes += bytes;
@@ -1041,9 +1041,9 @@ void gve_handle_report_stats(struct gve_priv *priv)
if (priv->tx) {
for (idx = 0; idx < priv->tx_cfg.num_queues; idx++) {
do {
- start = u64_stats_fetch_begin(&priv->tx[idx].statss);
+ start = u64_stats_fetch_begin_irq(&priv->tx[idx].statss);
tx_bytes = priv->tx[idx].bytes_done;
- } while (u64_stats_fetch_retry(&priv->tx[idx].statss, start));
+ } while (u64_stats_fetch_retry_irq(&priv->tx[idx].statss, start));
stats[stats_idx++] = (struct stats) {
.stat_name = cpu_to_be32(TX_WAKE_CNT),
.value = cpu_to_be64(priv->tx[idx].wake_queue),
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
index 57d5d79..1b57b67 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
@@ -375,7 +375,7 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq,
u64_stats_update_begin(&stats->syncp);
do {
- start = u64_stats_fetch_begin(&rxq_stats->syncp);
+ start = u64_stats_fetch_begin_irq(&rxq_stats->syncp);
stats->bytes = rxq_stats->bytes;
stats->packets = rxq_stats->packets;
stats->errors = rxq_stats->csum_errors +
@@ -384,7 +384,7 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq,
stats->other_errors = rxq_stats->other_errors;
stats->dropped = rxq_stats->dropped;
stats->rx_buf_empty = rxq_stats->rx_buf_empty;
- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&rxq_stats->syncp, start));
u64_stats_update_end(&stats->syncp);
}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
index 75fa344..ff37b6f 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
@@ -61,7 +61,7 @@ void hinic_txq_get_stats(struct hinic_txq *txq,
u64_stats_update_begin(&stats->syncp);
do {
- start = u64_stats_fetch_begin(&txq_stats->syncp);
+ start = u64_stats_fetch_begin_irq(&txq_stats->syncp);
stats->bytes = txq_stats->bytes;
stats->packets = txq_stats->packets;
stats->busy = txq_stats->busy;
@@ -69,7 +69,7 @@ void hinic_txq_get_stats(struct hinic_txq *txq,
stats->dropped = txq_stats->dropped;
stats->big_frags_pkts = txq_stats->big_frags_pkts;
stats->big_udp_pkts = txq_stats->big_udp_pkts;
- } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&txq_stats->syncp, start));
u64_stats_update_end(&stats->syncp);
}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index dfc1f32..5ab230aa 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3373,21 +3373,21 @@ static void nfp_net_stat64(struct net_device *netdev,
unsigned int start;
do {
- start = u64_stats_fetch_begin(&r_vec->rx_sync);
+ start = u64_stats_fetch_begin_irq(&r_vec->rx_sync);
data[0] = r_vec->rx_pkts;
data[1] = r_vec->rx_bytes;
data[2] = r_vec->rx_drops;
- } while (u64_stats_fetch_retry(&r_vec->rx_sync, start));
+ } while (u64_stats_fetch_retry_irq(&r_vec->rx_sync, start));
stats->rx_packets += data[0];
stats->rx_bytes += data[1];
stats->rx_dropped += data[2];
do {
- start = u64_stats_fetch_begin(&r_vec->tx_sync);
+ start = u64_stats_fetch_begin_irq(&r_vec->tx_sync);
data[0] = r_vec->tx_pkts;
data[1] = r_vec->tx_bytes;
data[2] = r_vec->tx_errors;
- } while (u64_stats_fetch_retry(&r_vec->tx_sync, start));
+ } while (u64_stats_fetch_retry_irq(&r_vec->tx_sync, start));
stats->tx_packets += data[0];
stats->tx_bytes += data[1];
stats->tx_errors += data[2];
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index bfcd90f..d4136d3 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -498,7 +498,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
unsigned int start;
do {
- start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync);
+ start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].rx_sync);
data[0] = nn->r_vecs[i].rx_pkts;
tmp[0] = nn->r_vecs[i].hw_csum_rx_ok;
tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok;
@@ -506,10 +506,10 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
tmp[3] = nn->r_vecs[i].hw_csum_rx_error;
tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail;
tmp[5] = nn->r_vecs[i].hw_tls_rx;
- } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start));
+ } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].rx_sync, start));
do {
- start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync);
+ start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].tx_sync);
data[1] = nn->r_vecs[i].tx_pkts;
data[2] = nn->r_vecs[i].tx_busy;
tmp[6] = nn->r_vecs[i].hw_csum_tx;
@@ -519,7 +519,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
tmp[10] = nn->r_vecs[i].hw_tls_tx;
tmp[11] = nn->r_vecs[i].tls_tx_fallback;
tmp[12] = nn->r_vecs[i].tls_tx_no_fallback;
- } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start));
+ } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].tx_sync, start));
data += NN_RVEC_PER_Q_STATS;
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index ad6dbf01..4fb0638 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -67,10 +67,10 @@ static int nsim_change_mtu(struct net_device *dev, int new_mtu)
unsigned int start;
do {
- start = u64_stats_fetch_begin(&ns->syncp);
+ start = u64_stats_fetch_begin_irq(&ns->syncp);
stats->tx_bytes = ns->tx_bytes;
stats->tx_packets = ns->tx_packets;
- } while (u64_stats_fetch_retry(&ns->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&ns->syncp, start));
}
static int
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 461c037..cee39ae 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2175,9 +2175,9 @@ static inline u64 sta_get_tidstats_msdu(struct ieee80211_sta_rx_stats *rxstats,
u64 value;
do {
- start = u64_stats_fetch_begin(&rxstats->syncp);
+ start = u64_stats_fetch_begin_irq(&rxstats->syncp);
value = rxstats->msdu[tid];
- } while (u64_stats_fetch_retry(&rxstats->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
return value;
}
@@ -2241,9 +2241,9 @@ static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats)
u64 value;
do {
- start = u64_stats_fetch_begin(&rxstats->syncp);
+ start = u64_stats_fetch_begin_irq(&rxstats->syncp);
value = rxstats->bytes;
- } while (u64_stats_fetch_retry(&rxstats->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
return value;
}
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 9c047c1..7239814 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1078,9 +1078,9 @@ static void mpls_get_stats(struct mpls_dev *mdev,
p = per_cpu_ptr(mdev->stats, i);
do {
- start = u64_stats_fetch_begin(&p->syncp);
+ start = u64_stats_fetch_begin_irq(&p->syncp);
local = p->stats;
- } while (u64_stats_fetch_retry(&p->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&p->syncp, start));
stats->rx_packets += local.rx_packets;
stats->rx_bytes += local.rx_bytes;
--
1.8.3.1
1
2

[PATCH openEuler-1.0-LTS 1/3] mm: hwpoison: refactor refcount check handling
by Yongqiang Liu 04 Feb '23
by Yongqiang Liu 04 Feb '23
04 Feb '23
From: Yang Shi <shy828301(a)gmail.com>
stable inclusion
from stable-v5.15.86
commit a62b1bc603a1ded739e7cf543da29a3eb93cc534
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6AR36
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit dd0f230a0a80ff396c7ce587f16429f2a8131344 upstream.
Memory failure will report failure if the page still has extra pinned
refcount other than from hwpoison after the handler is done. Actually
the check is not necessary for all handlers, so move the check into
specific handlers. This would make the following keeping shmem page in
page cache patch easier.
There may be expected extra pin for some cases, for example, when the
page is dirty and in swapcache.
Link: https://lkml.kernel.org/r/20211020210755.23964-5-shy828301@gmail.com
Signed-off-by: Yang Shi <shy828301(a)gmail.com>
Signed-off-by: Naoya Horiguchi <naoya.horiguchi(a)nec.com>
Suggested-by: Naoya Horiguchi <naoya.horiguchi(a)nec.com>
Cc: Hugh Dickins <hughd(a)google.com>
Cc: Kirill A. Shutemov <kirill.shutemov(a)linux.intel.com>
Cc: Matthew Wilcox <willy(a)infradead.org>
Cc: Oscar Salvador <osalvador(a)suse.de>
Cc: Peter Xu <peterx(a)redhat.com>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Cc: Naoya Horiguchi <naoya.horiguchi(a)linux.dev>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Ze Zuo <zuoze1(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/memory-failure.c | 93 +++++++++++++++++++++++++++++++--------------
1 file changed, 64 insertions(+), 29 deletions(-)
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 9a816fdf812d..b653637d5a00 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -655,12 +655,44 @@ static int truncate_error_page(struct page *p, unsigned long pfn,
return ret;
}
+struct page_state {
+ unsigned long mask;
+ unsigned long res;
+ enum mf_action_page_type type;
+
+ /* Callback ->action() has to unlock the relevant page inside it. */
+ int (*action)(struct page_state *ps, struct page *p);
+};
+
+/*
+ * Return true if page is still referenced by others, otherwise return
+ * false.
+ *
+ * The extra_pins is true when one extra refcount is expected.
+ */
+static bool has_extra_refcount(struct page_state *ps, struct page *p,
+ bool extra_pins)
+{
+ int count = page_count(p) - 1;
+
+ if (extra_pins)
+ count -= 1;
+
+ if (count > 0) {
+ pr_err("Memory failure: %#lx: %s still referenced by %d users\n",
+ page_to_pfn(p), action_page_types[ps->type], count);
+ return true;
+ }
+
+ return false;
+}
+
/*
* Error hit kernel page.
* Do nothing, try to be lucky and not touch this instead. For a few cases we
* could be more sophisticated.
*/
-static int me_kernel(struct page *p, unsigned long pfn)
+static int me_kernel(struct page_state *ps, struct page *p)
{
unlock_page(p);
return MF_IGNORED;
@@ -669,9 +701,9 @@ static int me_kernel(struct page *p, unsigned long pfn)
/*
* Page in unknown state. Do nothing.
*/
-static int me_unknown(struct page *p, unsigned long pfn)
+static int me_unknown(struct page_state *ps, struct page *p)
{
- pr_err("Memory failure: %#lx: Unknown page state\n", pfn);
+ pr_err("Memory failure: %#lx: Unknown page state\n", page_to_pfn(p));
unlock_page(p);
return MF_FAILED;
}
@@ -679,7 +711,7 @@ static int me_unknown(struct page *p, unsigned long pfn)
/*
* Clean (or cleaned) page cache page.
*/
-static int me_pagecache_clean(struct page *p, unsigned long pfn)
+static int me_pagecache_clean(struct page_state *ps, struct page *p)
{
int ret;
struct address_space *mapping;
@@ -716,9 +748,13 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
*
* Open: to take i_mutex or not for this? Right now we don't.
*/
- ret = truncate_error_page(p, pfn, mapping);
+ ret = truncate_error_page(p, page_to_pfn(p), mapping);
out:
unlock_page(p);
+
+ if (has_extra_refcount(ps, p, false))
+ ret = MF_FAILED;
+
return ret;
}
@@ -727,7 +763,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
* Issues: when the error hit a hole page the error is not properly
* propagated.
*/
-static int me_pagecache_dirty(struct page *p, unsigned long pfn)
+static int me_pagecache_dirty(struct page_state *ps, struct page *p)
{
struct address_space *mapping = page_mapping(p);
@@ -771,7 +807,7 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn)
mapping_set_error(mapping, -EIO);
}
- return me_pagecache_clean(p, pfn);
+ return me_pagecache_clean(ps, p);
}
/*
@@ -793,9 +829,10 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn)
* Clean swap cache pages can be directly isolated. A later page fault will
* bring in the known good data from disk.
*/
-static int me_swapcache_dirty(struct page *p, unsigned long pfn)
+static int me_swapcache_dirty(struct page_state *ps, struct page *p)
{
int ret;
+ bool extra_pins = false;
ClearPageDirty(p);
/* Trigger EIO in shmem: */
@@ -803,10 +840,17 @@ static int me_swapcache_dirty(struct page *p, unsigned long pfn)
ret = delete_from_lru_cache(p) ? MF_FAILED : MF_DELAYED;
unlock_page(p);
+
+ if (ret == MF_DELAYED)
+ extra_pins = true;
+
+ if (has_extra_refcount(ps, p, extra_pins))
+ ret = MF_FAILED;
+
return ret;
}
-static int me_swapcache_clean(struct page *p, unsigned long pfn)
+static int me_swapcache_clean(struct page_state *ps, struct page *p)
{
int ret;
@@ -814,6 +858,10 @@ static int me_swapcache_clean(struct page *p, unsigned long pfn)
ret = delete_from_lru_cache(p) ? MF_FAILED : MF_RECOVERED;
unlock_page(p);
+
+ if (has_extra_refcount(ps, p, false))
+ ret = MF_FAILED;
+
return ret;
}
@@ -823,7 +871,7 @@ static int me_swapcache_clean(struct page *p, unsigned long pfn)
* - Error on hugepage is contained in hugepage unit (not in raw page unit.)
* To narrow down kill region to one page, we need to break up pmd.
*/
-static int me_huge_page(struct page *p, unsigned long pfn)
+static int me_huge_page(struct page_state *ps, struct page *p)
{
int res;
struct page *hpage = compound_head(p);
@@ -834,7 +882,7 @@ static int me_huge_page(struct page *p, unsigned long pfn)
mapping = page_mapping(hpage);
if (mapping) {
- res = truncate_error_page(hpage, pfn, mapping);
+ res = truncate_error_page(hpage, page_to_pfn(p), mapping);
unlock_page(hpage);
} else {
res = MF_FAILED;
@@ -852,6 +900,9 @@ static int me_huge_page(struct page *p, unsigned long pfn)
}
}
+ if (has_extra_refcount(ps, p, false))
+ res = MF_FAILED;
+
return res;
}
@@ -878,14 +929,7 @@ static int me_huge_page(struct page *p, unsigned long pfn)
#define slab (1UL << PG_slab)
#define reserved (1UL << PG_reserved)
-static struct page_state {
- unsigned long mask;
- unsigned long res;
- enum mf_action_page_type type;
-
- /* Callback ->action() has to unlock the relevant page inside it. */
- int (*action)(struct page *p, unsigned long pfn);
-} error_states[] = {
+static struct page_state error_states[] = {
{ reserved, reserved, MF_MSG_KERNEL, me_kernel },
/*
* free pages are specially detected outside this table:
@@ -946,19 +990,10 @@ static int page_action(struct page_state *ps, struct page *p,
unsigned long pfn)
{
int result;
- int count;
/* page p should be unlocked after returning from ps->action(). */
- result = ps->action(p, pfn);
+ result = ps->action(ps, p);
- count = page_count(p) - 1;
- if (ps->action == me_swapcache_dirty && result == MF_DELAYED)
- count--;
- if (count > 0) {
- pr_err("Memory failure: %#lx: %s still referenced by %d users\n",
- pfn, action_page_types[ps->type], count);
- result = MF_FAILED;
- }
action_result(pfn, ps->type, result);
/* Could do more checks here if page looks ok */
--
2.25.1
1
2

[PATCH openEuler-1.0-LTS 1/6] dhugetlb: backport dynamic hugetlb feature
by Yongqiang Liu 04 Feb '23
by Yongqiang Liu 04 Feb '23
04 Feb '23
From: Liu Shixin <liushixin2(a)hauwei.com>
hulk inclusion
category: feature
bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/I6BDME
CVE: NA
--------------------------------
This feature has already beed supported on x86_64 and this is the origin
description:
Dynamic hugetlb which is based on Hugetlb, supports to be splited
dynamically in a specified cgroup. We add a hugetlb_pool in a
mem_cgroup to manage dynamic hugetlb for corresponding cgroup.
After dynamic hugepages are allocated for a cgroup, these hugepages
can be used as 1G/2M/4K pages by split/merge opreation.
It is now supported on arm64. This feature will be limited to depends on
ARM64_4K_PAGES and not support cont-bits hugepage. We merge the previous
patches into one patch which is patch[1]. While merge the code ,we found
some code can be isolated by config DYNAMIC_HUGETLB, so we add patch[2] to
re-isolated them. In patch[3], we restrict the feature on mentioned limit.
The patch[4] add skip of dissolve hugepage which may conflict with memory
hotplug and memory failure. The patch[5] set DYNAMIC_HUGETLB to y in
hulk_defconfig to enable by default.
This patch includes all previous patches and the patches list is recorded
in bugzilla.
Signed-off-by: Liu Shixin <liushixin2(a)hauwei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/Kconfig | 9 +
fs/hugetlbfs/inode.c | 4 +
include/linux/gfp.h | 4 +-
include/linux/hugetlb.h | 97 +++
include/linux/memcontrol.h | 15 +
include/linux/page-flags.h | 3 +
include/trace/events/dhugetlb.h | 123 ++++
include/trace/events/mmflags.h | 1 +
kernel/cgroup/cgroup.c | 6 +
mm/huge_memory.c | 16 +-
mm/hugetlb.c | 1188 ++++++++++++++++++++++++++++++-
mm/internal.h | 1 +
mm/memcontrol.c | 391 ++++++++++
mm/page_alloc.c | 33 +-
14 files changed, 1862 insertions(+), 29 deletions(-)
create mode 100644 include/trace/events/dhugetlb.h
diff --git a/fs/Kconfig b/fs/Kconfig
index 5921bfbebee4..e8800d8a73b3 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -211,6 +211,15 @@ config TMPFS_INODE64
If unsure, say N.
+config DYNAMIC_HUGETLB
+ bool "Dynamic HugeTLB"
+ depends on HUGETLB_PAGE
+ depends on MEMCG
+ depends on CGROUP_HUGETLB
+ help
+ Dynamic hugepage are used in memcg and can be splited into small pages
+ automatically. The tasks in the memcg prefer to alloc dynamic hugepage.
+
config HUGETLBFS
bool "HugeTLB file system support"
depends on X86 || IA64 || SPARC64 || (S390 && 64BIT) || \
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 005e05c442c5..30a29936372c 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1164,6 +1164,8 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
* private inode. This simplifies hugetlbfs_destroy_inode.
*/
mpol_shared_policy_init(&p->policy, NULL);
+ /* Initialize hpool here in case of a quick call to destroy */
+ p->hpool = get_dhugetlb_pool_from_task(current);
return &p->vfs_inode;
}
@@ -1178,6 +1180,8 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
{
hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb));
mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy);
+ dhugetlb_pool_put(HUGETLBFS_I(inode)->hpool);
+ HUGETLBFS_I(inode)->hpool = NULL;
call_rcu(&inode->i_rcu, hugetlbfs_i_callback);
}
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 152cb9bdf436..74b0375d7d2b 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -501,7 +501,9 @@ static inline void arch_alloc_page(struct page *page, int order) { }
struct page *
__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
nodemask_t *nodemask);
-
+void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags,
+ unsigned int alloc_flags);
+bool free_pages_prepare(struct page *page, unsigned int order, bool check_free);
static inline struct page *
__alloc_pages(gfp_t gfp_mask, unsigned int order, int preferred_nid)
{
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 2d2b06b36bd0..3a82ea9283ec 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -289,6 +289,7 @@ struct hugetlbfs_inode_info {
struct shared_policy policy;
struct inode vfs_inode;
unsigned int seals;
+ struct dhugetlb_pool *hpool;
};
static inline struct hugetlbfs_inode_info *HUGETLBFS_I(struct inode *inode)
@@ -655,6 +656,102 @@ static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr
#endif /* CONFIG_HUGETLB_PAGE */
+#ifdef CONFIG_DYNAMIC_HUGETLB
+/* The number of small_page_pool for a dhugetlb_pool */
+#define NR_SMPOOL num_possible_cpus()
+/* The max page number in a small_page_pool */
+#define MAX_SMPOOL_PAGE 1024
+/* number to move between list */
+#define BATCH_SMPOOL_PAGE (MAX_SMPOOL_PAGE >> 2)
+/* We don't need to try 5 times, or we can't migrate the pages. */
+#define HPOOL_RECLAIM_RETRIES 5
+
+extern struct static_key_false dhugetlb_enabled_key;
+#define dhugetlb_enabled (static_branch_unlikely(&dhugetlb_enabled_key))
+
+#define DEFAULT_PAGESIZE 4096
+extern rwlock_t dhugetlb_pagelist_rwlock;
+struct dhugetlb_pagelist {
+ unsigned long count;
+ struct dhugetlb_pool *hpool[0];
+};
+extern struct dhugetlb_pagelist *dhugetlb_pagelist_t;
+
+struct split_pages {
+ struct list_head list;
+ unsigned long start_pfn;
+ unsigned long free_pages;
+};
+
+struct small_page_pool {
+ spinlock_t lock;
+ unsigned long free_pages;
+ long used_pages;
+ struct list_head head_page;
+};
+
+struct dhugetlb_pool {
+ int nid;
+ spinlock_t lock;
+ spinlock_t reserved_lock;
+ atomic_t refcnt;
+
+ struct mem_cgroup *attach_memcg;
+
+ struct list_head dhugetlb_1G_freelists;
+ struct list_head dhugetlb_2M_freelists;
+ struct list_head dhugetlb_4K_freelists;
+
+ struct list_head split_1G_freelists;
+ struct list_head split_2M_freelists;
+
+ unsigned long total_nr_pages;
+
+ unsigned long total_reserved_1G;
+ unsigned long free_reserved_1G;
+ unsigned long mmap_reserved_1G;
+ unsigned long used_1G;
+ unsigned long free_unreserved_1G;
+ unsigned long nr_split_1G;
+
+ unsigned long total_reserved_2M;
+ unsigned long free_reserved_2M;
+ unsigned long mmap_reserved_2M;
+ unsigned long used_2M;
+ unsigned long free_unreserved_2M;
+ unsigned long nr_split_2M;
+
+ unsigned long free_pages;
+ struct small_page_pool smpool[0];
+};
+
+bool dhugetlb_pool_get(struct dhugetlb_pool *hpool);
+void dhugetlb_pool_put(struct dhugetlb_pool *hpool);
+struct dhugetlb_pool *hpool_alloc(unsigned long nid);
+int alloc_hugepage_from_hugetlb(struct dhugetlb_pool *hpool,
+ unsigned long nid, unsigned long size);
+bool free_dhugetlb_pool(struct dhugetlb_pool *hpool);
+int update_dhugetlb_pagelist(unsigned long idx, struct dhugetlb_pool *hpool);
+struct dhugetlb_pool *get_dhugetlb_pool_from_dhugetlb_pagelist(
+ struct page *page);
+struct dhugetlb_pool *get_dhugetlb_pool_from_task(struct task_struct *tsk);
+bool move_pages_from_hpool_to_smpool(struct dhugetlb_pool *hpool,
+ struct small_page_pool *smpool);
+void move_pages_from_smpool_to_hpool(struct dhugetlb_pool *hpool,
+ struct small_page_pool *smpool);
+void dhugetlb_reserve_hugepages(struct dhugetlb_pool *hpool,
+ unsigned long count, bool gigantic);
+#else
+#define dhugetlb_enabled 0
+struct dhugetlb_pool {};
+static inline struct dhugetlb_pool *get_dhugetlb_pool_from_task(
+ struct task_struct *tsk)
+{
+ return NULL;
+}
+static inline void dhugetlb_pool_put(struct dhugetlb_pool *hpool) { return; }
+#endif /* CONFIG_DYNAMIC_HUGETLB */
+
static inline spinlock_t *huge_pte_lock(struct hstate *h,
struct mm_struct *mm, pte_t *pte)
{
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 4517d132d1e2..22f40d5e0e8b 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -326,6 +326,7 @@ struct mem_cgroup {
};
struct mem_cgroup_extension {
+ struct dhugetlb_pool *hpool;
#ifdef CONFIG_MEMCG_QOS
/* Currently support 0 and -1.
* in the future it can expand to other value.
@@ -1406,4 +1407,18 @@ static inline void memcg_put_cache_ids(void)
#endif /* CONFIG_MEMCG_KMEM */
+#ifdef CONFIG_DYNAMIC_HUGETLB
+struct dhugetlb_pool *get_dhugetlb_pool_from_memcg(struct mem_cgroup *memcg);
+struct page *alloc_page_from_dhugetlb_pool(gfp_t gfp_mask);
+void free_page_to_dhugetlb_pool(struct page *page);
+int dhugetlb_pool_force_empty(struct mem_cgroup *memcg);
+bool dhugetlb_pool_is_free(struct cgroup_subsys_state *css);
+#else
+static inline struct page *alloc_page_from_dhugetlb_pool(gfp_t gfp_mask)
+{
+ return NULL;
+}
+static inline void free_page_to_dhugetlb_pool(struct page *page) {}
+#endif
+
#endif /* _LINUX_MEMCONTROL_H */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 0c5d1c4c71e6..fd6cd68e00a2 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -102,6 +102,7 @@ enum pageflags {
PG_idle,
#endif
PG_percpu_ref,
+ PG_pool,
__NR_PAGEFLAGS,
/* Filesystems */
@@ -284,6 +285,7 @@ PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD)
__PAGEFLAG(Slab, slab, PF_NO_TAIL)
__PAGEFLAG(SlobFree, slob_free, PF_NO_TAIL)
PAGEFLAG(Checked, checked, PF_NO_COMPOUND) /* Used by some filesystems */
+PAGEFLAG(Pool, pool, PF_NO_TAIL)
/* Xen */
PAGEFLAG(Pinned, pinned, PF_NO_COMPOUND)
@@ -770,6 +772,7 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)
1UL << PG_private | 1UL << PG_private_2 | \
1UL << PG_writeback | 1UL << PG_reserved | \
1UL << PG_slab | 1UL << PG_active | \
+ 1UL << PG_pool | \
1UL << PG_unevictable | __PG_MLOCKED)
/*
diff --git a/include/trace/events/dhugetlb.h b/include/trace/events/dhugetlb.h
new file mode 100644
index 000000000000..20b3a54589d1
--- /dev/null
+++ b/include/trace/events/dhugetlb.h
@@ -0,0 +1,123 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM dhugetlb
+
+#if !defined(_TRACE_DHUGETLB_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DHUGETLB_H
+
+#include <linux/tracepoint.h>
+#include <trace/events/mmflags.h>
+
+#define DHUGETLB_SPLIT_1G 0x01u
+#define DHUGETLB_SPLIT_2M 0x02u
+#define DHUGETLB_MERGE_4K 0x04u
+#define DHUGETLB_MIGRATE_4K 0x08u
+#define DHUGETLB_RESV_1G 0x10u
+#define DHUGETLB_UNRESV_1G 0x20u
+#define DHUGETLB_RESV_2M 0x40u
+#define DHUGETLB_UNRESV_2M 0x80u
+#define DHUGETLB_ALLOC_1G 0x100u
+#define DHUGETLB_FREE_1G 0x200u
+#define DHUGETLB_ALLOC_2M 0x400u
+#define DHUGETLB_FREE_2M 0x800u
+
+#define __def_action_names \
+ {(unsigned long)DHUGETLB_SPLIT_1G, "split_1G_to_2M"}, \
+ {(unsigned long)DHUGETLB_SPLIT_2M, "split_2M_to_4K"}, \
+ {(unsigned long)DHUGETLB_MERGE_4K, "merge_4K_to_2M"}, \
+ {(unsigned long)DHUGETLB_MIGRATE_4K, "migrate_4K_to_2M"}, \
+ {(unsigned long)DHUGETLB_RESV_1G, "resv_1G_page"}, \
+ {(unsigned long)DHUGETLB_UNRESV_1G, "unresv_1G_page"}, \
+ {(unsigned long)DHUGETLB_RESV_2M, "resv_2M_page"}, \
+ {(unsigned long)DHUGETLB_UNRESV_2M, "unresv_2M_page"}, \
+ {(unsigned long)DHUGETLB_ALLOC_1G, "alloc_1G_page"}, \
+ {(unsigned long)DHUGETLB_FREE_1G, "free_1G_page"}, \
+ {(unsigned long)DHUGETLB_ALLOC_2M, "alloc_2M_page"}, \
+ {(unsigned long)DHUGETLB_FREE_2M, "free_2M_page"}
+
+#define show_action(action) \
+ (action) ? __print_flags(action, "", \
+ __def_action_names \
+ ) : "none"
+
+TRACE_EVENT(dhugetlb_split_merge,
+
+ TP_PROTO(const void *hpool, struct page *page, unsigned long action),
+
+ TP_ARGS(hpool, page, action),
+
+ TP_STRUCT__entry(
+ __field( const void *, hpool )
+ __field( unsigned long, pfn )
+ __field( unsigned long, action )
+ ),
+
+ TP_fast_assign(
+ __entry->hpool = hpool;
+ __entry->pfn = page ? page_to_pfn(page) : -1UL;
+ __entry->action = action;
+ ),
+
+ TP_printk("hpool=%p page=%p pfn=%lu action=%s",
+ __entry->hpool,
+ __entry->pfn != -1UL ? pfn_to_page(__entry->pfn) : NULL,
+ __entry->pfn != -1UL ? __entry->pfn : 0,
+ show_action(__entry->action))
+);
+
+TRACE_EVENT(dhugetlb_acct_memory,
+
+ TP_PROTO(const void *hpool, unsigned long count, unsigned long action),
+
+ TP_ARGS(hpool, count, action),
+
+ TP_STRUCT__entry(
+ __field( const void *, hpool )
+ __field( unsigned long, count )
+ __field( unsigned long, action )
+ ),
+
+ TP_fast_assign(
+ __entry->hpool = hpool;
+ __entry->count = count;
+ __entry->action = action;
+ ),
+
+ TP_printk("hpool=%p action=%s, mmap_count=%lu",
+ __entry->hpool,
+ show_action(__entry->action),
+ __entry->count)
+);
+
+TRACE_EVENT(dhugetlb_alloc_free,
+
+ TP_PROTO(const void *hpool, struct page *page, unsigned long count,
+ unsigned long action),
+
+ TP_ARGS(hpool, page, count, action),
+
+ TP_STRUCT__entry(
+ __field( const void *, hpool )
+ __field( unsigned long, pfn )
+ __field( unsigned long, count )
+ __field( unsigned long, action )
+ ),
+
+ TP_fast_assign(
+ __entry->hpool = hpool;
+ __entry->pfn = page ? page_to_pfn(page) : -1UL;
+ __entry->count = count;
+ __entry->action = action;
+ ),
+
+ TP_printk("hpool=%p page=%p pfn=%lu action=%s free_count=%lu",
+ __entry->hpool,
+ __entry->pfn != -1UL ? pfn_to_page(__entry->pfn) : NULL,
+ __entry->pfn != -1UL ? __entry->pfn : 0,
+ show_action(__entry->action),
+ __entry->count)
+);
+
+#endif /* _TRACE_DHUGETLB_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index b817bf1885a0..4d06b47129f3 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -81,6 +81,7 @@
#define __def_pageflag_names \
{1UL << PG_locked, "locked" }, \
+ {1UL << PG_pool, "pool" }, \
{1UL << PG_waiters, "waiters" }, \
{1UL << PG_error, "error" }, \
{1UL << PG_referenced, "referenced" }, \
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 7456882e1a0f..b01490b71f32 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -65,6 +65,7 @@
/* let's not notify more than 100 times per second */
#define CGROUP_FILE_NOTIFY_MIN_INTV DIV_ROUND_UP(HZ, 100)
+bool dhugetlb_pool_is_free(struct cgroup_subsys_state *css);
/*
* cgroup_mutex is the master lock. Any modification to cgroup or its
* hierarchy must be performed while holding it.
@@ -5280,6 +5281,11 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
if (css_has_online_children(&cgrp->self))
return -EBUSY;
+#ifdef CONFIG_MEMCG
+ /* If we use dynamic hugetlb, make sure dhugtlb_pool is free */
+ if (!dhugetlb_pool_is_free(cgrp->subsys[memory_cgrp_id]))
+ return -EBUSY;
+#endif
/*
* Mark @cgrp and the associated csets dead. The former prevents
* further task migration and child creation by disabling
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index f8319265c1cf..484ffdbf5f45 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -396,6 +396,20 @@ static int __init hugepage_init(void)
return -EINVAL;
}
+ /*
+ * When we alloc some pages(order = 0), system may help us to alloc
+ * a page(order > 0) due to transparent hugepage. This result
+ * dynamic hugetlb to be skipped. Actually, using dynamic hugetlb
+ * means we have already optimized the program, so we should not
+ * use transparent hugepage in addition.
+ * (May result negative optimization)
+ */
+ if (dhugetlb_enabled) {
+ transparent_hugepage_flags = 0;
+ pr_info("transparent hugepage is disabled due to confilct with dynamic hugetlb\n");
+ return -EINVAL;
+ }
+
/*
* hugepages can't be allocated by the buddy allocator
*/
@@ -2946,9 +2960,9 @@ static unsigned long deferred_split_count(struct shrinker *shrink,
{
struct pglist_data *pgdata = NODE_DATA(sc->nid);
unsigned long *split_queue_len = &pgdata->split_queue_len;
+#ifdef CONFIG_MEMCG
struct mem_cgroup_extension *memcg_ext;
-#ifdef CONFIG_MEMCG
if (sc->memcg) {
memcg_ext = container_of(sc->memcg, struct mem_cgroup_extension, memcg);
split_queue_len = &memcg_ext->split_queue_len;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 495d8b5b38fc..4c8c91acd6d5 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -27,6 +27,12 @@
#include <linux/jhash.h>
#include <linux/mman.h>
#include <linux/share_pool.h>
+#include <linux/kthread.h>
+#include <linux/cpuhotplug.h>
+#include <linux/freezer.h>
+#include <linux/delay.h>
+#include <linux/migrate.h>
+#include <linux/mm_inline.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -39,8 +45,14 @@
#include <linux/userfaultfd_k.h>
#include <linux/page_owner.h>
#include <linux/share_pool.h>
+#include <linux/memblock.h>
#include "internal.h"
+#if (defined CONFIG_DYNAMIC_HUGETLB) && (!defined __GENKSYMS__)
+#define CREATE_TRACE_POINTS
+#include <trace/events/dhugetlb.h>
+#endif
+
int hugetlb_max_hstate __read_mostly;
unsigned int default_hstate_idx;
struct hstate hstates[HUGE_MAX_HSTATE];
@@ -89,7 +101,8 @@ static inline void ClearPageHugeFreed(struct page *head)
}
/* Forward declaration */
-static int hugetlb_acct_memory(struct hstate *h, long delta);
+static int hugetlb_acct_memory(struct hstate *h, long delta,
+ struct dhugetlb_pool *hpool);
static inline void unlock_or_release_subpool(struct hugepage_subpool *spool)
{
@@ -103,7 +116,7 @@ static inline void unlock_or_release_subpool(struct hugepage_subpool *spool)
if (free) {
if (spool->min_hpages != -1)
hugetlb_acct_memory(spool->hstate,
- -spool->min_hpages);
+ -spool->min_hpages, NULL);
kfree(spool);
}
}
@@ -123,7 +136,7 @@ struct hugepage_subpool *hugepage_new_subpool(struct hstate *h, long max_hpages,
spool->hstate = h;
spool->min_hpages = min_hpages;
- if (min_hpages != -1 && hugetlb_acct_memory(h, min_hpages)) {
+ if (min_hpages != -1 && hugetlb_acct_memory(h, min_hpages, NULL)) {
kfree(spool);
return NULL;
}
@@ -149,13 +162,17 @@ void hugepage_put_subpool(struct hugepage_subpool *spool)
* a subpool minimum size must be manitained.
*/
static long hugepage_subpool_get_pages(struct hugepage_subpool *spool,
- long delta)
+ long delta, struct dhugetlb_pool *hpool)
{
long ret = delta;
if (!spool)
return ret;
+ /* Skip subpool when hugetlb file belongs to a hugetlb_pool */
+ if (dhugetlb_enabled && hpool)
+ return ret;
+
spin_lock(&spool->lock);
if (spool->max_hpages != -1) { /* maximum size accounting */
@@ -194,13 +211,17 @@ static long hugepage_subpool_get_pages(struct hugepage_subpool *spool,
* in the case where a subpool minimum size must be maintained.
*/
static long hugepage_subpool_put_pages(struct hugepage_subpool *spool,
- long delta)
+ long delta, struct dhugetlb_pool *hpool)
{
long ret = delta;
if (!spool)
return delta;
+ /* Skip subpool when hugetlb file belongs to a hugetlb_pool */
+ if (dhugetlb_enabled && hpool)
+ return ret;
+
spin_lock(&spool->lock);
if (spool->max_hpages != -1) /* maximum size accounting */
@@ -594,12 +615,13 @@ void hugetlb_fix_reserve_counts(struct inode *inode)
struct hugepage_subpool *spool = subpool_inode(inode);
long rsv_adjust;
bool reserved = false;
+ struct dhugetlb_pool *hpool = HUGETLBFS_I(inode)->hpool;
- rsv_adjust = hugepage_subpool_get_pages(spool, 1);
+ rsv_adjust = hugepage_subpool_get_pages(spool, 1, hpool);
if (rsv_adjust > 0) {
struct hstate *h = hstate_inode(inode);
- if (!hugetlb_acct_memory(h, 1))
+ if (!hugetlb_acct_memory(h, 1, hpool))
reserved = true;
} else if (!rsv_adjust) {
reserved = true;
@@ -1300,6 +1322,56 @@ static inline void ClearPageHugeTemporary(struct page *page)
page[2].mapping = NULL;
}
+#ifdef CONFIG_DYNAMIC_HUGETLB
+static void free_huge_page_to_dhugetlb_pool(struct page *page,
+ bool restore_reserve)
+{
+ struct hstate *h = page_hstate(page);
+ struct dhugetlb_pool *hpool;
+
+ hpool = get_dhugetlb_pool_from_dhugetlb_pagelist(page);
+ if (unlikely(!hpool)) {
+ pr_err("dhugetlb: free error: get hpool failed\n");
+ return;
+ }
+
+ spin_lock(&hpool->lock);
+ ClearPagePool(page);
+ set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
+ if (!hstate_is_gigantic(h)) {
+ list_add(&page->lru, &hpool->dhugetlb_2M_freelists);
+ hpool->free_reserved_2M++;
+ hpool->used_2M--;
+ if (restore_reserve) {
+ hpool->mmap_reserved_2M++;
+ trace_dhugetlb_acct_memory(hpool,
+ hpool->mmap_reserved_2M,
+ DHUGETLB_RESV_2M);
+ }
+ trace_dhugetlb_alloc_free(hpool, page, hpool->free_reserved_2M,
+ DHUGETLB_FREE_2M);
+ } else {
+ list_add(&page->lru, &hpool->dhugetlb_1G_freelists);
+ hpool->free_reserved_1G++;
+ hpool->used_1G--;
+ if (restore_reserve) {
+ hpool->mmap_reserved_1G++;
+ trace_dhugetlb_acct_memory(hpool,
+ hpool->mmap_reserved_1G,
+ DHUGETLB_RESV_1G);
+ }
+ trace_dhugetlb_alloc_free(hpool, page, hpool->free_reserved_1G,
+ DHUGETLB_FREE_1G);
+ }
+ spin_unlock(&hpool->lock);
+ dhugetlb_pool_put(hpool);
+}
+#else
+void free_huge_page_to_dhugetlb_pool(struct page *page, bool restore_reserve)
+{
+}
+#endif
+
void free_huge_page(struct page *page)
{
/*
@@ -1320,6 +1392,17 @@ void free_huge_page(struct page *page)
restore_reserve = PagePrivate(page);
ClearPagePrivate(page);
+ if (dhugetlb_enabled && PagePool(page)) {
+ spin_lock(&hugetlb_lock);
+ clear_page_huge_active(page);
+ list_del(&page->lru);
+ hugetlb_cgroup_uncharge_page(hstate_index(h),
+ pages_per_huge_page(h), page);
+ spin_unlock(&hugetlb_lock);
+ free_huge_page_to_dhugetlb_pool(page, restore_reserve);
+ return;
+ }
+
/*
* If PagePrivate() was set on page, page allocation consumed a
* reservation. If the page was associated with a subpool, there
@@ -1335,7 +1418,7 @@ void free_huge_page(struct page *page)
* after page is free. Therefore, force restore_reserve
* operation.
*/
- if (hugepage_subpool_put_pages(spool, 1) == 0)
+ if (hugepage_subpool_put_pages(spool, 1, NULL) == 0)
restore_reserve = true;
}
@@ -2211,6 +2294,81 @@ static void restore_reserve_on_error(struct hstate *h,
}
}
+#ifdef CONFIG_DYNAMIC_HUGETLB
+static struct page *__alloc_huge_page_from_dhugetlb_pool(
+ struct dhugetlb_pool *hpool, int idx, bool need_unreserved)
+{
+ unsigned long flags;
+ struct page *page = NULL;
+
+ spin_lock_irqsave(&hpool->lock, flags);
+ if (hstate_is_gigantic(&hstates[idx]) && hpool->free_reserved_1G) {
+ page = list_entry(hpool->dhugetlb_1G_freelists.next,
+ struct page, lru);
+ list_del(&page->lru);
+ hpool->free_reserved_1G--;
+ hpool->used_1G++;
+ if (need_unreserved) {
+ SetPagePrivate(page);
+ hpool->mmap_reserved_1G--;
+ trace_dhugetlb_acct_memory(hpool,
+ hpool->mmap_reserved_1G,
+ DHUGETLB_UNRESV_1G);
+ }
+ trace_dhugetlb_alloc_free(hpool, page, hpool->free_reserved_1G,
+ DHUGETLB_ALLOC_1G);
+ } else if (!hstate_is_gigantic(&hstates[idx]) &&
+ hpool->free_reserved_2M) {
+ page = list_entry(hpool->dhugetlb_2M_freelists.next,
+ struct page, lru);
+ list_del(&page->lru);
+ hpool->free_reserved_2M--;
+ hpool->used_2M++;
+ if (need_unreserved) {
+ SetPagePrivate(page);
+ hpool->mmap_reserved_2M--;
+ trace_dhugetlb_acct_memory(hpool,
+ hpool->mmap_reserved_2M,
+ DHUGETLB_UNRESV_2M);
+ }
+ trace_dhugetlb_alloc_free(hpool, page, hpool->free_reserved_2M,
+ DHUGETLB_ALLOC_2M);
+ }
+ if (page) {
+ INIT_LIST_HEAD(&page->lru);
+ set_compound_page_dtor(page, HUGETLB_PAGE_DTOR);
+ set_page_refcounted(page);
+ SetPagePool(page);
+ }
+ spin_unlock_irqrestore(&hpool->lock, flags);
+
+ return page;
+}
+
+static struct page *alloc_huge_page_from_dhugetlb_pool(
+ struct vm_area_struct *vma, int idx, int avoid_reserve,
+ long gbl_chg, struct dhugetlb_pool *hpool)
+{
+ struct page *page;
+ bool need_unreserved = false;
+
+ if (!avoid_reserve && vma_has_reserves(vma, gbl_chg))
+ need_unreserved = true;
+
+ page = __alloc_huge_page_from_dhugetlb_pool(hpool, idx,
+ need_unreserved);
+
+ return page;
+}
+#else
+static inline struct page *alloc_huge_page_from_dhugetlb_pool(
+ struct vm_area_struct *vma, int idx, int avoid_reserve,
+ long gbl_chg, struct dhugetlb_pool *hpool)
+{
+ return NULL;
+}
+#endif
+
struct page *alloc_huge_page(struct vm_area_struct *vma,
unsigned long addr, int avoid_reserve)
{
@@ -2221,6 +2379,8 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
long gbl_chg;
int ret, idx;
struct hugetlb_cgroup *h_cg;
+ struct dhugetlb_pool *hpool =
+ HUGETLBFS_I(file_inode(vma->vm_file))->hpool;
idx = hstate_index(h);
/*
@@ -2240,7 +2400,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
* checked against any subpool limit.
*/
if (map_chg || avoid_reserve) {
- gbl_chg = hugepage_subpool_get_pages(spool, 1);
+ gbl_chg = hugepage_subpool_get_pages(spool, 1, hpool);
if (gbl_chg < 0) {
vma_end_reservation(h, vma, addr);
return ERR_PTR(-ENOSPC);
@@ -2262,6 +2422,26 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
if (ret)
goto out_subpool_put;
+ if (dhugetlb_enabled && hpool) {
+ page = alloc_huge_page_from_dhugetlb_pool(vma, idx,
+ avoid_reserve,
+ gbl_chg, hpool);
+ if (page) {
+ /*
+ * Use hugetlb_lock to manage the account of
+ * hugetlb cgroup.
+ */
+ spin_lock(&hugetlb_lock);
+ list_add(&page->lru, &h->hugepage_activelist);
+ hugetlb_cgroup_commit_charge(idx,
+ pages_per_huge_page(hstate_vma(vma)),
+ h_cg, page);
+ spin_unlock(&hugetlb_lock);
+ goto out;
+ }
+ goto out_uncharge_cgroup;
+ }
+
spin_lock(&hugetlb_lock);
/*
* glb_chg is passed to indicate whether or not a page must be taken
@@ -2284,7 +2464,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
}
hugetlb_cgroup_commit_charge(idx, pages_per_huge_page(h), h_cg, page);
spin_unlock(&hugetlb_lock);
-
+out:
set_page_private(page, (unsigned long)spool);
map_commit = vma_commit_reservation(h, vma, addr);
@@ -2300,8 +2480,8 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
*/
long rsv_adjust;
- rsv_adjust = hugepage_subpool_put_pages(spool, 1);
- hugetlb_acct_memory(h, -rsv_adjust);
+ rsv_adjust = hugepage_subpool_put_pages(spool, 1, hpool);
+ hugetlb_acct_memory(h, -rsv_adjust, hpool);
}
return page;
@@ -2309,7 +2489,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
hugetlb_cgroup_uncharge_cgroup(idx, pages_per_huge_page(h), h_cg);
out_subpool_put:
if (map_chg || avoid_reserve)
- hugepage_subpool_put_pages(spool, 1);
+ hugepage_subpool_put_pages(spool, 1, hpool);
vma_end_reservation(h, vma, addr);
return ERR_PTR(-ENOSPC);
}
@@ -3098,6 +3278,932 @@ static void hugetlb_register_all_nodes(void) { }
#endif
+#ifdef CONFIG_DYNAMIC_HUGETLB
+static bool enable_dhugetlb;
+DEFINE_STATIC_KEY_FALSE(dhugetlb_enabled_key);
+DEFINE_RWLOCK(dhugetlb_pagelist_rwlock);
+struct dhugetlb_pagelist *dhugetlb_pagelist_t;
+
+bool dhugetlb_pool_get(struct dhugetlb_pool *hpool)
+{
+ if (!hpool)
+ return false;
+
+ return atomic_inc_not_zero(&hpool->refcnt);
+}
+
+void dhugetlb_pool_put(struct dhugetlb_pool *hpool)
+{
+ if (!dhugetlb_enabled || !hpool)
+ return;
+
+ if (atomic_dec_and_test(&hpool->refcnt)) {
+ css_put(&hpool->attach_memcg->css);
+ kfree(hpool);
+ }
+}
+
+struct dhugetlb_pool *hpool_alloc(unsigned long nid)
+{
+ int i;
+ struct dhugetlb_pool *hpool;
+
+ hpool = kzalloc(sizeof(struct dhugetlb_pool) +
+ NR_SMPOOL * sizeof(struct small_page_pool), GFP_KERNEL);
+ if (!hpool)
+ return NULL;
+
+ spin_lock_init(&hpool->lock);
+ spin_lock_init(&hpool->reserved_lock);
+ hpool->nid = nid;
+ atomic_set(&hpool->refcnt, 1);
+ INIT_LIST_HEAD(&hpool->dhugetlb_1G_freelists);
+ INIT_LIST_HEAD(&hpool->dhugetlb_2M_freelists);
+ INIT_LIST_HEAD(&hpool->dhugetlb_4K_freelists);
+ INIT_LIST_HEAD(&hpool->split_1G_freelists);
+ INIT_LIST_HEAD(&hpool->split_2M_freelists);
+
+ for (i = 0; i < NR_SMPOOL; i++) {
+ spin_lock_init(&hpool->smpool[i].lock);
+ INIT_LIST_HEAD(&hpool->smpool[i].head_page);
+ }
+
+ return hpool;
+}
+
+int alloc_hugepage_from_hugetlb(struct dhugetlb_pool *hpool,
+ unsigned long nid, unsigned long size)
+{
+ int ret;
+ struct page *page, *next;
+ unsigned long idx;
+ unsigned long i = 0;
+ struct hstate *h = size_to_hstate(PUD_SIZE);
+
+ if (!h)
+ return -ENOMEM;
+
+ spin_lock(&hpool->lock);
+ spin_lock(&hugetlb_lock);
+ if (h->free_huge_pages_node[nid] < size) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
+
+ list_for_each_entry_safe(page, next, &h->hugepage_freelists[nid], lru) {
+ idx = page_to_pfn(page) >> (PUD_SHIFT - PAGE_SHIFT);
+ ret = update_dhugetlb_pagelist(idx, hpool);
+ if (ret)
+ continue;
+ ClearPageHugeFreed(page);
+ list_move_tail(&page->lru, &hpool->dhugetlb_1G_freelists);
+ h->free_huge_pages--;
+ h->free_huge_pages_node[nid]--;
+ hpool->total_nr_pages++;
+ hpool->free_unreserved_1G++;
+ if (++i == size)
+ break;
+ }
+ ret = 0;
+out_unlock:
+ spin_unlock(&hugetlb_lock);
+ spin_unlock(&hpool->lock);
+ return ret;
+}
+
+/*
+ * When we assign a hugepage to dhugetlb_pool, we need to record it in
+ * dhugetlb_pagelist_t. In this situation, we just need read_lock because
+ * there is not conflit when write to dhugetlb_pagelist_t->hpool.
+ *
+ * If page's pfn is greater than dhugetlb_pagelist_t->count (which may
+ * occurs due to memory hotplug), we need to realloc enough memory so that
+ * pfn = dhugetlb_pagelist_t->count - 1 and then record it.
+ * In this situation, we need write_lock because while we are reallocating,
+ * the read request should wait.
+ */
+int update_dhugetlb_pagelist(unsigned long idx, struct dhugetlb_pool *hpool)
+{
+ read_lock(&dhugetlb_pagelist_rwlock);
+ if (idx >= dhugetlb_pagelist_t->count) {
+ unsigned long size;
+ struct dhugetlb_pagelist *tmp;
+
+ read_unlock(&dhugetlb_pagelist_rwlock);
+ write_lock(&dhugetlb_pagelist_rwlock);
+
+ size = sizeof(struct dhugetlb_pagelist) +
+ (idx + 1) * sizeof(struct dhugetlb_pool *);
+ tmp = krealloc(dhugetlb_pagelist_t, size, GFP_ATOMIC);
+ if (!tmp) {
+ write_unlock(&dhugetlb_pagelist_rwlock);
+ return -ENOMEM;
+ }
+ tmp->count = idx + 1;
+ dhugetlb_pagelist_t = tmp;
+
+ write_unlock(&dhugetlb_pagelist_rwlock);
+ read_lock(&dhugetlb_pagelist_rwlock);
+ }
+ dhugetlb_pagelist_t->hpool[idx] = hpool;
+ read_unlock(&dhugetlb_pagelist_rwlock);
+ return 0;
+}
+
+struct dhugetlb_pool *get_dhugetlb_pool_from_dhugetlb_pagelist(
+ struct page *page)
+{
+ struct dhugetlb_pool *hpool = NULL;
+ unsigned long idx = page_to_pfn(page) >> (PUD_SHIFT - PAGE_SHIFT);
+
+ read_lock(&dhugetlb_pagelist_rwlock);
+ if (idx < dhugetlb_pagelist_t->count)
+ hpool = dhugetlb_pagelist_t->hpool[idx];
+ read_unlock(&dhugetlb_pagelist_rwlock);
+ if (dhugetlb_pool_get(hpool))
+ return hpool;
+ return NULL;
+}
+
+struct dhugetlb_pool *get_dhugetlb_pool_from_task(struct task_struct *tsk)
+{
+ struct mem_cgroup *memcg;
+ struct dhugetlb_pool *hpool;
+
+ if (!dhugetlb_enabled)
+ return NULL;
+
+ rcu_read_lock();
+ memcg = mem_cgroup_from_task(tsk);
+ rcu_read_unlock();
+
+ hpool = get_dhugetlb_pool_from_memcg(memcg);
+
+ return hpool;
+}
+
+static void add_new_huge_page_to_pool(struct dhugetlb_pool *hpool,
+ struct page *page, bool gigantic)
+{
+ lockdep_assert_held(&hpool->lock);
+ VM_BUG_ON_PAGE(page_mapcount(page), page);
+ INIT_LIST_HEAD(&page->lru);
+
+ if (gigantic) {
+ prep_compound_gigantic_page(page, PUD_SHIFT - PAGE_SHIFT);
+ list_add_tail(&page->lru, &hpool->dhugetlb_1G_freelists);
+ hpool->free_unreserved_1G++;
+ } else {
+ prep_new_page(page, PMD_SHIFT - PAGE_SHIFT, __GFP_COMP, 0);
+ set_page_count(page, 0);
+ list_add_tail(&page->lru, &hpool->dhugetlb_2M_freelists);
+ hpool->free_unreserved_2M++;
+ }
+ set_page_private(page, 0);
+ page->mapping = NULL;
+ set_compound_page_dtor(page, HUGETLB_PAGE_DTOR);
+ set_hugetlb_cgroup(page, NULL);
+}
+
+static void free_dhugetlb_pcpool(struct dhugetlb_pool *hpool)
+{
+ int i;
+ struct small_page_pool *smpool;
+
+ for (i = 0; i < NR_SMPOOL; i++) {
+ smpool = &hpool->smpool[i];
+ list_splice(&smpool->head_page, &hpool->dhugetlb_4K_freelists);
+ smpool->free_pages = 0;
+ smpool->used_pages = 0;
+ INIT_LIST_HEAD(&smpool->head_page);
+ }
+}
+
+static void __free_dhugetlb_small_page(struct dhugetlb_pool *hpool)
+{
+ struct page *page, *next;
+ struct split_pages *split_huge, *split_next;
+
+ if (list_empty(&hpool->dhugetlb_4K_freelists))
+ return;
+
+ list_for_each_entry_safe(page, next,
+ &hpool->dhugetlb_4K_freelists, lru) {
+ list_del(&page->lru);
+ add_new_huge_page_to_pool(hpool, page, false);
+ }
+
+ list_for_each_entry_safe(split_huge, split_next,
+ &hpool->split_2M_freelists, list) {
+ list_del(&split_huge->list);
+ kfree(split_huge);
+ hpool->nr_split_2M--;
+ }
+
+ hpool->free_pages = 0;
+ INIT_LIST_HEAD(&hpool->dhugetlb_4K_freelists);
+}
+
+static void free_dhugetlb_small_page(struct dhugetlb_pool *hpool)
+{
+ struct page *page, *next;
+ unsigned long nr_pages = 1 << (PMD_SHIFT - PAGE_SHIFT);
+
+ lockdep_assert_held(&hpool->lock);
+ if (list_empty(&hpool->dhugetlb_4K_freelists))
+ return;
+
+ list_for_each_entry_safe(page, next,
+ &hpool->dhugetlb_4K_freelists, lru) {
+ if (page_to_pfn(page) % nr_pages != 0)
+ list_del(&page->lru);
+ }
+
+ __free_dhugetlb_small_page(hpool);
+}
+
+static void __free_dhugetlb_huge_page(struct dhugetlb_pool *hpool)
+{
+ struct page *page, *next;
+ struct split_pages *split_giga, *split_next;
+
+ if (list_empty(&hpool->dhugetlb_2M_freelists))
+ return;
+
+ list_for_each_entry_safe(page, next,
+ &hpool->dhugetlb_2M_freelists, lru) {
+ list_del(&page->lru);
+ add_new_huge_page_to_pool(hpool, page, true);
+ }
+ list_for_each_entry_safe(split_giga, split_next,
+ &hpool->split_1G_freelists, list) {
+ list_del(&split_giga->list);
+ kfree(split_giga);
+ hpool->nr_split_1G--;
+ }
+
+ hpool->total_reserved_2M = 0;
+ hpool->free_reserved_2M = 0;
+ hpool->free_unreserved_2M = 0;
+ INIT_LIST_HEAD(&hpool->dhugetlb_2M_freelists);
+}
+
+static void free_dhugetlb_huge_page(struct dhugetlb_pool *hpool)
+{
+ struct page *page, *next;
+ unsigned long nr_pages = 1 << (PUD_SHIFT - PAGE_SHIFT);
+ unsigned long block_size = 1 << (PMD_SHIFT - PAGE_SHIFT);
+ int i;
+
+ lockdep_assert_held(&hpool->lock);
+ if (list_empty(&hpool->dhugetlb_2M_freelists))
+ return;
+
+ list_for_each_entry_safe(page, next,
+ &hpool->dhugetlb_2M_freelists, lru) {
+ set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
+ atomic_set(compound_mapcount_ptr(page), 0);
+ for (i = 1; i < block_size; i++)
+ clear_compound_head(&page[i]);
+ set_compound_order(page, 0);
+ __ClearPageHead(page);
+ if (page_to_pfn(page) % nr_pages != 0)
+ list_del(&page->lru);
+ }
+ __free_dhugetlb_huge_page(hpool);
+}
+
+static int try_migrate_page(struct page *page, unsigned long nid)
+{
+ unsigned long pfn = page_to_pfn(page);
+ int ret = 0;
+
+ LIST_HEAD(source);
+
+ if (!pfn_valid(pfn))
+ return 0;
+ BUG_ON(PageHuge(page) || PageTransHuge(page));
+ /*
+ * HWPoison pages have elevated reference counts so the migration
+ * would fail on them. It also doesn't make any sense to migrate them
+ * in the first place. Still try to unmap such a page in case it is
+ * still mapped(e.g. current hwpoison implementation doesn't unmap
+ * KSM pages but keep the unmap as the catch all safety net).
+ */
+ if (PageHWPoison(page)) {
+ if (WARN_ON(PageLRU(page)))
+ isolate_lru_page(page);
+ if (page_mapped(page))
+ try_to_unmap(page,
+ TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS);
+ return 0;
+ }
+
+ if (!get_page_unless_zero(page))
+ return 0;
+ /*
+ * We can skip free pages. And we can deal with pages on
+ * LRU and non-lru movable pages.
+ */
+ if (PageLRU(page))
+ ret = isolate_lru_page(page);
+ else
+ ret = isolate_movable_page(page, ISOLATE_UNEVICTABLE);
+ put_page(page);
+ if (ret) {
+ if (page_count(page))
+ ret = -EBUSY;
+ return ret;
+ }
+ list_add_tail(&page->lru, &source);
+ if (!__PageMovable(page))
+ inc_node_page_state(page,
+ NR_ISOLATED_ANON + page_is_file_cache(page));
+
+ ret = migrate_pages(&source, alloc_new_node_page, NULL, nid,
+ MIGRATE_SYNC_LIGHT, MR_COMPACTION);
+ if (ret)
+ putback_movable_pages(&source);
+ return ret;
+}
+
+static void try_migrate_pages(struct dhugetlb_pool *hpool)
+{
+ int i, j;
+ unsigned long nr_free_pages;
+ struct split_pages *split_giga, *next;
+ unsigned int nr_pages = 1 << (PMD_SHIFT - PAGE_SHIFT);
+ struct page *page;
+ int sleep_interval = 100; /* wait for the migration */
+
+ spin_unlock(&hpool->lock);
+ for (i = NR_SMPOOL - 1; i >= 0; i--)
+ spin_unlock(&hpool->smpool[i].lock);
+
+ msleep(sleep_interval);
+ dhugetlb_pool_force_empty(hpool->attach_memcg);
+
+ spin_lock(&hpool->lock);
+ nr_free_pages = hpool->free_pages;
+ spin_unlock(&hpool->lock);
+ for (i = 0; i < NR_SMPOOL; i++) {
+ spin_lock(&hpool->smpool[i].lock);
+ nr_free_pages += hpool->smpool[i].free_pages;
+ spin_unlock(&hpool->smpool[i].lock);
+ }
+
+ if (nr_free_pages >> HUGETLB_PAGE_ORDER < hpool->nr_split_2M) {
+ list_for_each_entry_safe(split_giga, next,
+ &hpool->split_1G_freelists, list) {
+ for (i = 0; i < nr_pages; i++) {
+ if (PageCompound(pfn_to_page(
+ split_giga->start_pfn + i * nr_pages)))
+ continue;
+ page = pfn_to_page(split_giga->start_pfn +
+ i * nr_pages);
+ for (j = 0; j < nr_pages; j++) {
+ if (PagePool(page + j))
+ try_migrate_page(page + j,
+ hpool->nid);
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < NR_SMPOOL; i++)
+ spin_lock(&hpool->smpool[i].lock);
+ spin_lock(&hpool->lock);
+}
+
+/*
+ * If there are some pages are still in use. We will try to reclaim/migrate it.
+ * After trying at most HPOOL_RECLAIM_RETRIES times, we may success.
+ * Or we will print the failed information and return false.
+ */
+static bool free_dhugetlb_pages(struct dhugetlb_pool *hpool)
+{
+ int i;
+ long used_pages;
+ int try_count = 0;
+
+retry:
+ used_pages = 0;
+ for (i = 0; i < NR_SMPOOL; i++)
+ used_pages += hpool->smpool[i].used_pages;
+
+ if (try_count < HPOOL_RECLAIM_RETRIES &&
+ (used_pages || hpool->used_2M || hpool->used_1G)) {
+ try_migrate_pages(hpool);
+ try_count++;
+ goto retry;
+ }
+
+ if (used_pages)
+ pr_err("dhugetlb: some 4K pages not free, memcg: %s delete failed!\n",
+ hpool->attach_memcg->css.cgroup->kn->name);
+ else if (hpool->used_2M)
+ pr_err("dhugetlb: some 2M pages not free, memcg: %s delete failed!\n",
+ hpool->attach_memcg->css.cgroup->kn->name);
+ else if (hpool->used_1G)
+ pr_err("dhugetlb: some 1G pages not free, memcg: %s delete failed!\n",
+ hpool->attach_memcg->css.cgroup->kn->name);
+ else {
+ free_dhugetlb_pcpool(hpool);
+ free_dhugetlb_small_page(hpool);
+ free_dhugetlb_huge_page(hpool);
+ return true;
+ }
+ return false;
+}
+
+static void free_back_hugetlb(struct dhugetlb_pool *hpool)
+{
+ int nid;
+ unsigned int nr_pages;
+ unsigned long pfn, idx;
+ struct page *page, *page_next, *p;
+ struct hstate *h = size_to_hstate(PUD_SIZE);
+
+ if (!h)
+ return;
+
+ spin_lock(&hugetlb_lock);
+ list_for_each_entry_safe(page, page_next,
+ &hpool->dhugetlb_1G_freelists, lru) {
+ nr_pages = 1 << huge_page_order(h);
+ pfn = page_to_pfn(page);
+ for (; nr_pages--; pfn++) {
+ p = pfn_to_page(pfn);
+ p->mapping = NULL;
+ }
+ SetPageHugeFreed(page);
+ set_compound_page_dtor(page, HUGETLB_PAGE_DTOR);
+ nid = page_to_nid(page);
+ BUG_ON(nid >= MAX_NUMNODES);
+ list_move(&page->lru, &h->hugepage_freelists[nid]);
+ h->free_huge_pages_node[nid]++;
+ read_lock(&dhugetlb_pagelist_rwlock);
+ idx = page_to_pfn(page) >> (PUD_SHIFT - PAGE_SHIFT);
+ if (idx < dhugetlb_pagelist_t->count)
+ dhugetlb_pagelist_t->hpool[idx] = NULL;
+ read_unlock(&dhugetlb_pagelist_rwlock);
+ }
+ h->free_huge_pages += hpool->total_nr_pages;
+ hpool->total_nr_pages = 0;
+ hpool->free_unreserved_1G = 0;
+ hpool->free_reserved_1G = 0;
+ hpool->total_reserved_1G = 0;
+ INIT_LIST_HEAD(&hpool->dhugetlb_1G_freelists);
+ spin_unlock(&hugetlb_lock);
+}
+
+bool free_dhugetlb_pool(struct dhugetlb_pool *hpool)
+{
+ int i;
+ bool ret = false;
+
+ for (i = 0; i < NR_SMPOOL; i++)
+ spin_lock(&hpool->smpool[i].lock);
+ spin_lock(&hpool->lock);
+
+ ret = free_dhugetlb_pages(hpool);
+ if (!ret)
+ goto out_unlock;
+
+ free_back_hugetlb(hpool);
+
+out_unlock:
+ spin_unlock(&hpool->lock);
+ for (i = NR_SMPOOL - 1; i >= 0; i--)
+ spin_unlock(&hpool->smpool[i].lock);
+
+ if (ret)
+ dhugetlb_pool_put(hpool);
+ return ret;
+}
+
+static void __split_free_huge_page(struct dhugetlb_pool *hpool,
+ struct page *page)
+{
+ int i;
+ int order_h = PUD_SHIFT - PAGE_SHIFT;
+ int order_m = PMD_SHIFT - PAGE_SHIFT;
+ int blocks = 1 << (order_h - order_m);
+ struct page *p = page + 1;
+
+ lockdep_assert_held(&hpool->lock);
+ set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
+ atomic_set(compound_mapcount_ptr(page), 0);
+ for (i = 1; i < (1 << order_h); i++, p = mem_map_next(p, page, i))
+ clear_compound_head(p);
+
+ set_compound_order(page, 0);
+ __ClearPageHead(page);
+
+ /* make it be 2M huge pages and put it to huge pool */
+ for (i = 0; i < blocks; i++, page += (1 << order_m))
+ add_new_huge_page_to_pool(hpool, page, false);
+}
+
+static void __split_free_small_page(struct dhugetlb_pool *hpool,
+ struct page *page)
+{
+ int i;
+ int nr_pages = 1 << (PMD_SHIFT - PAGE_SHIFT);
+
+ lockdep_assert_held(&hpool->lock);
+ set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
+ set_compound_order(page, 0);
+ for (i = 0; i < nr_pages; i++) {
+ if (i != 0) {
+ page[i].mapping = NULL;
+ clear_compound_head(&page[i]);
+ } else
+ __ClearPageHead(page);
+
+ /*
+ * If a hugepage is mapped in private mode, the PG_uptodate bit
+ * will not be cleared when the hugepage freed. Clear the
+ * hugepage using free_pages_prepare() here.
+ */
+ free_pages_prepare(&page[i], 0, false);
+ hpool->free_pages++;
+ list_add_tail(&page[i].lru, &hpool->dhugetlb_4K_freelists);
+ }
+}
+
+static bool split_free_huge_page(struct dhugetlb_pool *hpool)
+{
+ struct page *page;
+ struct split_pages *split_page;
+
+ lockdep_assert_held(&hpool->lock);
+
+ if (!hpool->free_unreserved_1G)
+ return false;
+
+ split_page = kzalloc(sizeof(struct split_pages), GFP_ATOMIC);
+ if (!split_page)
+ return false;
+
+ page = list_entry(hpool->dhugetlb_1G_freelists.next, struct page, lru);
+ list_del(&page->lru);
+ hpool->free_unreserved_1G--;
+
+ split_page->start_pfn = page_to_pfn(page);
+ list_add(&split_page->list, &hpool->split_1G_freelists);
+ hpool->nr_split_1G++;
+
+ trace_dhugetlb_split_merge(hpool, page, DHUGETLB_SPLIT_1G);
+
+ __split_free_huge_page(hpool, page);
+ return true;
+}
+
+static bool split_free_small_page(struct dhugetlb_pool *hpool)
+{
+ struct page *page;
+ struct split_pages *split_page;
+
+ lockdep_assert_held(&hpool->lock);
+
+ if (!hpool->free_unreserved_2M && !split_free_huge_page(hpool))
+ return false;
+
+ split_page = kzalloc(sizeof(struct split_pages), GFP_ATOMIC);
+ if (!split_page)
+ return false;
+
+ page = list_entry(hpool->dhugetlb_2M_freelists.next, struct page, lru);
+ list_del(&page->lru);
+ hpool->free_unreserved_2M--;
+
+ split_page->start_pfn = page_to_pfn(page);
+ list_add(&split_page->list, &hpool->split_2M_freelists);
+ hpool->nr_split_2M++;
+
+ trace_dhugetlb_split_merge(hpool, page, DHUGETLB_SPLIT_2M);
+
+ __split_free_small_page(hpool, page);
+ return true;
+}
+
+bool move_pages_from_hpool_to_smpool(struct dhugetlb_pool *hpool,
+ struct small_page_pool *smpool)
+{
+ int i = 0;
+ struct page *page, *next;
+
+ if (!hpool->free_pages && !split_free_small_page(hpool))
+ return false;
+
+ list_for_each_entry_safe(page, next,
+ &hpool->dhugetlb_4K_freelists, lru) {
+ list_del(&page->lru);
+ hpool->free_pages--;
+ list_add_tail(&page->lru, &smpool->head_page);
+ smpool->free_pages++;
+ if (++i == BATCH_SMPOOL_PAGE)
+ break;
+ }
+ return true;
+}
+
+void move_pages_from_smpool_to_hpool(struct dhugetlb_pool *hpool,
+ struct small_page_pool *smpool)
+{
+ int i = 0;
+ struct page *page, *next;
+
+ list_for_each_entry_safe(page, next, &smpool->head_page, lru) {
+ list_del(&page->lru);
+ smpool->free_pages--;
+ list_add(&page->lru, &hpool->dhugetlb_4K_freelists);
+ hpool->free_pages++;
+ if (++i == BATCH_SMPOOL_PAGE)
+ break;
+ }
+}
+
+static unsigned long list_len(struct list_head *head)
+{
+ unsigned long len = 0;
+ struct page *page;
+
+ list_for_each_entry(page, head, lru)
+ len++;
+
+ return len;
+}
+
+static void hugetlb_migrate_pages(struct dhugetlb_pool *hpool,
+ unsigned long count)
+{
+ int i, try;
+ struct page *page;
+ struct split_pages *split_huge, *split_next;
+ unsigned long nr_pages = 1 << (PMD_SHIFT - PAGE_SHIFT);
+ LIST_HEAD(wait_page_list);
+
+ list_for_each_entry_safe(split_huge, split_next,
+ &hpool->split_2M_freelists, list) {
+ /*
+ * Isolate free page first because we dont want them to be
+ * allocated.
+ */
+ for (i = 0; i < nr_pages; i++) {
+ page = pfn_to_page(split_huge->start_pfn + i);
+ if (!PagePool(page))
+ list_move(&page->lru, &wait_page_list);
+ }
+
+ for (try = 0; try < HPOOL_RECLAIM_RETRIES; try++) {
+ /*
+ * Unlock and try migration, after migration we need
+ * to lock back.
+ */
+ for (i = 0; i < NR_SMPOOL; i++)
+ hpool->smpool[i].free_pages =
+ list_len(&hpool->smpool[i].head_page);
+ hpool->free_pages =
+ list_len(&hpool->dhugetlb_4K_freelists);
+ spin_unlock(&hpool->lock);
+ for (i = NR_SMPOOL - 1; i >= 0; i--)
+ spin_unlock(&hpool->smpool[i].lock);
+
+ for (i = 0; i < nr_pages; i++) {
+ page = pfn_to_page(split_huge->start_pfn + i);
+ if (PagePool(page))
+ try_migrate_page(page, hpool->nid);
+ }
+ for (i = 0; i < NR_SMPOOL; i++)
+ spin_lock(&hpool->smpool[i].lock);
+ spin_lock(&hpool->lock);
+
+ /*
+ * Isolate free page. If all page in the split_huge
+ * is free, return it.
+ */
+ split_huge->free_pages = 0;
+ for (i = 0; i < nr_pages; i++) {
+ page = pfn_to_page(split_huge->start_pfn + i);
+ if (!PagePool(page)) {
+ list_move(&page->lru, &wait_page_list);
+ split_huge->free_pages++;
+ }
+ }
+ if (split_huge->free_pages == nr_pages)
+ break;
+ }
+ if (split_huge->free_pages == nr_pages) {
+ for (i = 0; i < nr_pages; i++) {
+ page = pfn_to_page(split_huge->start_pfn + i);
+ list_del(&page->lru);
+ }
+ INIT_LIST_HEAD(&wait_page_list);
+ page = pfn_to_page(split_huge->start_pfn);
+ add_new_huge_page_to_pool(hpool, page, false);
+ list_del(&split_huge->list);
+ kfree(split_huge);
+ hpool->nr_split_2M--;
+
+ trace_dhugetlb_split_merge(hpool, page,
+ DHUGETLB_MIGRATE_4K);
+
+ if (--count == 0)
+ return;
+ } else {
+ /* Failed, put back the isolate pages */
+ list_splice(&wait_page_list,
+ &hpool->dhugetlb_4K_freelists);
+ INIT_LIST_HEAD(&wait_page_list);
+ }
+ }
+}
+
+static unsigned long merge_free_split_huge(struct dhugetlb_pool *hpool,
+ unsigned long count)
+{
+ int i;
+ struct page *page;
+ struct split_pages *split_huge, *split_next;
+ unsigned long nr_pages = 1 << (PMD_SHIFT - PAGE_SHIFT);
+
+ list_for_each_entry_safe(split_huge, split_next,
+ &hpool->split_2M_freelists, list) {
+ split_huge->free_pages = 0;
+ for (i = 0; i < nr_pages; i++) {
+ page = pfn_to_page(split_huge->start_pfn + i);
+ if (!PagePool(page))
+ split_huge->free_pages++;
+ }
+ if (split_huge->free_pages == nr_pages) {
+ for (i = 0; i < nr_pages; i++) {
+ page = pfn_to_page(split_huge->start_pfn + i);
+ list_del(&page->lru);
+ }
+ page = pfn_to_page(split_huge->start_pfn);
+ add_new_huge_page_to_pool(hpool, page, false);
+ list_del(&split_huge->list);
+ kfree(split_huge);
+ hpool->nr_split_2M--;
+
+ trace_dhugetlb_split_merge(hpool, page,
+ DHUGETLB_MERGE_4K);
+
+ if (--count == 0)
+ return 0;
+ }
+ }
+ return count;
+}
+
+static void merge_free_small_page(struct dhugetlb_pool *hpool,
+ unsigned long count)
+{
+ int i;
+ unsigned long need_migrate;
+
+ if (!hpool->nr_split_2M)
+ return;
+
+ need_migrate = merge_free_split_huge(hpool, count);
+ if (need_migrate)
+ hugetlb_migrate_pages(hpool, need_migrate);
+
+ for (i = 0; i < NR_SMPOOL; i++)
+ hpool->smpool[i].free_pages =
+ list_len(&hpool->smpool[i].head_page);
+ hpool->free_pages = list_len(&hpool->dhugetlb_4K_freelists);
+}
+
+static void dhugetlb_collect_2M_pages(struct dhugetlb_pool *hpool,
+ unsigned long count)
+{
+ int i;
+
+ while (hpool->free_unreserved_1G &&
+ count > hpool->free_unreserved_2M)
+ split_free_huge_page(hpool);
+
+ /*
+ * If we try to merge 4K pages to 2M, we need to unlock hpool->lock
+ * first, and then try to lock every lock in order to avoid deadlock.
+ */
+ if (count > hpool->free_unreserved_2M) {
+ spin_unlock(&hpool->lock);
+ for (i = 0; i < NR_SMPOOL; i++)
+ spin_lock(&hpool->smpool[i].lock);
+ spin_lock(&hpool->lock);
+ merge_free_small_page(hpool, count - hpool->free_unreserved_2M);
+ for (i = NR_SMPOOL - 1; i >= 0; i--)
+ spin_unlock(&hpool->smpool[i].lock);
+ }
+}
+
+/*
+ * Parameter gigantic: true means reserve 1G pages and false means reserve
+ * 2M pages. When we want to reserve 2M pages more than
+ * hpool->free_unreserved_2M, we have to try split/merge. Still, we can't
+ * guarantee success.
+ */
+void dhugetlb_reserve_hugepages(struct dhugetlb_pool *hpool,
+ unsigned long count, bool gigantic)
+{
+ unsigned long delta;
+
+ spin_lock(&hpool->lock);
+ if (gigantic) {
+ if (count > hpool->total_reserved_1G) {
+ delta = min(count - hpool->total_reserved_1G,
+ hpool->free_unreserved_1G);
+ hpool->total_reserved_1G += delta;
+ hpool->free_reserved_1G += delta;
+ hpool->free_unreserved_1G -= delta;
+ } else {
+ delta = min(hpool->total_reserved_1G - count,
+ hpool->free_reserved_1G -
+ hpool->mmap_reserved_1G);
+ hpool->total_reserved_1G -= delta;
+ hpool->free_reserved_1G -= delta;
+ hpool->free_unreserved_1G += delta;
+ }
+ } else {
+ if (count > hpool->total_reserved_2M) {
+ delta = count - hpool->total_reserved_2M;
+ if (delta > hpool->free_unreserved_2M)
+ dhugetlb_collect_2M_pages(hpool, delta);
+ delta = min(count - hpool->total_reserved_2M,
+ hpool->free_unreserved_2M);
+ hpool->total_reserved_2M += delta;
+ hpool->free_reserved_2M += delta;
+ hpool->free_unreserved_2M -= delta;
+ } else {
+ delta = min(hpool->total_reserved_2M - count,
+ hpool->free_reserved_2M -
+ hpool->mmap_reserved_2M);
+ hpool->total_reserved_2M -= delta;
+ hpool->free_reserved_2M -= delta;
+ hpool->free_unreserved_2M += delta;
+ }
+ }
+ spin_unlock(&hpool->lock);
+}
+
+static int dhugetlb_acct_memory(struct hstate *h, long delta,
+ struct dhugetlb_pool *hpool)
+{
+ int ret = -ENOMEM;
+
+ if (delta == 0)
+ return 0;
+
+ spin_lock(&hpool->lock);
+ if (hstate_is_gigantic(h)) {
+ if (delta > 0 && delta <= hpool->free_reserved_1G -
+ hpool->mmap_reserved_1G) {
+ hpool->mmap_reserved_1G += delta;
+ ret = 0;
+ trace_dhugetlb_acct_memory(hpool,
+ hpool->mmap_reserved_1G,
+ DHUGETLB_RESV_1G);
+ } else if (delta < 0) {
+ hpool->mmap_reserved_1G -= (unsigned long)(-delta);
+ WARN_ON(hpool->mmap_reserved_1G < 0);
+ ret = 0;
+ trace_dhugetlb_acct_memory(hpool,
+ hpool->mmap_reserved_1G,
+ DHUGETLB_UNRESV_1G);
+ }
+ } else {
+ if (delta > 0 && delta <= hpool->free_reserved_2M -
+ hpool->mmap_reserved_2M) {
+ hpool->mmap_reserved_2M += delta;
+ ret = 0;
+ trace_dhugetlb_acct_memory(hpool,
+ hpool->mmap_reserved_2M,
+ DHUGETLB_RESV_2M);
+ } else if (delta < 0) {
+ hpool->mmap_reserved_2M -= (unsigned long)(-delta);
+ WARN_ON(hpool->mmap_reserved_2M < 0);
+ ret = 0;
+ trace_dhugetlb_acct_memory(hpool,
+ hpool->mmap_reserved_2M,
+ DHUGETLB_UNRESV_2M);
+ }
+ }
+ spin_unlock(&hpool->lock);
+
+ return ret;
+}
+#else
+static int dhugetlb_acct_memory(struct hstate *h, long delta,
+ struct dhugetlb_pool *hpool)
+{
+ return 0;
+}
+#endif /* CONFIG_DYNAMIC_HUGETLB */
+
static int __init hugetlb_init(void)
{
int i;
@@ -3134,6 +4240,23 @@ static int __init hugetlb_init(void)
hugetlb_register_all_nodes();
hugetlb_cgroup_file_init();
+#ifdef CONFIG_DYNAMIC_HUGETLB
+ if (enable_dhugetlb) {
+ unsigned long count = max(max_pfn >> (PUD_SHIFT - PAGE_SHIFT),
+ (unsigned long)DEFAULT_PAGESIZE);
+ unsigned long size = sizeof(struct dhugetlb_pagelist) +
+ count * sizeof(struct dhugetlb_pool *);
+ dhugetlb_pagelist_t = kzalloc(size, GFP_KERNEL);
+ if (dhugetlb_pagelist_t) {
+ dhugetlb_pagelist_t->count = count;
+ static_branch_enable(&dhugetlb_enabled_key);
+ pr_info("Dynamic 1G hugepage enabled\n");
+ } else
+ pr_info("Dynamic 1G hugepage disabled due to out of memory, need %lu\n",
+ size);
+ }
+#endif
+
#ifdef CONFIG_SMP
num_fault_mutexes = roundup_pow_of_two(8 * num_possible_cpus());
#else
@@ -3270,6 +4393,16 @@ static int __init hugetlb_nrpages_setup(char *s)
}
__setup("hugepages=", hugetlb_nrpages_setup);
+#ifdef CONFIG_DYNAMIC_HUGETLB
+static int __init dhugetlb_setup(char *s)
+{
+ if (!strcmp(s, "on"))
+ enable_dhugetlb = true;
+ return 1;
+}
+__setup("dynamic_1G_hugepage=", dhugetlb_setup);
+#endif
+
static int __init hugetlb_default_setup(char *s)
{
default_hstate_size = memparse(s, &s);
@@ -3471,10 +4604,14 @@ unsigned long hugetlb_total_pages(void)
return nr_total_pages;
}
-static int hugetlb_acct_memory(struct hstate *h, long delta)
+static int hugetlb_acct_memory(struct hstate *h, long delta,
+ struct dhugetlb_pool *hpool)
{
int ret = -ENOMEM;
+ if (dhugetlb_enabled && hpool)
+ return dhugetlb_acct_memory(h, delta, hpool);
+
spin_lock(&hugetlb_lock);
/*
* When cpuset is configured, it breaks the strict hugetlb page
@@ -3535,6 +4672,8 @@ static void hugetlb_vm_op_close(struct vm_area_struct *vma)
struct hugepage_subpool *spool = subpool_vma(vma);
unsigned long reserve, start, end;
long gbl_reserve;
+ struct dhugetlb_pool *hpool =
+ HUGETLBFS_I(file_inode(vma->vm_file))->hpool;
if (!resv || !is_vma_resv_set(vma, HPAGE_RESV_OWNER))
return;
@@ -3551,8 +4690,8 @@ static void hugetlb_vm_op_close(struct vm_area_struct *vma)
* Decrement reserve counts. The global reserve count may be
* adjusted if the subpool has a minimum size.
*/
- gbl_reserve = hugepage_subpool_put_pages(spool, reserve);
- hugetlb_acct_memory(h, -gbl_reserve);
+ gbl_reserve = hugepage_subpool_put_pages(spool, reserve, hpool);
+ hugetlb_acct_memory(h, -gbl_reserve, hpool);
}
}
@@ -4934,6 +6073,7 @@ int hugetlb_reserve_pages(struct inode *inode,
struct hugepage_subpool *spool = subpool_inode(inode);
struct resv_map *resv_map;
long gbl_reserve;
+ struct dhugetlb_pool *hpool = HUGETLBFS_I(inode)->hpool;
/* This should never happen */
if (from > to) {
@@ -4986,7 +6126,7 @@ int hugetlb_reserve_pages(struct inode *inode,
* the subpool has a minimum size, there may be some global
* reservations already in place (gbl_reserve).
*/
- gbl_reserve = hugepage_subpool_get_pages(spool, chg);
+ gbl_reserve = hugepage_subpool_get_pages(spool, chg, hpool);
if (gbl_reserve < 0) {
ret = -ENOSPC;
goto out_err;
@@ -4996,10 +6136,10 @@ int hugetlb_reserve_pages(struct inode *inode,
* Check enough hugepages are available for the reservation.
* Hand the pages back to the subpool if there are not
*/
- ret = hugetlb_acct_memory(h, gbl_reserve);
+ ret = hugetlb_acct_memory(h, gbl_reserve, hpool);
if (ret < 0) {
/* put back original number of pages, chg */
- (void)hugepage_subpool_put_pages(spool, chg);
+ (void)hugepage_subpool_put_pages(spool, chg, hpool);
goto out_err;
}
@@ -5028,8 +6168,9 @@ int hugetlb_reserve_pages(struct inode *inode,
long rsv_adjust;
rsv_adjust = hugepage_subpool_put_pages(spool,
- chg - add);
- hugetlb_acct_memory(h, -rsv_adjust);
+ chg - add,
+ hpool);
+ hugetlb_acct_memory(h, -rsv_adjust, hpool);
}
}
return 0;
@@ -5051,6 +6192,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
long chg = 0;
struct hugepage_subpool *spool = subpool_inode(inode);
long gbl_reserve;
+ struct dhugetlb_pool *hpool = HUGETLBFS_I(inode)->hpool;
/*
* Since this routine can be called in the evict inode path for all
@@ -5075,8 +6217,8 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
* If the subpool has a minimum size, the number of global
* reservations to be released may be adjusted.
*/
- gbl_reserve = hugepage_subpool_put_pages(spool, (chg - freed));
- hugetlb_acct_memory(h, -gbl_reserve);
+ gbl_reserve = hugepage_subpool_put_pages(spool, (chg - freed), hpool);
+ hugetlb_acct_memory(h, -gbl_reserve, hpool);
return 0;
}
diff --git a/mm/internal.h b/mm/internal.h
index 1b861446c751..deffd247b010 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -182,6 +182,7 @@ extern void __putback_isolated_page(struct page *page, unsigned int order,
int mt);
extern void __free_pages_core(struct page *page, unsigned int order);
extern void prep_compound_page(struct page *page, unsigned int order);
+extern int check_new_page(struct page *page);
extern void post_alloc_hook(struct page *page, unsigned int order,
gfp_t gfp_flags);
extern int user_min_free_kbytes;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 63b91a030b02..bdc90e6fc082 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -997,6 +997,41 @@ static __always_inline struct mem_cgroup *get_mem_cgroup_from_current(void)
return get_mem_cgroup_from_mm(current->mm);
}
+#ifdef CONFIG_DYNAMIC_HUGETLB
+void free_page_to_dhugetlb_pool(struct page *page)
+{
+ struct dhugetlb_pool *hpool;
+ struct small_page_pool *smpool;
+ unsigned long flags;
+
+ hpool = get_dhugetlb_pool_from_dhugetlb_pagelist(page);
+ if (unlikely(!hpool)) {
+ pr_err("dhugetlb: free error: get hpool failed\n");
+ return;
+ }
+
+ smpool = &hpool->smpool[smp_processor_id()];
+ spin_lock_irqsave(&smpool->lock, flags);
+
+ ClearPagePool(page);
+ if (!free_pages_prepare(page, 0, false)) {
+ SetPagePool(page);
+ goto out;
+ }
+ list_add(&page->lru, &smpool->head_page);
+ smpool->free_pages++;
+ smpool->used_pages--;
+ if (smpool->free_pages > MAX_SMPOOL_PAGE) {
+ spin_lock(&hpool->lock);
+ move_pages_from_smpool_to_hpool(hpool, smpool);
+ spin_unlock(&hpool->lock);
+ }
+out:
+ spin_unlock_irqrestore(&smpool->lock, flags);
+ dhugetlb_pool_put(hpool);
+}
+#endif /* CONFIG_DYNAMIC_HUGETLB */
+
/**
* mem_cgroup_iter - iterate over memory cgroup hierarchy
* @root: hierarchy root
@@ -3118,6 +3153,31 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg)
return 0;
}
+#ifdef CONFIG_DYNAMIC_HUGETLB
+int dhugetlb_pool_force_empty(struct mem_cgroup *memcg)
+{
+ lru_add_drain_all();
+
+ drain_all_stock(memcg);
+
+ while (page_counter_read(&memcg->memory)) {
+ int progress;
+
+ if (signal_pending(current))
+ return -EINTR;
+
+ progress = try_to_free_mem_cgroup_pages(memcg, 1,
+ GFP_HIGHUSER_MOVABLE,
+ false);
+
+ if (!progress) {
+ congestion_wait(BLK_RW_ASYNC, HZ/10);
+ break;
+ }
+ }
+ return 0;
+}
+#endif
static ssize_t mem_cgroup_force_empty_write(struct kernfs_open_file *of,
char *buf, size_t nbytes,
@@ -4652,6 +4712,305 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
return ret;
}
+#ifdef CONFIG_DYNAMIC_HUGETLB
+struct dhugetlb_pool *get_dhugetlb_pool_from_memcg(struct mem_cgroup *memcg)
+{
+ struct mem_cgroup_extension *memcg_ext;
+
+ if (!memcg)
+ return NULL;
+
+ memcg_ext = container_of(memcg, struct mem_cgroup_extension, memcg);
+ if (dhugetlb_pool_get(memcg_ext->hpool))
+ return memcg_ext->hpool;
+ return NULL;
+}
+
+static void set_dhugetlb_pool_to_memcg(struct mem_cgroup *memcg,
+ struct dhugetlb_pool *hpool)
+{
+ struct mem_cgroup_extension *memcg_ext;
+
+ memcg_ext = container_of(memcg, struct mem_cgroup_extension, memcg);
+
+ memcg_ext->hpool = hpool;
+}
+
+static bool should_allocate_from_dhugetlb_pool(gfp_t gfp_mask)
+{
+ gfp_t gfp = gfp_mask & GFP_HIGHUSER_MOVABLE;
+
+ if (current->flags & PF_KTHREAD)
+ return false;
+
+ /*
+ * The cgroup only charges anonymous and file pages from usespage.
+ * some filesystem maybe has masked out the __GFP_IO | __GFP_FS
+ * to avoid recursive memory request. eg: loop device, xfs.
+ */
+ if ((gfp | __GFP_IO | __GFP_FS) != GFP_HIGHUSER_MOVABLE)
+ return false;
+
+ return true;
+}
+
+static struct page *__alloc_page_from_dhugetlb_pool(void)
+{
+ bool ret;
+ struct dhugetlb_pool *hpool;
+ struct small_page_pool *smpool;
+ struct page *page = NULL;
+ unsigned long flags;
+
+ hpool = get_dhugetlb_pool_from_task(current);
+ if (unlikely(!hpool))
+ goto out;
+
+ smpool = &hpool->smpool[smp_processor_id()];
+ spin_lock_irqsave(&smpool->lock, flags);
+
+ if (smpool->free_pages == 0) {
+ spin_lock(&hpool->lock);
+ ret = move_pages_from_hpool_to_smpool(hpool, smpool);
+ spin_unlock(&hpool->lock);
+ if (!ret)
+ goto unlock;
+ }
+
+ page = list_entry(smpool->head_page.next, struct page, lru);
+ list_del(&page->lru);
+ smpool->free_pages--;
+ smpool->used_pages++;
+ check_new_page(page);
+ SetPagePool(page);
+unlock:
+ spin_unlock_irqrestore(&smpool->lock, flags);
+out:
+ dhugetlb_pool_put(hpool);
+ return page;
+}
+
+struct page *alloc_page_from_dhugetlb_pool(gfp_t gfp_mask)
+{
+ struct page *page = NULL;
+
+ if (should_allocate_from_dhugetlb_pool(gfp_mask))
+ page = __alloc_page_from_dhugetlb_pool();
+
+ return page;
+}
+
+static void assign_new_dhugetlb_pool(struct mem_cgroup *memcg,
+ unsigned long nid)
+{
+ struct dhugetlb_pool *hpool;
+
+ hpool = hpool_alloc(nid);
+ if (!hpool)
+ return;
+
+ hpool->attach_memcg = memcg;
+ css_get(&memcg->css);
+ set_dhugetlb_pool_to_memcg(memcg, hpool);
+}
+
+static int update_dhugetlb_pool(struct mem_cgroup *memcg,
+ unsigned long nid, unsigned long size)
+{
+ int ret;
+ struct dhugetlb_pool *hpool = get_dhugetlb_pool_from_memcg(memcg);
+
+ if (!hpool) {
+ if (memcg_has_children(memcg))
+ return -EINVAL;
+ assign_new_dhugetlb_pool(memcg, nid);
+ hpool = get_dhugetlb_pool_from_memcg(memcg);
+ }
+ if (!hpool)
+ return -ENOMEM;
+ if (hpool->attach_memcg != memcg || hpool->nid != nid) {
+ dhugetlb_pool_put(hpool);
+ return -EINVAL;
+ }
+
+ ret = alloc_hugepage_from_hugetlb(hpool, nid, size);
+
+ dhugetlb_pool_put(hpool);
+ return ret;
+}
+
+/*
+ * Test whether an process can allocate specified memory size.
+ *
+ * Input must be in format '<nid> <size>'.
+ * size is regarded as how many it does 1G huge page.
+ */
+static ssize_t memcg_write_dhugetlb(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ int ret;
+ unsigned long nid, size;
+ char *endp;
+ struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+
+ if (!dhugetlb_enabled)
+ return -EINVAL;
+
+ buf = strstrip(buf);
+ nid = memparse(buf, &endp);
+ if (*endp != ' ' || nid >= MAX_NUMNODES)
+ return -EINVAL;
+
+ buf = endp + 1;
+ size = memparse(buf, &endp);
+ if (*endp != '\0' || size == 0)
+ return -EINVAL;
+
+ ret = update_dhugetlb_pool(memcg, nid, size);
+
+ return ret ?: nbytes;
+}
+
+static int memcg_read_dhugetlb(struct seq_file *m, void *v)
+{
+ int i;
+ unsigned long free_pages;
+ long used_pages = 0;
+ struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
+ struct dhugetlb_pool *hpool = get_dhugetlb_pool_from_memcg(memcg);
+
+ if (!dhugetlb_enabled)
+ return 0;
+ if (!hpool) {
+ seq_printf(m, "Curent hierarchial have not memory pool.\n");
+ return 0;
+ }
+
+ for (i = 0; i < NR_SMPOOL; i++)
+ spin_lock(&hpool->smpool[i].lock);
+ spin_lock(&hpool->lock);
+
+ free_pages = hpool->free_pages;
+ for (i = 0; i < NR_SMPOOL; i++) {
+ free_pages += hpool->smpool[i].free_pages;
+ used_pages += hpool->smpool[i].used_pages;
+ }
+
+ seq_printf(m, "dhugetlb_total_pages %ld\n"
+ "1G_total_reserved_pages %ld\n"
+ "1G_free_reserved_pages %ld\n"
+ "1G_mmap_reserved_pages %ld\n"
+ "1G_used_pages %ld\n"
+ "1G_free_unreserved_pages %ld\n"
+ "2M_total_reserved_pages %ld\n"
+ "2M_free_reserved_pages %ld\n"
+ "2M_mmap_reserved_pages %ld\n"
+ "2M_used_pages %ld\n"
+ "2M_free_unreserved_pages %ld\n"
+ "4K_free_pages %ld\n"
+ "4K_used_pages %ld\n",
+ hpool->total_nr_pages,
+ hpool->total_reserved_1G,
+ hpool->free_reserved_1G,
+ hpool->mmap_reserved_1G,
+ hpool->used_1G,
+ hpool->free_unreserved_1G,
+ hpool->total_reserved_2M,
+ hpool->free_reserved_2M,
+ hpool->mmap_reserved_2M,
+ hpool->used_2M,
+ hpool->free_unreserved_2M,
+ free_pages,
+ used_pages);
+
+ spin_unlock(&hpool->lock);
+ for (i = NR_SMPOOL - 1; i >= 0; i--)
+ spin_unlock(&hpool->smpool[i].lock);
+ dhugetlb_pool_put(hpool);
+ return 0;
+}
+
+static int update_reserve_pages(struct kernfs_open_file *of,
+ char *buf, bool gigantic)
+{
+ unsigned long size;
+ char *endp;
+ struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+ struct dhugetlb_pool *hpool;
+
+ if (!dhugetlb_enabled)
+ return -EINVAL;
+
+ buf = strstrip(buf);
+ size = memparse(buf, &endp);
+ if (*endp != '\0')
+ return -EINVAL;
+
+ hpool = get_dhugetlb_pool_from_memcg(memcg);
+ if (!hpool)
+ return -EINVAL;
+ spin_lock(&hpool->reserved_lock);
+ dhugetlb_reserve_hugepages(hpool, size, gigantic);
+ spin_unlock(&hpool->reserved_lock);
+ dhugetlb_pool_put(hpool);
+ return 0;
+}
+
+static ssize_t dhugetlb_1G_reserve_write(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ return update_reserve_pages(of, buf, true) ?: nbytes;
+}
+
+static ssize_t dhugetlb_2M_reserve_write(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ return update_reserve_pages(of, buf, false) ?: nbytes;
+}
+
+static void dhugetlb_pool_inherits(struct mem_cgroup *memcg,
+ struct mem_cgroup *parent)
+{
+ struct dhugetlb_pool *hpool;
+
+ hpool = get_dhugetlb_pool_from_memcg(parent);
+ if (!hpool)
+ return;
+
+ set_dhugetlb_pool_to_memcg(memcg, hpool);
+ dhugetlb_pool_put(hpool);
+}
+
+static bool dhugetlb_pool_free(struct mem_cgroup *memcg)
+{
+ bool ret = true;
+ struct dhugetlb_pool *hpool;
+
+ hpool = get_dhugetlb_pool_from_memcg(memcg);
+ if (hpool && hpool->attach_memcg == memcg)
+ ret = free_dhugetlb_pool(hpool);
+ dhugetlb_pool_put(hpool);
+ return ret;
+}
+
+bool dhugetlb_pool_is_free(struct cgroup_subsys_state *css)
+{
+ if (dhugetlb_enabled)
+ return dhugetlb_pool_free(mem_cgroup_from_css(css));
+ return true;
+}
+#else
+static void dhugetlb_pool_inherits(struct mem_cgroup *memcg,
+ struct mem_cgroup *parent)
+{
+}
+
+bool dhugetlb_pool_is_free(struct cgroup_subsys_state *css)
+{
+ return true;
+}
+#endif /* CONFIG_DYNAMIC_HUGETLB */
+
static struct cftype mem_cgroup_legacy_files[] = {
{
.name = "usage_in_bytes",
@@ -4700,6 +5059,27 @@ static struct cftype mem_cgroup_legacy_files[] = {
.write = memcg_write_event_control,
.flags = CFTYPE_NO_PREFIX | CFTYPE_WORLD_WRITABLE,
},
+#ifdef CONFIG_DYNAMIC_HUGETLB
+ {
+ .name = "dhugetlb.nr_pages",
+ .write = memcg_write_dhugetlb,
+ .seq_show = memcg_read_dhugetlb,
+ .flags = CFTYPE_NO_PREFIX | CFTYPE_WORLD_WRITABLE |
+ CFTYPE_NOT_ON_ROOT,
+ },
+ {
+ .name = "dhugetlb.1G.reserved_pages",
+ .write = dhugetlb_1G_reserve_write,
+ .flags = CFTYPE_NO_PREFIX | CFTYPE_WORLD_WRITABLE |
+ CFTYPE_NOT_ON_ROOT,
+ },
+ {
+ .name = "dhugetlb.2M.reserved_pages",
+ .write = dhugetlb_2M_reserve_write,
+ .flags = CFTYPE_NO_PREFIX | CFTYPE_WORLD_WRITABLE |
+ CFTYPE_NOT_ON_ROOT,
+ },
+#endif
{
.name = "swappiness",
.read_u64 = mem_cgroup_swappiness_read,
@@ -5063,6 +5443,9 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
return &memcg->css;
}
+ if (dhugetlb_enabled)
+ dhugetlb_pool_inherits(memcg, parent);
+
error = memcg_online_kmem(memcg);
if (error)
goto fail;
@@ -5681,6 +6064,14 @@ static int mem_cgroup_can_attach(struct cgroup_taskset *tset)
if (!p)
return 0;
+ if (dhugetlb_enabled) {
+ struct dhugetlb_pool *hpool = get_dhugetlb_pool_from_task(p);
+
+ if (hpool) {
+ dhugetlb_pool_put(hpool);
+ return -EPERM;
+ }
+ }
/*
* We are now commited to this value whatever it is. Changes in this
* tunable will only affect upcoming migrations, not the current one.
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a6a2f254f61f..e722d73a3724 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1052,7 +1052,7 @@ static int free_tail_pages_check(struct page *head_page, struct page *page)
return ret;
}
-static __always_inline bool free_pages_prepare(struct page *page,
+__always_inline bool free_pages_prepare(struct page *page,
unsigned int order, bool check_free)
{
int bad = 0;
@@ -2012,7 +2012,7 @@ static void check_new_page_bad(struct page *page)
/*
* This page is about to be returned from the page allocator
*/
-static inline int check_new_page(struct page *page)
+inline int check_new_page(struct page *page)
{
if (likely(page_expected_state(page,
PAGE_FLAGS_CHECK_AT_PREP|__PG_HWPOISON)))
@@ -2075,8 +2075,8 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
set_page_owner(page, order, gfp_flags);
}
-static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags,
- unsigned int alloc_flags)
+void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags,
+ unsigned int alloc_flags)
{
int i;
@@ -2955,6 +2955,12 @@ void free_unref_page(struct page *page)
unsigned long flags;
unsigned long pfn = page_to_pfn(page);
+ /* Free dynamic hugetlb page */
+ if (dhugetlb_enabled && PagePool(page)) {
+ free_page_to_dhugetlb_pool(page);
+ return;
+ }
+
if (!free_unref_page_prepare(page, pfn))
return;
@@ -2972,6 +2978,16 @@ void free_unref_page_list(struct list_head *list)
unsigned long flags, pfn;
int batch_count = 0;
+ /* Free dynamic hugetlb pages */
+ if (dhugetlb_enabled) {
+ list_for_each_entry_safe(page, next, list, lru) {
+ if (PagePool(page)) {
+ list_del(&page->lru);
+ free_page_to_dhugetlb_pool(page);
+ }
+ }
+ }
+
/* Prepare pages for freeing */
list_for_each_entry_safe(page, next, list, lru) {
pfn = page_to_pfn(page);
@@ -4785,6 +4801,15 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
finalise_ac(gfp_mask, &ac);
+ /* Dynamic hugetlb allocation attemp */
+ if (dhugetlb_enabled && likely(order == 0)) {
+ page = alloc_page_from_dhugetlb_pool(gfp_mask);
+ if (page) {
+ prep_new_page(page, order, gfp_mask, alloc_flags);
+ goto out;
+ }
+ }
+
/* First allocation attempt */
page = get_page_from_freelist(alloc_mask, order, alloc_flags, &ac);
if (likely(page))
--
2.25.1
1
5

03 Feb '23
From: Sebastian Andrzej Siewior <bigeasy(a)linutronix.de>
stable inclusion
from stable-v5.10.142
commit d71a1c9fce184718d1b3a51a9e8a6e31cbbb45ce
category: bugfix
bugzilla: 188217
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
-------------------------------------------------
commit 278d3ba61563ceed3cb248383ced19e14ec7bc1f upstream.
On 32bit-UP u64_stats_fetch_begin() disables only preemption. If the
reader is in preemptible context and the writer side
(u64_stats_update_begin*()) runs in an interrupt context (IRQ or
softirq) then the writer can update the stats during the read operation.
This update remains undetected.
Use u64_stats_fetch_begin_irq() to ensure the stats fetch on 32bit-UP
are not interrupted by a writer. 32bit-SMP remains unaffected by this
change.
Cc: "David S. Miller" <davem(a)davemloft.net>
Cc: Catherine Sullivan <csully(a)google.com>
Cc: David Awogbemila <awogbemila(a)google.com>
Cc: Dimitris Michailidis <dmichail(a)fungible.com>
Cc: Eric Dumazet <edumazet(a)google.com>
Cc: Hans Ulli Kroll <ulli.kroll(a)googlemail.com>
Cc: Jakub Kicinski <kuba(a)kernel.org>
Cc: Jeroen de Borst <jeroendb(a)google.com>
Cc: Johannes Berg <johannes(a)sipsolutions.net>
Cc: Linus Walleij <linus.walleij(a)linaro.org>
Cc: Paolo Abeni <pabeni(a)redhat.com>
Cc: Simon Horman <simon.horman(a)corigine.com>
Cc: linux-arm-kernel(a)lists.infradead.org
Cc: linux-wireless(a)vger.kernel.org
Cc: netdev(a)vger.kernel.org
Cc: oss-drivers(a)corigine.com
Cc: stable(a)vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy(a)linutronix.de>
Reviewed-by: Simon Horman <simon.horman(a)corigine.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
(cherry picked from commit d71a1c9fce184718d1b3a51a9e8a6e31cbbb45ce)
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
Conflicts:
drivers/net/ethernet/huawei/hinic/hinic_rx.c
drivers/net/ethernet/huawei/hinic/hinic_tx.c
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
---
drivers/net/ethernet/cortina/gemini.c | 24 +++++++++++-----------
drivers/net/ethernet/google/gve/gve_ethtool.c | 16 +++++++--------
drivers/net/ethernet/google/gve/gve_main.c | 12 +++++------
drivers/net/ethernet/huawei/hinic/hinic_rx.c | 4 ++--
drivers/net/ethernet/huawei/hinic/hinic_tx.c | 4 ++--
.../net/ethernet/netronome/nfp/nfp_net_common.c | 8 ++++----
.../net/ethernet/netronome/nfp/nfp_net_ethtool.c | 8 ++++----
drivers/net/netdevsim/netdev.c | 4 ++--
net/mac80211/sta_info.c | 8 ++++----
net/mpls/af_mpls.c | 4 ++--
10 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 3685878..b22ea40 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1920,7 +1920,7 @@ static void gmac_get_stats64(struct net_device *netdev,
/* Racing with RX NAPI */
do {
- start = u64_stats_fetch_begin(&port->rx_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp);
stats->rx_packets = port->stats.rx_packets;
stats->rx_bytes = port->stats.rx_bytes;
@@ -1932,11 +1932,11 @@ static void gmac_get_stats64(struct net_device *netdev,
stats->rx_crc_errors = port->stats.rx_crc_errors;
stats->rx_frame_errors = port->stats.rx_frame_errors;
- } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start));
/* Racing with MIB and TX completion interrupts */
do {
- start = u64_stats_fetch_begin(&port->ir_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp);
stats->tx_errors = port->stats.tx_errors;
stats->tx_packets = port->stats.tx_packets;
@@ -1946,15 +1946,15 @@ static void gmac_get_stats64(struct net_device *netdev,
stats->rx_missed_errors = port->stats.rx_missed_errors;
stats->rx_fifo_errors = port->stats.rx_fifo_errors;
- } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start));
/* Racing with hard_start_xmit */
do {
- start = u64_stats_fetch_begin(&port->tx_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp);
stats->tx_dropped = port->stats.tx_dropped;
- } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start));
stats->rx_dropped += stats->rx_missed_errors;
}
@@ -2032,18 +2032,18 @@ static void gmac_get_ethtool_stats(struct net_device *netdev,
/* Racing with MIB interrupt */
do {
p = values;
- start = u64_stats_fetch_begin(&port->ir_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp);
for (i = 0; i < RX_STATS_NUM; i++)
*p++ = port->hw_stats[i];
- } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start));
values = p;
/* Racing with RX NAPI */
do {
p = values;
- start = u64_stats_fetch_begin(&port->rx_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp);
for (i = 0; i < RX_STATUS_NUM; i++)
*p++ = port->rx_stats[i];
@@ -2051,13 +2051,13 @@ static void gmac_get_ethtool_stats(struct net_device *netdev,
*p++ = port->rx_csum_stats[i];
*p++ = port->rx_napi_exits;
- } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start));
values = p;
/* Racing with TX start_xmit */
do {
p = values;
- start = u64_stats_fetch_begin(&port->tx_stats_syncp);
+ start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp);
for (i = 0; i < TX_MAX_FRAGS; i++) {
*values++ = port->tx_frag_stats[i];
@@ -2066,7 +2066,7 @@ static void gmac_get_ethtool_stats(struct net_device *netdev,
*values++ = port->tx_frags_linearized;
*values++ = port->tx_hw_csummed;
- } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start));
+ } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start));
}
static int gmac_get_ksettings(struct net_device *netdev,
diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c
index 66f9b37..80a8c0c 100644
--- a/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -172,14 +172,14 @@ static int gve_get_sset_count(struct net_device *netdev, int sset)
struct gve_rx_ring *rx = &priv->rx[ring];
start =
- u64_stats_fetch_begin(&priv->rx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
tmp_rx_pkts = rx->rpackets;
tmp_rx_bytes = rx->rbytes;
tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail;
tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
tmp_rx_desc_err_dropped_pkt =
rx->rx_desc_err_dropped_pkt;
- } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
start));
rx_pkts += tmp_rx_pkts;
rx_bytes += tmp_rx_bytes;
@@ -193,10 +193,10 @@ static int gve_get_sset_count(struct net_device *netdev, int sset)
if (priv->tx) {
do {
start =
- u64_stats_fetch_begin(&priv->tx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
tmp_tx_pkts = priv->tx[ring].pkt_done;
tmp_tx_bytes = priv->tx[ring].bytes_done;
- } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
start));
tx_pkts += tmp_tx_pkts;
tx_bytes += tmp_tx_bytes;
@@ -254,13 +254,13 @@ static int gve_get_sset_count(struct net_device *netdev, int sset)
data[i++] = rx->cnt;
do {
start =
- u64_stats_fetch_begin(&priv->rx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
tmp_rx_bytes = rx->rbytes;
tmp_rx_skb_alloc_fail = rx->rx_skb_alloc_fail;
tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail;
tmp_rx_desc_err_dropped_pkt =
rx->rx_desc_err_dropped_pkt;
- } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
start));
data[i++] = tmp_rx_bytes;
/* rx dropped packets */
@@ -313,9 +313,9 @@ static int gve_get_sset_count(struct net_device *netdev, int sset)
data[i++] = tx->done;
do {
start =
- u64_stats_fetch_begin(&priv->tx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
tmp_tx_bytes = tx->bytes_done;
- } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
start));
data[i++] = tmp_tx_bytes;
data[i++] = tx->wake_queue;
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 6cb75bb..f0c1e6c8 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -40,10 +40,10 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) {
do {
start =
- u64_stats_fetch_begin(&priv->rx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->rx[ring].statss);
packets = priv->rx[ring].rpackets;
bytes = priv->rx[ring].rbytes;
- } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->rx[ring].statss,
start));
s->rx_packets += packets;
s->rx_bytes += bytes;
@@ -53,10 +53,10 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) {
do {
start =
- u64_stats_fetch_begin(&priv->tx[ring].statss);
+ u64_stats_fetch_begin_irq(&priv->tx[ring].statss);
packets = priv->tx[ring].pkt_done;
bytes = priv->tx[ring].bytes_done;
- } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
+ } while (u64_stats_fetch_retry_irq(&priv->tx[ring].statss,
start));
s->tx_packets += packets;
s->tx_bytes += bytes;
@@ -1041,9 +1041,9 @@ void gve_handle_report_stats(struct gve_priv *priv)
if (priv->tx) {
for (idx = 0; idx < priv->tx_cfg.num_queues; idx++) {
do {
- start = u64_stats_fetch_begin(&priv->tx[idx].statss);
+ start = u64_stats_fetch_begin_irq(&priv->tx[idx].statss);
tx_bytes = priv->tx[idx].bytes_done;
- } while (u64_stats_fetch_retry(&priv->tx[idx].statss, start));
+ } while (u64_stats_fetch_retry_irq(&priv->tx[idx].statss, start));
stats[stats_idx++] = (struct stats) {
.stat_name = cpu_to_be32(TX_WAKE_CNT),
.value = cpu_to_be64(priv->tx[idx].wake_queue),
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
index 57d5d79..1b57b67 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
@@ -375,7 +375,7 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq,
u64_stats_update_begin(&stats->syncp);
do {
- start = u64_stats_fetch_begin(&rxq_stats->syncp);
+ start = u64_stats_fetch_begin_irq(&rxq_stats->syncp);
stats->bytes = rxq_stats->bytes;
stats->packets = rxq_stats->packets;
stats->errors = rxq_stats->csum_errors +
@@ -384,7 +384,7 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq,
stats->other_errors = rxq_stats->other_errors;
stats->dropped = rxq_stats->dropped;
stats->rx_buf_empty = rxq_stats->rx_buf_empty;
- } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&rxq_stats->syncp, start));
u64_stats_update_end(&stats->syncp);
}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
index 75fa344..ff37b6f 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
@@ -61,7 +61,7 @@ void hinic_txq_get_stats(struct hinic_txq *txq,
u64_stats_update_begin(&stats->syncp);
do {
- start = u64_stats_fetch_begin(&txq_stats->syncp);
+ start = u64_stats_fetch_begin_irq(&txq_stats->syncp);
stats->bytes = txq_stats->bytes;
stats->packets = txq_stats->packets;
stats->busy = txq_stats->busy;
@@ -69,7 +69,7 @@ void hinic_txq_get_stats(struct hinic_txq *txq,
stats->dropped = txq_stats->dropped;
stats->big_frags_pkts = txq_stats->big_frags_pkts;
stats->big_udp_pkts = txq_stats->big_udp_pkts;
- } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&txq_stats->syncp, start));
u64_stats_update_end(&stats->syncp);
}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index dfc1f32..5ab230aa 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3373,21 +3373,21 @@ static void nfp_net_stat64(struct net_device *netdev,
unsigned int start;
do {
- start = u64_stats_fetch_begin(&r_vec->rx_sync);
+ start = u64_stats_fetch_begin_irq(&r_vec->rx_sync);
data[0] = r_vec->rx_pkts;
data[1] = r_vec->rx_bytes;
data[2] = r_vec->rx_drops;
- } while (u64_stats_fetch_retry(&r_vec->rx_sync, start));
+ } while (u64_stats_fetch_retry_irq(&r_vec->rx_sync, start));
stats->rx_packets += data[0];
stats->rx_bytes += data[1];
stats->rx_dropped += data[2];
do {
- start = u64_stats_fetch_begin(&r_vec->tx_sync);
+ start = u64_stats_fetch_begin_irq(&r_vec->tx_sync);
data[0] = r_vec->tx_pkts;
data[1] = r_vec->tx_bytes;
data[2] = r_vec->tx_errors;
- } while (u64_stats_fetch_retry(&r_vec->tx_sync, start));
+ } while (u64_stats_fetch_retry_irq(&r_vec->tx_sync, start));
stats->tx_packets += data[0];
stats->tx_bytes += data[1];
stats->tx_errors += data[2];
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index bfcd90f..d4136d3 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -498,7 +498,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
unsigned int start;
do {
- start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync);
+ start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].rx_sync);
data[0] = nn->r_vecs[i].rx_pkts;
tmp[0] = nn->r_vecs[i].hw_csum_rx_ok;
tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok;
@@ -506,10 +506,10 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
tmp[3] = nn->r_vecs[i].hw_csum_rx_error;
tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail;
tmp[5] = nn->r_vecs[i].hw_tls_rx;
- } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start));
+ } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].rx_sync, start));
do {
- start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync);
+ start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].tx_sync);
data[1] = nn->r_vecs[i].tx_pkts;
data[2] = nn->r_vecs[i].tx_busy;
tmp[6] = nn->r_vecs[i].hw_csum_tx;
@@ -519,7 +519,7 @@ static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
tmp[10] = nn->r_vecs[i].hw_tls_tx;
tmp[11] = nn->r_vecs[i].tls_tx_fallback;
tmp[12] = nn->r_vecs[i].tls_tx_no_fallback;
- } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start));
+ } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].tx_sync, start));
data += NN_RVEC_PER_Q_STATS;
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index ad6dbf01..4fb0638 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -67,10 +67,10 @@ static int nsim_change_mtu(struct net_device *dev, int new_mtu)
unsigned int start;
do {
- start = u64_stats_fetch_begin(&ns->syncp);
+ start = u64_stats_fetch_begin_irq(&ns->syncp);
stats->tx_bytes = ns->tx_bytes;
stats->tx_packets = ns->tx_packets;
- } while (u64_stats_fetch_retry(&ns->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&ns->syncp, start));
}
static int
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 461c037..cee39ae 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2175,9 +2175,9 @@ static inline u64 sta_get_tidstats_msdu(struct ieee80211_sta_rx_stats *rxstats,
u64 value;
do {
- start = u64_stats_fetch_begin(&rxstats->syncp);
+ start = u64_stats_fetch_begin_irq(&rxstats->syncp);
value = rxstats->msdu[tid];
- } while (u64_stats_fetch_retry(&rxstats->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
return value;
}
@@ -2241,9 +2241,9 @@ static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats)
u64 value;
do {
- start = u64_stats_fetch_begin(&rxstats->syncp);
+ start = u64_stats_fetch_begin_irq(&rxstats->syncp);
value = rxstats->bytes;
- } while (u64_stats_fetch_retry(&rxstats->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
return value;
}
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 9c047c1..7239814 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1078,9 +1078,9 @@ static void mpls_get_stats(struct mpls_dev *mdev,
p = per_cpu_ptr(mdev->stats, i);
do {
- start = u64_stats_fetch_begin(&p->syncp);
+ start = u64_stats_fetch_begin_irq(&p->syncp);
local = p->stats;
- } while (u64_stats_fetch_retry(&p->syncp, start));
+ } while (u64_stats_fetch_retry_irq(&p->syncp, start));
stats->rx_packets += local.rx_packets;
stats->rx_bytes += local.rx_bytes;
--
1.8.3.1
1
2
From: Matthias May <matthias.may(a)westermo.com>
stable inclusion
from stable-v5.10.138
commit 38b83883ce4e4efe8ff0a727192219cac2668d42
category: bugfix
bugzilla: 188217
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
-------------------------------------------------
commit ca2bb69514a8bc7f83914122f0d596371352416c upstream.
According to Guillaume Nault RT_TOS should never be used for IPv6.
Quote:
RT_TOS() is an old macro used to interprete IPv4 TOS as described in
the obsolete RFC 1349. It's conceptually wrong to use it even in IPv4
code, although, given the current state of the code, most of the
existing calls have no consequence.
But using RT_TOS() in IPv6 code is always a bug: IPv6 never had a "TOS"
field to be interpreted the RFC 1349 way. There's no historical
compatibility to worry about.
Fixes: 3a56f86f1be6 ("geneve: handle ipv6 priority like ipv4 tos")
Acked-by: Guillaume Nault <gnault(a)redhat.com>
Signed-off-by: Matthias May <matthias.may(a)westermo.com>
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
(cherry picked from commit 38b83883ce4e4efe8ff0a727192219cac2668d42)
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
---
drivers/net/geneve.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 5ddb2db..ba9947d 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -850,8 +850,7 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
use_cache = false;
}
- fl6->flowlabel = ip6_make_flowinfo(RT_TOS(prio),
- info->key.label);
+ fl6->flowlabel = ip6_make_flowinfo(prio, info->key.label);
dst_cache = (struct dst_cache *)&info->dst_cache;
if (use_cache) {
dst = dst_cache_get_ip6(dst_cache, &fl6->saddr);
--
1.8.3.1
2
7

01 Feb '23
CONFIG_EFI_ZBOOT is introduced to openEuler 22.03 LTS SP1 by this
commit for loongarch and enabled by default:
e46780727555("efi/libstub: implement generic EFI zboot").
However, if is enabled, the compiled version cannot be booted on
openEuler 22.03 LTS. So, disable it on this version.
Signed-off-by: Xie XiuQi <xiexiuqi(a)huawei.com>
---
arch/arm64/configs/openeuler_defconfig | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index fbb71f7520a8..63f2adbbc778 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -15,18 +15,6 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_BUILD_SALT=""
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_XZ=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_HAVE_KERNEL_LZ4=y
-CONFIG_HAVE_KERNEL_ZSTD=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_LZMA is not set
-# CONFIG_KERNEL_XZ is not set
-# CONFIG_KERNEL_LZO is not set
-# CONFIG_KERNEL_LZ4 is not set
-# CONFIG_KERNEL_ZSTD is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SYSVIPC=y
@@ -2008,7 +1996,7 @@ CONFIG_EFI_SOFT_RESERVE=y
CONFIG_EFI_PARAMS_FROM_FDT=y
CONFIG_EFI_RUNTIME_WRAPPERS=y
CONFIG_EFI_GENERIC_STUB=y
-CONFIG_EFI_ZBOOT=y
+# CONFIG_EFI_ZBOOT is not set
CONFIG_EFI_ARMSTUB_DTB_LOADER=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
--
2.33.0
1
0

[PATCH openEuler-5.10] Add relationship graph of openEuler kernel branches
by Zheng Zengkai 01 Feb '23
by Zheng Zengkai 01 Feb '23
01 Feb '23
openEuler inclusion
category: doc
bugzilla: https://gitee.com/openeuler/kernel/issues/I6CAZ5
-----------------------------
Newcomers may get confused about the relationship of openEuler kernel
branches, so add relationship graph of openEuler kernel branches to
README in openEuler kernel master branch.
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
README_openEuler | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 README_openEuler
diff --git a/README_openEuler b/README_openEuler
new file mode 100644
index 000000000000..7ec06f5b2538
--- /dev/null
+++ b/README_openEuler
@@ -0,0 +1,45 @@
+README for openEuler kernel branches
+
+Relationship of openEuler kernel 4.19 branches:
+
+------------------------------------------------------------------> Linux 4.19.y
+ |
+ | tag: v4.19.13
+ |
+ -----------------------------------------------------------> openEuler-1.0-LTS
+
+Relationship of openEuler kernel 5.10 branches:
+
+------------------------------------------------------------------> Linux 5.10.y
+ |
+ | tag: v5.10
+ |
+ --------------------------------------------------------------------> OLK-5.10
+ | | | | |
+ | tag: 5.10.0-4.0.0 |
+ | | | | |
+ ------^-----^-----^-----^--------------> openEuler-21.03(Innovative version)
+ | | | |
+ | tag: 5.10.0-5.0.0
+ | | | |
+ ------^-----^-----^--------------> openEuler-21.09(Innovative version)
+ | | |
+ | tag: 5.10.0-60.0.0
+ | | |
+ ------^-----^------------------------------> openEuler-22.03-LTS
+ | |
+ | tag: 5.10.0-106.0.0
+ | |
+ ------^--------------> openEuler-22.09(Innovative version)
+ |
+ | tag: 5.10.0-136.0.0
+ |
+ ---------------------------> openEuler-22.03-LTS-SP1
+
+Relationship of openEuler kernel 6.x branches:
+
+-------------------------------------------------------------------> Linux 6.1.y
+ |
+ | tag: v6.1
+ |
+ -----------------------------------------------> devel-6.1(Innovative version)
--
2.20.1
1
0

[PATCH openEuler-5.10-LTS-SP1 01/25] x86/nospec: Unwreck the RSB stuffing
by Jialin Zhang 31 Jan '23
by Jialin Zhang 31 Jan '23
31 Jan '23
From: Peter Zijlstra <peterz(a)infradead.org>
stable inclusion
from stable-v5.10.141
commit adee8f3082b01e5dab620d651e3ec75f57c0c855
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I685FC
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 4e3aa9238277597c6c7624f302d81a7b568b6f2d upstream.
Commit 2b1299322016 ("x86/speculation: Add RSB VM Exit protections")
made a right mess of the RSB stuffing, rewrite the whole thing to not
suck.
Thanks to Andrew for the enlightening comment about Post-Barrier RSB
things so we can make this code less magical.
Cc: stable(a)vger.kernel.org
Signed-off-by: Peter Zijlstra (Intel) <peterz(a)infradead.org>
Link: https://lkml.kernel.org/r/YvuNdDWoUZSBjYcm@worktop.programming.kicks-ass.net
[bwh: Backported to 5.10: adjust context]
Signed-off-by: Ben Hutchings <benh(a)debian.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
Reviewed-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
arch/x86/include/asm/nospec-branch.h | 80 ++++++++++++++--------------
1 file changed, 39 insertions(+), 41 deletions(-)
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index a406ca726f46..e847b4afe7ac 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -35,33 +35,44 @@
#define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */
/*
+ * Common helper for __FILL_RETURN_BUFFER and __FILL_ONE_RETURN.
+ */
+#define __FILL_RETURN_SLOT \
+ ANNOTATE_INTRA_FUNCTION_CALL; \
+ call 772f; \
+ int3; \
+772:
+
+/*
+ * Stuff the entire RSB.
+ *
* Google experimented with loop-unrolling and this turned out to be
* the optimal version — two calls, each with their own speculation
* trap should their return address end up getting used, in a loop.
*/
-#define __FILL_RETURN_BUFFER(reg, nr, sp) \
- mov $(nr/2), reg; \
-771: \
- ANNOTATE_INTRA_FUNCTION_CALL; \
- call 772f; \
-773: /* speculation trap */ \
- UNWIND_HINT_EMPTY; \
- pause; \
- lfence; \
- jmp 773b; \
-772: \
- ANNOTATE_INTRA_FUNCTION_CALL; \
- call 774f; \
-775: /* speculation trap */ \
- UNWIND_HINT_EMPTY; \
- pause; \
- lfence; \
- jmp 775b; \
-774: \
- add $(BITS_PER_LONG/8) * 2, sp; \
- dec reg; \
- jnz 771b; \
- /* barrier for jnz misprediction */ \
+#define __FILL_RETURN_BUFFER(reg, nr) \
+ mov $(nr/2), reg; \
+771: \
+ __FILL_RETURN_SLOT \
+ __FILL_RETURN_SLOT \
+ add $(BITS_PER_LONG/8) * 2, %_ASM_SP; \
+ dec reg; \
+ jnz 771b; \
+ /* barrier for jnz misprediction */ \
+ lfence;
+
+/*
+ * Stuff a single RSB slot.
+ *
+ * To mitigate Post-Barrier RSB speculation, one CALL instruction must be
+ * forced to retire before letting a RET instruction execute.
+ *
+ * On PBRSB-vulnerable CPUs, it is not safe for a RET to be executed
+ * before this point.
+ */
+#define __FILL_ONE_RETURN \
+ __FILL_RETURN_SLOT \
+ add $(BITS_PER_LONG/8), %_ASM_SP; \
lfence;
#ifdef __ASSEMBLY__
@@ -120,28 +131,15 @@
#endif
.endm
-.macro ISSUE_UNBALANCED_RET_GUARD
- ANNOTATE_INTRA_FUNCTION_CALL
- call .Lunbalanced_ret_guard_\@
- int3
-.Lunbalanced_ret_guard_\@:
- add $(BITS_PER_LONG/8), %_ASM_SP
- lfence
-.endm
-
/*
* A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
* monstrosity above, manually.
*/
-.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2
-.ifb \ftr2
- ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr
-.else
- ALTERNATIVE_2 "jmp .Lskip_rsb_\@", "", \ftr, "jmp .Lunbalanced_\@", \ftr2
-.endif
- __FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)
-.Lunbalanced_\@:
- ISSUE_UNBALANCED_RET_GUARD
+.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2=ALT_NOT(X86_FEATURE_ALWAYS)
+ ALTERNATIVE_2 "jmp .Lskip_rsb_\@", \
+ __stringify(__FILL_RETURN_BUFFER(\reg,\nr)), \ftr, \
+ __stringify(__FILL_ONE_RETURN), \ftr2
+
.Lskip_rsb_\@:
.endm
--
2.25.1
1
24

[PATCH openEuler-5.10-LTS 01/11] rndis_wlan: Prevent buffer overflow in rndis_query_oid
by Jialin Zhang 31 Jan '23
by Jialin Zhang 31 Jan '23
31 Jan '23
From: Szymon Heidrich <szymon.heidrich(a)gmail.com>
maillist inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6AQJP
CVE: CVE-2023-23559
Reference: https://patchwork.kernel.org/project/linux-wireless/patch/20230111175031.70…
-------------------------------
Since resplen and respoffs are signed integers sufficiently
large values of unsigned int len and offset members of RNDIS
response will result in negative values of prior variables.
This may be utilized to bypass implemented security checks
to either extract memory contents by manipulating offset or
overflow the data buffer via memcpy by manipulating both
offset and len.
Additionally assure that sum of resplen and respoffs does not
overflow so buffer boundaries are kept.
Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
Signed-off-by: Szymon Heidrich <szymon.heidrich(a)gmail.com>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 75b5d545b49e..dc076d844868 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -694,8 +694,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
struct rndis_query *get;
struct rndis_query_c *get_c;
} u;
- int ret, buflen;
- int resplen, respoffs, copylen;
+ int ret;
+ size_t buflen, resplen, respoffs, copylen;
buflen = *len + sizeof(*u.get);
if (buflen < CONTROL_BUFFER_SIZE)
@@ -730,22 +730,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
if (respoffs > buflen) {
/* Device returned data offset outside buffer, error. */
- netdev_dbg(dev->net, "%s(%s): received invalid "
- "data offset: %d > %d\n", __func__,
- oid_to_string(oid), respoffs, buflen);
+ netdev_dbg(dev->net,
+ "%s(%s): received invalid data offset: %zu > %zu\n",
+ __func__, oid_to_string(oid), respoffs, buflen);
ret = -EINVAL;
goto exit_unlock;
}
- if ((resplen + respoffs) > buflen) {
- /* Device would have returned more data if buffer would
- * have been big enough. Copy just the bits that we got.
- */
- copylen = buflen - respoffs;
- } else {
- copylen = resplen;
- }
+ copylen = min(resplen, buflen - respoffs);
if (copylen > *len)
copylen = *len;
--
2.25.1
1
10

[PATCH openEuler-5.10-LTS-SP1 01/11] mm/vmpressure: fix data-race with memcg->socket_pressure
by Jialin Zhang 31 Jan '23
by Jialin Zhang 31 Jan '23
31 Jan '23
From: Yuanzheng Song <songyuanzheng(a)huawei.com>
mainline inclusion
from mainline-v5.16-rc1
commit 7e6ec49c18988f1b8dab0677271dafde5f8d9a43
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6AW65
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
When reading memcg->socket_pressure in mem_cgroup_under_socket_pressure()
and writing memcg->socket_pressure in vmpressure() at the same time, the
following data-race occurs:
BUG: KCSAN: data-race in __sk_mem_reduce_allocated / vmpressure
write to 0xffff8881286f4938 of 8 bytes by task 24550 on cpu 3:
vmpressure+0x218/0x230 mm/vmpressure.c:307
shrink_node_memcgs+0x2b9/0x410 mm/vmscan.c:2658
shrink_node+0x9d2/0x11d0 mm/vmscan.c:2769
shrink_zones+0x29f/0x470 mm/vmscan.c:2972
do_try_to_free_pages+0x193/0x6e0 mm/vmscan.c:3027
try_to_free_mem_cgroup_pages+0x1c0/0x3f0 mm/vmscan.c:3345
reclaim_high mm/memcontrol.c:2440 [inline]
mem_cgroup_handle_over_high+0x18b/0x4d0 mm/memcontrol.c:2624
tracehook_notify_resume include/linux/tracehook.h:197 [inline]
exit_to_user_mode_loop kernel/entry/common.c:164 [inline]
exit_to_user_mode_prepare+0x110/0x170 kernel/entry/common.c:191
syscall_exit_to_user_mode+0x16/0x30 kernel/entry/common.c:266
ret_from_fork+0x15/0x30 arch/x86/entry/entry_64.S:289
read to 0xffff8881286f4938 of 8 bytes by interrupt on cpu 1:
mem_cgroup_under_socket_pressure include/linux/memcontrol.h:1483 [inline]
sk_under_memory_pressure include/net/sock.h:1314 [inline]
__sk_mem_reduce_allocated+0x1d2/0x270 net/core/sock.c:2696
__sk_mem_reclaim+0x44/0x50 net/core/sock.c:2711
sk_mem_reclaim include/net/sock.h:1490 [inline]
......
net_rx_action+0x17a/0x480 net/core/dev.c:6864
__do_softirq+0x12c/0x2af kernel/softirq.c:298
run_ksoftirqd+0x13/0x20 kernel/softirq.c:653
smpboot_thread_fn+0x33f/0x510 kernel/smpboot.c:165
kthread+0x1fc/0x220 kernel/kthread.c:292
ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:296
Fix it by using READ_ONCE() and WRITE_ONCE() to read and write
memcg->socket_pressure.
Link: https://lkml.kernel.org/r/20211025082843.671690-1-songyuanzheng@huawei.com
Signed-off-by: Yuanzheng Song <songyuanzheng(a)huawei.com>
Reviewed-by: Muchun Song <songmuchun(a)bytedance.com>
Cc: Shakeel Butt <shakeelb(a)google.com>
Cc: Roman Gushchin <guro(a)fb.com>
Cc: Johannes Weiner <hannes(a)cmpxchg.org>
Cc: Michal Hocko <mhocko(a)suse.com>
Cc: Matthew Wilcox (Oracle) <willy(a)infradead.org>
Cc: Alex Shi <alexs(a)kernel.org>
Cc: Wei Yang <richard.weiyang(a)gmail.com>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Cai Xinchen <caixinchen1(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
include/linux/memcontrol.h | 2 +-
mm/vmpressure.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index abb2476bd282..89e4f01c5710 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -1921,7 +1921,7 @@ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && memcg->tcpmem_pressure)
return true;
do {
- if (time_before(jiffies, memcg->socket_pressure))
+ if (time_before(jiffies, READ_ONCE(memcg->socket_pressure)))
return true;
} while ((memcg = parent_mem_cgroup(memcg)));
return false;
diff --git a/mm/vmpressure.c b/mm/vmpressure.c
index d69019fc3789..c6a7eca666f6 100644
--- a/mm/vmpressure.c
+++ b/mm/vmpressure.c
@@ -304,7 +304,7 @@ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree,
* asserted for a second in which subsequent
* pressure events can occur.
*/
- memcg->socket_pressure = jiffies + HZ;
+ WRITE_ONCE(memcg->socket_pressure, jiffies + HZ);
}
}
}
--
2.25.1
1
10

30 Jan '23
From: Neel Natu <neelnatu(a)google.com>
mainline inclusion
from mainline-v6.1-rc1
commit 9847f21225c4eb0b843cb2b72ed83b32edb1e6f2
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6AXHU
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/…
-----------------------------------------
An argument list like "arg=val arg2 \"" can trigger a page fault if the
page pointed by 'args[0xffffffff]' is not mapped and potential memory
corruption otherwise (unlikely but possible if the bogus address is mapped
and contents happen to match the ascii value of the quote character).
The fix is to ensure that we load 'args[i-1]' only when (i > 0).
Prior to this commit the following command would trigger an
unhandled page fault in the kernel:
root@(none):/linus/fs/fat# insmod ./fat.ko "foo=bar \""
[ 33.870507] BUG: unable to handle page fault for address: ffff888204252608
[ 33.872180] #PF: supervisor read access in kernel mode
[ 33.873414] #PF: error_code(0x0000) - not-present page
[ 33.874650] PGD 4401067 P4D 4401067 PUD 0
[ 33.875321] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC PTI
[ 33.876113] CPU: 16 PID: 399 Comm: insmod Not tainted 5.19.0-dbg-DEV #4
[ 33.877193] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-debian-1.16.0-4 04/01/2014
[ 33.878739] RIP: 0010:next_arg+0xd1/0x110
[ 33.879399] Code: 22 75 1d 41 c6 04 01 00 41 80 f8 22 74 18 eb 35 4c 89 0e 45 31 d2 4c 89 cf 48 c7 02 00 00 00 00 41 80 f8 22 75 1f 41 8d 42 ff <41> 80 3c 01 22 75 14 41 c6 04 01 00 eb 0d 48 c7 02 00 00 00 00 41
[ 33.882338] RSP: 0018:ffffc90001253d08 EFLAGS: 00010246
[ 33.883174] RAX: 00000000ffffffff RBX: ffff888104252608 RCX: 0fc317bba1c1dd00
[ 33.884311] RDX: ffffc90001253d40 RSI: ffffc90001253d48 RDI: ffff888104252609
[ 33.885450] RBP: ffffc90001253d10 R08: 0000000000000022 R09: ffff888104252609
[ 33.886595] R10: 0000000000000000 R11: ffffffff82c7ff20 R12: 0000000000000282
[ 33.887748] R13: 00000000ffff8000 R14: 0000000000000000 R15: 0000000000007fff
[ 33.888887] FS: 00007f04ec7432c0(0000) GS:ffff88813d300000(0000) knlGS:0000000000000000
[ 33.890183] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 33.891111] CR2: ffff888204252608 CR3: 0000000100f36005 CR4: 0000000000170ee0
[ 33.892241] Call Trace:
[ 33.892641] <TASK>
[ 33.892989] parse_args+0x8f/0x220
[ 33.893538] load_module+0x138b/0x15a0
[ 33.894149] ? prepare_coming_module+0x50/0x50
[ 33.894879] ? kernel_read_file_from_fd+0x5f/0x90
[ 33.895639] __se_sys_finit_module+0xce/0x130
[ 33.896342] __x64_sys_finit_module+0x1d/0x20
[ 33.897042] do_syscall_64+0x44/0xa0
[ 33.897622] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[ 33.898434] RIP: 0033:0x7f04ec85ef79
[ 33.899009] Code: 48 8d 3d da db 0d 00 0f 05 eb a5 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c7 9e 0d 00 f7 d8 64 89 01 48
[ 33.901912] RSP: 002b:00007fffae81bfe8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[ 33.903081] RAX: ffffffffffffffda RBX: 0000559c5f1d2640 RCX: 00007f04ec85ef79
[ 33.904191] RDX: 0000000000000000 RSI: 0000559c5f1d12a0 RDI: 0000000000000003
[ 33.905304] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
[ 33.906421] R10: 0000000000000003 R11: 0000000000000246 R12: 0000559c5f1d12a0
[ 33.907526] R13: 0000000000000000 R14: 0000559c5f1d25f0 R15: 0000559c5f1d12a0
[ 33.908631] </TASK>
[ 33.908986] Modules linked in: fat(+) [last unloaded: fat]
[ 33.909843] CR2: ffff888204252608
[ 33.910375] ---[ end trace 0000000000000000 ]---
[ 33.911172] RIP: 0010:next_arg+0xd1/0x110
[ 33.911796] Code: 22 75 1d 41 c6 04 01 00 41 80 f8 22 74 18 eb 35 4c 89 0e 45 31 d2 4c 89 cf 48 c7 02 00 00 00 00 41 80 f8 22 75 1f 41 8d 42 ff <41> 80 3c 01 22 75 14 41 c6 04 01 00 eb 0d 48 c7 02 00 00 00 00 41
[ 33.914643] RSP: 0018:ffffc90001253d08 EFLAGS: 00010246
[ 33.915446] RAX: 00000000ffffffff RBX: ffff888104252608 RCX: 0fc317bba1c1dd00
[ 33.916544] RDX: ffffc90001253d40 RSI: ffffc90001253d48 RDI: ffff888104252609
[ 33.917636] RBP: ffffc90001253d10 R08: 0000000000000022 R09: ffff888104252609
[ 33.918727] R10: 0000000000000000 R11: ffffffff82c7ff20 R12: 0000000000000282
[ 33.919821] R13: 00000000ffff8000 R14: 0000000000000000 R15: 0000000000007fff
[ 33.920908] FS: 00007f04ec7432c0(0000) GS:ffff88813d300000(0000) knlGS:0000000000000000
[ 33.922125] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 33.923017] CR2: ffff888204252608 CR3: 0000000100f36005 CR4: 0000000000170ee0
[ 33.924098] Kernel panic - not syncing: Fatal exception
[ 33.925776] Kernel Offset: disabled
[ 33.926347] Rebooting in 10 seconds..
Link: https://lkml.kernel.org/r/20220728232434.1666488-1-neelnatu@google.com
Signed-off-by: Neel Natu <neelnatu(a)google.com>
Reviewed-by: Eric Dumazet <edumazet(a)google.com>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Zhang Zekun <zhangzekun11(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
lib/cmdline.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/cmdline.c b/lib/cmdline.c
index 171c19b6888e..f32d76261cc1 100644
--- a/lib/cmdline.c
+++ b/lib/cmdline.c
@@ -233,7 +233,7 @@ char *next_arg(char *args, char **param, char **val)
args[i-1] = '\0';
}
}
- if (quoted && args[i-1] == '"')
+ if (quoted && i > 0 && args[i-1] == '"')
args[i-1] = '\0';
if (args[i]) {
--
2.25.1
1
2

[PATCH openEuler-1.0-LTS 1/3] net: sched: atm: dont intepret cls results when asked to drop
by Yongqiang Liu 30 Jan '23
by Yongqiang Liu 30 Jan '23
30 Jan '23
From: Jamal Hadi Salim <jhs(a)mojatatu.com>
stable inclusion
from stable-v4.19.269
commit 5374c455ebe6102e3d5f1842c6d8ff72b3ca659f
category: bugfix
bugzilla: 188250, https://gitee.com/src-openeuler/kernel/issues/I6AQG9
CVE: CVE-2023-23455
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit a2965c7be0522eaa18808684b7b82b248515511b ]
If asked to drop a packet via TC_ACT_SHOT it is unsafe to assume
res.class contains a valid pointer
Fixes: b0188d4dbe5f ("[NET_SCHED]: sch_atm: Lindent")
Signed-off-by: Jamal Hadi Salim <jhs(a)mojatatu.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
net/sched/sch_atm.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 91bd5c839303..a3084a12239e 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -394,10 +394,13 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
result = tcf_classify(skb, fl, &res, true);
if (result < 0)
continue;
+ if (result == TC_ACT_SHOT)
+ goto done;
+
flow = (struct atm_flow_data *)res.class;
if (!flow)
flow = lookup_flow(sch, res.classid);
- goto done;
+ goto drop;
}
}
flow = NULL;
--
2.25.1
1
2

[PATCH openEuler-1.0-LTS 1/2] net: sched: cbq: dont intepret cls results when asked to drop
by Yongqiang Liu 29 Jan '23
by Yongqiang Liu 29 Jan '23
29 Jan '23
From: Jamal Hadi Salim <jhs(a)mojatatu.com>
mainline inclusion
from mainline-v6.2-rc3
commit caa4b35b4317d5147b3ab0fbdc9c075c7d2e9c12
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6AQIL
CVE: CVE-2023-23454
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
If asked to drop a packet via TC_ACT_SHOT it is unsafe to assume that
res.class contains a valid pointer
Sample splat reported by Kyle Zeng
[ 5.405624] 0: reclassify loop, rule prio 0, protocol 800
[ 5.406326] ==================================================================
[ 5.407240] BUG: KASAN: slab-out-of-bounds in cbq_enqueue+0x54b/0xea0
[ 5.407987] Read of size 1 at addr ffff88800e3122aa by task poc/299
[ 5.408731]
[ 5.408897] CPU: 0 PID: 299 Comm: poc Not tainted 5.10.155+ #15
[ 5.409516] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS 1.15.0-1 04/01/2014
[ 5.410439] Call Trace:
[ 5.410764] dump_stack+0x87/0xcd
[ 5.411153] print_address_description+0x7a/0x6b0
[ 5.411687] ? vprintk_func+0xb9/0xc0
[ 5.411905] ? printk+0x76/0x96
[ 5.412110] ? cbq_enqueue+0x54b/0xea0
[ 5.412323] kasan_report+0x17d/0x220
[ 5.412591] ? cbq_enqueue+0x54b/0xea0
[ 5.412803] __asan_report_load1_noabort+0x10/0x20
[ 5.413119] cbq_enqueue+0x54b/0xea0
[ 5.413400] ? __kasan_check_write+0x10/0x20
[ 5.413679] __dev_queue_xmit+0x9c0/0x1db0
[ 5.413922] dev_queue_xmit+0xc/0x10
[ 5.414136] ip_finish_output2+0x8bc/0xcd0
[ 5.414436] __ip_finish_output+0x472/0x7a0
[ 5.414692] ip_finish_output+0x5c/0x190
[ 5.414940] ip_output+0x2d8/0x3c0
[ 5.415150] ? ip_mc_finish_output+0x320/0x320
[ 5.415429] __ip_queue_xmit+0x753/0x1760
[ 5.415664] ip_queue_xmit+0x47/0x60
[ 5.415874] __tcp_transmit_skb+0x1ef9/0x34c0
[ 5.416129] tcp_connect+0x1f5e/0x4cb0
[ 5.416347] tcp_v4_connect+0xc8d/0x18c0
[ 5.416577] __inet_stream_connect+0x1ae/0xb40
[ 5.416836] ? local_bh_enable+0x11/0x20
[ 5.417066] ? lock_sock_nested+0x175/0x1d0
[ 5.417309] inet_stream_connect+0x5d/0x90
[ 5.417548] ? __inet_stream_connect+0xb40/0xb40
[ 5.417817] __sys_connect+0x260/0x2b0
[ 5.418037] __x64_sys_connect+0x76/0x80
[ 5.418267] do_syscall_64+0x31/0x50
[ 5.418477] entry_SYSCALL_64_after_hwframe+0x61/0xc6
[ 5.418770] RIP: 0033:0x473bb7
[ 5.418952] Code: 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00
00 00 90 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2a 00 00
00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 18 89 54 24 0c 48 89 34
24 89
[ 5.420046] RSP: 002b:00007fffd20eb0f8 EFLAGS: 00000246 ORIG_RAX:
000000000000002a
[ 5.420472] RAX: ffffffffffffffda RBX: 00007fffd20eb578 RCX: 0000000000473bb7
[ 5.420872] RDX: 0000000000000010 RSI: 00007fffd20eb110 RDI: 0000000000000007
[ 5.421271] RBP: 00007fffd20eb150 R08: 0000000000000001 R09: 0000000000000004
[ 5.421671] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
[ 5.422071] R13: 00007fffd20eb568 R14: 00000000004fc740 R15: 0000000000000002
[ 5.422471]
[ 5.422562] Allocated by task 299:
[ 5.422782] __kasan_kmalloc+0x12d/0x160
[ 5.423007] kasan_kmalloc+0x5/0x10
[ 5.423208] kmem_cache_alloc_trace+0x201/0x2e0
[ 5.423492] tcf_proto_create+0x65/0x290
[ 5.423721] tc_new_tfilter+0x137e/0x1830
[ 5.423957] rtnetlink_rcv_msg+0x730/0x9f0
[ 5.424197] netlink_rcv_skb+0x166/0x300
[ 5.424428] rtnetlink_rcv+0x11/0x20
[ 5.424639] netlink_unicast+0x673/0x860
[ 5.424870] netlink_sendmsg+0x6af/0x9f0
[ 5.425100] __sys_sendto+0x58d/0x5a0
[ 5.425315] __x64_sys_sendto+0xda/0xf0
[ 5.425539] do_syscall_64+0x31/0x50
[ 5.425764] entry_SYSCALL_64_after_hwframe+0x61/0xc6
[ 5.426065]
[ 5.426157] The buggy address belongs to the object at ffff88800e312200
[ 5.426157] which belongs to the cache kmalloc-128 of size 128
[ 5.426955] The buggy address is located 42 bytes to the right of
[ 5.426955] 128-byte region [ffff88800e312200, ffff88800e312280)
[ 5.427688] The buggy address belongs to the page:
[ 5.427992] page:000000009875fabc refcount:1 mapcount:0
mapping:0000000000000000 index:0x0 pfn:0xe312
[ 5.428562] flags: 0x100000000000200(slab)
[ 5.428812] raw: 0100000000000200 dead000000000100 dead000000000122
ffff888007843680
[ 5.429325] raw: 0000000000000000 0000000000100010 00000001ffffffff
ffff88800e312401
[ 5.429875] page dumped because: kasan: bad access detected
[ 5.430214] page->mem_cgroup:ffff88800e312401
[ 5.430471]
[ 5.430564] Memory state around the buggy address:
[ 5.430846] ffff88800e312180: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 5.431267] ffff88800e312200: 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 fc
[ 5.431705] >ffff88800e312280: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 5.432123] ^
[ 5.432391] ffff88800e312300: 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 fc
[ 5.432810] ffff88800e312380: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 5.433229] ==================================================================
[ 5.433648] Disabling lock debugging due to kernel taint
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Kyle Zeng <zengyhkyle(a)gmail.com>
Signed-off-by: Jamal Hadi Salim <jhs(a)mojatatu.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Conflicts:
net/sched/sch_cbq.c
Signed-off-by: Zhengchao Shao <shaozhengchao(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Liu Jian <liujian56(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
net/sched/sch_cbq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index bc62e1b24653..dd8e83aac042 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -236,6 +236,8 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
result = tcf_classify(skb, fl, &res, true);
if (!fl || result < 0)
goto fallback;
+ if (result == TC_ACT_SHOT)
+ return NULL;
cl = (void *)res.class;
if (!cl) {
@@ -256,8 +258,6 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
case TC_ACT_TRAP:
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
/* fall through */
- case TC_ACT_SHOT:
- return NULL;
case TC_ACT_RECLASSIFY:
return cbq_reclassify(skb, cl);
}
--
2.25.1
1
1

18 Jan '23
From: Huajingjing <huajingjing1(a)huawei.com>
driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I67J42
CVE: NA
-------------------------------------------------
The BMA software is a system management software offered by Huawei.
It supports the status monitoring, performance monitoring and
event monitoring of various components, including server CPUs,
memory hard disks, NICs, IB cards, PCIe cards,
RAID controller cards and optical modules.
In this version, the system resets due to the BMA spin lock
when the memory usage is too high, the vulnerability has been rectified.
Signed-off-by: Hua Jingjing <huajingjingjing1(a)huawei.com>
Reviewed-by: Chen Jiesong <chenjiesong(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
.../ethernet/huawei/bma/cdev_drv/bma_cdev.c | 2 +-
.../huawei/bma/edma_drv/bma_devintf.c | 110 +++++++++++-------
.../ethernet/huawei/bma/edma_drv/bma_pci.h | 2 +-
.../huawei/bma/kbox_drv/kbox_include.h | 2 +-
.../ethernet/huawei/bma/kbox_drv/kbox_panic.c | 4 +-
.../huawei/bma/kbox_drv/kbox_printk.c | 4 +-
.../huawei/bma/kbox_drv/kbox_ram_op.c | 2 +-
.../ethernet/huawei/bma/veth_drv/veth_hb.c | 7 +-
.../ethernet/huawei/bma/veth_drv/veth_hb.h | 2 +-
9 files changed, 81 insertions(+), 54 deletions(-)
diff --git a/drivers/net/ethernet/huawei/bma/cdev_drv/bma_cdev.c b/drivers/net/ethernet/huawei/bma/cdev_drv/bma_cdev.c
index 0348a83005d6..9468a5a0c768 100644
--- a/drivers/net/ethernet/huawei/bma/cdev_drv/bma_cdev.c
+++ b/drivers/net/ethernet/huawei/bma/cdev_drv/bma_cdev.c
@@ -28,7 +28,7 @@
#ifdef DRV_VERSION
#define CDEV_VERSION MICRO_TO_STR(DRV_VERSION)
#else
-#define CDEV_VERSION "0.3.4"
+#define CDEV_VERSION "0.3.5"
#endif
#define CDEV_DEFAULT_NUM 4
diff --git a/drivers/net/ethernet/huawei/bma/edma_drv/bma_devintf.c b/drivers/net/ethernet/huawei/bma/edma_drv/bma_devintf.c
index 7817f58f8635..556130ab8a65 100644
--- a/drivers/net/ethernet/huawei/bma/edma_drv/bma_devintf.c
+++ b/drivers/net/ethernet/huawei/bma/edma_drv/bma_devintf.c
@@ -419,8 +419,10 @@ EXPORT_SYMBOL(bma_intf_int_to_bmc);
int bma_intf_is_link_ok(void)
{
- return (g_bma_dev->edma_host.statistics.remote_status ==
- REGISTERED) ? 1 : 0;
+ if ((&g_bma_dev->edma_host != NULL) &&
+ (g_bma_dev->edma_host.statistics.remote_status == REGISTERED))
+ return 1;
+ return 0;
}
EXPORT_SYMBOL(bma_intf_is_link_ok);
@@ -460,14 +462,10 @@ int bma_cdev_recv_msg(void *handle, char __user *data, size_t count)
}
EXPORT_SYMBOL_GPL(bma_cdev_recv_msg);
-int bma_cdev_add_msg(void *handle, const char __user *msg, size_t msg_len)
+static int check_cdev_add_msg_param(struct bma_priv_data_s *handle,
+const char __user *msg, size_t msg_len)
{
struct bma_priv_data_s *priv = NULL;
- struct edma_msg_hdr_s *hdr = NULL;
- unsigned long flags = 0;
- int total_len = 0;
- int ret = 0;
- struct edma_host_s *phost = &g_bma_dev->edma_host;
if (!handle || !msg || msg_len == 0) {
BMA_LOG(DLOG_DEBUG, "input NULL point!\n");
@@ -479,54 +477,80 @@ int bma_cdev_add_msg(void *handle, const char __user *msg, size_t msg_len)
return -EINVAL;
}
- priv = (struct bma_priv_data_s *)handle;
+ priv = handle;
if (priv->user.type >= TYPE_MAX) {
BMA_LOG(DLOG_DEBUG, "error type = %d\n", priv->user.type);
return -EFAULT;
}
- total_len = SIZE_OF_MSG_HDR + msg_len;
+
+ return 0;
+}
+
+static void edma_msg_hdr_init(struct edma_msg_hdr_s *hdr,
+ struct bma_priv_data_s *private_data,
+ char *msg_buf, size_t msg_len)
+{
+ hdr->type = private_data->user.type;
+ hdr->sub_type = private_data->user.sub_type;
+ hdr->user_id = private_data->user.user_id;
+ hdr->datalen = msg_len;
+ BMA_LOG(DLOG_DEBUG, "msg_len is %ld\n", msg_len);
+
+ memcpy(hdr->data, msg_buf, msg_len);
+}
+
+int bma_cdev_add_msg(void *handle, const char __user *msg, size_t msg_len)
+{
+ struct bma_priv_data_s *priv = NULL;
+ struct edma_msg_hdr_s *hdr = NULL;
+ unsigned long flags = 0;
+ unsigned int total_len = 0;
+ int ret = 0;
+ struct edma_host_s *phost = &g_bma_dev->edma_host;
+ char *msg_buf = NULL;
+
+ ret = check_cdev_add_msg_param(handle, msg, msg_len);
+ if (ret != 0)
+ return ret;
+
+ priv = (struct bma_priv_data_s *)handle;
+
+ total_len = (unsigned int)(SIZE_OF_MSG_HDR + msg_len);
+ if (phost->msg_send_write + total_len > HOST_MAX_SEND_MBX_LEN - SIZE_OF_MBX_HDR) {
+ BMA_LOG(DLOG_DEBUG, "msg lost,msg_send_write: %u,msg_len:%u,max_len: %d\n",
+ phost->msg_send_write, total_len, HOST_MAX_SEND_MBX_LEN);
+ return -ENOSPC;
+ }
+
+ msg_buf = (char *)kmalloc(msg_len, GFP_KERNEL);
+ if (!msg_buf) {
+ BMA_LOG(DLOG_ERROR, "malloc msg_buf failed\n");
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(msg_buf, msg, msg_len)) {
+ BMA_LOG(DLOG_ERROR, "copy_from_user error\n");
+ kfree(msg_buf);
+ return -EFAULT;
+ }
spin_lock_irqsave(&phost->send_msg_lock, flags);
- if (phost->msg_send_write + total_len <=
- HOST_MAX_SEND_MBX_LEN - SIZE_OF_MBX_HDR) {
- hdr = (struct edma_msg_hdr_s *)(phost->msg_send_buf +
- phost->msg_send_write);
- hdr->type = priv->user.type;
- hdr->sub_type = priv->user.sub_type;
- hdr->user_id = priv->user.user_id;
- hdr->datalen = msg_len;
- BMA_LOG(DLOG_DEBUG, "msg_len is %ld\n", msg_len);
-
- if (copy_from_user(hdr->data, msg, msg_len)) {
- BMA_LOG(DLOG_ERROR, "copy_from_user error\n");
- ret = -EFAULT;
- goto end;
- }
+ hdr = (struct edma_msg_hdr_s *)(phost->msg_send_buf + phost->msg_send_write);
+ edma_msg_hdr_init(hdr, priv, msg_buf, msg_len);
- phost->msg_send_write += total_len;
- phost->statistics.send_bytes += total_len;
- phost->statistics.send_pkgs++;
+ phost->msg_send_write += total_len;
+ phost->statistics.send_bytes += total_len;
+ phost->statistics.send_pkgs++;
#ifdef EDMA_TIMER
- (void)mod_timer(&phost->timer, jiffies_64);
+ (void)mod_timer(&phost->timer, jiffies_64);
#endif
- BMA_LOG(DLOG_DEBUG, "msg_send_write = %d\n",
- phost->msg_send_write);
-
- ret = msg_len;
- goto end;
- } else {
- BMA_LOG(DLOG_DEBUG,
- "msg lost,msg_send_write: %d,msg_len:%d,max_len: %d\n",
- phost->msg_send_write, total_len,
- HOST_MAX_SEND_MBX_LEN);
- ret = -ENOSPC;
- goto end;
- }
+ BMA_LOG(DLOG_DEBUG, "msg_send_write = %d\n", phost->msg_send_write);
-end:
+ ret = msg_len;
spin_unlock_irqrestore(&g_bma_dev->edma_host.send_msg_lock, flags);
+ kfree(msg_buf);
return ret;
}
EXPORT_SYMBOL_GPL(bma_cdev_add_msg);
diff --git a/drivers/net/ethernet/huawei/bma/edma_drv/bma_pci.h b/drivers/net/ethernet/huawei/bma/edma_drv/bma_pci.h
index 2851e583666a..b6a0d11704a2 100644
--- a/drivers/net/ethernet/huawei/bma/edma_drv/bma_pci.h
+++ b/drivers/net/ethernet/huawei/bma/edma_drv/bma_pci.h
@@ -71,7 +71,7 @@ struct bma_pci_dev_s {
#ifdef DRV_VERSION
#define BMA_VERSION MICRO_TO_STR(DRV_VERSION)
#else
-#define BMA_VERSION "0.3.4"
+#define BMA_VERSION "0.3.5"
#endif
#ifdef CONFIG_ARM64
diff --git a/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_include.h b/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_include.h
index ffadf3727734..b027306e52c1 100644
--- a/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_include.h
+++ b/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_include.h
@@ -23,7 +23,7 @@
#ifdef DRV_VERSION
#define KBOX_VERSION MICRO_TO_STR(DRV_VERSION)
#else
-#define KBOX_VERSION "0.3.4"
+#define KBOX_VERSION "0.3.5"
#endif
#define UNUSED(x) (x = x)
diff --git a/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_panic.c b/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_panic.c
index 0c17cd2bae49..2b142ae9bff6 100644
--- a/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_panic.c
+++ b/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_panic.c
@@ -135,7 +135,7 @@ int kbox_panic_init(void)
int ret = KBOX_TRUE;
g_panic_info_buf = kmalloc(SLOT_LENGTH, GFP_KERNEL);
- if (IS_ERR(g_panic_info_buf) || !g_panic_info_buf) {
+ if (!g_panic_info_buf) {
KBOX_MSG("kmalloc g_panic_info_buf fail!\n");
ret = -ENOMEM;
goto fail;
@@ -144,7 +144,7 @@ int kbox_panic_init(void)
memset(g_panic_info_buf, 0, SLOT_LENGTH);
g_panic_info_buf_tmp = kmalloc(SLOT_LENGTH, GFP_KERNEL);
- if (IS_ERR(g_panic_info_buf_tmp) || !g_panic_info_buf_tmp) {
+ if (!g_panic_info_buf_tmp) {
KBOX_MSG("kmalloc g_panic_info_buf_tmp fail!\n");
ret = -ENOMEM;
goto fail;
diff --git a/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_printk.c b/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_printk.c
index 3b04ba206108..630a1e16ea24 100644
--- a/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_printk.c
+++ b/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_printk.c
@@ -304,7 +304,7 @@ int kbox_printk_init(int kbox_proc_exist)
g_printk_info_buf = kmalloc(SECTION_PRINTK_LEN,
GFP_KERNEL);
- if (IS_ERR(g_printk_info_buf) || !g_printk_info_buf) {
+ if (!g_printk_info_buf) {
KBOX_MSG("kmalloc g_printk_info_buf fail!\n");
ret = -ENOMEM;
goto fail;
@@ -314,7 +314,7 @@ int kbox_printk_init(int kbox_proc_exist)
g_printk_info_buf_tmp = kmalloc(SECTION_PRINTK_LEN,
GFP_KERNEL);
- if (IS_ERR(g_printk_info_buf_tmp) || !g_printk_info_buf_tmp) {
+ if (!g_printk_info_buf_tmp) {
KBOX_MSG("kmalloc g_printk_info_buf_tmp fail!\n");
ret = -ENOMEM;
goto fail;
diff --git a/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_ram_op.c b/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_ram_op.c
index 49690bab1cef..9f6dfe55e3fb 100644
--- a/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_ram_op.c
+++ b/drivers/net/ethernet/huawei/bma/kbox_drv/kbox_ram_op.c
@@ -432,7 +432,7 @@ int kbox_write_op(long long offset, unsigned int count,
return KBOX_FALSE;
temp_buf_char = kmalloc(TEMP_BUF_DATA_SIZE, GFP_KERNEL);
- if (!temp_buf_char || IS_ERR(temp_buf_char)) {
+ if (!temp_buf_char) {
KBOX_MSG("kmalloc temp_buf_char fail!\n");
up(&user_sem);
return -ENOMEM;
diff --git a/drivers/net/ethernet/huawei/bma/veth_drv/veth_hb.c b/drivers/net/ethernet/huawei/bma/veth_drv/veth_hb.c
index 9681ce3bfc7b..e226582693b6 100644
--- a/drivers/net/ethernet/huawei/bma/veth_drv/veth_hb.c
+++ b/drivers/net/ethernet/huawei/bma/veth_drv/veth_hb.c
@@ -638,6 +638,7 @@ s32 veth_refill_rxskb(struct bspveth_rxtx_q *prx_queue, int queue)
next_to_fill = (next_to_fill + 1) & BSPVETH_POINT_MASK;
}
+ mb();/* memory barriers. */
prx_queue->next_to_fill = next_to_fill;
tail = prx_queue->tail;
@@ -672,6 +673,7 @@ s32 bspveth_setup_rx_skb(struct bspveth_device *pvethdev,
if (!idx) /* Can't alloc even one packets */
return -EFAULT;
+ mb();/* memory barriers. */
prx_queue->next_to_fill = idx;
VETH_LOG(DLOG_DEBUG, "prx_queue->next_to_fill=%d\n",
@@ -886,8 +888,6 @@ s32 bspveth_setup_all_rx_resources(struct bspveth_device *pvethdev)
err = bspveth_setup_rx_resources(pvethdev,
pvethdev->prx_queue[qid]);
if (err) {
- kfree(pvethdev->prx_queue[qid]);
- pvethdev->prx_queue[qid] = NULL;
VETH_LOG(DLOG_ERROR,
"Allocation for Rx Queue %u failed\n", qid);
@@ -1328,6 +1328,7 @@ s32 veth_send_one_pkt(struct sk_buff *skb, int queue)
pbd_v->off = off;
pbd_v->len = skb->len;
+ mb();/* memory barriers. */
head = (head + 1) & BSPVETH_POINT_MASK;
ptx_queue->head = head;
@@ -1424,6 +1425,7 @@ s32 veth_free_txskb(struct bspveth_rxtx_q *ptx_queue, int queue)
next_to_free = (next_to_free + 1) & BSPVETH_POINT_MASK;
}
+ mb(); /* memory barriers. */
ptx_queue->next_to_free = next_to_free;
tail = ptx_queue->tail;
@@ -1522,6 +1524,7 @@ s32 veth_recv_pkt(struct bspveth_rxtx_q *prx_queue, int queue)
}
}
+ mb();/* memory barriers. */
prx_queue->tail = tail;
head = prx_queue->head;
diff --git a/drivers/net/ethernet/huawei/bma/veth_drv/veth_hb.h b/drivers/net/ethernet/huawei/bma/veth_drv/veth_hb.h
index 9a4d699e6421..503636549320 100644
--- a/drivers/net/ethernet/huawei/bma/veth_drv/veth_hb.h
+++ b/drivers/net/ethernet/huawei/bma/veth_drv/veth_hb.h
@@ -31,7 +31,7 @@ extern "C" {
#ifdef DRV_VERSION
#define VETH_VERSION MICRO_TO_STR(DRV_VERSION)
#else
-#define VETH_VERSION "0.3.4"
+#define VETH_VERSION "0.3.5"
#endif
#define MODULE_NAME "veth"
--
2.25.1
1
1

[PATCH V2 RESEND openEuler-22.03-LTS] selftests/rseq: check if libc rseq support is registered
by 任敏敏(联通集团联通数字科技有 限公司本部) 18 Jan '23
by 任敏敏(联通集团联通数字科技有 限公司本部) 18 Jan '23
18 Jan '23
From: Michael Jeanson <mjeanson(a)efficios.com>
mainline inclusion
from mainline-v6.0-rc1
commit d1a997ba4c1bf65497d956aea90de42a6398f73a
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I69PT8
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit d1a997ba4c1bf65497d956aea90de42a6398f73a upstream.
When checking for libc rseq support in the library constructor, don't
only depend on the symbols presence, check that the registration was
completed.
This targets a scenario where the libc has rseq support but it is not
wired for the current architecture in 'bits/rseq.h', we want to fallback
to our internal registration mechanism.
Signed-off-by: Michael Jeanson <mjeanson(a)efficios.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz(a)infradead.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers(a)efficios.com>
Link: https://lore.kernel.org/r/20220614154830.1367382-4-mjeanson@efficios.com
Signed-off-by: rminmin <renmm6(a)chinaunicom.cn>
---
tools/testing/selftests/rseq/rseq.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c
index 986b9458efb2..4177f9507bbe 100644
--- a/tools/testing/selftests/rseq/rseq.c
+++ b/tools/testing/selftests/rseq/rseq.c
@@ -111,7 +111,8 @@ void rseq_init(void)
libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");
- if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p) {
+ if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p &&
+ *libc_rseq_size_p != 0) {
/* rseq registration owned by glibc */
rseq_offset = *libc_rseq_offset_p;
rseq_size = *libc_rseq_size_p;
--
2.33.0
Èç¹ûÄúŽíÎóœÓÊÕÁËžÃÓÊŒþ£¬ÇëÍš¹ýµç×ÓÓÊŒþÁ¢ŒŽÍšÖªÎÒÃÇ¡£Çë»ØžŽÓÊŒþµœ hqs-spmc@chinaunicom.cn£¬ŒŽ¿ÉÒÔÍ˶©ŽËÓÊŒþ¡£ÎÒÃÇœ«Á¢ŒŽœ«ÄúµÄÐÅÏ¢ŽÓÎÒÃǵķ¢ËÍĿŒÖÐÉŸ³ý¡£ If you have received this email in error please notify us immediately by e-mail. Please reply to hqs-spmc(a)chinaunicom.cn ,you can unsubscribe from this mail. We will immediately remove your information from send catalogue of our.
1
0

[PATCH openEuler-5.10-LTS-SP1 01/14] tracing/osnoise: Properly unhook events if start_per_cpu_kthreads() fails
by Jialin Zhang 18 Jan '23
by Jialin Zhang 18 Jan '23
18 Jan '23
From: Nikita Yushchenko <nikita.yushchenko(a)virtuozzo.com>
mainline inclusion
from mainline-v5.17-rc1
commit 0878355b51f5f26632e652c848a8e174bb02d22d
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I699A9
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
If start_per_cpu_kthreads() called from osnoise_workload_start() returns
error, event hooks are left in broken state: unhook_irq_events() called
but unhook_thread_events() and unhook_softirq_events() not called, and
trace_osnoise_callback_enabled flag not cleared.
On the next tracer enable, hooks get not installed due to
trace_osnoise_callback_enabled flag.
And on the further tracer disable an attempt to remove non-installed
hooks happened, hitting a WARN_ON_ONCE() in tracepoint_remove_func().
Fix the error path by adding the missing part of cleanup.
While at this, introduce osnoise_unhook_events() to avoid code
duplication between this error path and normal tracer disable.
Link: https://lkml.kernel.org/r/20220109153459.3701773-1-nikita.yushchenko@virtuo…
Cc: stable(a)vger.kernel.org
Fixes: bce29ac9ce0b ("trace: Add osnoise tracer")
Acked-by: Daniel Bristot de Oliveira <bristot(a)kernel.org>
Signed-off-by: Nikita Yushchenko <nikita.yushchenko(a)virtuozzo.com>
Signed-off-by: Steven Rostedt <rostedt(a)goodmis.org>
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Reviewed-by: Xu Kuohai <xukuohai(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
kernel/trace/trace_osnoise.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
index cfb80feb291e..3f806a3be8b2 100644
--- a/kernel/trace/trace_osnoise.c
+++ b/kernel/trace/trace_osnoise.c
@@ -2103,6 +2103,13 @@ static int osnoise_hook_events(void)
return -EINVAL;
}
+static void osnoise_unhook_events(void)
+{
+ unhook_thread_events();
+ unhook_softirq_events();
+ unhook_irq_events();
+}
+
/*
* osnoise_workload_start - start the workload and hook to events
*/
@@ -2135,7 +2142,14 @@ static int osnoise_workload_start(void)
retval = start_per_cpu_kthreads();
if (retval) {
- unhook_irq_events();
+ trace_osnoise_callback_enabled = false;
+ /*
+ * Make sure that ftrace_nmi_enter/exit() see
+ * trace_osnoise_callback_enabled as false before continuing.
+ */
+ barrier();
+
+ osnoise_unhook_events();
return retval;
}
@@ -2166,9 +2180,7 @@ static void osnoise_workload_stop(void)
stop_per_cpu_kthreads();
- unhook_irq_events();
- unhook_softirq_events();
- unhook_thread_events();
+ osnoise_unhook_events();
}
static void osnoise_tracer_start(struct trace_array *tr)
--
2.25.1
1
13

18 Jan '23
From: Hugh Dickins <hughd(a)google.com>
mainline inclusion
from mainline-v5.18-rc1
commit 56a8c8eb1eaf21261be8cdc4e3715239ac087342
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6113U
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
Mikulas asked in "Do we still need commit a0ee5ec520ed ('tmpfs: allocate
on read when stacked')?" in [1]
Lukas noticed this unusual behavior of loop device backed by tmpfs in [2].
Normally, shmem_file_read_iter() copies the ZERO_PAGE when reading
holes; but if it looks like it might be a read for "a stacking
filesystem", it allocates actual pages to the page cache, and even marks
them as dirty. And reads from the loop device do satisfy the test that
is used.
This oddity was added for an old version of unionfs, to help to limit
its usage to the limited size of the tmpfs mount involved; but about the
same time as the tmpfs mod went in (2.6.25), unionfs was reworked to
proceed differently; and the mod kept just in case others needed it.
Do we still need it? I cannot answer with more certainty than "Probably
not". It's nasty enough that we really should try to delete it; but if
a regression is reported somewhere, then we might have to revert later.
It's not quite as simple as just removing the test (as Mikulas did):
xfstests generic/013 hung because splice from tmpfs failed on page not
up-to-date and page mapping unset. That can be fixed just by marking
the ZERO_PAGE as Uptodate, which of course it is: do so in
pagecache_init() - it might be useful to others than tmpfs.
My intention, though, was to stop using the ZERO_PAGE here altogether:
surely iov_iter_zero() is better for this case? Sadly not: it relies on
clear_user(), and the x86 clear_user() is slower than its copy_user() [3].
But while we are still using the ZERO_PAGE, let's stop dirtying its
struct page cacheline with unnecessary get_page() and put_page().
Link: https://lore.kernel.org/linux-mm/alpine.LRH.2.02.2007210510230.6959@file01.… [1]
Link: https://lore.kernel.org/linux-mm/20211126075100.gd64odg2bcptiqeb@work/ [2]
Link: https://lore.kernel.org/lkml/2f5ca5e4-e250-a41c-11fb-a7f4ebc7e1c9@google.co… [3]
Link: https://lkml.kernel.org/r/90bc5e69-9984-b5fa-a685-be55f2b64b@google.com
Signed-off-by: Hugh Dickins <hughd(a)google.com>
Reported-by: Mikulas Patocka <mpatocka(a)redhat.com>
Reported-by: Lukas Czerner <lczerner(a)redhat.com>
Acked-by: Darrick J. Wong <djwong(a)kernel.org>
Reviewed-by: Christoph Hellwig <hch(a)lst.de>
Cc: Zdenek Kabelac <zkabelac(a)redhat.com>
Cc: "Darrick J. Wong" <djwong(a)kernel.org>
Cc: Miklos Szeredi <miklos(a)szeredi.hu>
Cc: Borislav Petkov <bp(a)suse.de>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com>
Reviewed-by: tong tiangen <tongtiangen(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
mm/filemap.c | 6 ++++++
mm/shmem.c | 20 ++++++--------------
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index 98b448d9873f..a44baa79c1e7 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -996,6 +996,12 @@ void __init pagecache_init(void)
init_waitqueue_head(&page_wait_table[i]);
page_writeback_init();
+
+ /*
+ * tmpfs uses the ZERO_PAGE for reading holes: it is up-to-date,
+ * and splice's page_cache_pipe_buf_confirm() needs to see that.
+ */
+ SetPageUptodate(ZERO_PAGE(0));
}
/*
diff --git a/mm/shmem.c b/mm/shmem.c
index ad2d68150ed2..c5028634afee 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2573,19 +2573,10 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
struct address_space *mapping = inode->i_mapping;
pgoff_t index;
unsigned long offset;
- enum sgp_type sgp = SGP_READ;
int error = 0;
ssize_t retval = 0;
loff_t *ppos = &iocb->ki_pos;
- /*
- * Might this read be for a stacking filesystem? Then when reading
- * holes of a sparse file, we actually need to allocate those pages,
- * and even mark them dirty, so it cannot exceed the max_blocks limit.
- */
- if (!iter_is_iovec(to))
- sgp = SGP_CACHE;
-
index = *ppos >> PAGE_SHIFT;
offset = *ppos & ~PAGE_MASK;
@@ -2594,6 +2585,7 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
pgoff_t end_index;
unsigned long nr, ret;
loff_t i_size = i_size_read(inode);
+ bool got_page;
end_index = i_size >> PAGE_SHIFT;
if (index > end_index)
@@ -2604,15 +2596,13 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
break;
}
- error = shmem_getpage(inode, index, &page, sgp);
+ error = shmem_getpage(inode, index, &page, SGP_READ);
if (error) {
if (error == -EINVAL)
error = 0;
break;
}
if (page) {
- if (sgp == SGP_CACHE)
- set_page_dirty(page);
unlock_page(page);
}
@@ -2646,9 +2636,10 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
*/
if (!offset)
mark_page_accessed(page);
+ got_page = true;
} else {
page = ZERO_PAGE(0);
- get_page(page);
+ got_page = false;
}
/*
@@ -2661,7 +2652,8 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
index += offset >> PAGE_SHIFT;
offset &= ~PAGE_MASK;
- put_page(page);
+ if (got_page)
+ put_page(page);
if (!iov_iter_count(to))
break;
if (ret < nr) {
--
2.25.1
1
20

[PATCH openEuler-1.0-LTS] USB: Fix kABI for usb_device->reset_in_progress
by Yongqiang Liu 18 Jan '23
by Yongqiang Liu 18 Jan '23
18 Jan '23
From: Yuyao Lin <linyuyao1(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla:https://gitee.com/src-openeuler/kernel/issues/I675RE
CVE: CVE-2022-4662
--------------------------------
Fix kABI by using __GENKSYMS__ for usb_device->reset_in_progress.
Signed-off-by: Yuyao Lin <linyuyao1(a)huawei.com>
Reviewed-by: zhangjialin <zhangjialin11(a)huawei.com>
Reviewed-by: Wei Li <liwei391(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
include/linux/usb.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 317eedae1c10..9c10a16c3abe 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -665,7 +665,6 @@ struct usb_device {
unsigned can_submit:1;
unsigned persist_enabled:1;
- unsigned reset_in_progress:1;
unsigned have_langid:1;
unsigned authorized:1;
unsigned authenticated:1;
@@ -677,6 +676,11 @@ struct usb_device {
unsigned usb2_hw_lpm_allowed:1;
unsigned usb3_lpm_u1_enabled:1;
unsigned usb3_lpm_u2_enabled:1;
+
+#ifndef __GENKSYMS__
+ unsigned reset_in_progress:1;
+#endif
+
int string_langid;
/* static strings from the device */
--
2.25.1
1
0

[PATCH openEuler-1.0-LTS] USB: Fix kABI for usb_device->reset_in_progress
by Yongqiang Liu 18 Jan '23
by Yongqiang Liu 18 Jan '23
18 Jan '23
From: Yuyao Lin <linyuyao1(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla:https://gitee.com/src-openeuler/kernel/issues/I675RE
CVE: CVE-2022-4662
--------------------------------
Fix kABI by using __GENKSYMS__ for usb_device->reset_in_progress.
Signed-off-by: Yuyao Lin <linyuyao1(a)huawei.com>
Reviewed-by: zhangjialin 00591957 <zhangjialin11(a)huawei.com>
Reviewed-by: Wei Li <liwei391(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
include/linux/usb.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 317eedae1c10..9c10a16c3abe 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -665,7 +665,6 @@ struct usb_device {
unsigned can_submit:1;
unsigned persist_enabled:1;
- unsigned reset_in_progress:1;
unsigned have_langid:1;
unsigned authorized:1;
unsigned authenticated:1;
@@ -677,6 +676,11 @@ struct usb_device {
unsigned usb2_hw_lpm_allowed:1;
unsigned usb3_lpm_u1_enabled:1;
unsigned usb3_lpm_u2_enabled:1;
+
+#ifndef __GENKSYMS__
+ unsigned reset_in_progress:1;
+#endif
+
int string_langid;
/* static strings from the device */
--
2.25.1
1
0

[PATCH openEuler-1.0-LTS] rndis_wlan: Prevent buffer overflow in rndis_query_oid
by Yongqiang Liu 18 Jan '23
by Yongqiang Liu 18 Jan '23
18 Jan '23
From: Szymon Heidrich <szymon.heidrich(a)gmail.com>
maillist inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6AQJP
CVE: CVE-2023-23559
Reference: https://patchwork.kernel.org/project/linux-wireless/patch/20230111175031.70…
-------------------------------
Since resplen and respoffs are signed integers sufficiently
large values of unsigned int len and offset members of RNDIS
response will result in negative values of prior variables.
This may be utilized to bypass implemented security checks
to either extract memory contents by manipulating offset or
overflow the data buffer via memcpy by manipulating both
offset and len.
Additionally assure that sum of resplen and respoffs does not
overflow so buffer boundaries are kept.
Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
Signed-off-by: Szymon Heidrich <szymon.heidrich(a)gmail.com>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
Reviewed-by: Liu Jian <liujian56(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 51e4e92d95a0..0bbeb61ec3a3 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -712,8 +712,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
struct rndis_query *get;
struct rndis_query_c *get_c;
} u;
- int ret, buflen;
- int resplen, respoffs, copylen;
+ int ret;
+ size_t buflen, resplen, respoffs, copylen;
buflen = *len + sizeof(*u.get);
if (buflen < CONTROL_BUFFER_SIZE)
@@ -748,22 +748,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
if (respoffs > buflen) {
/* Device returned data offset outside buffer, error. */
- netdev_dbg(dev->net, "%s(%s): received invalid "
- "data offset: %d > %d\n", __func__,
- oid_to_string(oid), respoffs, buflen);
+ netdev_dbg(dev->net,
+ "%s(%s): received invalid data offset: %zu > %zu\n",
+ __func__, oid_to_string(oid), respoffs, buflen);
ret = -EINVAL;
goto exit_unlock;
}
- if ((resplen + respoffs) > buflen) {
- /* Device would have returned more data if buffer would
- * have been big enough. Copy just the bits that we got.
- */
- copylen = buflen - respoffs;
- } else {
- copylen = resplen;
- }
+ copylen = min(resplen, buflen - respoffs);
if (copylen > *len)
copylen = *len;
--
2.25.1
1
0

[openEuler-22.03-LTS] rndis_wlan: Prevent buffer overflow in rndis_query_oid
by Wang Yufen 17 Jan '23
by Wang Yufen 17 Jan '23
17 Jan '23
From: Szymon Heidrich <szymon.heidrich(a)gmail.com>
maillist inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6AQJP
CVE: CVE-2023-23559
Reference: https://patchwork.kernel.org/project/linux-wireless/patch/20230111175031.70…
-------------------------------
Since resplen and respoffs are signed integers sufficiently
large values of unsigned int len and offset members of RNDIS
response will result in negative values of prior variables.
This may be utilized to bypass implemented security checks
to either extract memory contents by manipulating offset or
overflow the data buffer via memcpy by manipulating both
offset and len.
Additionally assure that sum of resplen and respoffs does not
overflow so buffer boundaries are kept.
Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
Signed-off-by: Szymon Heidrich <szymon.heidrich(a)gmail.com>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
---
drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 75b5d54..dc076d8 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -694,8 +694,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
struct rndis_query *get;
struct rndis_query_c *get_c;
} u;
- int ret, buflen;
- int resplen, respoffs, copylen;
+ int ret;
+ size_t buflen, resplen, respoffs, copylen;
buflen = *len + sizeof(*u.get);
if (buflen < CONTROL_BUFFER_SIZE)
@@ -730,22 +730,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
if (respoffs > buflen) {
/* Device returned data offset outside buffer, error. */
- netdev_dbg(dev->net, "%s(%s): received invalid "
- "data offset: %d > %d\n", __func__,
- oid_to_string(oid), respoffs, buflen);
+ netdev_dbg(dev->net,
+ "%s(%s): received invalid data offset: %zu > %zu\n",
+ __func__, oid_to_string(oid), respoffs, buflen);
ret = -EINVAL;
goto exit_unlock;
}
- if ((resplen + respoffs) > buflen) {
- /* Device would have returned more data if buffer would
- * have been big enough. Copy just the bits that we got.
- */
- copylen = buflen - respoffs;
- } else {
- copylen = resplen;
- }
+ copylen = min(resplen, buflen - respoffs);
if (copylen > *len)
copylen = *len;
--
1.8.3.1
1
0

17 Jan '23
From: Szymon Heidrich <szymon.heidrich(a)gmail.com>
maillist inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6AQJP
CVE: CVE-2023-23559
Reference: https://patchwork.kernel.org/project/linux-wireless/patch/20230111175031.70…
-------------------------------
Since resplen and respoffs are signed integers sufficiently
large values of unsigned int len and offset members of RNDIS
response will result in negative values of prior variables.
This may be utilized to bypass implemented security checks
to either extract memory contents by manipulating offset or
overflow the data buffer via memcpy by manipulating both
offset and len.
Additionally assure that sum of resplen and respoffs does not
overflow so buffer boundaries are kept.
Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
Signed-off-by: Szymon Heidrich <szymon.heidrich(a)gmail.com>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
---
drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 75b5d54..dc076d8 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -694,8 +694,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
struct rndis_query *get;
struct rndis_query_c *get_c;
} u;
- int ret, buflen;
- int resplen, respoffs, copylen;
+ int ret;
+ size_t buflen, resplen, respoffs, copylen;
buflen = *len + sizeof(*u.get);
if (buflen < CONTROL_BUFFER_SIZE)
@@ -730,22 +730,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
if (respoffs > buflen) {
/* Device returned data offset outside buffer, error. */
- netdev_dbg(dev->net, "%s(%s): received invalid "
- "data offset: %d > %d\n", __func__,
- oid_to_string(oid), respoffs, buflen);
+ netdev_dbg(dev->net,
+ "%s(%s): received invalid data offset: %zu > %zu\n",
+ __func__, oid_to_string(oid), respoffs, buflen);
ret = -EINVAL;
goto exit_unlock;
}
- if ((resplen + respoffs) > buflen) {
- /* Device would have returned more data if buffer would
- * have been big enough. Copy just the bits that we got.
- */
- copylen = buflen - respoffs;
- } else {
- copylen = resplen;
- }
+ copylen = min(resplen, buflen - respoffs);
if (copylen > *len)
copylen = *len;
--
1.8.3.1
1
0

17 Jan '23
From: Szymon Heidrich <szymon.heidrich(a)gmail.com>
maillist inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6AQJP
CVE: CVE-2023-23559
Reference: https://patchwork.kernel.org/project/linux-wireless/patch/20230111175031.70…
-------------------------------
Since resplen and respoffs are signed integers sufficiently
large values of unsigned int len and offset members of RNDIS
response will result in negative values of prior variables.
This may be utilized to bypass implemented security checks
to either extract memory contents by manipulating offset or
overflow the data buffer via memcpy by manipulating both
offset and len.
Additionally assure that sum of resplen and respoffs does not
overflow so buffer boundaries are kept.
Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
Signed-off-by: Szymon Heidrich <szymon.heidrich(a)gmail.com>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
---
drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 51e4e92..0bbeb61 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -712,8 +712,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
struct rndis_query *get;
struct rndis_query_c *get_c;
} u;
- int ret, buflen;
- int resplen, respoffs, copylen;
+ int ret;
+ size_t buflen, resplen, respoffs, copylen;
buflen = *len + sizeof(*u.get);
if (buflen < CONTROL_BUFFER_SIZE)
@@ -748,22 +748,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
if (respoffs > buflen) {
/* Device returned data offset outside buffer, error. */
- netdev_dbg(dev->net, "%s(%s): received invalid "
- "data offset: %d > %d\n", __func__,
- oid_to_string(oid), respoffs, buflen);
+ netdev_dbg(dev->net,
+ "%s(%s): received invalid data offset: %zu > %zu\n",
+ __func__, oid_to_string(oid), respoffs, buflen);
ret = -EINVAL;
goto exit_unlock;
}
- if ((resplen + respoffs) > buflen) {
- /* Device would have returned more data if buffer would
- * have been big enough. Copy just the bits that we got.
- */
- copylen = buflen - respoffs;
- } else {
- copylen = resplen;
- }
+ copylen = min(resplen, buflen - respoffs);
if (copylen > *len)
copylen = *len;
--
1.8.3.1
1
0
From: Szymon Heidrich <szymon.heidrich(a)gmail.com>
maillist inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6AQJP
CVE: CVE-2023-23559
Reference: https://patchwork.kernel.org/project/linux-wireless/patch/20230111175031.70…
-------------------------------
Since resplen and respoffs are signed integers sufficiently
large values of unsigned int len and offset members of RNDIS
response will result in negative values of prior variables.
This may be utilized to bypass implemented security checks
to either extract memory contents by manipulating offset or
overflow the data buffer via memcpy by manipulating both
offset and len.
Additionally assure that sum of resplen and respoffs does not
overflow so buffer boundaries are kept.
Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
Signed-off-by: Szymon Heidrich <szymon.heidrich(a)gmail.com>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
---
drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 51e4e92..0bbeb61 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -712,8 +712,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
struct rndis_query *get;
struct rndis_query_c *get_c;
} u;
- int ret, buflen;
- int resplen, respoffs, copylen;
+ int ret;
+ size_t buflen, resplen, respoffs, copylen;
buflen = *len + sizeof(*u.get);
if (buflen < CONTROL_BUFFER_SIZE)
@@ -748,22 +748,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
if (respoffs > buflen) {
/* Device returned data offset outside buffer, error. */
- netdev_dbg(dev->net, "%s(%s): received invalid "
- "data offset: %d > %d\n", __func__,
- oid_to_string(oid), respoffs, buflen);
+ netdev_dbg(dev->net,
+ "%s(%s): received invalid data offset: %zu > %zu\n",
+ __func__, oid_to_string(oid), respoffs, buflen);
ret = -EINVAL;
goto exit_unlock;
}
- if ((resplen + respoffs) > buflen) {
- /* Device would have returned more data if buffer would
- * have been big enough. Copy just the bits that we got.
- */
- copylen = buflen - respoffs;
- } else {
- copylen = resplen;
- }
+ copylen = min(resplen, buflen - respoffs);
if (copylen > *len)
copylen = *len;
--
1.8.3.1
1
0

16 Jan '23
Tong Tiangen (2):
arm64: fix return value type of memcpy_mcs()
kasan: add kasan support for memcpy_mcs()
arch/arm64/include/asm/string.h | 4 ++--
mm/kasan/common.c | 12 ++++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
--
2.25.1
1
2
Tong Tiangen (2):
arm64: fix return value type of memcpy_mcs()
kasan: add kasan support for memcpy_mcs()
arch/arm64/include/asm/string.h | 4 ++--
mm/kasan/common.c | 12 ++++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
--
2.25.1
1
2

[PATCH openEuler-22.03-LTS] selftests/rseq: check if libc rseq support is registered
by MinMin Ren 12 Jan '23
by MinMin Ren 12 Jan '23
12 Jan '23
From: Michael Jeanson <mjeanson(a)efficios.com>
mainline inclusion
from mainline-v6.0-rc1
commit d1a997ba4c1bf65497d956aea90de42a6398f73a
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I69PT8
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit d1a997ba4c1bf65497d956aea90de42a6398f73a upstream.
When checking for libc rseq support in the library constructor, don't
only depend on the symbols presence, check that the registration was
completed.
This targets a scenario where the libc has rseq support but it is not
wired for the current architecture in 'bits/rseq.h', we want to fallback
to our internal registration mechanism.
Signed-off-by: Michael Jeanson <mjeanson(a)efficios.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz(a)infradead.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers(a)efficios.com>
Link: https://lore.kernel.org/r/20220614154830.1367382-4-mjeanson@efficios.com
Signed-off-by: rminmin <rmm0811(a)gmail.com>
---
tools/testing/selftests/rseq/rseq.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c
index 986b9458efb2..4177f9507bbe 100644
--- a/tools/testing/selftests/rseq/rseq.c
+++ b/tools/testing/selftests/rseq/rseq.c
@@ -111,7 +111,8 @@ void rseq_init(void)
libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset");
libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size");
libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags");
- if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p) {
+ if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p &&
+ *libc_rseq_size_p != 0) {
/* rseq registration owned by glibc */
rseq_offset = *libc_rseq_offset_p;
rseq_size = *libc_rseq_size_p;
--
2.33.0
1
0

[PATCH openEuler-1.0-LTS 1/6] crypto: ecdh - avoid unaligned accesses in ecdh_set_secret()
by Yongqiang Liu 11 Jan '23
by Yongqiang Liu 11 Jan '23
11 Jan '23
From: Ard Biesheuvel <ardb(a)kernel.org>
stable inclusion
from stable-v4.19.164
commit 85637bc064f4fd5539d4173798d8cb55dde7fc0a
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I65ZD2
CVE: NA
--------------------------------
commit 17858b140bf49961b71d4e73f1c3ea9bc8e7dda0 upstream.
ecdh_set_secret() casts a void* pointer to a const u64* in order to
feed it into ecc_is_key_valid(). This is not generally permitted by
the C standard, and leads to actual misalignment faults on ARMv6
cores. In some cases, these are fixed up in software, but this still
leads to performance hits that are entirely avoidable.
So let's copy the key into the ctx buffer first, which we will do
anyway in the common case, and which guarantees correct alignment.
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb(a)kernel.org>
Signed-off-by: Herbert Xu <herbert(a)gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: GUO Zihua <guozihua(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
crypto/ecdh.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index bf6300175b9c..a6e1a5d43fa7 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -57,12 +57,13 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
return ecc_gen_privkey(ctx->curve_id, ctx->ndigits,
ctx->private_key);
- if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
- (const u64 *)params.key, params.key_size) < 0)
- return -EINVAL;
-
memcpy(ctx->private_key, params.key, params.key_size);
+ if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
+ ctx->private_key, params.key_size) < 0) {
+ memzero_explicit(ctx->private_key, params.key_size);
+ return -EINVAL;
+ }
return 0;
}
--
2.25.1
1
5

[PATCH openEuler-1.0-LTS 01/13] audit: fix undefined behavior in bit shift for AUDIT_BIT
by Yongqiang Liu 11 Jan '23
by Yongqiang Liu 11 Jan '23
11 Jan '23
From: Gaosheng Cui <cuigaosheng1(a)huawei.com>
stable inclusion
from stable-v4.19.268
commit bbd0427fc0241bccb2c56235cbaad9fd63cd615b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I69KBO
CVE: NA
--------------------------------
[ Upstream commit 986d93f55bdeab1cac858d1e47b41fac10b2d7f6 ]
Shifting signed 32-bit value by 31 bits is undefined, so changing
significant bit to unsigned. The UBSAN warning calltrace like below:
UBSAN: shift-out-of-bounds in kernel/auditfilter.c:179:23
left shift of 1 by 31 places cannot be represented in type 'int'
Call Trace:
<TASK>
dump_stack_lvl+0x7d/0xa5
dump_stack+0x15/0x1b
ubsan_epilogue+0xe/0x4e
__ubsan_handle_shift_out_of_bounds+0x1e7/0x20c
audit_register_class+0x9d/0x137
audit_classes_init+0x4d/0xb8
do_one_initcall+0x76/0x430
kernel_init_freeable+0x3b3/0x422
kernel_init+0x24/0x1e0
ret_from_fork+0x1f/0x30
</TASK>
Signed-off-by: Gaosheng Cui <cuigaosheng1(a)huawei.com>
[PM: remove bad 'Fixes' tag as issue predates git, added in v2.6.6-rc1]
Signed-off-by: Paul Moore <paul(a)paul-moore.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
include/uapi/linux/audit.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 818ae690ab79..b163911b1d39 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -177,7 +177,7 @@
#define AUDIT_MAX_KEY_LEN 256
#define AUDIT_BITMASK_SIZE 64
#define AUDIT_WORD(nr) ((__u32)((nr)/32))
-#define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32))
+#define AUDIT_BIT(nr) (1U << ((nr) - AUDIT_WORD(nr)*32))
#define AUDIT_SYSCALL_CLASSES 16
#define AUDIT_CLASS_DIR_WRITE 0
--
2.25.1
1
12

[PATCH openEuler-1.0-LTS 1/2] USB: core: Prevent nested device-reset calls
by Yongqiang Liu 11 Jan '23
by Yongqiang Liu 11 Jan '23
11 Jan '23
From: Alan Stern <stern(a)rowland.harvard.edu>
stable inclusion
from stable-v4.19.258
commit cc9a12e12808af178c600cc485338bac2e37d2a8
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I675RE
CVE: CVE-2022-4662
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 9c6d778800b921bde3bff3cff5003d1650f942d1 upstream.
Automatic kernel fuzzing revealed a recursive locking violation in
usb-storage:
============================================
WARNING: possible recursive locking detected
5.18.0 #3 Not tainted
--------------------------------------------
kworker/1:3/1205 is trying to acquire lock:
ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at:
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230
but task is already holding lock:
ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at:
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230
...
stack backtrace:
CPU: 1 PID: 1205 Comm: kworker/1:3 Not tainted 5.18.0 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Workqueue: usb_hub_wq hub_event
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
print_deadlock_bug kernel/locking/lockdep.c:2988 [inline]
check_deadlock kernel/locking/lockdep.c:3031 [inline]
validate_chain kernel/locking/lockdep.c:3816 [inline]
__lock_acquire.cold+0x152/0x3ca kernel/locking/lockdep.c:5053
lock_acquire kernel/locking/lockdep.c:5665 [inline]
lock_acquire+0x1ab/0x520 kernel/locking/lockdep.c:5630
__mutex_lock_common kernel/locking/mutex.c:603 [inline]
__mutex_lock+0x14f/0x1610 kernel/locking/mutex.c:747
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230
usb_reset_device+0x37d/0x9a0 drivers/usb/core/hub.c:6109
r871xu_dev_remove+0x21a/0x270 drivers/staging/rtl8712/usb_intf.c:622
usb_unbind_interface+0x1bd/0x890 drivers/usb/core/driver.c:458
device_remove drivers/base/dd.c:545 [inline]
device_remove+0x11f/0x170 drivers/base/dd.c:537
__device_release_driver drivers/base/dd.c:1222 [inline]
device_release_driver_internal+0x1a7/0x2f0 drivers/base/dd.c:1248
usb_driver_release_interface+0x102/0x180 drivers/usb/core/driver.c:627
usb_forced_unbind_intf+0x4d/0xa0 drivers/usb/core/driver.c:1118
usb_reset_device+0x39b/0x9a0 drivers/usb/core/hub.c:6114
This turned out not to be an error in usb-storage but rather a nested
device reset attempt. That is, as the rtl8712 driver was being
unbound from a composite device in preparation for an unrelated USB
reset (that driver does not have pre_reset or post_reset callbacks),
its ->remove routine called usb_reset_device() -- thus nesting one
reset call within another.
Performing a reset as part of disconnect processing is a questionable
practice at best. However, the bug report points out that the USB
core does not have any protection against nested resets. Adding a
reset_in_progress flag and testing it will prevent such errors in the
future.
Link: https://lore.kernel.org/all/CAB7eexKUpvX-JNiLzhXBDWgfg2T9e9_0Tw4HQ6keN==voR…
Cc: stable(a)vger.kernel.org
Reported-and-tested-by: Rondreis <linhaoguo86(a)gmail.com>
Signed-off-by: Alan Stern <stern(a)rowland.harvard.edu>
Link: https://lore.kernel.org/r/YwkflDxvg0KWqyZK@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yuyao Lin <linyuyao1(a)huawei.com>
Reviewed-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/usb/core/hub.c | 10 ++++++++++
include/linux/usb.h | 2 ++
2 files changed, 12 insertions(+)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index adc8e3a0138f..b983a333ca32 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5747,6 +5747,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
* the reset is over (using their post_reset method).
*
* Return: The same as for usb_reset_and_verify_device().
+ * However, if a reset is already in progress (for instance, if a
+ * driver doesn't have pre_ or post_reset() callbacks, and while
+ * being unbound or re-bound during the ongoing reset its disconnect()
+ * or probe() routine tries to perform a second, nested reset), the
+ * routine returns -EINPROGRESS.
*
* Note:
* The caller must own the device lock. For example, it's safe to use
@@ -5780,6 +5785,10 @@ int usb_reset_device(struct usb_device *udev)
return -EISDIR;
}
+ if (udev->reset_in_progress)
+ return -EINPROGRESS;
+ udev->reset_in_progress = 1;
+
port_dev = hub->ports[udev->portnum - 1];
/*
@@ -5844,6 +5853,7 @@ int usb_reset_device(struct usb_device *udev)
usb_autosuspend_device(udev);
memalloc_noio_restore(noio_flag);
+ udev->reset_in_progress = 0;
return ret;
}
EXPORT_SYMBOL_GPL(usb_reset_device);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 3e1e31f73d0e..317eedae1c10 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -580,6 +580,7 @@ struct usb3_lpm_parameters {
* @level: number of USB hub ancestors
* @can_submit: URBs may be submitted
* @persist_enabled: USB_PERSIST enabled for this device
+ * @reset_in_progress: the device is being reset
* @have_langid: whether string_langid is valid
* @authorized: policy has said we can use it;
* (user space) policy determines if we authorize this device to be
@@ -664,6 +665,7 @@ struct usb_device {
unsigned can_submit:1;
unsigned persist_enabled:1;
+ unsigned reset_in_progress:1;
unsigned have_langid:1;
unsigned authorized:1;
unsigned authenticated:1;
--
2.25.1
1
1

[PATCH openEuler-1.0-LTS 1/8] mm/hwpoison: do not lock page again when me_huge_page() successfully recovers
by Yongqiang Liu 11 Jan '23
by Yongqiang Liu 11 Jan '23
11 Jan '23
From: Naoya Horiguchi <naoya.horiguchi(a)nec.com>
mainline inclusion
from mainline-v5.13
commit ea6d0630100b285f059d0a8d8e86f38a46407536
category: bugfix
bugzilla: 188222, https://gitee.com/openeuler/kernel/issues/I69SHF
CVE: NA
--------------------------------
Currently me_huge_page() temporary unlocks page to perform some actions
then locks it again later. My testcase (which calls hard-offline on
some tail page in a hugetlb, then accesses the address of the hugetlb
range) showed that page allocation code detects this page lock on buddy
page and printed out "BUG: Bad page state" message.
check_new_page_bad() does not consider a page with __PG_HWPOISON as bad
page, so this flag works as kind of filter, but this filtering doesn't
work in this case because the "bad page" is not the actual hwpoisoned
page. So stop locking page again. Actions to be taken depend on the
page type of the error, so page unlocking should be done in ->action()
callbacks. So let's make it assumed and change all existing callbacks
that way.
Link: https://lkml.kernel.org/r/20210609072029.74645-1-nao.horiguchi@gmail.com
Fixes: commit 78bb920344b8 ("mm: hwpoison: dissolve in-use hugepage in unrecoverable memory error")
Signed-off-by: Naoya Horiguchi <naoya.horiguchi(a)nec.com>
Cc: Oscar Salvador <osalvador(a)suse.de>
Cc: Michal Hocko <mhocko(a)suse.com>
Cc: Tony Luck <tony.luck(a)intel.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar(a)linux.vnet.ibm.com>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Ma Wupeng <mawupeng1(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
mm/memory-failure.c | 44 ++++++++++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 55c175f57223..9a816fdf812d 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -662,6 +662,7 @@ static int truncate_error_page(struct page *p, unsigned long pfn,
*/
static int me_kernel(struct page *p, unsigned long pfn)
{
+ unlock_page(p);
return MF_IGNORED;
}
@@ -671,6 +672,7 @@ static int me_kernel(struct page *p, unsigned long pfn)
static int me_unknown(struct page *p, unsigned long pfn)
{
pr_err("Memory failure: %#lx: Unknown page state\n", pfn);
+ unlock_page(p);
return MF_FAILED;
}
@@ -679,6 +681,7 @@ static int me_unknown(struct page *p, unsigned long pfn)
*/
static int me_pagecache_clean(struct page *p, unsigned long pfn)
{
+ int ret;
struct address_space *mapping;
delete_from_lru_cache(p);
@@ -687,8 +690,10 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
* For anonymous pages we're done the only reference left
* should be the one m_f() holds.
*/
- if (PageAnon(p))
- return MF_RECOVERED;
+ if (PageAnon(p)) {
+ ret = MF_RECOVERED;
+ goto out;
+ }
/*
* Now truncate the page in the page cache. This is really
@@ -702,7 +707,8 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
/*
* Page has been teared down in the meanwhile
*/
- return MF_FAILED;
+ ret = MF_FAILED;
+ goto out;
}
/*
@@ -710,7 +716,10 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
*
* Open: to take i_mutex or not for this? Right now we don't.
*/
- return truncate_error_page(p, pfn, mapping);
+ ret = truncate_error_page(p, pfn, mapping);
+out:
+ unlock_page(p);
+ return ret;
}
/*
@@ -786,24 +795,26 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn)
*/
static int me_swapcache_dirty(struct page *p, unsigned long pfn)
{
+ int ret;
+
ClearPageDirty(p);
/* Trigger EIO in shmem: */
ClearPageUptodate(p);
- if (!delete_from_lru_cache(p))
- return MF_DELAYED;
- else
- return MF_FAILED;
+ ret = delete_from_lru_cache(p) ? MF_FAILED : MF_DELAYED;
+ unlock_page(p);
+ return ret;
}
static int me_swapcache_clean(struct page *p, unsigned long pfn)
{
+ int ret;
+
delete_from_swap_cache(p);
- if (!delete_from_lru_cache(p))
- return MF_RECOVERED;
- else
- return MF_FAILED;
+ ret = delete_from_lru_cache(p) ? MF_FAILED : MF_RECOVERED;
+ unlock_page(p);
+ return ret;
}
/*
@@ -824,6 +835,7 @@ static int me_huge_page(struct page *p, unsigned long pfn)
mapping = page_mapping(hpage);
if (mapping) {
res = truncate_error_page(hpage, pfn, mapping);
+ unlock_page(hpage);
} else {
res = MF_FAILED;
unlock_page(hpage);
@@ -838,7 +850,6 @@ static int me_huge_page(struct page *p, unsigned long pfn)
page_ref_inc(p);
res = MF_RECOVERED;
}
- lock_page(hpage);
}
return res;
@@ -871,6 +882,8 @@ static struct page_state {
unsigned long mask;
unsigned long res;
enum mf_action_page_type type;
+
+ /* Callback ->action() has to unlock the relevant page inside it. */
int (*action)(struct page *p, unsigned long pfn);
} error_states[] = {
{ reserved, reserved, MF_MSG_KERNEL, me_kernel },
@@ -935,6 +948,7 @@ static int page_action(struct page_state *ps, struct page *p,
int result;
int count;
+ /* page p should be unlocked after returning from ps->action(). */
result = ps->action(p, pfn);
count = page_count(p) - 1;
@@ -1235,7 +1249,7 @@ static int memory_failure_hugetlb(unsigned long pfn, int flags)
goto out;
}
- res = identify_page_state(pfn, p, page_flags);
+ return identify_page_state(pfn, p, page_flags);
out:
unlock_page(head);
return res;
@@ -1533,6 +1547,8 @@ int memory_failure(unsigned long pfn, int flags)
identify_page_state:
res = identify_page_state(pfn, p, page_flags);
+ mutex_unlock(&mf_mutex);
+ return res;
unlock_page:
unlock_page(p);
unlock_mutex:
--
2.25.1
1
7
您好!
Kernel SIG 邀请您参加 2023-01-13 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler Kernel SIG双周例会
会议内容:
1. 进展update
2. 议题征集中
欢迎大家积极申报议题(新增议题可以回复邮件反馈,或者录入会议看板)
会议链接:https://us06web.zoom.us/j/82433422280?pwd=S2FtQmg2cTVJdUpZeExoOGNyRzlUQT09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2023-01-13 14:00,
The subject of the conference is openEuler Kernel SIG双周例会,
Summary:
1. 进展update
2. 议题征集中
欢迎大家积极申报议题(新增议题可以回复邮件反馈,或者录入会议看板)
You can join the meeting at https://us06web.zoom.us/j/82433422280?pwd=S2FtQmg2cTVJdUpZeExoOGNyRzlUQT09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
1
0

[PATCH openEuler-5.10-LTS 1/5] USB: core: Prevent nested device-reset calls
by Jialin Zhang 11 Jan '23
by Jialin Zhang 11 Jan '23
11 Jan '23
From: Alan Stern <stern(a)rowland.harvard.edu>
mainline inclusion
from mainline-v6.0-rc4
commit 9c6d778800b921bde3bff3cff5003d1650f942d1
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I675RE
CVE: CVE-2022-4662
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
Automatic kernel fuzzing revealed a recursive locking violation in
usb-storage:
============================================
WARNING: possible recursive locking detected
5.18.0 #3 Not tainted
--------------------------------------------
kworker/1:3/1205 is trying to acquire lock:
ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at:
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230
but task is already holding lock:
ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at:
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230
...
stack backtrace:
CPU: 1 PID: 1205 Comm: kworker/1:3 Not tainted 5.18.0 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Workqueue: usb_hub_wq hub_event
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
print_deadlock_bug kernel/locking/lockdep.c:2988 [inline]
check_deadlock kernel/locking/lockdep.c:3031 [inline]
validate_chain kernel/locking/lockdep.c:3816 [inline]
__lock_acquire.cold+0x152/0x3ca kernel/locking/lockdep.c:5053
lock_acquire kernel/locking/lockdep.c:5665 [inline]
lock_acquire+0x1ab/0x520 kernel/locking/lockdep.c:5630
__mutex_lock_common kernel/locking/mutex.c:603 [inline]
__mutex_lock+0x14f/0x1610 kernel/locking/mutex.c:747
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230
usb_reset_device+0x37d/0x9a0 drivers/usb/core/hub.c:6109
r871xu_dev_remove+0x21a/0x270 drivers/staging/rtl8712/usb_intf.c:622
usb_unbind_interface+0x1bd/0x890 drivers/usb/core/driver.c:458
device_remove drivers/base/dd.c:545 [inline]
device_remove+0x11f/0x170 drivers/base/dd.c:537
__device_release_driver drivers/base/dd.c:1222 [inline]
device_release_driver_internal+0x1a7/0x2f0 drivers/base/dd.c:1248
usb_driver_release_interface+0x102/0x180 drivers/usb/core/driver.c:627
usb_forced_unbind_intf+0x4d/0xa0 drivers/usb/core/driver.c:1118
usb_reset_device+0x39b/0x9a0 drivers/usb/core/hub.c:6114
This turned out not to be an error in usb-storage but rather a nested
device reset attempt. That is, as the rtl8712 driver was being
unbound from a composite device in preparation for an unrelated USB
reset (that driver does not have pre_reset or post_reset callbacks),
its ->remove routine called usb_reset_device() -- thus nesting one
reset call within another.
Performing a reset as part of disconnect processing is a questionable
practice at best. However, the bug report points out that the USB
core does not have any protection against nested resets. Adding a
reset_in_progress flag and testing it will prevent such errors in the
future.
Link: https://lore.kernel.org/all/CAB7eexKUpvX-JNiLzhXBDWgfg2T9e9_0Tw4HQ6keN==voR…
Cc: stable(a)vger.kernel.org
Reported-and-tested-by: Rondreis <linhaoguo86(a)gmail.com>
Signed-off-by: Alan Stern <stern(a)rowland.harvard.edu>
Link: https://lore.kernel.org/r/YwkflDxvg0KWqyZK@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yuyao Lin <linyuyao1(a)huawei.com>
Reviewed-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
---
drivers/usb/core/hub.c | 10 ++++++++++
include/linux/usb.h | 2 ++
2 files changed, 12 insertions(+)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 18ee3914b468..53b3d77fba6a 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5967,6 +5967,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
* the reset is over (using their post_reset method).
*
* Return: The same as for usb_reset_and_verify_device().
+ * However, if a reset is already in progress (for instance, if a
+ * driver doesn't have pre_ or post_reset() callbacks, and while
+ * being unbound or re-bound during the ongoing reset its disconnect()
+ * or probe() routine tries to perform a second, nested reset), the
+ * routine returns -EINPROGRESS.
*
* Note:
* The caller must own the device lock. For example, it's safe to use
@@ -6000,6 +6005,10 @@ int usb_reset_device(struct usb_device *udev)
return -EISDIR;
}
+ if (udev->reset_in_progress)
+ return -EINPROGRESS;
+ udev->reset_in_progress = 1;
+
port_dev = hub->ports[udev->portnum - 1];
/*
@@ -6064,6 +6073,7 @@ int usb_reset_device(struct usb_device *udev)
usb_autosuspend_device(udev);
memalloc_noio_restore(noio_flag);
+ udev->reset_in_progress = 0;
return ret;
}
EXPORT_SYMBOL_GPL(usb_reset_device);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index d6a41841b93e..a093667991bb 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -580,6 +580,7 @@ struct usb3_lpm_parameters {
* @devaddr: device address, XHCI: assigned by HW, others: same as devnum
* @can_submit: URBs may be submitted
* @persist_enabled: USB_PERSIST enabled for this device
+ * @reset_in_progress: the device is being reset
* @have_langid: whether string_langid is valid
* @authorized: policy has said we can use it;
* (user space) policy determines if we authorize this device to be
@@ -665,6 +666,7 @@ struct usb_device {
unsigned can_submit:1;
unsigned persist_enabled:1;
+ unsigned reset_in_progress:1;
unsigned have_langid:1;
unsigned authorized:1;
unsigned authenticated:1;
--
2.25.1
1
4

[PATCH openEuler-1.0-LTS] arm64: Kconfig: default unset ARCH_LLC_128_LINE_SIZE
by Laibin Qiu 11 Jan '23
by Laibin Qiu 11 Jan '23
11 Jan '23
From: Wang ShaoBo <bobo.shaobowang(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I47W8L
CVE: NA
---------------------------
This patch default set CONFIG_ARCH_LLC_128_LINE_SIZE=n.
Signed-off-by: Wang ShaoBo <bobo.shaobowang(a)huawei.com>
Reviewed-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
arch/arm64/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 927d6666770e..003e333ad864 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -928,7 +928,7 @@ config ARCH_HAS_CACHE_LINE_SIZE
config ARCH_LLC_128_LINE_SIZE
bool "Force 128 bytes alignment for fitting LLC cacheline"
depends on ARM64
- default y
+ default n
help
As specific machine's LLC cacheline size may be up to
128 bytes, gaining performance improvement from fitting
--
2.25.1
1
0

10 Jan '23
From: Zhou Guanghui <zhouguanghui1(a)huawei.com>
ascend inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I67NC1
CVE: NA
------------------------------------------
Add header file will generates kabi change problem. Clean up by
__GENKSYMS__.
Signed-off-by: Zhou Guanghui <zhouguanghui1(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
include/linux/share_pool.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h
index 2ebfb3d5be13..974082a6747e 100644
--- a/include/linux/share_pool.h
+++ b/include/linux/share_pool.h
@@ -8,8 +8,11 @@
#include <linux/printk.h>
#include <linux/hashtable.h>
#include <linux/numa.h>
+
+#if defined(CONFIG_ASCEND_SHARE_POOL) && !defined(__GENKSYMS__)
#include <linux/hugetlb.h>
#include <linux/memcontrol.h>
+#endif
#define SP_HUGEPAGE (1 << 0)
#define SP_HUGEPAGE_ONLY (1 << 1)
--
2.25.1
1
0

10 Jan '23
From: Tony Lu <tonylu(a)linux.alibaba.com>
anolis inclusion
from devel-5.10-v5.10.134-12
commit b90e28f7170e1ae40c572f9f80a50bbdc8f8b99f
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I697AN
CVE: NA
Reference: https://gitee.com/anolis/cloud-kernel/commit/b90e28f7170e1ae40c572f9f80a50b…
---------------------------
OpenAnolis Bug Tracker:0000282
This is achieved by broadcasting ARP or ND packets to all of its slave
devices on transmit side. The switch will take further actions based on
proper configuration.
A new sysctl knob "net.bonding.broadcast_arp_or_nd" is introduced which
controls the behaviour of broadcasting.
Signed-off-by: Tony Lu <tonylu(a)linux.alibaba.com>
Acked-by: Dust Li <dust.li(a)linux.alibaba.com>
Signed-off-by: Qiao Ma <mqaio(a)linux.alibaba.com>
Reviewed-by: Shile Zhang <shile.zhang(a)linux.alibaba.com>
Acked-by: Dust Li <dust.li(a)linux.alibaba.com>
Signed-off-by: Wang Yufen <wangyufen(a)huawei.com>
---
Documentation/networking/ip-sysctl.rst | 11 ++++++++++
drivers/net/bonding/Makefile | 2 +-
drivers/net/bonding/bond_main.c | 40 ++++++++++++++++++++++++++++++++++
drivers/net/bonding/bond_sysctl.c | 32 +++++++++++++++++++++++++++
include/net/bonding.h | 4 ++++
5 files changed, 88 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/bonding/bond_sysctl.c
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index 4822a05..4953fa9 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -2656,3 +2656,14 @@ max_dgram_qlen - INTEGER
Default: 10
+
+``/proc/sys/net/bonding/*``
+========================
+
+broadcast_arp_or_nd - INTEGER
+ Control broadcasting ARP or ND messages to all slaves
+
+ 0: Not broadcasting
+ 1: Broadcasting
+
+ Default: 0
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 30e8ae3..9dd55d9 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -5,7 +5,7 @@
obj-$(CONFIG_BONDING) += bonding.o
-bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_sysfs_slave.o bond_debugfs.o bond_netlink.o bond_options.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_sysfs_slave.o bond_debugfs.o bond_netlink.o bond_options.o bond_sysctl.o
proc-$(CONFIG_PROC_FS) += bond_procfs.o
bonding-objs += $(proc-y)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index d382790..4d534d5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4532,6 +4532,39 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave)
return ret;
}
+/* Check whether the skb is arp or nd msg */
+static inline bool skb_is_arp_or_nd(struct sk_buff *skb)
+{
+ switch (ntohs(skb->protocol)) {
+ case ETH_P_ARP:
+ return true;
+ case ETH_P_IPV6:
+ if (pskb_may_pull(skb, sizeof(struct ipv6hdr) +
+ sizeof(struct nd_msg))) {
+ struct ipv6hdr *hdr = ipv6_hdr(skb);
+ u8 nexthdr = hdr->nexthdr;
+ struct icmp6hdr *icmp6;
+
+ if (nexthdr == IPPROTO_ICMPV6) {
+ icmp6 = icmp6_hdr(skb);
+
+ if ((icmp6->icmp6_type ==
+ NDISC_NEIGHBOUR_SOLICITATION ||
+ icmp6->icmp6_type ==
+ NDISC_NEIGHBOUR_ADVERTISEMENT) &&
+ icmp6->icmp6_code == 0) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb,
+ struct net_device *bond_dev);
+
static struct slave *bond_xmit_3ad_xor_slave_get(struct bonding *bond,
struct sk_buff *skb,
struct bond_up_slave *slaves)
@@ -4560,6 +4593,10 @@ static netdev_tx_t bond_3ad_xor_xmit(struct sk_buff *skb,
struct bond_up_slave *slaves;
struct slave *slave;
+ /* Broadcast to all slaves. */
+ if (sysctl_bond_broadcast_arp_or_nd && skb_is_arp_or_nd(skb))
+ return bond_xmit_broadcast(skb, dev);
+
slaves = rcu_dereference(bond->usable_slaves);
slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves);
if (likely(slave))
@@ -5476,6 +5513,7 @@ static int __init bonding_init(void)
goto err_link;
bond_create_debugfs();
+ bond_create_sysctl();
for (i = 0; i < max_bonds; i++) {
res = bond_create(&init_net, NULL);
@@ -5492,6 +5530,7 @@ static int __init bonding_init(void)
return res;
err:
bond_destroy_debugfs();
+ bond_destroy_sysctl();
bond_netlink_fini();
err_link:
unregister_pernet_subsys(&bond_net_ops);
@@ -5504,6 +5543,7 @@ static void __exit bonding_exit(void)
unregister_netdevice_notifier(&bond_netdev_notifier);
bond_destroy_debugfs();
+ bond_destroy_sysctl();
bond_netlink_fini();
unregister_pernet_subsys(&bond_net_ops);
diff --git a/drivers/net/bonding/bond_sysctl.c b/drivers/net/bonding/bond_sysctl.c
new file mode 100644
index 00000000..17404d3
--- /dev/null
+++ b/drivers/net/bonding/bond_sysctl.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <net/net_namespace.h>
+#include <linux/sysctl.h>
+#include <net/bonding.h>
+
+int sysctl_bond_broadcast_arp_or_nd __read_mostly;
+EXPORT_SYMBOL(sysctl_bond_broadcast_arp_or_nd);
+
+struct ctl_table_header *bond_broadcast_arp_or_nd_table_header;
+
+static struct ctl_table bond_broadcast_arp_or_nd_table[] = {
+ {
+ .procname = "broadcast_arp_or_nd",
+ .data = &sysctl_bond_broadcast_arp_or_nd,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ {}
+};
+
+void bond_create_sysctl(void)
+{
+ bond_broadcast_arp_or_nd_table_header =
+ register_net_sysctl(&init_net, "net/bonding",
+ bond_broadcast_arp_or_nd_table);
+}
+
+void bond_destroy_sysctl(void)
+{
+ unregister_net_sysctl_table(bond_broadcast_arp_or_nd_table_header);
+}
diff --git a/include/net/bonding.h b/include/net/bonding.h
index 67d6760..6ea7a29 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -114,6 +114,8 @@ static inline int is_netpoll_tx_blocked(struct net_device *dev)
#define is_netpoll_tx_blocked(dev) (0)
#endif
+extern int sysctl_bond_broadcast_arp_or_nd;
+
struct bond_params {
int mode;
int xmit_policy;
@@ -659,6 +661,8 @@ struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev,
int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave);
void bond_slave_arr_work_rearm(struct bonding *bond, unsigned long delay);
void bond_work_init_all(struct bonding *bond);
+void bond_create_sysctl(void);
+void bond_destroy_sysctl(void);
#ifdef CONFIG_PROC_FS
void bond_create_proc_entry(struct bonding *bond);
--
1.8.3.1
1
0

[PATCH openEuler-1.0-LTS 1/4] kobject: Fix slab-out-of-bounds in fill_kobj_path()
by Yongqiang Liu 10 Jan '23
by Yongqiang Liu 10 Jan '23
10 Jan '23
From: Xia Fukun <xiafukun(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I697JG
CVE: NA
--------------------------------
In kobject_get_path(), if kobj->name is changed between calls
get_kobj_path_length() and fill_kobj_path() and the length becomes
longer, then fill_kobj_path() will have an out-of-bounds bug.
The actual current problem occurs when the ixgbe probe.
In ixgbe_mii_bus_init(), if the length of netdev->dev.kobj.name
length becomes longer, out-of-bounds will occur.
cpu0 cpu1
ixgbe_probe
register_netdev(netdev)
netdev_register_kobject
device_add
kobject_uevent // Sending ADD events
systemd-udevd // rename netdev
dev_change_name
device_rename
kobject_rename
ixgbe_mii_bus_init |
mdiobus_register |
__mdiobus_register |
device_register |
device_add |
kobject_uevent |
kobject_get_path |
len = get_kobj_path_length // old name |
path = kzalloc(len, gfp_mask); |
kobj->name = name;
/* name length becomes
* longer
*/
fill_kobj_path /* kobj path length is
* longer than path,
* resulting in out of
* bounds when filling path
*/
This is the kasan report:
==================================================================
BUG: KASAN: slab-out-of-bounds in fill_kobj_path+0x50/0xc0
Write of size 7 at addr ff1100090573d1fd by task kworker/28:1/673
Workqueue: events work_for_cpu_fn
Call Trace:
<TASK>
dump_stack_lvl+0x34/0x48
print_address_description.constprop.0+0x86/0x1e7
print_report+0x36/0x4f
kasan_report+0xad/0x130
kasan_check_range+0x35/0x1c0
memcpy+0x39/0x60
fill_kobj_path+0x50/0xc0
kobject_get_path+0x5a/0xc0
kobject_uevent_env+0x140/0x460
device_add+0x5c7/0x910
__mdiobus_register+0x14e/0x490
ixgbe_probe.cold+0x441/0x574 [ixgbe]
local_pci_probe+0x78/0xc0
work_for_cpu_fn+0x26/0x40
process_one_work+0x3b6/0x6a0
worker_thread+0x368/0x520
kthread+0x165/0x1a0
ret_from_fork+0x1f/0x30
This reproducer triggers that bug:
while:
do
rmmod ixgbe
sleep 0.5
modprobe ixgbe
sleep 0.5
When calling fill_kobj_path() to fill path, if the name length of
kobj becomes longer, return failure and retry. This fixes the problem.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Wang Hai <wanghai38(a)huawei.com>
Signed-off-by: Xia Fukun <xiafukun(a)huawei.com>
Reviewed-by: songping yu <yusongping(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
lib/kobject.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/lib/kobject.c b/lib/kobject.c
index c82b88b2e860..d724a5dbcf9b 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -135,7 +135,7 @@ static int get_kobj_path_length(struct kobject *kobj)
return length;
}
-static void fill_kobj_path(struct kobject *kobj, char *path, int length)
+static int fill_kobj_path(struct kobject *kobj, char *path, int length)
{
struct kobject *parent;
@@ -144,12 +144,16 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length)
int cur = strlen(kobject_name(parent));
/* back up enough to print this name with '/' */
length -= cur;
+ if (length <= 0)
+ return -EINVAL;
memcpy(path + length, kobject_name(parent), cur);
*(path + --length) = '/';
}
pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj),
kobj, __func__, path);
+
+ return 0;
}
/**
@@ -165,13 +169,17 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
char *path;
int len;
+retry:
len = get_kobj_path_length(kobj);
if (len == 0)
return NULL;
path = kzalloc(len, gfp_mask);
if (!path)
return NULL;
- fill_kobj_path(kobj, path, len);
+ if (fill_kobj_path(kobj, path, len)) {
+ kfree(path);
+ goto retry;
+ }
return path;
}
--
2.25.1
1
3

[PATCH openEuler-1.0-LTS] timekeeping: Avoiding false sharing in field access of tk_core
by Laibin Qiu 10 Jan '23
by Laibin Qiu 10 Jan '23
10 Jan '23
From: Wang ShaoBo <bobo.shaobowang(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I47W8L
CVE: NA
---------------------------
We detect a performance deterioration when using Unixbench, we use the dichotomy to
locate the patch 7e66740ad725 ("MPAM / ACPI: Refactoring MPAM init process and set
MPAM ACPI as entrance"), In comparing two commit df5defd901ff ("KVM: X86: MMU: Use
the correct inherited permissions to get shadow page") and ac4dbb7554ef ("ACPI 6.x:
Add definitions for MPAM table") we get following testing result:
CMD: ./Run -c xx context1
RESULT:
+-------------UnixBench context1-----------+
+---------+--------------+-----------------+
+ + ac4dbb7554ef + df5defd901ff +
+---------+--------------+---------+-------+
+ Cores + Score + Score +
+---------+--------------+-----------------+
+ 1 + 522.8 + 535.7 +
+---------+--------------+-----------------+
+ 24 + 11231.5 + 12111.2 +
+---------+--------------+-----------------+
+ 48 + 8535.1 + 8745.1 +
+---------+--------------+-----------------+
+ 72 + 10821.9 + 10343.8 +
+---------+--------------+-----------------+
+ 96 + 15238.5 + 42947.8 +
+---------+--------------+-----------------+
We found a irrefutable difference in latency sampling when using the perf tool:
HEAD:ac4dbb7554ef HEAD:df5defd901ff
45.18% [kernel] [k] ktime_get_coarse_real_ts64 -> 1.78% [kernel] [k] ktime_get_coarse_real_ts64
...
65.87 │ dmb ishld //smp_rmb()
Through ftrace we get the calltrace and and detected the number of visits of
ktime_get_coarse_real_ts64, which frequently visits tk_core->seq and
tk_core->timekeeper->tkr_mono:
- 48.86% [kernel] [k] ktime_get_coarse_real_ts64
- 5.76% ktime_get_coarse_real_ts64 #about 111437657 times per 10 seconds
- 14.70% __audit_syscall_entry
syscall_trace_enter
el0_svc_common
el0_svc_handler
+ el0_svc
- 2.85% current_time
So this may be performance degradation caused by interference when happened different
fields access, We compare .bss and .data section of this two version:
HEAD:ac4dbb7554ef
`->
ffff00000962e680 l O .bss 0000000000000110 tk_core
ffff000009355680 l O .data 0000000000000078 tk_fast_mono
ffff0000093557a0 l O .data 0000000000000090 dummy_clock
ffff000009355700 l O .data 0000000000000078 tk_fast_raw
ffff000009355778 l O .data 0000000000000028 timekeeping_syscore_ops
ffff00000962e640 l O .bss 0000000000000008 cycles_at_suspend
HEAD:df5defd901ff
`->
ffff00000957dbc0 l O .bss 0000000000000110 tk_core
ffff0000092b4e80 l O .data 0000000000000078 tk_fast_mono
ffff0000092b4fa0 l O .data 0000000000000090 dummy_clock
ffff0000092b4f00 l O .data 0000000000000078 tk_fast_raw
ffff0000092b4f78 l O .data 0000000000000028 timekeeping_syscore_ops
ffff00000957db80 l O .bss 0000000000000008 cycles_at_suspend
By comparing this two version tk_core's address: ffff00000962e680 is 128Byte aligned
but latter df5defd901ff is 64Byte aligned, the memory storage layout of tk_core has
undergone subtle changes:
HEAD:ac4dbb7554ef
`-> |<--------formmer 64Bytes---------->|<------------latter 64Byte------------->|
0xffff00000957dbc0_>|<-seq 8Bytes->|<-tkr_mono 56Bytes->|<-thr_raw 56Bytes->|<-xtime_sec 8Bytes->|
0xffff00000957dc00_>...
HEAD:df5defd901ff
`-> |<------formmer 64Bytes---->|<------------latter 64Byte-------->|
0xffff00000962e680_>|<-Other variables 64Bytes->|<-seq 8Bytes->|<-tkr_mono 56Bytes->|
0xffff00000962e6c0_>..
We testified thr_raw,xtime_sec fields interfere strongly with seq,tkr_mono field because of
frequent load/store operation, this will cause as known false sharing.
We add a 64Bytes padding field in tk_core for reservation of any after usefull usage and
keep tk_core 128Byte aligned, this can avoid changes in the way tk_core's layout is stored,
In this solution, layout of tk_core always like this:
crash> struct -o tk_core_t
struct tk_core_t {
[0] u64 padding[8];
[64] seqcount_t seq;
[72] struct timekeeper timekeeper;
}
SIZE: 336
crash> struct -o timekeeper
struct timekeeper {
[0] struct tk_read_base tkr_mono;
[56] struct tk_read_base tkr_raw;
[112] u64 xtime_sec;
[120] unsigned long ktime_sec;
...
}
SIZE: 264
After appling our own solution:
+---------+--------------+
+ + Our solution +
+---------+--------------+
+ Cores + Score +
+---------+--------------+
+ 1 + 548.9 +
+---------+--------------+
+ 24 + 11018.3 +
+---------+--------------+
+ 48 + 8938.2 +
+---------+--------------+
+ 72 + 14610.7 +
+---------+--------------+
+ 96 + 40811.7 +
+---------+--------------+
Signed-off-by: Wang ShaoBo <bobo.shaobowang(a)huawei.com>
Reviewed-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com>
Signed-off-by: Laibin Qiu <qiulaibin(a)huawei.com>
---
arch/arm64/Kconfig | 9 +++++++++
arch/arm64/include/asm/cache.h | 6 ++++++
kernel/time/timekeeping.c | 7 +++++++
3 files changed, 22 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0ad6ce436355..927d6666770e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -925,6 +925,15 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
+config ARCH_LLC_128_LINE_SIZE
+ bool "Force 128 bytes alignment for fitting LLC cacheline"
+ depends on ARM64
+ default y
+ help
+ As specific machine's LLC cacheline size may be up to
+ 128 bytes, gaining performance improvement from fitting
+ 128 Bytes LLC cache aligned.
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
---help---
diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
index d1c46d75885f..ccb013f822ba 100644
--- a/arch/arm64/include/asm/cache.h
+++ b/arch/arm64/include/asm/cache.h
@@ -40,6 +40,12 @@
#define L1_CACHE_SHIFT (6)
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+#ifdef CONFIG_ARCH_LLC_128_LINE_SIZE
+#ifndef ____cacheline_aligned_128
+#define ____cacheline_aligned_128 __attribute__((__aligned__(128)))
+#endif
+#endif
+
#define CLIDR_LOUU_SHIFT 27
#define CLIDR_LOC_SHIFT 24
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index f246818e35db..0ebfe476b6b4 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -48,9 +48,16 @@ enum timekeeping_adv_mode {
* cache line.
*/
static struct {
+#ifdef CONFIG_ARCH_LLC_128_LINE_SIZE
+ u64 padding[8];
+#endif
seqcount_t seq;
struct timekeeper timekeeper;
+#ifdef CONFIG_ARCH_LLC_128_LINE_SIZE
+} tk_core ____cacheline_aligned_128 = {
+#else
} tk_core ____cacheline_aligned = {
+#endif
.seq = SEQCNT_ZERO(tk_core.seq),
};
--
2.25.1
1
0

[PATCH openEuler-5.10-LTS 1/9] xfs: get rid of assert from xfs_btree_islastblock
by Zheng Zengkai 06 Jan '23
by Zheng Zengkai 06 Jan '23
06 Jan '23
From: Guo Xuenan <guoxuenan(a)huawei.com>
mainline inclusion
from mainline-v6.1-rc4
commit 8c25febf23963431686f04874b96321288504127
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4KIAO
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
xfs_btree_check_block contains debugging knobs. With XFS_DEBUG setting up,
turn on the debugging knob can trigger the assert of xfs_btree_islastblock,
test script as follows:
while true
do
mount $disk $mountpoint
fsstress -d $testdir -l 0 -n 10000 -p 4 >/dev/null
echo 1 > /sys/fs/xfs/sda/errortag/btree_chk_sblk
sleep 10
umount $mountpoint
done
Kick off fsstress and only *then* turn on the debugging knob. If it
happens that the knob gets turned on after the cntbt lookup succeeds
but before the call to xfs_btree_islastblock, then we *can* end up in
the situation where a previously checked btree block suddenly starts
returning EFSCORRUPTED from xfs_btree_check_block. Kaboom.
Darrick give a very detailed explanation as follows:
Looking back at commit 27d9ee577dcce, I think the point of all this was
to make sure that the cursor has actually performed a lookup, and that
the btree block at whatever level we're asking about is ok.
If the caller hasn't ever done a lookup, the bc_levels array will be
empty, so cur->bc_levels[level].bp pointer will be NULL. The call to
xfs_btree_get_block will crash anyway, so the "ASSERT(block);" part is
pointless.
If the caller did a lookup but the lookup failed due to block
corruption, the corresponding cur->bc_levels[level].bp pointer will also
be NULL, and we'll still crash. The "ASSERT(xfs_btree_check_block);"
logic is also unnecessary.
If the cursor level points to an inode root, the block buffer will be
incore, so it had better always be consistent.
If the caller ignores a failed lookup after a successful one and calls
this function, the cursor state is garbage and the assert wouldn't have
tripped anyway. So get rid of the assert.
Fixes: 27d9ee577dcc ("xfs: actually check xfs_btree_check_block return in xfs_btree_islastblock")
Signed-off-by: Guo Xuenan <guoxuenan(a)huawei.com>
Reviewed-by: Darrick J. Wong <djwong(a)kernel.org>
Signed-off-by: Darrick J. Wong <djwong(a)kernel.org>
Signed-off-by: Guo Xuenan <guoxuenan(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
fs/xfs/libxfs/xfs_btree.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h
index 10e50cbacacf..ba11d2a4b686 100644
--- a/fs/xfs/libxfs/xfs_btree.h
+++ b/fs/xfs/libxfs/xfs_btree.h
@@ -523,7 +523,6 @@ xfs_btree_islastblock(
struct xfs_buf *bp;
block = xfs_btree_get_block(cur, level, &bp);
- ASSERT(block && xfs_btree_check_block(cur, block, level, bp) == 0);
if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK);
--
2.20.1
1
8

[PATCH openEuler-1.0-LTS] tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line
by Yongqiang Liu 05 Jan '23
by Yongqiang Liu 05 Jan '23
05 Jan '23
From: Yang Jihong <yangjihong1(a)huawei.com>
mainline inclusion
from mainline-v6.2-rc1
commit c1ac03af6ed45d05786c219d102f37eb44880f28
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I69283
CVE: NA
--------------------------------
print_trace_line may overflow seq_file buffer. If the event is not
consumed, the while loop keeps peeking this event, causing a infinite loop.
Link: https://lkml.kernel.org/r/20221129113009.182425-1-yangjihong1@huawei.com
Cc: Masami Hiramatsu <mhiramat(a)kernel.org>
Cc: stable(a)vger.kernel.org
Fixes: 088b1e427dbba ("ftrace: pipe fixes")
Signed-off-by: Yang Jihong <yangjihong1(a)huawei.com>
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
Signed-off-by: Yang Jihong <yangjihong1(a)huawei.com>
Reviewed-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Reviewed-by: Ye Weihua <yeweihua4(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
kernel/trace/trace.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index feed30698280..9daaee7a9dd2 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -5771,7 +5771,20 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
ret = print_trace_line(iter);
if (ret == TRACE_TYPE_PARTIAL_LINE) {
- /* don't print partial lines */
+ /*
+ * If one print_trace_line() fills entire trace_seq in one shot,
+ * trace_seq_to_user() will returns -EBUSY because save_len == 0,
+ * In this case, we need to consume it, otherwise, loop will peek
+ * this event next time, resulting in an infinite loop.
+ */
+ if (save_len == 0) {
+ iter->seq.full = 0;
+ trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n");
+ trace_consume(iter);
+ break;
+ }
+
+ /* In other cases, don't print partial lines */
iter->seq.seq.len = save_len;
break;
}
--
2.25.1
1
0

[PATCH openEuler-1.0-LTS 1/2] misc: sgi-gru: fix use-after-free error in gru_set_context_option, gru_fault and gru_handle_user_call_os
by Yongqiang Liu 05 Jan '23
by Yongqiang Liu 05 Jan '23
05 Jan '23
From: Zheng Wang <zyytlz.wz(a)163.com>
mainline inclusion
from mainline-v6.2-rc1
commit 643a16a0eb1d6ac23744bb6e90a00fc21148a9dc
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5UBUF
CVE: CVE-2022-3424
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?i…
--------------------------------
In some bad situation, the gts may be freed gru_check_chiplet_assignment.
The call chain can be gru_unload_context->gru_free_gru_context->gts_drop
and kfree finally. However, the caller didn't know if the gts is freed
or not and use it afterwards. This will trigger a Use after Free bug.
Fix it by introducing a return value to see if it's in error path or not.
Free the gts in caller if gru_check_chiplet_assignment check failed.
Fixes: 55484c45dbec ("gru: allow users to specify gru chiplet 2")
Signed-off-by: Zheng Wang <zyytlz.wz(a)163.com>
Acked-by: Dimitri Sivanich <sivanich(a)hpe.com>
Link: https://lore.kernel.org/r/20221110035033.19498-1-zyytlz.wz@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Reviewed-by: Kuohai Xu <xukuohai(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/misc/sgi-gru/grufault.c | 13 +++++++++++--
drivers/misc/sgi-gru/grumain.c | 22 ++++++++++++++++++----
drivers/misc/sgi-gru/grutables.h | 2 +-
3 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 93be82fc338a..16df731e63c5 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -661,6 +661,7 @@ int gru_handle_user_call_os(unsigned long cb)
if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB)
return -EINVAL;
+again:
gts = gru_find_lock_gts(cb);
if (!gts)
return -EINVAL;
@@ -669,7 +670,11 @@ int gru_handle_user_call_os(unsigned long cb)
if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
goto exit;
- gru_check_context_placement(gts);
+ if (gru_check_context_placement(gts)) {
+ gru_unlock_gts(gts);
+ gru_unload_context(gts, 1);
+ goto again;
+ }
/*
* CCH may contain stale data if ts_force_cch_reload is set.
@@ -887,7 +892,11 @@ int gru_set_context_option(unsigned long arg)
} else {
gts->ts_user_blade_id = req.val1;
gts->ts_user_chiplet_id = req.val0;
- gru_check_context_placement(gts);
+ if (gru_check_context_placement(gts)) {
+ gru_unlock_gts(gts);
+ gru_unload_context(gts, 1);
+ return ret;
+ }
}
break;
case sco_gseg_owner:
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index ab174f28e3be..8c3e0317c115 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -729,9 +729,10 @@ static int gru_check_chiplet_assignment(struct gru_state *gru,
* chiplet. Misassignment can occur if the process migrates to a different
* blade or if the user changes the selected blade/chiplet.
*/
-void gru_check_context_placement(struct gru_thread_state *gts)
+int gru_check_context_placement(struct gru_thread_state *gts)
{
struct gru_state *gru;
+ int ret = 0;
/*
* If the current task is the context owner, verify that the
@@ -739,15 +740,23 @@ void gru_check_context_placement(struct gru_thread_state *gts)
* references. Pthread apps use non-owner references to the CBRs.
*/
gru = gts->ts_gru;
+ /*
+ * If gru or gts->ts_tgid_owner isn't initialized properly, return
+ * success to indicate that the caller does not need to unload the
+ * gru context.The caller is responsible for their inspection and
+ * reinitialization if needed.
+ */
if (!gru || gts->ts_tgid_owner != current->tgid)
- return;
+ return ret;
if (!gru_check_chiplet_assignment(gru, gts)) {
STAT(check_context_unload);
- gru_unload_context(gts, 1);
+ ret = -EINVAL;
} else if (gru_retarget_intr(gts)) {
STAT(check_context_retarget_intr);
}
+
+ return ret;
}
@@ -947,7 +956,12 @@ vm_fault_t gru_fault(struct vm_fault *vmf)
mutex_lock(>s->ts_ctxlock);
preempt_disable();
- gru_check_context_placement(gts);
+ if (gru_check_context_placement(gts)) {
+ preempt_enable();
+ mutex_unlock(>s->ts_ctxlock);
+ gru_unload_context(gts, 1);
+ return VM_FAULT_NOPAGE;
+ }
if (!gts->ts_gru) {
STAT(load_user_context);
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
index 3e041b6f7a68..2becf4c3f7ca 100644
--- a/drivers/misc/sgi-gru/grutables.h
+++ b/drivers/misc/sgi-gru/grutables.h
@@ -652,7 +652,7 @@ extern int gru_user_flush_tlb(unsigned long arg);
extern int gru_user_unload_context(unsigned long arg);
extern int gru_get_exception_detail(unsigned long arg);
extern int gru_set_context_option(unsigned long address);
-extern void gru_check_context_placement(struct gru_thread_state *gts);
+extern int gru_check_context_placement(struct gru_thread_state *gts);
extern int gru_cpu_fault_map_id(void);
extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
extern void gru_flush_all_tlb(struct gru_state *gru);
--
2.25.1
1
1
hulk inclusion
bugzilla: https://gitee.com/openeuler/kernel/issues/I68D0O
This defconfig is based on openEuler-22.03-LTS-SP1:
cp /boot/config-5.10.0-136.12.0.86.oe2203sp1.x86_64 arch/x86/configs/openeuler_defconfig
make update_oedefconfig
Signed-off-by: Xie XiuQi <xiexiuqi(a)huawei.com>
---
arch/x86/configs/openeuler_defconfig | 8938 ++++++++++++++++++++++++++
1 file changed, 8938 insertions(+)
create mode 100644 arch/x86/configs/openeuler_defconfig
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
new file mode 100644
index 000000000000..8a824f33bc5b
--- /dev/null
+++ b/arch/x86/configs/openeuler_defconfig
@@ -0,0 +1,8938 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/x86 6.1.0 Kernel Configuration
+#
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_TABLE_SORT=y
+CONFIG_THREAD_INFO_IN_TASK=y
+
+#
+# General setup
+#
+CONFIG_INIT_ENV_ARG_LIMIT=32
+# CONFIG_COMPILE_TEST is not set
+# CONFIG_WERROR is not set
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_BUILD_SALT=""
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_HAVE_KERNEL_ZSTD=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
+# CONFIG_KERNEL_ZSTD is not set
+CONFIG_DEFAULT_INIT=""
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_WATCH_QUEUE is not set
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_USELIB is not set
+CONFIG_AUDIT=y
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+CONFIG_AUDITSYSCALL=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_INJECTION=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
+CONFIG_IRQ_MSI_IOMMU=y
+CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
+CONFIG_GENERIC_IRQ_RESERVATION_MODE=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+# CONFIG_GENERIC_IRQ_DEBUGFS is not set
+# end of IRQ subsystem
+
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_ARCH_CLOCKSOURCE_INIT=y
+CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+# CONFIG_NO_HZ_IDLE is not set
+CONFIG_NO_HZ_FULL=y
+CONFIG_CONTEXT_TRACKING_USER=y
+# CONFIG_CONTEXT_TRACKING_USER_FORCE is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100
+# end of Timers subsystem
+
+CONFIG_BPF=y
+CONFIG_HAVE_EBPF_JIT=y
+CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
+
+#
+# BPF subsystem
+#
+CONFIG_BPF_SYSCALL=y
+CONFIG_BPF_JIT=y
+CONFIG_BPF_JIT_ALWAYS_ON=y
+CONFIG_BPF_JIT_DEFAULT_ON=y
+# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set
+# CONFIG_BPF_PRELOAD is not set
+# CONFIG_BPF_LSM is not set
+# end of BPF subsystem
+
+CONFIG_PREEMPT_BUILD=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_COUNT=y
+CONFIG_PREEMPTION=y
+CONFIG_PREEMPT_DYNAMIC=y
+# CONFIG_SCHED_CORE is not set
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_SCHED_AVG_IRQ=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_PSI=y
+CONFIG_PSI_DEFAULT_DISABLED=y
+# end of CPU/Task time and stats accounting
+
+CONFIG_CPU_ISOLATION=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_EXPERT is not set
+CONFIG_SRCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TASKS_RCU_GENERIC=y
+CONFIG_TASKS_RCU=y
+CONFIG_TASKS_RUDE_RCU=y
+CONFIG_TASKS_TRACE_RCU=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_NOCB_CPU=y
+# CONFIG_RCU_NOCB_CPU_DEFAULT_ALL is not set
+# end of RCU Subsystem
+
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_IKHEADERS is not set
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
+# CONFIG_PRINTK_INDEX is not set
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
+
+#
+# Scheduler features
+#
+# CONFIG_UCLAMP_TASK is not set
+# end of Scheduler features
+
+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
+CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_GCC12_NO_ARRAY_BOUNDS=y
+CONFIG_ARCH_SUPPORTS_INT128=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y
+CONFIG_CGROUPS=y
+CONFIG_PAGE_COUNTER=y
+# CONFIG_CGROUP_FAVOR_DYNMODS is not set
+CONFIG_MEMCG=y
+CONFIG_MEMCG_KMEM=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CGROUP_WRITEBACK=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_RDMA=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
+# CONFIG_CGROUP_MISC is not set
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_SOCK_CGROUP_DATA=y
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_TIME_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_SCHED_AUTOGROUP=y
+# CONFIG_SYSFS_DEPRECATED is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+CONFIG_RD_LZ4=y
+CONFIG_RD_ZSTD=y
+CONFIG_BOOT_CONFIG=y
+# CONFIG_BOOT_CONFIG_EMBED is not set
+CONFIG_INITRAMFS_PRESERVE_MTIME=y
+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LD_ORPHAN_WARN=y
+CONFIG_SYSCTL=y
+CONFIG_HAVE_UID16=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_HAVE_PCSPKR_PLATFORM=y
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+CONFIG_MULTIUSER=y
+CONFIG_SGETMASK_SYSCALL=y
+CONFIG_SYSFS_SYSCALL=y
+CONFIG_FHANDLE=y
+CONFIG_POSIX_TIMERS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_FUTEX_PI=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_IO_URING=y
+CONFIG_ADVISE_SYSCALLS=y
+CONFIG_MEMBARRIER=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y
+CONFIG_KALLSYMS_BASE_RELATIVE=y
+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
+CONFIG_KCMP=y
+CONFIG_RSEQ=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_GUEST_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+# end of Kernel Performance Events And Counters
+
+CONFIG_SYSTEM_DATA_VERIFICATION=y
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# end of General setup
+
+CONFIG_64BIT=y
+CONFIG_X86_64=y
+CONFIG_X86=y
+CONFIG_INSTRUCTION_DECODER=y
+CONFIG_OUTPUT_FORMAT="elf64-x86-64"
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_MMU=y
+CONFIG_ARCH_MMAP_RND_BITS_MIN=28
+CONFIG_ARCH_MMAP_RND_BITS_MAX=32
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_NR_GPIO=1024
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_HAVE_INTEL_TXT=y
+CONFIG_X86_64_SMP=y
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_DYNAMIC_PHYSICAL_MASK=y
+CONFIG_PGTABLE_LEVELS=5
+
+#
+# Processor type and features
+#
+CONFIG_SMP=y
+CONFIG_X86_FEATURE_NAMES=y
+CONFIG_X86_X2APIC=y
+CONFIG_X86_MPPARSE=y
+# CONFIG_GOLDFISH is not set
+CONFIG_X86_CPU_RESCTRL=y
+CONFIG_X86_EXTENDED_PLATFORM=y
+# CONFIG_X86_NUMACHIP is not set
+# CONFIG_X86_VSMP is not set
+CONFIG_X86_UV=y
+# CONFIG_X86_GOLDFISH is not set
+# CONFIG_X86_INTEL_MID is not set
+CONFIG_X86_INTEL_LPSS=y
+CONFIG_X86_AMD_PLATFORM_DEVICE=y
+CONFIG_IOSF_MBI=y
+# CONFIG_IOSF_MBI_DEBUG is not set
+CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_HYPERVISOR_GUEST=y
+CONFIG_PARAVIRT=y
+# CONFIG_PARAVIRT_DEBUG is not set
+CONFIG_PARAVIRT_SPINLOCKS=y
+CONFIG_X86_HV_CALLBACK_VECTOR=y
+CONFIG_XEN=y
+# CONFIG_XEN_PV is not set
+CONFIG_XEN_PVHVM=y
+CONFIG_XEN_PVHVM_SMP=y
+CONFIG_XEN_PVHVM_GUEST=y
+CONFIG_XEN_SAVE_RESTORE=y
+# CONFIG_XEN_DEBUG_FS is not set
+# CONFIG_XEN_PVH is not set
+CONFIG_KVM_GUEST=y
+CONFIG_ARCH_CPUIDLE_HALTPOLL=y
+# CONFIG_PVH is not set
+CONFIG_PARAVIRT_TIME_ACCOUNTING=y
+CONFIG_PARAVIRT_CLOCK=y
+# CONFIG_JAILHOUSE_GUEST is not set
+# CONFIG_ACRN_GUEST is not set
+# CONFIG_INTEL_TDX_GUEST is not set
+# CONFIG_MK8 is not set
+# CONFIG_MPSC is not set
+# CONFIG_MCORE2 is not set
+# CONFIG_MATOM is not set
+CONFIG_GENERIC_CPU=y
+CONFIG_X86_INTERNODE_CACHE_SHIFT=6
+CONFIG_X86_L1_CACHE_SHIFT=6
+CONFIG_X86_TSC=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_CMOV=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=64
+CONFIG_X86_DEBUGCTLMSR=y
+CONFIG_IA32_FEAT_CTL=y
+CONFIG_X86_VMX_FEATURE_NAMES=y
+CONFIG_CPU_SUP_INTEL=y
+CONFIG_CPU_SUP_AMD=y
+CONFIG_CPU_SUP_HYGON=y
+CONFIG_CPU_SUP_CENTAUR=y
+CONFIG_CPU_SUP_ZHAOXIN=y
+CONFIG_HPET_TIMER=y
+CONFIG_HPET_EMULATE_RTC=y
+CONFIG_DMI=y
+# CONFIG_GART_IOMMU is not set
+CONFIG_BOOT_VESA_SUPPORT=y
+CONFIG_MAXSMP=y
+CONFIG_NR_CPUS_RANGE_BEGIN=8192
+CONFIG_NR_CPUS_RANGE_END=8192
+CONFIG_NR_CPUS_DEFAULT=8192
+CONFIG_NR_CPUS=8192
+CONFIG_SCHED_CLUSTER=y
+CONFIG_SCHED_SMT=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_MC_PRIO=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
+CONFIG_X86_MCE=y
+CONFIG_X86_MCELOG_LEGACY=y
+CONFIG_X86_MCE_INTEL=y
+CONFIG_X86_MCE_AMD=y
+CONFIG_X86_MCE_THRESHOLD=y
+CONFIG_X86_MCE_INJECT=m
+
+#
+# Performance monitoring
+#
+CONFIG_PERF_EVENTS_INTEL_UNCORE=m
+CONFIG_PERF_EVENTS_INTEL_RAPL=m
+CONFIG_PERF_EVENTS_INTEL_CSTATE=m
+CONFIG_PERF_EVENTS_AMD_POWER=m
+CONFIG_PERF_EVENTS_AMD_UNCORE=y
+CONFIG_PERF_EVENTS_AMD_BRS=y
+# end of Performance monitoring
+
+CONFIG_X86_16BIT=y
+CONFIG_X86_ESPFIX64=y
+CONFIG_X86_VSYSCALL_EMULATION=y
+CONFIG_X86_IOPL_IOPERM=y
+CONFIG_MICROCODE=y
+CONFIG_MICROCODE_INTEL=y
+CONFIG_MICROCODE_AMD=y
+# CONFIG_MICROCODE_LATE_LOADING is not set
+CONFIG_X86_MSR=y
+CONFIG_X86_CPUID=y
+CONFIG_X86_5LEVEL=y
+CONFIG_X86_DIRECT_GBPAGES=y
+# CONFIG_X86_CPA_STATISTICS is not set
+CONFIG_X86_MEM_ENCRYPT=y
+CONFIG_AMD_MEM_ENCRYPT=y
+# CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT is not set
+CONFIG_NUMA=y
+CONFIG_AMD_NUMA=y
+CONFIG_X86_64_ACPI_NUMA=y
+CONFIG_NUMA_EMU=y
+CONFIG_NODES_SHIFT=10
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+# CONFIG_ARCH_MEMORY_PROBE is not set
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_X86_PMEM_LEGACY_DEVICE=y
+CONFIG_X86_PMEM_LEGACY=m
+CONFIG_X86_CHECK_BIOS_CORRUPTION=y
+# CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK is not set
+CONFIG_MTRR=y
+CONFIG_MTRR_SANITIZER=y
+CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1
+CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
+CONFIG_X86_PAT=y
+CONFIG_ARCH_USES_PG_UNCACHED=y
+CONFIG_X86_UMIP=y
+# CONFIG_X86_KERNEL_IBT is not set
+CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
+CONFIG_X86_INTEL_TSX_MODE_OFF=y
+# CONFIG_X86_INTEL_TSX_MODE_ON is not set
+# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set
+CONFIG_X86_SGX=y
+CONFIG_EFI=y
+CONFIG_EFI_STUB=y
+CONFIG_EFI_MIXED=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+CONFIG_SCHED_HRTICK=y
+CONFIG_KEXEC=y
+CONFIG_KEXEC_FILE=y
+CONFIG_ARCH_HAS_KEXEC_PURGATORY=y
+CONFIG_KEXEC_SIG=y
+CONFIG_KEXEC_SIG_FORCE=y
+CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y
+CONFIG_CRASH_DUMP=y
+CONFIG_KEXEC_JUMP=y
+CONFIG_PHYSICAL_START=0x1000000
+CONFIG_RELOCATABLE=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_X86_NEED_RELOCS=y
+CONFIG_PHYSICAL_ALIGN=0x200000
+CONFIG_DYNAMIC_MEMORY_LAYOUT=y
+CONFIG_RANDOMIZE_MEMORY=y
+CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0xa
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set
+# CONFIG_DEBUG_HOTPLUG_CPU0 is not set
+# CONFIG_COMPAT_VDSO is not set
+CONFIG_LEGACY_VSYSCALL_XONLY=y
+# CONFIG_LEGACY_VSYSCALL_NONE is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_MODIFY_LDT_SYSCALL=y
+# CONFIG_STRICT_SIGALTSTACK_SIZE is not set
+CONFIG_HAVE_LIVEPATCH=y
+CONFIG_LIVEPATCH=y
+# end of Processor type and features
+
+CONFIG_SPECULATION_MITIGATIONS=y
+CONFIG_PAGE_TABLE_ISOLATION=y
+CONFIG_RETPOLINE=y
+CONFIG_RETHUNK=y
+CONFIG_CPU_UNRET_ENTRY=y
+CONFIG_CPU_IBPB_ENTRY=y
+CONFIG_CPU_IBRS_ENTRY=y
+CONFIG_ARCH_HAS_ADD_PAGES=y
+CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
+
+#
+# Power management and ACPI options
+#
+CONFIG_ARCH_HIBERNATION_HEADER=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HIBERNATION=y
+CONFIG_HIBERNATION_SNAPSHOT_DEV=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_USERSPACE_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_PM_SLEEP_DEBUG=y
+# CONFIG_PM_TRACE_RTC is not set
+CONFIG_PM_CLK=y
+CONFIG_PM_GENERIC_DOMAINS=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
+# CONFIG_ENERGY_MODEL is not set
+CONFIG_ARCH_SUPPORTS_ACPI=y
+CONFIG_ACPI=y
+CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
+CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y
+CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
+# CONFIG_ACPI_DEBUGGER is not set
+CONFIG_ACPI_SPCR_TABLE=y
+# CONFIG_ACPI_FPDT is not set
+CONFIG_ACPI_LPIT=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y
+CONFIG_ACPI_EC_DEBUGFS=m
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_VIDEO=m
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_TAD=m
+CONFIG_ACPI_DOCK=y
+CONFIG_ACPI_CPU_FREQ_PSS=y
+CONFIG_ACPI_PROCESSOR_CSTATE=y
+CONFIG_ACPI_PROCESSOR_IDLE=y
+CONFIG_ACPI_CPPC_LIB=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_IPMI=m
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_PROCESSOR_AGGREGATOR=m
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_PLATFORM_PROFILE=m
+CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y
+CONFIG_ACPI_TABLE_UPGRADE=y
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_PCI_SLOT=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_HOTPLUG_MEMORY=y
+CONFIG_ACPI_HOTPLUG_IOAPIC=y
+CONFIG_ACPI_SBS=m
+CONFIG_ACPI_HED=y
+# CONFIG_ACPI_CUSTOM_METHOD is not set
+CONFIG_ACPI_BGRT=y
+CONFIG_ACPI_NFIT=m
+# CONFIG_NFIT_SECURITY_DEBUG is not set
+CONFIG_ACPI_NUMA=y
+CONFIG_ACPI_HMAT=y
+CONFIG_HAVE_ACPI_APEI=y
+CONFIG_HAVE_ACPI_APEI_NMI=y
+CONFIG_ACPI_APEI=y
+CONFIG_ACPI_APEI_GHES=y
+CONFIG_ACPI_APEI_PCIEAER=y
+CONFIG_ACPI_APEI_MEMORY_FAILURE=y
+CONFIG_ACPI_APEI_EINJ=m
+# CONFIG_ACPI_APEI_ERST_DEBUG is not set
+CONFIG_ACPI_DPTF=y
+CONFIG_DPTF_POWER=m
+# CONFIG_DPTF_PCH_FIVR is not set
+CONFIG_ACPI_WATCHDOG=y
+CONFIG_ACPI_EXTLOG=m
+CONFIG_ACPI_ADXL=y
+# CONFIG_ACPI_CONFIGFS is not set
+# CONFIG_ACPI_PFRUT is not set
+CONFIG_ACPI_PCC=y
+CONFIG_PMIC_OPREGION=y
+CONFIG_ACPI_PRMT=y
+CONFIG_X86_PM_TIMER=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+
+#
+# CPU frequency scaling drivers
+#
+CONFIG_X86_INTEL_PSTATE=y
+# CONFIG_X86_PCC_CPUFREQ is not set
+# CONFIG_X86_AMD_PSTATE is not set
+# CONFIG_X86_AMD_PSTATE_UT is not set
+CONFIG_X86_ACPI_CPUFREQ=m
+CONFIG_X86_ACPI_CPUFREQ_CPB=y
+CONFIG_X86_POWERNOW_K8=m
+CONFIG_X86_AMD_FREQ_SENSITIVITY=m
+# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
+CONFIG_X86_P4_CLOCKMOD=m
+
+#
+# shared options
+#
+CONFIG_X86_SPEEDSTEP_LIB=m
+# end of CPU Frequency scaling
+
+#
+# CPU Idle
+#
+CONFIG_CPU_IDLE=y
+# CONFIG_CPU_IDLE_GOV_LADDER is not set
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_IDLE_GOV_TEO=y
+CONFIG_CPU_IDLE_GOV_HALTPOLL=y
+CONFIG_HALTPOLL_CPUIDLE=y
+# end of CPU Idle
+
+CONFIG_INTEL_IDLE=y
+# end of Power management and ACPI options
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCI_XEN=y
+CONFIG_MMCONF_FAM10H=y
+CONFIG_ISA_DMA_API=y
+CONFIG_AMD_NB=y
+# end of Bus options (PCI etc.)
+
+#
+# Binary Emulations
+#
+CONFIG_IA32_EMULATION=y
+# CONFIG_X86_X32_ABI is not set
+CONFIG_COMPAT_32=y
+CONFIG_COMPAT=y
+CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
+# end of Binary Emulations
+
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_KVM_PFNCACHE=y
+CONFIG_HAVE_KVM_IRQCHIP=y
+CONFIG_HAVE_KVM_IRQFD=y
+CONFIG_HAVE_KVM_IRQ_ROUTING=y
+CONFIG_HAVE_KVM_DIRTY_RING=y
+CONFIG_HAVE_KVM_DIRTY_RING_TSO=y
+CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y
+CONFIG_HAVE_KVM_EVENTFD=y
+CONFIG_KVM_MMIO=y
+CONFIG_KVM_ASYNC_PF=y
+CONFIG_HAVE_KVM_MSI=y
+CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
+CONFIG_KVM_VFIO=y
+CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
+CONFIG_KVM_COMPAT=y
+CONFIG_HAVE_KVM_IRQ_BYPASS=y
+CONFIG_HAVE_KVM_NO_POLL=y
+CONFIG_KVM_XFER_TO_GUEST_WORK=y
+CONFIG_HAVE_KVM_PM_NOTIFIER=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=m
+CONFIG_KVM_INTEL=m
+CONFIG_X86_SGX_KVM=y
+CONFIG_KVM_AMD=m
+CONFIG_KVM_AMD_SEV=y
+# CONFIG_KVM_XEN is not set
+CONFIG_KVM_EXTERNAL_WRITE_TRACKING=y
+CONFIG_AS_AVX512=y
+CONFIG_AS_SHA1_NI=y
+CONFIG_AS_SHA256_NI=y
+CONFIG_AS_TPAUSE=y
+
+#
+# General architecture-dependent options
+#
+CONFIG_CRASH_CORE=y
+CONFIG_KEXEC_CORE=y
+CONFIG_HAVE_IMA_KEXEC=y
+CONFIG_HOTPLUG_SMT=y
+CONFIG_GENERIC_ENTRY=y
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+# CONFIG_STATIC_KEYS_SELFTEST is not set
+# CONFIG_STATIC_CALL_SELFTEST is not set
+CONFIG_OPTPROBES=y
+CONFIG_KPROBES_ON_FTRACE=y
+CONFIG_UPROBES=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_KRETPROBES=y
+CONFIG_KRETPROBE_ON_RETHOOK=y
+CONFIG_USER_RETURN_NOTIFIER=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_KPROBES_ON_FTRACE=y
+CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
+CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
+CONFIG_HAVE_NMI=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
+CONFIG_ARCH_HAS_SET_MEMORY=y
+CONFIG_ARCH_HAS_SET_DIRECT_MAP=y
+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
+CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
+CONFIG_ARCH_WANTS_NO_INSTR=y
+CONFIG_HAVE_ASM_MODVERSIONS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
+CONFIG_HAVE_RUST=y
+CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
+CONFIG_HAVE_USER_RETURN_NOTIFIER=y
+CONFIG_HAVE_PERF_EVENTS_NMI=y
+CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y
+CONFIG_MMU_GATHER_TABLE_FREE=y
+CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
+CONFIG_MMU_GATHER_MERGE_VMAS=y
+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
+CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
+CONFIG_HAVE_CMPXCHG_LOCAL=y
+CONFIG_HAVE_CMPXCHG_DOUBLE=y
+CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
+CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y
+CONFIG_HAVE_ARCH_SECCOMP=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_SECCOMP=y
+CONFIG_SECCOMP_FILTER=y
+# CONFIG_SECCOMP_CACHE_DEBUG is not set
+CONFIG_HAVE_ARCH_STACKLEAK=y
+CONFIG_HAVE_STACKPROTECTOR=y
+CONFIG_STACKPROTECTOR=y
+CONFIG_STACKPROTECTOR_STRONG=y
+CONFIG_ARCH_SUPPORTS_LTO_CLANG=y
+CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y
+CONFIG_LTO_NONE=y
+CONFIG_ARCH_SUPPORTS_CFI_CLANG=y
+CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
+CONFIG_HAVE_CONTEXT_TRACKING_USER=y
+CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MOVE_PUD=y
+CONFIG_HAVE_MOVE_PMD=y
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y
+CONFIG_HAVE_ARCH_HUGE_VMAP=y
+CONFIG_HAVE_ARCH_HUGE_VMALLOC=y
+CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
+CONFIG_HAVE_ARCH_SOFT_DIRTY=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
+CONFIG_HAVE_EXIT_THREAD=y
+CONFIG_ARCH_MMAP_RND_BITS=28
+CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=8
+CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_HAVE_OBJTOOL=y
+CONFIG_HAVE_JUMP_LABEL_HACK=y
+CONFIG_HAVE_NOINSTR_HACK=y
+CONFIG_HAVE_NOINSTR_VALIDATION=y
+CONFIG_HAVE_UACCESS_VALIDATION=y
+CONFIG_HAVE_STACK_VALIDATION=y
+CONFIG_HAVE_RELIABLE_STACKTRACE=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_COMPAT_OLD_SIGACTION=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_HAVE_ARCH_VMAP_STACK=y
+CONFIG_VMAP_STACK=y
+CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y
+CONFIG_RANDOMIZE_KSTACK_OFFSET=y
+# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
+CONFIG_STRICT_KERNEL_RWX=y
+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
+CONFIG_STRICT_MODULE_RWX=y
+CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
+CONFIG_ARCH_USE_MEMREMAP_PROT=y
+# CONFIG_LOCK_EVENT_COUNTS is not set
+CONFIG_ARCH_HAS_MEM_ENCRYPT=y
+CONFIG_ARCH_HAS_CC_PLATFORM=y
+CONFIG_HAVE_STATIC_CALL=y
+CONFIG_HAVE_STATIC_CALL_INLINE=y
+CONFIG_HAVE_PREEMPT_DYNAMIC=y
+CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y
+CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y
+CONFIG_ARCH_HAS_ELFCORE_COMPAT=y
+CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y
+CONFIG_DYNAMIC_SIGFRAME=y
+CONFIG_HAVE_ARCH_NODE_DEV_GROUP=y
+CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
+# end of GCOV-based kernel profiling
+
+CONFIG_HAVE_GCC_PLUGINS=y
+# end of General architecture-dependent options
+
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULE_SIG_FORMAT=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set
+CONFIG_MODVERSIONS=y
+CONFIG_ASM_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_MODULE_SIG_ALL=y
+# CONFIG_MODULE_SIG_SHA1 is not set
+# CONFIG_MODULE_SIG_SHA224 is not set
+CONFIG_MODULE_SIG_SHA256=y
+# CONFIG_MODULE_SIG_SHA384 is not set
+# CONFIG_MODULE_SIG_SHA512 is not set
+CONFIG_MODULE_SIG_HASH="sha256"
+CONFIG_MODULE_COMPRESS_NONE=y
+# CONFIG_MODULE_COMPRESS_GZIP is not set
+# CONFIG_MODULE_COMPRESS_XZ is not set
+# CONFIG_MODULE_COMPRESS_ZSTD is not set
+# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
+CONFIG_MODPROBE_PATH="/sbin/modprobe"
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_BLOCK=y
+CONFIG_BLOCK_LEGACY_AUTOLOAD=y
+CONFIG_BLK_CGROUP_RWSTAT=y
+CONFIG_BLK_DEV_BSG_COMMON=y
+CONFIG_BLK_ICQ=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_INTEGRITY_T10=m
+CONFIG_BLK_DEV_ZONED=y
+CONFIG_BLK_DEV_THROTTLING=y
+# CONFIG_BLK_DEV_THROTTLING_LOW is not set
+CONFIG_BLK_WBT=y
+CONFIG_BLK_WBT_MQ=y
+# CONFIG_BLK_CGROUP_IOLATENCY is not set
+# CONFIG_BLK_CGROUP_FC_APPID is not set
+# CONFIG_BLK_CGROUP_IOCOST is not set
+# CONFIG_BLK_CGROUP_IOPRIO is not set
+CONFIG_BLK_DEBUG_FS=y
+CONFIG_BLK_DEBUG_FS_ZONED=y
+# CONFIG_BLK_SED_OPAL is not set
+# CONFIG_BLK_INLINE_ENCRYPTION is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_AIX_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+# CONFIG_CMDLINE_PARTITION is not set
+# end of Partition Types
+
+CONFIG_BLOCK_COMPAT=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_MQ_VIRTIO=y
+CONFIG_BLK_MQ_RDMA=y
+CONFIG_BLK_PM=y
+CONFIG_BLOCK_HOLDER_DEPRECATED=y
+CONFIG_BLK_MQ_STACKING=y
+
+#
+# IO Schedulers
+#
+CONFIG_MQ_IOSCHED_DEADLINE=y
+CONFIG_MQ_IOSCHED_KYBER=y
+CONFIG_IOSCHED_BFQ=y
+CONFIG_BFQ_GROUP_IOSCHED=y
+# CONFIG_BFQ_CGROUP_DEBUG is not set
+# end of IO Schedulers
+
+CONFIG_PREEMPT_NOTIFIERS=y
+CONFIG_PADATA=y
+CONFIG_ASN1=y
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
+CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y
+CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y
+CONFIG_FREEZER=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
+CONFIG_ELFCORE=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_BINFMT_SCRIPT=y
+CONFIG_BINFMT_MISC=m
+CONFIG_COREDUMP=y
+# end of Executable file formats
+
+#
+# Memory Management options
+#
+CONFIG_ZPOOL=y
+CONFIG_SWAP=y
+CONFIG_ZSWAP=y
+# CONFIG_ZSWAP_DEFAULT_ON is not set
+# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y
+# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set
+# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set
+# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set
+# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lzo"
+CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
+# CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD is not set
+# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
+CONFIG_ZSWAP_ZPOOL_DEFAULT="zbud"
+CONFIG_ZBUD=y
+# CONFIG_Z3FOLD is not set
+CONFIG_ZSMALLOC=y
+CONFIG_ZSMALLOC_STAT=y
+
+#
+# SLAB allocator options
+#
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+CONFIG_SLAB_MERGE_DEFAULT=y
+CONFIG_SLAB_FREELIST_RANDOM=y
+# CONFIG_SLAB_FREELIST_HARDENED is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_SLUB_CPU_PARTIAL=y
+# end of SLAB allocator options
+
+CONFIG_SHUFFLE_PAGE_ALLOCATOR=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_HAVE_FAST_GUP=y
+CONFIG_NUMA_KEEP_MEMINFO=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_HAVE_BOOTMEM_INFO_NODE=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_MHP_MEMMAP_ON_MEMORY=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
+CONFIG_MEMORY_BALLOON=y
+CONFIG_BALLOON_COMPACTION=y
+CONFIG_COMPACTION=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_PAGE_REPORTING=y
+CONFIG_MIGRATION=y
+CONFIG_DEVICE_MIGRATION=y
+CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y
+CONFIG_ARCH_ENABLE_THP_MIGRATION=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU_NOTIFIER=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
+CONFIG_MEMORY_FAILURE=y
+CONFIG_HWPOISON_INJECT=m
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
+# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set
+CONFIG_THP_SWAP=y
+# CONFIG_READ_ONLY_THP_FOR_FS is not set
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_USE_PERCPU_NUMA_NODE_ID=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_FRONTSWAP=y
+# CONFIG_CMA is not set
+CONFIG_MEM_SOFT_DIRTY=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
+CONFIG_PAGE_IDLE_FLAG=y
+CONFIG_IDLE_PAGE_TRACKING=y
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
+CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y
+CONFIG_ARCH_HAS_PTE_DEVMAP=y
+CONFIG_ZONE_DMA=y
+CONFIG_ZONE_DMA32=y
+CONFIG_ZONE_DEVICE=y
+CONFIG_HMM_MIRROR=y
+CONFIG_GET_FREE_REGION=y
+CONFIG_DEVICE_PRIVATE=y
+CONFIG_VMAP_PFN=y
+CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
+CONFIG_ARCH_HAS_PKEYS=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_PERCPU_STATS is not set
+# CONFIG_GUP_TEST is not set
+CONFIG_ARCH_HAS_PTE_SPECIAL=y
+CONFIG_MAPPING_DIRTY_HELPERS=y
+CONFIG_SECRETMEM=y
+# CONFIG_ANON_VMA_NAME is not set
+CONFIG_USERFAULTFD=y
+CONFIG_HAVE_ARCH_USERFAULTFD_WP=y
+CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y
+CONFIG_PTE_MARKER=y
+CONFIG_PTE_MARKER_UFFD_WP=y
+# CONFIG_LRU_GEN is not set
+
+#
+# Data Access Monitoring
+#
+# CONFIG_DAMON is not set
+# end of Data Access Monitoring
+# end of Memory Management options
+
+CONFIG_NET=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_REDIRECT=y
+CONFIG_SKB_EXTENSIONS=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
+CONFIG_UNIX=y
+CONFIG_UNIX_SCM=y
+CONFIG_AF_UNIX_OOB=y
+CONFIG_UNIX_DIAG=m
+CONFIG_TLS=m
+CONFIG_TLS_DEVICE=y
+# CONFIG_TLS_TOE is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_OFFLOAD=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_USER_COMPAT is not set
+CONFIG_XFRM_INTERFACE=m
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_XFRM_AH=m
+CONFIG_XFRM_ESP=m
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
+# CONFIG_SMC is not set
+CONFIG_XDP_SOCKETS=y
+# CONFIG_XDP_SOCKETS_DIAG is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_FIB_TRIE_STATS=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_ROUTE_CLASSID=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IP_TUNNEL=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE_COMMON=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
+CONFIG_NET_UDP_TUNNEL=m
+# CONFIG_NET_FOU is not set
+# CONFIG_NET_FOU_IP_TUNNELS is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
+# CONFIG_INET_ESPINTCP is not set
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TABLE_PERTURB_ORDER=16
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_INET_UDP_DIAG=m
+CONFIG_INET_RAW_DIAG=m
+# CONFIG_INET_DIAG_DESTROY is not set
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=m
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_NV=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_TCP_CONG_DCTCP=m
+# CONFIG_TCP_CONG_CDG is not set
+CONFIG_TCP_CONG_BBR=m
+CONFIG_DEFAULT_CUBIC=y
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
+# CONFIG_INET6_ESPINTCP is not set
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+# CONFIG_IPV6_ILA is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_VTI=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+# CONFIG_IPV6_SUBTREES is not set
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IPV6_PIMSM_V2=y
+# CONFIG_IPV6_SEG6_LWTUNNEL is not set
+# CONFIG_IPV6_SEG6_HMAC is not set
+# CONFIG_IPV6_RPL_LWTUNNEL is not set
+# CONFIG_IPV6_IOAM6_LWTUNNEL is not set
+CONFIG_NETLABEL=y
+# CONFIG_MPTCP is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NETWORK_PHY_TIMESTAMPING=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=m
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_INGRESS=y
+CONFIG_NETFILTER_EGRESS=y
+CONFIG_NETFILTER_SKIP_EGRESS=y
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_FAMILY_BRIDGE=y
+CONFIG_NETFILTER_FAMILY_ARP=y
+# CONFIG_NETFILTER_NETLINK_HOOK is not set
+# CONFIG_NETFILTER_NETLINK_ACCT is not set
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_NETLINK_OSF=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_LOG_SYSLOG=m
+CONFIG_NETFILTER_CONNCOUNT=m
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_ZONES=y
+CONFIG_NF_CONNTRACK_PROCFS=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CONNTRACK_LABELS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_GRE=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_BROADCAST=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NF_CT_NETLINK_HELPER=m
+CONFIG_NETFILTER_NETLINK_GLUE_CT=y
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_REDIRECT=y
+CONFIG_NF_NAT_MASQUERADE=y
+CONFIG_NETFILTER_SYNPROXY=m
+CONFIG_NF_TABLES=m
+CONFIG_NF_TABLES_INET=y
+CONFIG_NF_TABLES_NETDEV=y
+CONFIG_NFT_NUMGEN=m
+CONFIG_NFT_CT=m
+CONFIG_NFT_CONNLIMIT=m
+CONFIG_NFT_LOG=m
+CONFIG_NFT_LIMIT=m
+CONFIG_NFT_MASQ=m
+CONFIG_NFT_REDIR=m
+CONFIG_NFT_NAT=m
+# CONFIG_NFT_TUNNEL is not set
+CONFIG_NFT_OBJREF=m
+CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
+CONFIG_NFT_REJECT=m
+CONFIG_NFT_REJECT_INET=m
+CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
+CONFIG_NFT_FIB=m
+CONFIG_NFT_FIB_INET=m
+# CONFIG_NFT_XFRM is not set
+# CONFIG_NFT_SOCKET is not set
+# CONFIG_NFT_OSF is not set
+# CONFIG_NFT_TPROXY is not set
+# CONFIG_NFT_SYNPROXY is not set
+CONFIG_NF_DUP_NETDEV=m
+CONFIG_NFT_DUP_NETDEV=m
+CONFIG_NFT_FWD_NETDEV=m
+CONFIG_NFT_FIB_NETDEV=m
+# CONFIG_NFT_REJECT_NETDEV is not set
+# CONFIG_NF_FLOW_TABLE is not set
+CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XTABLES_COMPAT=y
+
+#
+# Xtables combined modules
+#
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_CONNMARK=m
+CONFIG_NETFILTER_XT_SET=m
+
+#
+# Xtables targets
+#
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_NAT=m
+CONFIG_NETFILTER_XT_TARGET_NETMAP=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
+CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+
+#
+# Xtables matches
+#
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CGROUP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ECN=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
+# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# end of Core Netfilter Configuration
+
+CONFIG_IP_SET=m
+CONFIG_IP_SET_MAX=256
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPMARK=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_IPMAC=m
+CONFIG_IP_SET_HASH_MAC=m
+CONFIG_IP_SET_HASH_NETPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETNET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_FO=m
+CONFIG_IP_VS_OVF=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+# CONFIG_IP_VS_MH is not set
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+# CONFIG_IP_VS_TWOS is not set
+
+#
+# IPVS SH scheduler
+#
+CONFIG_IP_VS_SH_TAB_BITS=8
+
+#
+# IPVS MH scheduler
+#
+CONFIG_IP_VS_MH_TAB_INDEX=12
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_VS_NFCT=y
+CONFIG_IP_VS_PE_SIP=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_SOCKET_IPV4=m
+CONFIG_NF_TPROXY_IPV4=m
+CONFIG_NF_TABLES_IPV4=y
+CONFIG_NFT_REJECT_IPV4=m
+CONFIG_NFT_DUP_IPV4=m
+CONFIG_NFT_FIB_IPV4=m
+CONFIG_NF_TABLES_ARP=y
+CONFIG_NF_DUP_IPV4=m
+CONFIG_NF_LOG_ARP=m
+CONFIG_NF_LOG_IPV4=m
+CONFIG_NF_REJECT_IPV4=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_SYNPROXY=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# end of IP: Netfilter Configuration
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_SOCKET_IPV6=m
+CONFIG_NF_TPROXY_IPV6=m
+CONFIG_NF_TABLES_IPV6=y
+CONFIG_NFT_REJECT_IPV6=m
+CONFIG_NFT_DUP_IPV6=m
+CONFIG_NFT_FIB_IPV6=m
+CONFIG_NF_DUP_IPV6=m
+CONFIG_NF_REJECT_IPV6=m
+CONFIG_NF_LOG_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+# CONFIG_IP6_NF_MATCH_SRH is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_TARGET_SYNPROXY=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
+# end of IPv6: Netfilter Configuration
+
+CONFIG_NF_DEFRAG_IPV6=m
+CONFIG_NF_TABLES_BRIDGE=m
+# CONFIG_NFT_BRIDGE_META is not set
+CONFIG_NFT_BRIDGE_REJECT=m
+# CONFIG_NF_CONNTRACK_BRIDGE is not set
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+# CONFIG_BPFILTER is not set
+# CONFIG_IP_DCCP is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5 is not set
+CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1=y
+# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
+CONFIG_SCTP_COOKIE_HMAC_MD5=y
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_INET_SCTP_DIAG=m
+# CONFIG_RDS is not set
+CONFIG_TIPC=m
+CONFIG_TIPC_MEDIA_IB=y
+CONFIG_TIPC_MEDIA_UDP=y
+CONFIG_TIPC_CRYPTO=y
+CONFIG_TIPC_DIAG=m
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_L2TP=m
+CONFIG_L2TP_DEBUGFS=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_STP=m
+CONFIG_GARP=m
+CONFIG_MRP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+CONFIG_BRIDGE_VLAN_FILTERING=y
+# CONFIG_BRIDGE_MRP is not set
+# CONFIG_BRIDGE_CFM is not set
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+CONFIG_6LOWPAN=m
+# CONFIG_6LOWPAN_DEBUGFS is not set
+# CONFIG_6LOWPAN_NHC is not set
+CONFIG_IEEE802154=m
+# CONFIG_IEEE802154_NL802154_EXPERIMENTAL is not set
+CONFIG_IEEE802154_SOCKET=m
+CONFIG_IEEE802154_6LOWPAN=m
+CONFIG_MAC802154=m
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+# CONFIG_NET_SCH_CBS is not set
+# CONFIG_NET_SCH_ETF is not set
+# CONFIG_NET_SCH_TAPRIO is not set
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_MQPRIO=m
+# CONFIG_NET_SCH_SKBPRIO is not set
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=y
+# CONFIG_NET_SCH_CAKE is not set
+CONFIG_NET_SCH_FQ=m
+CONFIG_NET_SCH_HHF=m
+CONFIG_NET_SCH_PIE=m
+# CONFIG_NET_SCH_FQ_PIE is not set
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_PLUG=m
+# CONFIG_NET_SCH_ETS is not set
+CONFIG_NET_SCH_DEFAULT=y
+# CONFIG_DEFAULT_FQ is not set
+# CONFIG_DEFAULT_CODEL is not set
+CONFIG_DEFAULT_FQ_CODEL=y
+# CONFIG_DEFAULT_SFQ is not set
+# CONFIG_DEFAULT_PFIFO_FAST is not set
+CONFIG_DEFAULT_NET_SCH="fq_codel"
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_BPF=m
+CONFIG_NET_CLS_FLOWER=m
+CONFIG_NET_CLS_MATCHALL=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+# CONFIG_NET_EMATCH_CANID is not set
+CONFIG_NET_EMATCH_IPSET=m
+# CONFIG_NET_EMATCH_IPT is not set
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_SAMPLE=m
+# CONFIG_NET_ACT_IPT is not set
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
+# CONFIG_NET_ACT_MPLS is not set
+CONFIG_NET_ACT_VLAN=m
+CONFIG_NET_ACT_BPF=m
+# CONFIG_NET_ACT_CONNMARK is not set
+# CONFIG_NET_ACT_CTINFO is not set
+CONFIG_NET_ACT_SKBMOD=m
+# CONFIG_NET_ACT_IFE is not set
+CONFIG_NET_ACT_TUNNEL_KEY=m
+# CONFIG_NET_ACT_GATE is not set
+# CONFIG_NET_TC_SKB_EXT is not set
+CONFIG_NET_SCH_FIFO=y
+CONFIG_DCB=y
+CONFIG_DNS_RESOLVER=m
+# CONFIG_BATMAN_ADV is not set
+CONFIG_OPENVSWITCH=m
+CONFIG_OPENVSWITCH_GRE=m
+CONFIG_OPENVSWITCH_VXLAN=m
+CONFIG_OPENVSWITCH_GENEVE=m
+CONFIG_VSOCKETS=m
+CONFIG_VSOCKETS_DIAG=m
+CONFIG_VSOCKETS_LOOPBACK=m
+CONFIG_VMWARE_VMCI_VSOCKETS=m
+CONFIG_VIRTIO_VSOCKETS=m
+CONFIG_VIRTIO_VSOCKETS_COMMON=m
+CONFIG_HYPERV_VSOCKETS=m
+CONFIG_NETLINK_DIAG=m
+CONFIG_MPLS=y
+CONFIG_NET_MPLS_GSO=y
+CONFIG_MPLS_ROUTING=m
+CONFIG_MPLS_IPTUNNEL=m
+CONFIG_NET_NSH=y
+# CONFIG_HSR is not set
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_L3_MASTER_DEV=y
+# CONFIG_QRTR is not set
+# CONFIG_NET_NCSI is not set
+CONFIG_PCPU_DEV_REFCNT=y
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_XPS=y
+CONFIG_CGROUP_NET_PRIO=y
+CONFIG_CGROUP_NET_CLASSID=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+CONFIG_BPF_STREAM_PARSER=y
+CONFIG_NET_FLOW_LIMIT=y
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+CONFIG_NET_DROP_MONITOR=y
+# end of Network testing
+# end of Networking options
+
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+CONFIG_CAN_GW=m
+# CONFIG_CAN_J1939 is not set
+# CONFIG_CAN_ISOTP is not set
+CONFIG_BT=m
+CONFIG_BT_BREDR=y
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
+CONFIG_BT_HS=y
+CONFIG_BT_LE=y
+# CONFIG_BT_6LOWPAN is not set
+# CONFIG_BT_LEDS is not set
+# CONFIG_BT_MSFTEXT is not set
+# CONFIG_BT_AOSPEXT is not set
+CONFIG_BT_DEBUGFS=y
+# CONFIG_BT_SELFTEST is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_INTEL=m
+CONFIG_BT_BCM=m
+CONFIG_BT_RTL=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
+CONFIG_BT_HCIBTUSB_BCM=y
+# CONFIG_BT_HCIBTUSB_MTK is not set
+CONFIG_BT_HCIBTUSB_RTL=y
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+# CONFIG_BT_HCIUART_INTEL is not set
+# CONFIG_BT_HCIUART_AG6XX is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+CONFIG_BT_ATH3K=m
+# CONFIG_BT_MTKSDIO is not set
+# CONFIG_BT_VIRTIO is not set
+# end of Bluetooth device drivers
+
+# CONFIG_AF_RXRPC is not set
+# CONFIG_AF_KCM is not set
+CONFIG_STREAM_PARSER=y
+# CONFIG_MCTP is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
+CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
+CONFIG_CFG80211_CRDA_SUPPORT=y
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_MAC80211=m
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+CONFIG_MAC80211_DEBUGFS=y
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
+CONFIG_RFKILL=m
+CONFIG_RFKILL_LEDS=y
+CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+CONFIG_CEPH_LIB=m
+# CONFIG_CEPH_LIB_PRETTYDEBUG is not set
+CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y
+# CONFIG_NFC is not set
+CONFIG_PSAMPLE=m
+# CONFIG_NET_IFE is not set
+CONFIG_LWTUNNEL=y
+CONFIG_LWTUNNEL_BPF=y
+CONFIG_DST_CACHE=y
+CONFIG_GRO_CELLS=y
+CONFIG_SOCK_VALIDATE_XMIT=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SOCK_MSG=y
+CONFIG_NET_DEVLINK=y
+CONFIG_PAGE_POOL=y
+# CONFIG_PAGE_POOL_STATS is not set
+CONFIG_FAILOVER=m
+CONFIG_ETHTOOL_NETLINK=y
+
+#
+# Device Drivers
+#
+CONFIG_HAVE_EISA=y
+# CONFIG_EISA is not set
+CONFIG_HAVE_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEAER_INJECT=m
+CONFIG_PCIE_ECRC=y
+CONFIG_PCIEASPM=y
+CONFIG_PCIEASPM_DEFAULT=y
+# CONFIG_PCIEASPM_POWERSAVE is not set
+# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
+# CONFIG_PCIEASPM_PERFORMANCE is not set
+CONFIG_PCIE_PME=y
+CONFIG_PCIE_DPC=y
+# CONFIG_PCIE_PTM is not set
+# CONFIG_PCIE_EDR is not set
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+CONFIG_PCI_STUB=y
+CONFIG_PCI_PF_STUB=m
+CONFIG_PCI_ATS=y
+CONFIG_PCI_LOCKLESS_CONFIG=y
+CONFIG_PCI_IOV=y
+CONFIG_PCI_PRI=y
+CONFIG_PCI_PASID=y
+# CONFIG_PCI_P2PDMA is not set
+CONFIG_PCI_LABEL=y
+CONFIG_PCI_HYPERV=m
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=64
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_ACPI=y
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_SHPC=y
+
+#
+# PCI controller drivers
+#
+CONFIG_VMD=y
+CONFIG_PCI_HYPERV_INTERFACE=m
+
+#
+# DesignWare PCI Core Support
+#
+# CONFIG_PCIE_DW_PLAT_HOST is not set
+# CONFIG_PCI_MESON is not set
+# end of DesignWare PCI Core Support
+
+#
+# Mobiveil PCIe Core Support
+#
+# end of Mobiveil PCIe Core Support
+
+#
+# Cadence PCIe controllers support
+#
+# end of Cadence PCIe controllers support
+# end of PCI controller drivers
+
+#
+# PCI Endpoint
+#
+# CONFIG_PCI_ENDPOINT is not set
+# end of PCI Endpoint
+
+#
+# PCI switch controller drivers
+#
+# CONFIG_PCI_SW_SWITCHTEC is not set
+# end of PCI switch controller drivers
+
+# CONFIG_CXL_BUS is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA is not set
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+# CONFIG_RAPIDIO is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_AUXILIARY_BUS=y
+# CONFIG_UEVENT_HELPER is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_DEVTMPFS_SAFE is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+
+#
+# Firmware loader
+#
+CONFIG_FW_LOADER=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_FW_LOADER_USER_HELPER is not set
+# CONFIG_FW_LOADER_COMPRESS is not set
+CONFIG_FW_CACHE=y
+# CONFIG_FW_UPLOAD is not set
+# end of Firmware loader
+
+CONFIG_WANT_DEV_COREDUMP=y
+CONFIG_ALLOW_DEV_COREDUMP=y
+CONFIG_DEV_COREDUMP=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
+CONFIG_HMEM_REPORTING=y
+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
+CONFIG_SYS_HYPERVISOR=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=m
+CONFIG_REGMAP_SPI=m
+CONFIG_DMA_SHARED_BUFFER=y
+# CONFIG_DMA_FENCE_TRACE is not set
+# end of Generic Driver Options
+
+#
+# Bus devices
+#
+# CONFIG_MHI_BUS is not set
+# CONFIG_MHI_BUS_EP is not set
+# end of Bus devices
+
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+
+#
+# Firmware Drivers
+#
+
+#
+# ARM System Control and Management Interface Protocol
+#
+# end of ARM System Control and Management Interface Protocol
+
+CONFIG_EDD=m
+# CONFIG_EDD_OFF is not set
+CONFIG_FIRMWARE_MEMMAP=y
+CONFIG_DMIID=y
+CONFIG_DMI_SYSFS=y
+CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
+CONFIG_ISCSI_IBFT_FIND=y
+CONFIG_ISCSI_IBFT=m
+CONFIG_FW_CFG_SYSFS=y
+# CONFIG_FW_CFG_SYSFS_CMDLINE is not set
+CONFIG_SYSFB=y
+# CONFIG_SYSFB_SIMPLEFB is not set
+# CONFIG_GOOGLE_FIRMWARE is not set
+
+#
+# EFI (Extensible Firmware Interface) Support
+#
+CONFIG_EFI_ESRT=y
+CONFIG_EFI_VARS_PSTORE=y
+CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y
+CONFIG_EFI_RUNTIME_MAP=y
+# CONFIG_EFI_FAKE_MEMMAP is not set
+CONFIG_EFI_SOFT_RESERVE=y
+CONFIG_EFI_DXE_MEM_ATTRIBUTES=y
+CONFIG_EFI_RUNTIME_WRAPPERS=y
+CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
+# CONFIG_EFI_BOOTLOADER_CONTROL is not set
+# CONFIG_EFI_CAPSULE_LOADER is not set
+# CONFIG_EFI_TEST is not set
+CONFIG_EFI_DEV_PATH_PARSER=y
+CONFIG_APPLE_PROPERTIES=y
+# CONFIG_RESET_ATTACK_MITIGATION is not set
+# CONFIG_EFI_RCI2_TABLE is not set
+# CONFIG_EFI_DISABLE_PCI_DMA is not set
+CONFIG_EFI_EARLYCON=y
+CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y
+# CONFIG_EFI_DISABLE_RUNTIME is not set
+# CONFIG_EFI_COCO_SECRET is not set
+# end of EFI (Extensible Firmware Interface) Support
+
+CONFIG_UEFI_CPER=y
+CONFIG_UEFI_CPER_X86=y
+
+#
+# Tegra firmware driver
+#
+# end of Tegra firmware driver
+# end of Firmware Drivers
+
+# CONFIG_GNSS is not set
+CONFIG_MTD=m
+# CONFIG_MTD_TESTS is not set
+
+#
+# Partition parsers
+#
+# CONFIG_MTD_AR7_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# end of Partition parsers
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+
+#
+# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK.
+#
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+# CONFIG_MTD_PARTITIONED_MASTER is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# end of RAM/ROM/Flash chip drivers
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+# end of Mapping drivers for chip access
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_MCHP23K256 is not set
+# CONFIG_MTD_MCHP48L640 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+# end of Self-contained MTD device drivers
+
+#
+# NAND
+#
+# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_RAW_NAND is not set
+# CONFIG_MTD_SPI_NAND is not set
+
+#
+# ECC engine support
+#
+# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set
+# CONFIG_MTD_NAND_ECC_SW_BCH is not set
+# CONFIG_MTD_NAND_ECC_MXIC is not set
+# end of ECC engine support
+# end of NAND
+
+#
+# LPDDR & LPDDR2 PCM memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# end of LPDDR & LPDDR2 PCM memory drivers
+
+CONFIG_MTD_SPI_NOR=m
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set
+CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y
+# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set
+CONFIG_MTD_UBI=m
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+CONFIG_MTD_UBI_GLUEBI=m
+# CONFIG_MTD_UBI_BLOCK is not set
+# CONFIG_MTD_HYPERBUS is not set
+# CONFIG_OF is not set
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG_MESSAGES is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_NULL_BLK=m
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_CDROM=m
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+CONFIG_ZRAM=m
+CONFIG_ZRAM_DEF_COMP_LZORLE=y
+# CONFIG_ZRAM_DEF_COMP_ZSTD is not set
+# CONFIG_ZRAM_DEF_COMP_LZO is not set
+CONFIG_ZRAM_DEF_COMP="lzo-rle"
+CONFIG_ZRAM_WRITEBACK=y
+# CONFIG_ZRAM_MEMORY_TRACKING is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=0
+# CONFIG_BLK_DEV_DRBD is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_XEN_BLKDEV_FRONTEND=m
+CONFIG_VIRTIO_BLK=m
+CONFIG_BLK_DEV_RBD=m
+# CONFIG_BLK_DEV_UBLK is not set
+
+#
+# NVME Support
+#
+CONFIG_NVME_CORE=m
+CONFIG_BLK_DEV_NVME=m
+CONFIG_NVME_MULTIPATH=y
+# CONFIG_NVME_VERBOSE_ERRORS is not set
+# CONFIG_NVME_HWMON is not set
+CONFIG_NVME_FABRICS=m
+CONFIG_NVME_RDMA=m
+CONFIG_NVME_FC=m
+CONFIG_NVME_TCP=m
+# CONFIG_NVME_AUTH is not set
+CONFIG_NVME_TARGET=m
+# CONFIG_NVME_TARGET_PASSTHRU is not set
+CONFIG_NVME_TARGET_LOOP=m
+CONFIG_NVME_TARGET_RDMA=m
+CONFIG_NVME_TARGET_FC=m
+CONFIG_NVME_TARGET_FCLOOP=m
+CONFIG_NVME_TARGET_TCP=m
+# CONFIG_NVME_TARGET_AUTH is not set
+# end of NVME Support
+
+#
+# Misc devices
+#
+CONFIG_SENSORS_LIS3LV02D=m
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_IBM_ASM is not set
+# CONFIG_PHANTOM is not set
+CONFIG_TIFM_CORE=m
+CONFIG_TIFM_7XX1=m
+# CONFIG_ICS932S401 is not set
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_SGI_XP=m
+CONFIG_HP_ILO=m
+CONFIG_SGI_GRU=m
+# CONFIG_SGI_GRU_DEBUG is not set
+CONFIG_APDS9802ALS=m
+CONFIG_ISL29003=m
+CONFIG_ISL29020=m
+CONFIG_SENSORS_TSL2550=m
+CONFIG_SENSORS_BH1770=m
+CONFIG_SENSORS_APDS990X=m
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+CONFIG_VMWARE_BALLOON=m
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_DW_XDATA_PCIE is not set
+# CONFIG_PCI_ENDPOINT_TEST is not set
+# CONFIG_XILINX_SDFEC is not set
+CONFIG_MISC_RTSX=m
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+CONFIG_EEPROM_LEGACY=m
+CONFIG_EEPROM_MAX6875=m
+CONFIG_EEPROM_93CX6=m
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_EEPROM_IDT_89HPESX is not set
+# CONFIG_EEPROM_EE1004 is not set
+# end of EEPROM support
+
+CONFIG_CB710_CORE=m
+# CONFIG_CB710_DEBUG is not set
+CONFIG_CB710_DEBUG_ASSUMPTIONS=y
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# end of Texas Instruments shared transport line discipline
+
+CONFIG_SENSORS_LIS3_I2C=m
+CONFIG_ALTERA_STAPL=m
+CONFIG_INTEL_MEI=m
+CONFIG_INTEL_MEI_ME=m
+# CONFIG_INTEL_MEI_TXE is not set
+# CONFIG_INTEL_MEI_GSC is not set
+# CONFIG_INTEL_MEI_HDCP is not set
+# CONFIG_INTEL_MEI_PXP is not set
+CONFIG_VMWARE_VMCI=m
+# CONFIG_GENWQE is not set
+# CONFIG_ECHO is not set
+# CONFIG_BCM_VK is not set
+# CONFIG_MISC_ALCOR_PCI is not set
+CONFIG_MISC_RTSX_PCI=m
+CONFIG_MISC_RTSX_USB=m
+# CONFIG_HABANA_AI is not set
+CONFIG_UACCE=m
+CONFIG_PVPANIC=y
+# CONFIG_PVPANIC_MMIO is not set
+# CONFIG_PVPANIC_PCI is not set
+# CONFIG_GP_PCI1XXXX is not set
+# end of Misc devices
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI_COMMON=y
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_BLK_DEV_BSG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_ENCLOSURE=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_SAS_HOST_SMP=y
+CONFIG_SCSI_SRP_ATTRS=m
+# end of SCSI Transports
+
+CONFIG_SCSI_LOWLEVEL=y
+CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+CONFIG_SCSI_CXGB4_ISCSI=m
+CONFIG_SCSI_BNX2_ISCSI=m
+CONFIG_SCSI_BNX2X_FCOE=m
+CONFIG_BE2ISCSI=m
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+CONFIG_SCSI_HPSA=m
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+CONFIG_SCSI_AACRAID=m
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_MVUMI is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_SCSI_ESAS2R is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_MPT3SAS=m
+CONFIG_SCSI_MPT2SAS_MAX_SGE=128
+CONFIG_SCSI_MPT3SAS_MAX_SGE=128
+CONFIG_SCSI_MPT2SAS=m
+# CONFIG_SCSI_MPI3MR is not set
+CONFIG_SCSI_SMARTPQI=m
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_MYRB is not set
+# CONFIG_SCSI_MYRS is not set
+CONFIG_VMWARE_PVSCSI=m
+# CONFIG_XEN_SCSI_FRONTEND is not set
+CONFIG_HYPERV_STORAGE=m
+CONFIG_LIBFC=m
+CONFIG_LIBFCOE=m
+CONFIG_FCOE=m
+CONFIG_FCOE_FNIC=m
+# CONFIG_SCSI_SNIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FDOMAIN_PCI is not set
+# CONFIG_SCSI_ISCI is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA_FC=m
+# CONFIG_TCM_QLA2XXX is not set
+CONFIG_SCSI_QLA_ISCSI=m
+CONFIG_QEDI=m
+CONFIG_QEDF=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_LPFC_DEBUG_FS is not set
+# CONFIG_SCSI_EFCT is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_WD719X is not set
+CONFIG_SCSI_DEBUG=m
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_BFA_FC is not set
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_CHELSIO_FCOE=m
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=y
+CONFIG_SCSI_DH_HP_SW=y
+CONFIG_SCSI_DH_EMC=y
+CONFIG_SCSI_DH_ALUA=y
+# end of SCSI device support
+
+CONFIG_ATA=m
+CONFIG_SATA_HOST=y
+CONFIG_PATA_TIMINGS=y
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_ATA_FORCE=y
+CONFIG_ATA_ACPI=y
+# CONFIG_SATA_ZPODD is not set
+CONFIG_SATA_PMP=y
+
+#
+# Controllers with non-SFF native interface
+#
+CONFIG_SATA_AHCI=m
+CONFIG_SATA_MOBILE_LPM_POLICY=0
+CONFIG_SATA_AHCI_PLATFORM=m
+# CONFIG_AHCI_DWC is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_SATA_ACARD_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_ATA_SFF=y
+
+#
+# SFF controllers with custom DMA interface
+#
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
+CONFIG_ATA_PIIX=m
+# CONFIG_SATA_DWC is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_ATP867X is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_RZ1000 is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_PATA_ACPI is not set
+CONFIG_ATA_GENERIC=m
+# CONFIG_PATA_LEGACY is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+# CONFIG_MD_MULTIPATH is not set
+CONFIG_MD_FAULTY=m
+# CONFIG_MD_CLUSTER is not set
+# CONFIG_BCACHE is not set
+CONFIG_BLK_DEV_DM_BUILTIN=y
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_DEBUG=y
+CONFIG_DM_BUFIO=m
+# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set
+CONFIG_DM_BIO_PRISON=m
+CONFIG_DM_PERSISTENT_DATA=m
+# CONFIG_DM_UNSTRIPED is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
+CONFIG_DM_CACHE_SMQ=m
+CONFIG_DM_WRITECACHE=m
+# CONFIG_DM_EBS is not set
+CONFIG_DM_ERA=m
+# CONFIG_DM_CLONE is not set
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_RAID=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+# CONFIG_DM_MULTIPATH_HST is not set
+# CONFIG_DM_MULTIPATH_IOA is not set
+CONFIG_DM_DELAY=m
+# CONFIG_DM_DUST is not set
+CONFIG_DM_UEVENT=y
+CONFIG_DM_FLAKEY=m
+CONFIG_DM_VERITY=m
+# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set
+# CONFIG_DM_VERITY_FEC is not set
+CONFIG_DM_SWITCH=m
+CONFIG_DM_LOG_WRITES=m
+CONFIG_DM_INTEGRITY=m
+# CONFIG_DM_ZONED is not set
+CONFIG_DM_AUDIT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
+CONFIG_TCM_USER2=m
+CONFIG_LOOPBACK_TARGET=m
+# CONFIG_TCM_FC is not set
+CONFIG_ISCSI_TARGET=m
+CONFIG_ISCSI_TARGET_CXGB4=m
+# CONFIG_SBP_TARGET is not set
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=128
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LOGGING=y
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_FIREWIRE=m
+CONFIG_FIREWIRE_OHCI=m
+CONFIG_FIREWIRE_SBP2=m
+CONFIG_FIREWIRE_NET=m
+# CONFIG_FIREWIRE_NOSY is not set
+# end of IEEE 1394 (FireWire) support
+
+CONFIG_MACINTOSH_DRIVERS=y
+CONFIG_MAC_EMUMOUSEBTN=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=m
+CONFIG_NET_CORE=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+# CONFIG_WIREGUARD is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_NET_FC=y
+CONFIG_IFB=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_RANDOM=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_IPVLAN_L3S=y
+CONFIG_IPVLAN=m
+CONFIG_IPVTAP=m
+CONFIG_VXLAN=m
+CONFIG_GENEVE=m
+# CONFIG_BAREUDP is not set
+# CONFIG_GTP is not set
+# CONFIG_AMT is not set
+CONFIG_MACSEC=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+CONFIG_NET_POLL_CONTROLLER=y
+CONFIG_NTB_NETDEV=m
+CONFIG_TUN=m
+CONFIG_TAP=m
+# CONFIG_TUN_VNET_CROSS_LE is not set
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_NLMON=m
+CONFIG_NET_VRF=m
+CONFIG_VSOCKMON=m
+# CONFIG_ARCNET is not set
+# CONFIG_ATM_DRIVERS is not set
+CONFIG_ETHERNET=y
+CONFIG_MDIO=m
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_AGERE is not set
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_ALTERA_TSE is not set
+CONFIG_NET_VENDOR_AMAZON=y
+CONFIG_ENA_ETHERNET=m
+CONFIG_NET_VENDOR_AMD=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_PCNET32 is not set
+CONFIG_AMD_XGBE=m
+# CONFIG_AMD_XGBE_DCB is not set
+CONFIG_AMD_XGBE_HAVE_ECC=y
+CONFIG_NET_VENDOR_AQUANTIA=y
+CONFIG_AQTION=m
+# CONFIG_NET_VENDOR_ARC is not set
+CONFIG_NET_VENDOR_ASIX=y
+# CONFIG_SPI_AX88796C is not set
+CONFIG_NET_VENDOR_ATHEROS=y
+CONFIG_ATL2=m
+CONFIG_ATL1=m
+CONFIG_ATL1E=m
+CONFIG_ATL1C=m
+CONFIG_ALX=m
+# CONFIG_CX_ECAT is not set
+CONFIG_NET_VENDOR_BROADCOM=y
+# CONFIG_B44 is not set
+# CONFIG_BCMGENET is not set
+CONFIG_BNX2=m
+CONFIG_CNIC=m
+CONFIG_TIGON3=m
+CONFIG_TIGON3_HWMON=y
+CONFIG_BNX2X=m
+CONFIG_BNX2X_SRIOV=y
+# CONFIG_SYSTEMPORT is not set
+CONFIG_BNXT=m
+CONFIG_BNXT_SRIOV=y
+CONFIG_BNXT_FLOWER_OFFLOAD=y
+CONFIG_BNXT_DCB=y
+CONFIG_BNXT_HWMON=y
+CONFIG_NET_VENDOR_CADENCE=y
+# CONFIG_MACB is not set
+CONFIG_NET_VENDOR_CAVIUM=y
+# CONFIG_THUNDER_NIC_PF is not set
+# CONFIG_THUNDER_NIC_VF is not set
+# CONFIG_THUNDER_NIC_BGX is not set
+# CONFIG_THUNDER_NIC_RGX is not set
+CONFIG_CAVIUM_PTP=y
+CONFIG_LIQUIDIO=m
+CONFIG_LIQUIDIO_VF=m
+CONFIG_NET_VENDOR_CHELSIO=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4=m
+# CONFIG_CHELSIO_T4_DCB is not set
+CONFIG_CHELSIO_T4VF=m
+CONFIG_CHELSIO_LIB=m
+CONFIG_CHELSIO_INLINE_CRYPTO=y
+CONFIG_CHELSIO_IPSEC_INLINE=m
+# CONFIG_CHELSIO_TLS_DEVICE is not set
+CONFIG_NET_VENDOR_CISCO=y
+CONFIG_ENIC=m
+# CONFIG_NET_VENDOR_CORTINA is not set
+CONFIG_NET_VENDOR_DAVICOM=y
+# CONFIG_DM9051 is not set
+CONFIG_DNET=m
+CONFIG_NET_VENDOR_DEC=y
+# CONFIG_NET_TULIP is not set
+CONFIG_NET_VENDOR_DLINK=y
+CONFIG_DL2K=m
+# CONFIG_SUNDANCE is not set
+CONFIG_NET_VENDOR_EMULEX=y
+CONFIG_BE2NET=m
+CONFIG_BE2NET_HWMON=y
+# CONFIG_BE2NET_BE2 is not set
+# CONFIG_BE2NET_BE3 is not set
+CONFIG_BE2NET_LANCER=y
+CONFIG_BE2NET_SKYHAWK=y
+CONFIG_NET_VENDOR_ENGLEDER=y
+# CONFIG_TSNEP is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+CONFIG_NET_VENDOR_FUNGIBLE=y
+# CONFIG_FUN_ETH is not set
+CONFIG_NET_VENDOR_GOOGLE=y
+# CONFIG_GVE is not set
+CONFIG_NET_VENDOR_HUAWEI=y
+CONFIG_HINIC=m
+# CONFIG_NET_VENDOR_I825XX is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+CONFIG_E1000=m
+CONFIG_E1000E=m
+CONFIG_E1000E_HWTS=y
+CONFIG_IGB=m
+CONFIG_IGB_HWMON=y
+CONFIG_IGB_DCA=y
+CONFIG_IGBVF=m
+# CONFIG_IXGB is not set
+CONFIG_IXGBE=m
+CONFIG_IXGBE_HWMON=y
+CONFIG_IXGBE_DCA=y
+CONFIG_IXGBE_DCB=y
+CONFIG_IXGBE_IPSEC=y
+CONFIG_IXGBEVF=m
+CONFIG_IXGBEVF_IPSEC=y
+CONFIG_I40E=m
+CONFIG_I40E_DCB=y
+CONFIG_IAVF=m
+CONFIG_I40EVF=m
+CONFIG_ICE=m
+CONFIG_ICE_SWITCHDEV=y
+CONFIG_ICE_HWTS=y
+CONFIG_FM10K=m
+# CONFIG_IGC is not set
+CONFIG_NET_VENDOR_WANGXUN=y
+CONFIG_NGBE=m
+CONFIG_TXGBE=m
+# CONFIG_JME is not set
+CONFIG_NET_VENDOR_ADI=y
+# CONFIG_ADIN1110 is not set
+CONFIG_NET_VENDOR_LITEX=y
+# CONFIG_NET_VENDOR_MARVELL is not set
+CONFIG_NET_VENDOR_MELLANOX=y
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_EN_DCB=y
+CONFIG_MLX4_CORE=m
+CONFIG_MLX4_DEBUG=y
+# CONFIG_MLX4_CORE_GEN2 is not set
+CONFIG_MLX5_CORE=m
+CONFIG_MLX5_FPGA=y
+CONFIG_MLX5_CORE_EN=y
+CONFIG_MLX5_EN_ARFS=y
+CONFIG_MLX5_EN_RXNFC=y
+CONFIG_MLX5_MPFS=y
+CONFIG_MLX5_ESWITCH=y
+CONFIG_MLX5_BRIDGE=y
+CONFIG_MLX5_CLS_ACT=y
+CONFIG_MLX5_TC_SAMPLE=y
+CONFIG_MLX5_CORE_EN_DCB=y
+CONFIG_MLX5_CORE_IPOIB=y
+# CONFIG_MLX5_EN_MACSEC is not set
+# CONFIG_MLX5_EN_IPSEC is not set
+# CONFIG_MLX5_EN_TLS is not set
+CONFIG_MLX5_SW_STEERING=y
+# CONFIG_MLX5_SF is not set
+CONFIG_MLXSW_CORE=m
+CONFIG_MLXSW_CORE_HWMON=y
+CONFIG_MLXSW_CORE_THERMAL=y
+CONFIG_MLXSW_PCI=m
+CONFIG_MLXSW_I2C=m
+CONFIG_MLXSW_SPECTRUM=m
+CONFIG_MLXSW_SPECTRUM_DCB=y
+CONFIG_MLXSW_MINIMAL=m
+CONFIG_MLXFW=m
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+CONFIG_NET_VENDOR_MICROSOFT=y
+# CONFIG_MICROSOFT_MANA is not set
+CONFIG_NET_VENDOR_MYRI=y
+CONFIG_MYRI10GE=m
+CONFIG_MYRI10GE_DCA=y
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_NET_VENDOR_NETERION=y
+# CONFIG_S2IO is not set
+CONFIG_NET_VENDOR_NETRONOME=y
+CONFIG_NFP=m
+CONFIG_NFP_APP_FLOWER=y
+CONFIG_NFP_APP_ABM_NIC=y
+# CONFIG_NFP_DEBUG is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+CONFIG_NET_VENDOR_OKI=y
+CONFIG_ETHOC=m
+CONFIG_NET_VENDOR_PACKET_ENGINES=y
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_NET_VENDOR_PENSANDO=y
+# CONFIG_IONIC is not set
+CONFIG_NET_VENDOR_QLOGIC=y
+CONFIG_QLA3XXX=m
+# CONFIG_QLCNIC is not set
+CONFIG_NETXEN_NIC=m
+CONFIG_QED=m
+CONFIG_QED_LL2=y
+CONFIG_QED_SRIOV=y
+CONFIG_QEDE=m
+CONFIG_QED_RDMA=y
+CONFIG_QED_ISCSI=y
+CONFIG_QED_FCOE=y
+CONFIG_QED_OOO=y
+CONFIG_NET_VENDOR_BROCADE=y
+# CONFIG_BNA is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RDC is not set
+CONFIG_NET_VENDOR_REALTEK=y
+# CONFIG_ATP is not set
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_R8169=m
+# CONFIG_NET_VENDOR_RENESAS is not set
+CONFIG_NET_VENDOR_ROCKER=y
+CONFIG_ROCKER=m
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+CONFIG_NET_VENDOR_SOLARFLARE=y
+CONFIG_SFC=m
+CONFIG_SFC_MTD=y
+CONFIG_SFC_MCDI_MON=y
+CONFIG_SFC_SRIOV=y
+CONFIG_SFC_MCDI_LOGGING=y
+# CONFIG_SFC_FALCON is not set
+# CONFIG_SFC_SIENA is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+CONFIG_NET_VENDOR_VERTEXCOM=y
+# CONFIG_MSE102X is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_NET_SB1000 is not set
+CONFIG_PHYLINK=m
+CONFIG_PHYLIB=y
+CONFIG_SWPHY=y
+CONFIG_LED_TRIGGER_PHY=y
+CONFIG_FIXED_PHY=y
+# CONFIG_SFP is not set
+
+#
+# MII PHY device drivers
+#
+CONFIG_AMD_PHY=m
+# CONFIG_ADIN_PHY is not set
+# CONFIG_ADIN1100_PHY is not set
+CONFIG_AQUANTIA_PHY=m
+CONFIG_AX88796B_PHY=m
+CONFIG_BROADCOM_PHY=m
+# CONFIG_BCM54140_PHY is not set
+CONFIG_BCM7XXX_PHY=m
+# CONFIG_BCM84881_PHY is not set
+CONFIG_BCM87XX_PHY=m
+CONFIG_BCM_NET_PHYLIB=m
+CONFIG_BCM_NET_PHYPTP=m
+CONFIG_CICADA_PHY=m
+CONFIG_CORTINA_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_INTEL_XWAY_PHY=m
+CONFIG_LSI_ET1011C_PHY=m
+CONFIG_MARVELL_PHY=m
+CONFIG_MARVELL_10G_PHY=m
+# CONFIG_MARVELL_88X2222_PHY is not set
+# CONFIG_MAXLINEAR_GPHY is not set
+# CONFIG_MEDIATEK_GE_PHY is not set
+CONFIG_MICREL_PHY=m
+CONFIG_MICROCHIP_PHY=m
+CONFIG_MICROCHIP_T1_PHY=m
+CONFIG_MICROSEMI_PHY=m
+# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_NATIONAL_PHY=m
+# CONFIG_NXP_C45_TJA11XX_PHY is not set
+# CONFIG_NXP_TJA11XX_PHY is not set
+CONFIG_QSEMI_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_RENESAS_PHY=m
+CONFIG_ROCKCHIP_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_STE10XP=m
+CONFIG_TERANETICS_PHY=m
+CONFIG_DP83822_PHY=m
+CONFIG_DP83TC811_PHY=m
+CONFIG_DP83848_PHY=m
+CONFIG_DP83867_PHY=m
+# CONFIG_DP83869_PHY is not set
+# CONFIG_DP83TD510_PHY is not set
+CONFIG_VITESSE_PHY=m
+CONFIG_XILINX_GMII2RGMII=m
+CONFIG_MICREL_KS8995MA=m
+# CONFIG_PSE_CONTROLLER is not set
+CONFIG_CAN_DEV=m
+CONFIG_CAN_VCAN=m
+# CONFIG_CAN_VXCAN is not set
+CONFIG_CAN_NETLINK=y
+CONFIG_CAN_CALC_BITTIMING=y
+# CONFIG_CAN_CAN327 is not set
+# CONFIG_CAN_KVASER_PCIEFD is not set
+CONFIG_CAN_SLCAN=m
+CONFIG_CAN_C_CAN=m
+CONFIG_CAN_C_CAN_PLATFORM=m
+CONFIG_CAN_C_CAN_PCI=m
+CONFIG_CAN_CC770=m
+# CONFIG_CAN_CC770_ISA is not set
+CONFIG_CAN_CC770_PLATFORM=m
+# CONFIG_CAN_CTUCANFD_PCI is not set
+# CONFIG_CAN_IFI_CANFD is not set
+# CONFIG_CAN_M_CAN is not set
+# CONFIG_CAN_PEAK_PCIEFD is not set
+CONFIG_CAN_SJA1000=m
+CONFIG_CAN_EMS_PCI=m
+# CONFIG_CAN_F81601 is not set
+CONFIG_CAN_KVASER_PCI=m
+CONFIG_CAN_PEAK_PCI=m
+CONFIG_CAN_PEAK_PCIEC=y
+CONFIG_CAN_PLX_PCI=m
+# CONFIG_CAN_SJA1000_ISA is not set
+CONFIG_CAN_SJA1000_PLATFORM=m
+CONFIG_CAN_SOFTING=m
+
+#
+# CAN SPI interfaces
+#
+# CONFIG_CAN_HI311X is not set
+# CONFIG_CAN_MCP251X is not set
+# CONFIG_CAN_MCP251XFD is not set
+# end of CAN SPI interfaces
+
+#
+# CAN USB interfaces
+#
+CONFIG_CAN_8DEV_USB=m
+CONFIG_CAN_EMS_USB=m
+# CONFIG_CAN_ESD_USB is not set
+# CONFIG_CAN_ETAS_ES58X is not set
+# CONFIG_CAN_GS_USB is not set
+CONFIG_CAN_KVASER_USB=m
+# CONFIG_CAN_MCBA_USB is not set
+CONFIG_CAN_PEAK_USB=m
+# CONFIG_CAN_UCAN is not set
+# end of CAN USB interfaces
+
+# CONFIG_CAN_DEBUG_DEVICES is not set
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_BUS=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_ACPI_MDIO=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_BITBANG=m
+# CONFIG_MDIO_BCM_UNIMAC is not set
+CONFIG_MDIO_CAVIUM=m
+# CONFIG_MDIO_GPIO is not set
+# CONFIG_MDIO_MVUSB is not set
+CONFIG_MDIO_THUNDER=m
+
+#
+# MDIO Multiplexers
+#
+
+#
+# PCS device drivers
+#
+# end of PCS device drivers
+
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOATM=m
+CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_SLIP=m
+CONFIG_SLHC=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_USB_NET_DRIVERS=y
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_LAN78XX=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_AX88179_178A=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_CDC_EEM=m
+CONFIG_USB_NET_CDC_NCM=m
+CONFIG_USB_NET_HUAWEI_CDC_NCM=m
+CONFIG_USB_NET_CDC_MBIM=m
+CONFIG_USB_NET_DM9601=m
+# CONFIG_USB_NET_SR9700 is not set
+# CONFIG_USB_NET_SR9800 is not set
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET_ENABLE=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_NET_CX82310_ETH=m
+CONFIG_USB_NET_KALMIA=m
+CONFIG_USB_NET_QMI_WWAN=m
+CONFIG_USB_HSO=m
+CONFIG_USB_NET_INT51X1=m
+CONFIG_USB_IPHETH=m
+CONFIG_USB_SIERRA_NET=m
+CONFIG_USB_VL600=m
+CONFIG_USB_NET_CH9200=m
+# CONFIG_USB_NET_AQC111 is not set
+CONFIG_USB_RTL8153_ECM=m
+CONFIG_WLAN=y
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+CONFIG_ATH_COMMON=m
+CONFIG_WLAN_VENDOR_ATH=y
+# CONFIG_ATH_DEBUG is not set
+# CONFIG_ATH5K is not set
+# CONFIG_ATH5K_PCI is not set
+CONFIG_ATH9K_HW=m
+CONFIG_ATH9K_COMMON=m
+CONFIG_ATH9K_COMMON_DEBUG=y
+CONFIG_ATH9K_BTCOEX_SUPPORT=y
+CONFIG_ATH9K=m
+CONFIG_ATH9K_PCI=y
+CONFIG_ATH9K_AHB=y
+CONFIG_ATH9K_DEBUGFS=y
+# CONFIG_ATH9K_STATION_STATISTICS is not set
+# CONFIG_ATH9K_DYNACK is not set
+CONFIG_ATH9K_WOW=y
+CONFIG_ATH9K_RFKILL=y
+# CONFIG_ATH9K_CHANNEL_CONTEXT is not set
+CONFIG_ATH9K_PCOEM=y
+# CONFIG_ATH9K_PCI_NO_EEPROM is not set
+CONFIG_ATH9K_HTC=m
+# CONFIG_ATH9K_HTC_DEBUGFS is not set
+# CONFIG_ATH9K_HWRNG is not set
+# CONFIG_ATH9K_COMMON_SPECTRAL is not set
+# CONFIG_CARL9170 is not set
+# CONFIG_ATH6KL is not set
+# CONFIG_AR5523 is not set
+# CONFIG_WIL6210 is not set
+CONFIG_ATH10K=m
+CONFIG_ATH10K_CE=y
+CONFIG_ATH10K_PCI=m
+# CONFIG_ATH10K_SDIO is not set
+# CONFIG_ATH10K_USB is not set
+# CONFIG_ATH10K_DEBUG is not set
+CONFIG_ATH10K_DEBUGFS=y
+# CONFIG_ATH10K_SPECTRAL is not set
+# CONFIG_ATH10K_TRACING is not set
+# CONFIG_WCN36XX is not set
+# CONFIG_ATH11K is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+CONFIG_WLAN_VENDOR_BROADCOM=y
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+CONFIG_BRCMUTIL=m
+CONFIG_BRCMSMAC=m
+CONFIG_BRCMSMAC_LEDS=y
+CONFIG_BRCMFMAC=m
+CONFIG_BRCMFMAC_PROTO_BCDC=y
+CONFIG_BRCMFMAC_PROTO_MSGBUF=y
+CONFIG_BRCMFMAC_SDIO=y
+CONFIG_BRCMFMAC_USB=y
+CONFIG_BRCMFMAC_PCIE=y
+# CONFIG_BRCM_TRACING is not set
+# CONFIG_BRCMDBG is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+CONFIG_WLAN_VENDOR_INTEL=y
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWL4965 is not set
+# CONFIG_IWL3945 is not set
+CONFIG_IWLWIFI=m
+CONFIG_IWLWIFI_LEDS=y
+CONFIG_IWLDVM=m
+CONFIG_IWLMVM=m
+CONFIG_IWLWIFI_OPMODE_MODULAR=y
+
+#
+# Debugging Options
+#
+# CONFIG_IWLWIFI_DEBUG is not set
+CONFIG_IWLWIFI_DEBUGFS=y
+# CONFIG_IWLWIFI_DEVICE_TRACING is not set
+# end of Debugging Options
+
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+CONFIG_WLAN_VENDOR_MARVELL=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_PCIE=m
+CONFIG_MWIFIEX_USB=m
+# CONFIG_MWL8K is not set
+CONFIG_WLAN_VENDOR_MEDIATEK=y
+CONFIG_MT7601U=m
+CONFIG_MT76_CORE=m
+CONFIG_MT76_LEDS=y
+CONFIG_MT76_USB=m
+CONFIG_MT76x02_LIB=m
+CONFIG_MT76x02_USB=m
+CONFIG_MT76x0_COMMON=m
+CONFIG_MT76x0U=m
+# CONFIG_MT76x0E is not set
+CONFIG_MT76x2_COMMON=m
+# CONFIG_MT76x2E is not set
+CONFIG_MT76x2U=m
+# CONFIG_MT7603E is not set
+# CONFIG_MT7615E is not set
+# CONFIG_MT7663U is not set
+# CONFIG_MT7663S is not set
+# CONFIG_MT7915E is not set
+# CONFIG_MT7921E is not set
+# CONFIG_MT7921S is not set
+# CONFIG_MT7921U is not set
+CONFIG_WLAN_VENDOR_MICROCHIP=y
+# CONFIG_WILC1000_SDIO is not set
+# CONFIG_WILC1000_SPI is not set
+CONFIG_WLAN_VENDOR_PURELIFI=y
+# CONFIG_PLFXLC is not set
+CONFIG_WLAN_VENDOR_RALINK=y
+CONFIG_RT2X00=m
+# CONFIG_RT2400PCI is not set
+# CONFIG_RT2500PCI is not set
+# CONFIG_RT61PCI is not set
+CONFIG_RT2800PCI=m
+CONFIG_RT2800PCI_RT33XX=y
+CONFIG_RT2800PCI_RT35XX=y
+CONFIG_RT2800PCI_RT53XX=y
+CONFIG_RT2800PCI_RT3290=y
+# CONFIG_RT2500USB is not set
+# CONFIG_RT73USB is not set
+CONFIG_RT2800USB=m
+CONFIG_RT2800USB_RT33XX=y
+CONFIG_RT2800USB_RT35XX=y
+CONFIG_RT2800USB_RT3573=y
+CONFIG_RT2800USB_RT53XX=y
+CONFIG_RT2800USB_RT55XX=y
+CONFIG_RT2800USB_UNKNOWN=y
+CONFIG_RT2800_LIB=m
+CONFIG_RT2800_LIB_MMIO=m
+CONFIG_RT2X00_LIB_MMIO=m
+CONFIG_RT2X00_LIB_PCI=m
+CONFIG_RT2X00_LIB_USB=m
+CONFIG_RT2X00_LIB=m
+CONFIG_RT2X00_LIB_FIRMWARE=y
+CONFIG_RT2X00_LIB_CRYPTO=y
+CONFIG_RT2X00_LIB_LEDS=y
+CONFIG_RT2X00_LIB_DEBUGFS=y
+# CONFIG_RT2X00_DEBUG is not set
+CONFIG_WLAN_VENDOR_REALTEK=y
+# CONFIG_RTL8180 is not set
+# CONFIG_RTL8187 is not set
+CONFIG_RTL_CARDS=m
+CONFIG_RTL8192CE=m
+CONFIG_RTL8192SE=m
+CONFIG_RTL8192DE=m
+CONFIG_RTL8723AE=m
+CONFIG_RTL8723BE=m
+CONFIG_RTL8188EE=m
+CONFIG_RTL8192EE=m
+CONFIG_RTL8821AE=m
+CONFIG_RTL8192CU=m
+CONFIG_RTLWIFI=m
+CONFIG_RTLWIFI_PCI=m
+CONFIG_RTLWIFI_USB=m
+# CONFIG_RTLWIFI_DEBUG is not set
+CONFIG_RTL8192C_COMMON=m
+CONFIG_RTL8723_COMMON=m
+CONFIG_RTLBTCOEXIST=m
+CONFIG_RTL8XXXU=m
+# CONFIG_RTL8XXXU_UNTESTED is not set
+# CONFIG_RTW88 is not set
+# CONFIG_RTW89 is not set
+# CONFIG_WLAN_VENDOR_RSI is not set
+CONFIG_WLAN_VENDOR_SILABS=y
+# CONFIG_WFX is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+CONFIG_WLAN_VENDOR_QUANTENNA=y
+# CONFIG_QTNFMAC_PCIE is not set
+CONFIG_MAC80211_HWSIM=m
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_VIRT_WIFI is not set
+CONFIG_WAN=y
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=m
+# CONFIG_HDLC_RAW_ETH is not set
+CONFIG_HDLC_CISCO=m
+CONFIG_HDLC_FR=m
+CONFIG_HDLC_PPP=m
+
+#
+# X.25/LAPB support is disabled
+#
+# CONFIG_PCI200SYN is not set
+# CONFIG_WANXL is not set
+# CONFIG_PC300TOO is not set
+# CONFIG_FARSYNC is not set
+CONFIG_IEEE802154_DRIVERS=m
+CONFIG_IEEE802154_FAKELB=m
+# CONFIG_IEEE802154_AT86RF230 is not set
+# CONFIG_IEEE802154_MRF24J40 is not set
+# CONFIG_IEEE802154_CC2520 is not set
+# CONFIG_IEEE802154_ATUSB is not set
+# CONFIG_IEEE802154_ADF7242 is not set
+# CONFIG_IEEE802154_CA8210 is not set
+# CONFIG_IEEE802154_MCR20A is not set
+# CONFIG_IEEE802154_HWSIM is not set
+
+#
+# Wireless WAN
+#
+# CONFIG_WWAN is not set
+# end of Wireless WAN
+
+CONFIG_XEN_NETDEV_FRONTEND=m
+CONFIG_VMXNET3=m
+CONFIG_FUJITSU_ES=m
+CONFIG_USB4_NET=m
+CONFIG_HYPERV_NET=m
+CONFIG_NETDEVSIM=m
+CONFIG_NET_FAILOVER=m
+CONFIG_ISDN=y
+CONFIG_ISDN_CAPI=y
+CONFIG_CAPI_TRACE=y
+CONFIG_ISDN_CAPI_MIDDLEWARE=y
+CONFIG_MISDN=m
+CONFIG_MISDN_DSP=m
+CONFIG_MISDN_L1OIP=m
+
+#
+# mISDN hardware drivers
+#
+CONFIG_MISDN_HFCPCI=m
+CONFIG_MISDN_HFCMULTI=m
+CONFIG_MISDN_HFCUSB=m
+CONFIG_MISDN_AVMFRITZ=m
+CONFIG_MISDN_SPEEDFAX=m
+CONFIG_MISDN_INFINEON=m
+CONFIG_MISDN_W6692=m
+CONFIG_MISDN_NETJET=m
+CONFIG_MISDN_HDLC=m
+CONFIG_MISDN_IPAC=m
+CONFIG_MISDN_ISAR=m
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_LEDS=y
+CONFIG_INPUT_FF_MEMLESS=m
+CONFIG_INPUT_SPARSEKMAP=m
+# CONFIG_INPUT_MATRIXKMAP is not set
+CONFIG_INPUT_VIVALDIFMAP=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADC is not set
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+# CONFIG_KEYBOARD_APPLESPI is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1050 is not set
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_DLINK_DIR685 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_TCA8418 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_LM8333 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_SAMSUNG is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_CYPRESS_SF is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_BYD=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_MOUSE_PS2_ELANTECH_SMBUS=y
+CONFIG_MOUSE_PS2_SENTELIC=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_PS2_FOCALTECH=y
+CONFIG_MOUSE_PS2_VMMOUSE=y
+CONFIG_MOUSE_PS2_SMBUS=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_APPLETOUCH=m
+CONFIG_MOUSE_BCM5974=m
+CONFIG_MOUSE_CYAPA=m
+CONFIG_MOUSE_ELAN_I2C=m
+CONFIG_MOUSE_ELAN_I2C_I2C=y
+CONFIG_MOUSE_ELAN_I2C_SMBUS=y
+CONFIG_MOUSE_VSXXXAA=m
+# CONFIG_MOUSE_GPIO is not set
+CONFIG_MOUSE_SYNAPTICS_I2C=m
+CONFIG_MOUSE_SYNAPTICS_USB=m
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TABLET=y
+CONFIG_TABLET_USB_ACECAD=m
+CONFIG_TABLET_USB_AIPTEK=m
+# CONFIG_TABLET_USB_HANWANG is not set
+CONFIG_TABLET_USB_KBTAB=m
+# CONFIG_TABLET_USB_PEGASUS is not set
+CONFIG_TABLET_SERIAL_WACOM4=m
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_ADC is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
+# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
+# CONFIG_TOUCHSCREEN_BU21013 is not set
+# CONFIG_TOUCHSCREEN_BU21029 is not set
+# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set
+# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set
+# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
+# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
+# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set
+# CONFIG_TOUCHSCREEN_EXC3000 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GOODIX is not set
+# CONFIG_TOUCHSCREEN_HIDEEP is not set
+# CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set
+# CONFIG_TOUCHSCREEN_ILI210X is not set
+# CONFIG_TOUCHSCREEN_ILITEK is not set
+# CONFIG_TOUCHSCREEN_S6SY761 is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_EKTF2127 is not set
+# CONFIG_TOUCHSCREEN_ELAN is not set
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_WACOM_W8001=m
+CONFIG_TOUCHSCREEN_WACOM_I2C=m
+# CONFIG_TOUCHSCREEN_MAX11801 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MMS114 is not set
+# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set
+# CONFIG_TOUCHSCREEN_MSG2638 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_IMAGIS is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_PIXCIR is not set
+# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set
+# CONFIG_TOUCHSCREEN_WM97XX is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
+# CONFIG_TOUCHSCREEN_TSC2004 is not set
+# CONFIG_TOUCHSCREEN_TSC2005 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_RM_TS is not set
+# CONFIG_TOUCHSCREEN_SILEAD is not set
+# CONFIG_TOUCHSCREEN_SIS_I2C is not set
+# CONFIG_TOUCHSCREEN_ST1232 is not set
+# CONFIG_TOUCHSCREEN_STMFTS is not set
+# CONFIG_TOUCHSCREEN_SUR40 is not set
+# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set
+# CONFIG_TOUCHSCREEN_SX8654 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+# CONFIG_TOUCHSCREEN_ZET6223 is not set
+# CONFIG_TOUCHSCREEN_ZFORCE is not set
+# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set
+# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
+# CONFIG_TOUCHSCREEN_IQS5XX is not set
+# CONFIG_TOUCHSCREEN_ZINITIX is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_BMA150 is not set
+# CONFIG_INPUT_E3X0_BUTTON is not set
+CONFIG_INPUT_PCSPKR=m
+# CONFIG_INPUT_MMA8450 is not set
+CONFIG_INPUT_APANEL=m
+# CONFIG_INPUT_GPIO_BEEPER is not set
+# CONFIG_INPUT_GPIO_DECODER is not set
+# CONFIG_INPUT_GPIO_VIBRA is not set
+CONFIG_INPUT_ATLAS_BTNS=m
+CONFIG_INPUT_ATI_REMOTE2=m
+CONFIG_INPUT_KEYSPAN_REMOTE=m
+# CONFIG_INPUT_KXTJ9 is not set
+CONFIG_INPUT_POWERMATE=m
+CONFIG_INPUT_YEALINK=m
+CONFIG_INPUT_CM109=m
+CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_PWM_VIBRA is not set
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
+# CONFIG_INPUT_DA7280_HAPTICS is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_IMS_PCU is not set
+# CONFIG_INPUT_IQS269A is not set
+# CONFIG_INPUT_IQS626A is not set
+# CONFIG_INPUT_IQS7222 is not set
+# CONFIG_INPUT_CMA3000 is not set
+CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
+# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set
+# CONFIG_INPUT_DRV260X_HAPTICS is not set
+# CONFIG_INPUT_DRV2665_HAPTICS is not set
+# CONFIG_INPUT_DRV2667_HAPTICS is not set
+CONFIG_RMI4_CORE=m
+CONFIG_RMI4_I2C=m
+CONFIG_RMI4_SPI=m
+CONFIG_RMI4_SMB=m
+CONFIG_RMI4_F03=y
+CONFIG_RMI4_F03_SERIO=m
+CONFIG_RMI4_2D_SENSOR=y
+CONFIG_RMI4_F11=y
+CONFIG_RMI4_F12=y
+CONFIG_RMI4_F30=y
+CONFIG_RMI4_F34=y
+# CONFIG_RMI4_F3A is not set
+# CONFIG_RMI4_F54 is not set
+CONFIG_RMI4_F55=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_SERIO_ALTERA_PS2=m
+# CONFIG_SERIO_PS2MULT is not set
+CONFIG_SERIO_ARC_PS2=m
+CONFIG_HYPERV_KEYBOARD=m
+# CONFIG_SERIO_GPIO_PS2 is not set
+# CONFIG_USERIO is not set
+# CONFIG_GAMEPORT is not set
+# end of Hardware I/O ports
+# end of Input device support
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_LDISC_AUTOLOAD=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_EARLYCON=y
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_PNP=y
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
+# CONFIG_SERIAL_8250_FINTEK is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_DMA=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_EXAR=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_DW=y
+# CONFIG_SERIAL_8250_RT288X is not set
+CONFIG_SERIAL_8250_LPSS=y
+CONFIG_SERIAL_8250_MID=y
+CONFIG_SERIAL_8250_PERICOM=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_KGDB_NMI is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX310X is not set
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_CONSOLE_POLL=y
+CONFIG_SERIAL_JSM=m
+# CONFIG_SERIAL_LANTIQ is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_SC16IS7XX is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_SERIAL_ARC=m
+CONFIG_SERIAL_ARC_NR_PORTS=1
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_FSL_LINFLEXUART is not set
+# CONFIG_SERIAL_SPRD is not set
+# end of Serial drivers
+
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+CONFIG_N_GSM=m
+CONFIG_NOZOMI=m
+# CONFIG_NULL_TTY is not set
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_IRQ=y
+CONFIG_HVC_XEN=y
+CONFIG_HVC_XEN_FRONTEND=y
+# CONFIG_SERIAL_DEV_BUS is not set
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+CONFIG_PPDEV=m
+CONFIG_VIRTIO_CONSOLE=m
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DMI_DECODE=y
+CONFIG_IPMI_PLAT_DATA=y
+CONFIG_IPMI_PANIC_EVENT=y
+CONFIG_IPMI_PANIC_STRING=y
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_SSIF=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_HW_RANDOM_INTEL=m
+CONFIG_HW_RANDOM_AMD=m
+# CONFIG_HW_RANDOM_BA431 is not set
+CONFIG_HW_RANDOM_VIA=m
+CONFIG_HW_RANDOM_VIRTIO=y
+# CONFIG_HW_RANDOM_XIPHERA is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_MWAVE is not set
+CONFIG_DEVMEM=y
+CONFIG_NVRAM=y
+CONFIG_DEVPORT=y
+CONFIG_HPET=y
+CONFIG_HPET_MMAP=y
+# CONFIG_HPET_MMAP_DEFAULT is not set
+CONFIG_HANGCHECK_TIMER=m
+CONFIG_UV_MMTIMER=m
+CONFIG_TCG_TPM=y
+CONFIG_HW_RANDOM_TPM=y
+CONFIG_TCG_TIS_CORE=y
+CONFIG_TCG_TIS=y
+CONFIG_TCG_TIS_SPI=m
+# CONFIG_TCG_TIS_SPI_CR50 is not set
+# CONFIG_TCG_TIS_I2C is not set
+# CONFIG_TCG_TIS_I2C_CR50 is not set
+CONFIG_TCG_TIS_I2C_ATMEL=m
+CONFIG_TCG_TIS_I2C_INFINEON=m
+CONFIG_TCG_TIS_I2C_NUVOTON=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+# CONFIG_TCG_XEN is not set
+CONFIG_TCG_CRB=y
+# CONFIG_TCG_VTPM_PROXY is not set
+CONFIG_TCG_TIS_ST33ZP24=m
+CONFIG_TCG_TIS_ST33ZP24_I2C=m
+CONFIG_TCG_TIS_ST33ZP24_SPI=m
+CONFIG_TELCLOCK=m
+# CONFIG_XILLYBUS is not set
+# CONFIG_XILLYUSB is not set
+# CONFIG_RANDOM_TRUST_CPU is not set
+# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
+# end of Character devices
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_ACPI_I2C_OPREGION=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MUX=m
+
+#
+# Multiplexer I2C Chip support
+#
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_LTC4306 is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+# CONFIG_I2C_MUX_PCA954x is not set
+# CONFIG_I2C_MUX_REG is not set
+CONFIG_I2C_MUX_MLXCPLD=m
+# end of Multiplexer I2C Chip support
+
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_SMBUS=m
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_AMD_MP2 is not set
+CONFIG_I2C_I801=m
+CONFIG_I2C_ISCH=m
+CONFIG_I2C_ISMT=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_NFORCE2_S4985=m
+# CONFIG_I2C_NVIDIA_GPU is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+
+#
+# ACPI drivers
+#
+CONFIG_I2C_SCMI=m
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_CBUS_GPIO is not set
+CONFIG_I2C_DESIGNWARE_CORE=m
+# CONFIG_I2C_DESIGNWARE_SLAVE is not set
+CONFIG_I2C_DESIGNWARE_PLATFORM=m
+# CONFIG_I2C_DESIGNWARE_AMDPSP is not set
+CONFIG_I2C_DESIGNWARE_BAYTRAIL=y
+# CONFIG_I2C_DESIGNWARE_PCI is not set
+# CONFIG_I2C_EMEV2 is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PCA_PLATFORM=m
+CONFIG_I2C_SIMTEC=m
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+CONFIG_I2C_DIOLAN_U2C=m
+# CONFIG_I2C_CP2615 is not set
+CONFIG_I2C_PARPORT=m
+# CONFIG_I2C_PCI1XXXX is not set
+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
+# CONFIG_I2C_TAOS_EVM is not set
+CONFIG_I2C_TINY_USB=m
+CONFIG_I2C_VIPERBOARD=m
+
+#
+# Other I2C/SMBus bus drivers
+#
+CONFIG_I2C_MLXCPLD=m
+# CONFIG_I2C_VIRTIO is not set
+# end of I2C Hardware Bus support
+
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_SLAVE is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# end of I2C support
+
+# CONFIG_I3C is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+# CONFIG_SPI_AXI_SPI_ENGINE is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_BUTTERFLY is not set
+# CONFIG_SPI_CADENCE is not set
+# CONFIG_SPI_DESIGNWARE is not set
+# CONFIG_SPI_NXP_FLEXSPI is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_INTEL_PCI is not set
+# CONFIG_SPI_INTEL_PLATFORM is not set
+# CONFIG_SPI_LM70_LLP is not set
+# CONFIG_SPI_MICROCHIP_CORE is not set
+# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set
+# CONFIG_SPI_LANTIQ_SSC is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX is not set
+# CONFIG_SPI_ROCKCHIP is not set
+# CONFIG_SPI_SC18IS602 is not set
+# CONFIG_SPI_SIFIVE is not set
+# CONFIG_SPI_MXIC is not set
+# CONFIG_SPI_XCOMM is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_ZYNQMP_GQSPI is not set
+# CONFIG_SPI_AMD is not set
+
+#
+# SPI Multiplexer support
+#
+# CONFIG_SPI_MUX is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_LOOPBACK_TEST is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_SPI_SLAVE is not set
+CONFIG_SPI_DYNAMIC=y
+# CONFIG_SPMI is not set
+# CONFIG_HSI is not set
+CONFIG_PPS=y
+# CONFIG_PPS_DEBUG is not set
+
+#
+# PPS clients support
+#
+# CONFIG_PPS_CLIENT_KTIMER is not set
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_PARPORT=m
+CONFIG_PPS_CLIENT_GPIO=m
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_DP83640_PHY=m
+# CONFIG_PTP_1588_CLOCK_INES is not set
+CONFIG_PTP_1588_CLOCK_KVM=m
+# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set
+# CONFIG_PTP_1588_CLOCK_IDTCM is not set
+# CONFIG_PTP_1588_CLOCK_VMW is not set
+# CONFIG_PTP_1588_CLOCK_OCP is not set
+# end of PTP clock support
+
+CONFIG_PINCTRL=y
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+CONFIG_GENERIC_PINCONF=y
+# CONFIG_DEBUG_PINCTRL is not set
+# CONFIG_PINCTRL_AMD is not set
+# CONFIG_PINCTRL_CY8C95X0 is not set
+# CONFIG_PINCTRL_MCP23S08 is not set
+# CONFIG_PINCTRL_SX150X is not set
+
+#
+# Intel pinctrl drivers
+#
+CONFIG_PINCTRL_BAYTRAIL=y
+# CONFIG_PINCTRL_CHERRYVIEW is not set
+# CONFIG_PINCTRL_LYNXPOINT is not set
+CONFIG_PINCTRL_INTEL=y
+# CONFIG_PINCTRL_ALDERLAKE is not set
+CONFIG_PINCTRL_BROXTON=m
+CONFIG_PINCTRL_CANNONLAKE=m
+CONFIG_PINCTRL_CEDARFORK=m
+CONFIG_PINCTRL_DENVERTON=m
+# CONFIG_PINCTRL_ELKHARTLAKE is not set
+CONFIG_PINCTRL_EMMITSBURG=m
+CONFIG_PINCTRL_GEMINILAKE=m
+CONFIG_PINCTRL_ICELAKE=m
+# CONFIG_PINCTRL_JASPERLAKE is not set
+# CONFIG_PINCTRL_LAKEFIELD is not set
+CONFIG_PINCTRL_LEWISBURG=m
+# CONFIG_PINCTRL_METEORLAKE is not set
+CONFIG_PINCTRL_SUNRISEPOINT=m
+# CONFIG_PINCTRL_TIGERLAKE is not set
+# end of Intel pinctrl drivers
+
+#
+# Renesas pinctrl drivers
+#
+# end of Renesas pinctrl drivers
+
+CONFIG_GPIOLIB=y
+CONFIG_GPIOLIB_FASTPATH_LIMIT=512
+CONFIG_GPIO_ACPI=y
+CONFIG_GPIOLIB_IRQCHIP=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_CDEV_V1=y
+CONFIG_GPIO_GENERIC=m
+
+#
+# Memory mapped GPIO drivers
+#
+CONFIG_GPIO_AMDPT=m
+# CONFIG_GPIO_DWAPB is not set
+# CONFIG_GPIO_EXAR is not set
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+CONFIG_GPIO_ICH=m
+# CONFIG_GPIO_MB86S7X is not set
+# CONFIG_GPIO_VX855 is not set
+# CONFIG_GPIO_AMD_FCH is not set
+# end of Memory mapped GPIO drivers
+
+#
+# Port-mapped I/O GPIO drivers
+#
+# CONFIG_GPIO_F7188X is not set
+# CONFIG_GPIO_IT87 is not set
+# CONFIG_GPIO_SCH is not set
+# CONFIG_GPIO_SCH311X is not set
+# CONFIG_GPIO_WINBOND is not set
+# CONFIG_GPIO_WS16C48 is not set
+# end of Port-mapped I/O GPIO drivers
+
+#
+# I2C GPIO expanders
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCA9570 is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_TPIC2810 is not set
+# end of I2C GPIO expanders
+
+#
+# MFD GPIO expanders
+#
+# end of MFD GPIO expanders
+
+#
+# PCI GPIO expanders
+#
+# CONFIG_GPIO_AMD8111 is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_PCI_IDIO_16 is not set
+# CONFIG_GPIO_PCIE_IDIO_24 is not set
+# CONFIG_GPIO_RDC321X is not set
+# end of PCI GPIO expanders
+
+#
+# SPI GPIO expanders
+#
+# CONFIG_GPIO_MAX3191X is not set
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_PISOSR is not set
+# CONFIG_GPIO_XRA1403 is not set
+# end of SPI GPIO expanders
+
+#
+# USB GPIO expanders
+#
+CONFIG_GPIO_VIPERBOARD=m
+# end of USB GPIO expanders
+
+#
+# Virtual GPIO drivers
+#
+# CONFIG_GPIO_AGGREGATOR is not set
+# CONFIG_GPIO_MOCKUP is not set
+# CONFIG_GPIO_VIRTIO is not set
+# CONFIG_GPIO_SIM is not set
+# end of Virtual GPIO drivers
+
+# CONFIG_W1 is not set
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_RESTART is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+CONFIG_POWER_SUPPLY_HWMON=y
+# CONFIG_PDA_POWER is not set
+# CONFIG_GENERIC_ADC_BATTERY is not set
+# CONFIG_IP5XXX_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_CHARGER_ADP5061 is not set
+# CONFIG_BATTERY_CW2015 is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_SAMSUNG_SDI is not set
+# CONFIG_BATTERY_SBS is not set
+# CONFIG_CHARGER_SBS is not set
+# CONFIG_MANAGER_SBS is not set
+# CONFIG_BATTERY_BQ27XXX is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_LT3651 is not set
+# CONFIG_CHARGER_LTC4162L is not set
+# CONFIG_CHARGER_MAX77976 is not set
+# CONFIG_CHARGER_BQ2415X is not set
+# CONFIG_CHARGER_BQ24257 is not set
+# CONFIG_CHARGER_BQ24735 is not set
+# CONFIG_CHARGER_BQ2515X is not set
+# CONFIG_CHARGER_BQ25890 is not set
+# CONFIG_CHARGER_BQ25980 is not set
+# CONFIG_CHARGER_BQ256XX is not set
+# CONFIG_BATTERY_GAUGE_LTC2941 is not set
+# CONFIG_BATTERY_GOLDFISH is not set
+# CONFIG_BATTERY_RT5033 is not set
+# CONFIG_CHARGER_RT9455 is not set
+# CONFIG_CHARGER_BD99954 is not set
+# CONFIG_BATTERY_UG3105 is not set
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+CONFIG_SENSORS_ABITUGURU=m
+CONFIG_SENSORS_ABITUGURU3=m
+# CONFIG_SENSORS_AD7314 is not set
+CONFIG_SENSORS_AD7414=m
+CONFIG_SENSORS_AD7418=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+# CONFIG_SENSORS_ADM1177 is not set
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ADT7X10=m
+# CONFIG_SENSORS_ADT7310 is not set
+CONFIG_SENSORS_ADT7410=m
+CONFIG_SENSORS_ADT7411=m
+CONFIG_SENSORS_ADT7462=m
+CONFIG_SENSORS_ADT7470=m
+CONFIG_SENSORS_ADT7475=m
+# CONFIG_SENSORS_AHT10 is not set
+# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set
+# CONFIG_SENSORS_AS370 is not set
+CONFIG_SENSORS_ASC7621=m
+# CONFIG_SENSORS_AXI_FAN_CONTROL is not set
+CONFIG_SENSORS_K8TEMP=m
+CONFIG_SENSORS_K10TEMP=m
+CONFIG_SENSORS_FAM15H_POWER=m
+CONFIG_SENSORS_APPLESMC=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
+# CONFIG_SENSORS_CORSAIR_CPRO is not set
+# CONFIG_SENSORS_CORSAIR_PSU is not set
+# CONFIG_SENSORS_DRIVETEMP is not set
+CONFIG_SENSORS_DS620=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_DELL_SMM=m
+# CONFIG_I8K is not set
+CONFIG_SENSORS_I5K_AMB=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_F71882FG=m
+CONFIG_SENSORS_F75375S=m
+CONFIG_SENSORS_FSCHMD=m
+# CONFIG_SENSORS_FTSTEUTATES is not set
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_G760A=m
+# CONFIG_SENSORS_G762 is not set
+# CONFIG_SENSORS_HIH6130 is not set
+CONFIG_SENSORS_IBMAEM=m
+CONFIG_SENSORS_IBMPEX=m
+# CONFIG_SENSORS_IIO_HWMON is not set
+CONFIG_SENSORS_I5500=m
+CONFIG_SENSORS_CORETEMP=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_JC42=m
+# CONFIG_SENSORS_POWR1220 is not set
+CONFIG_SENSORS_LINEAGE=m
+# CONFIG_SENSORS_LTC2945 is not set
+# CONFIG_SENSORS_LTC2947_I2C is not set
+# CONFIG_SENSORS_LTC2947_SPI is not set
+# CONFIG_SENSORS_LTC2990 is not set
+# CONFIG_SENSORS_LTC2992 is not set
+CONFIG_SENSORS_LTC4151=m
+CONFIG_SENSORS_LTC4215=m
+# CONFIG_SENSORS_LTC4222 is not set
+CONFIG_SENSORS_LTC4245=m
+# CONFIG_SENSORS_LTC4260 is not set
+CONFIG_SENSORS_LTC4261=m
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX127 is not set
+CONFIG_SENSORS_MAX16065=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_MAX1668=m
+CONFIG_SENSORS_MAX197=m
+# CONFIG_SENSORS_MAX31722 is not set
+# CONFIG_SENSORS_MAX31730 is not set
+# CONFIG_SENSORS_MAX31760 is not set
+# CONFIG_SENSORS_MAX6620 is not set
+# CONFIG_SENSORS_MAX6621 is not set
+CONFIG_SENSORS_MAX6639=m
+CONFIG_SENSORS_MAX6650=m
+CONFIG_SENSORS_MAX6697=m
+# CONFIG_SENSORS_MAX31790 is not set
+CONFIG_SENSORS_MCP3021=m
+# CONFIG_SENSORS_MLXREG_FAN is not set
+# CONFIG_SENSORS_TC654 is not set
+# CONFIG_SENSORS_TPS23861 is not set
+# CONFIG_SENSORS_MR75203 is not set
+# CONFIG_SENSORS_ADCXX is not set
+CONFIG_SENSORS_LM63=m
+# CONFIG_SENSORS_LM70 is not set
+CONFIG_SENSORS_LM73=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_LM93=m
+CONFIG_SENSORS_LM95234=m
+CONFIG_SENSORS_LM95241=m
+CONFIG_SENSORS_LM95245=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_NTC_THERMISTOR=m
+# CONFIG_SENSORS_NCT6683 is not set
+CONFIG_SENSORS_NCT6775_CORE=m
+CONFIG_SENSORS_NCT6775=m
+# CONFIG_SENSORS_NCT6775_I2C is not set
+# CONFIG_SENSORS_NCT7802 is not set
+# CONFIG_SENSORS_NCT7904 is not set
+# CONFIG_SENSORS_NPCM7XX is not set
+# CONFIG_SENSORS_NZXT_KRAKEN2 is not set
+# CONFIG_SENSORS_NZXT_SMART2 is not set
+CONFIG_SENSORS_PCF8591=m
+CONFIG_PMBUS=m
+CONFIG_SENSORS_PMBUS=m
+# CONFIG_SENSORS_ADM1266 is not set
+CONFIG_SENSORS_ADM1275=m
+# CONFIG_SENSORS_BEL_PFE is not set
+# CONFIG_SENSORS_BPA_RS600 is not set
+# CONFIG_SENSORS_DELTA_AHE50DC_FAN is not set
+# CONFIG_SENSORS_FSP_3Y is not set
+# CONFIG_SENSORS_IBM_CFFPS is not set
+# CONFIG_SENSORS_DPS920AB is not set
+# CONFIG_SENSORS_INSPUR_IPSPS is not set
+# CONFIG_SENSORS_IR35221 is not set
+# CONFIG_SENSORS_IR36021 is not set
+# CONFIG_SENSORS_IR38064 is not set
+# CONFIG_SENSORS_IRPS5401 is not set
+# CONFIG_SENSORS_ISL68137 is not set
+CONFIG_SENSORS_LM25066=m
+# CONFIG_SENSORS_LT7182S is not set
+CONFIG_SENSORS_LTC2978=m
+# CONFIG_SENSORS_LTC3815 is not set
+# CONFIG_SENSORS_MAX15301 is not set
+CONFIG_SENSORS_MAX16064=m
+# CONFIG_SENSORS_MAX16601 is not set
+# CONFIG_SENSORS_MAX20730 is not set
+# CONFIG_SENSORS_MAX20751 is not set
+# CONFIG_SENSORS_MAX31785 is not set
+CONFIG_SENSORS_MAX34440=m
+CONFIG_SENSORS_MAX8688=m
+# CONFIG_SENSORS_MP2888 is not set
+# CONFIG_SENSORS_MP2975 is not set
+# CONFIG_SENSORS_MP5023 is not set
+# CONFIG_SENSORS_PIM4328 is not set
+# CONFIG_SENSORS_PLI1209BC is not set
+# CONFIG_SENSORS_PM6764TR is not set
+# CONFIG_SENSORS_PXE1610 is not set
+# CONFIG_SENSORS_Q54SJ108A2 is not set
+# CONFIG_SENSORS_STPDDC60 is not set
+# CONFIG_SENSORS_TPS40422 is not set
+# CONFIG_SENSORS_TPS53679 is not set
+# CONFIG_SENSORS_TPS546D24 is not set
+CONFIG_SENSORS_UCD9000=m
+CONFIG_SENSORS_UCD9200=m
+# CONFIG_SENSORS_XDPE152 is not set
+# CONFIG_SENSORS_XDPE122 is not set
+CONFIG_SENSORS_ZL6100=m
+# CONFIG_SENSORS_SBTSI is not set
+# CONFIG_SENSORS_SBRMI is not set
+CONFIG_SENSORS_SHT15=m
+CONFIG_SENSORS_SHT21=m
+# CONFIG_SENSORS_SHT3x is not set
+# CONFIG_SENSORS_SHT4x is not set
+# CONFIG_SENSORS_SHTC1 is not set
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_DME1737=m
+CONFIG_SENSORS_EMC1403=m
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC2305 is not set
+CONFIG_SENSORS_EMC6W201=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_SCH56XX_COMMON=m
+CONFIG_SENSORS_SCH5627=m
+CONFIG_SENSORS_SCH5636=m
+# CONFIG_SENSORS_STTS751 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_ADC128D818 is not set
+CONFIG_SENSORS_ADS7828=m
+# CONFIG_SENSORS_ADS7871 is not set
+CONFIG_SENSORS_AMC6821=m
+CONFIG_SENSORS_INA209=m
+CONFIG_SENSORS_INA2XX=m
+# CONFIG_SENSORS_INA238 is not set
+# CONFIG_SENSORS_INA3221 is not set
+# CONFIG_SENSORS_TC74 is not set
+CONFIG_SENSORS_THMC50=m
+CONFIG_SENSORS_TMP102=m
+# CONFIG_SENSORS_TMP103 is not set
+# CONFIG_SENSORS_TMP108 is not set
+CONFIG_SENSORS_TMP401=m
+CONFIG_SENSORS_TMP421=m
+# CONFIG_SENSORS_TMP464 is not set
+# CONFIG_SENSORS_TMP513 is not set
+CONFIG_SENSORS_VIA_CPUTEMP=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+# CONFIG_SENSORS_W83773G is not set
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83795=m
+# CONFIG_SENSORS_W83795_FANCTRL is not set
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83L786NG=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_SENSORS_XGENE is not set
+
+#
+# ACPI drivers
+#
+CONFIG_SENSORS_ACPI_POWER=m
+CONFIG_SENSORS_ATK0110=m
+# CONFIG_SENSORS_ASUS_WMI is not set
+# CONFIG_SENSORS_ASUS_EC is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_NETLINK=y
+# CONFIG_THERMAL_STATISTICS is not set
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
+CONFIG_THERMAL_GOV_FAIR_SHARE=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_BANG_BANG=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_EMULATION=y
+
+#
+# Intel thermal drivers
+#
+CONFIG_INTEL_POWERCLAMP=m
+CONFIG_X86_THERMAL_VECTOR=y
+CONFIG_X86_PKG_TEMP_THERMAL=m
+CONFIG_INTEL_SOC_DTS_IOSF_CORE=m
+# CONFIG_INTEL_SOC_DTS_THERMAL is not set
+
+#
+# ACPI INT340X thermal drivers
+#
+CONFIG_INT340X_THERMAL=m
+CONFIG_ACPI_THERMAL_REL=m
+# CONFIG_INT3406_THERMAL is not set
+CONFIG_PROC_THERMAL_MMIO_RAPL=m
+# end of ACPI INT340X thermal drivers
+
+CONFIG_INTEL_PCH_THERMAL=m
+# CONFIG_INTEL_TCC_COOLING is not set
+# CONFIG_INTEL_MENLOW is not set
+CONFIG_INTEL_HFI_THERMAL=y
+# end of Intel thermal drivers
+
+# CONFIG_GENERIC_ADC_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
+CONFIG_WATCHDOG_OPEN_TIMEOUT=0
+CONFIG_WATCHDOG_SYSFS=y
+# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set
+
+#
+# Watchdog Pretimeout Governors
+#
+# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_WDAT_WDT=m
+# CONFIG_XILINX_WATCHDOG is not set
+# CONFIG_ZIIRAVE_WATCHDOG is not set
+# CONFIG_MLX_WDT is not set
+# CONFIG_CADENCE_WATCHDOG is not set
+# CONFIG_DW_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_ALIM1535_WDT=m
+CONFIG_ALIM7101_WDT=m
+# CONFIG_EBC_C384_WDT is not set
+# CONFIG_EXAR_WDT is not set
+CONFIG_F71808E_WDT=m
+CONFIG_SP5100_TCO=m
+CONFIG_SBC_FITPC2_WATCHDOG=m
+# CONFIG_EUROTECH_WDT is not set
+CONFIG_IB700_WDT=m
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
+CONFIG_IE6XX_WDT=m
+CONFIG_ITCO_WDT=m
+CONFIG_ITCO_VENDOR_SUPPORT=y
+CONFIG_IT8712F_WDT=m
+CONFIG_IT87_WDT=m
+CONFIG_HP_WATCHDOG=m
+CONFIG_HPWDT_NMI_DECODING=y
+# CONFIG_SC1200_WDT is not set
+# CONFIG_PC87413_WDT is not set
+CONFIG_NV_TCO=m
+# CONFIG_60XX_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_SMSC_SCH311X_WDT=m
+# CONFIG_SMSC37B787_WDT is not set
+# CONFIG_TQMX86_WDT is not set
+CONFIG_VIA_WDT=m
+CONFIG_W83627HF_WDT=m
+CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
+CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+CONFIG_INTEL_MEI_WDT=m
+# CONFIG_NI903X_WDT is not set
+# CONFIG_NIC7018_WDT is not set
+# CONFIG_MEN_A21_WDT is not set
+CONFIG_XEN_WDT=m
+
+#
+# PCI-based Watchdog Cards
+#
+CONFIG_PCIPCWATCHDOG=m
+CONFIG_WDTPCI=m
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+CONFIG_BCMA=m
+CONFIG_BCMA_HOST_PCI_POSSIBLE=y
+CONFIG_BCMA_HOST_PCI=y
+# CONFIG_BCMA_HOST_SOC is not set
+CONFIG_BCMA_DRIVER_PCI=y
+CONFIG_BCMA_DRIVER_GMAC_CMN=y
+CONFIG_BCMA_DRIVER_GPIO=y
+# CONFIG_BCMA_DEBUG is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_AS3711 is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_BCM590XX is not set
+# CONFIG_MFD_BD9571MWV is not set
+# CONFIG_MFD_AXP20X_I2C is not set
+# CONFIG_MFD_MADERA is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
+# CONFIG_MFD_DA9055 is not set
+# CONFIG_MFD_DA9062 is not set
+# CONFIG_MFD_DA9063 is not set
+# CONFIG_MFD_DA9150 is not set
+# CONFIG_MFD_DLN2 is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
+# CONFIG_MFD_MP2629 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set
+CONFIG_LPC_ICH=m
+CONFIG_LPC_SCH=m
+CONFIG_MFD_INTEL_LPSS=y
+CONFIG_MFD_INTEL_LPSS_ACPI=y
+CONFIG_MFD_INTEL_LPSS_PCI=y
+# CONFIG_MFD_INTEL_PMC_BXT is not set
+# CONFIG_MFD_IQS62X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_MAX14577 is not set
+# CONFIG_MFD_MAX77693 is not set
+# CONFIG_MFD_MAX77843 is not set
+# CONFIG_MFD_MAX8907 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_MT6360 is not set
+# CONFIG_MFD_MT6370 is not set
+# CONFIG_MFD_MT6397 is not set
+# CONFIG_MFD_MENF21BMC is not set
+# CONFIG_MFD_OCELOT is not set
+# CONFIG_EZX_PCAP is not set
+CONFIG_MFD_VIPERBOARD=m
+# CONFIG_MFD_RETU is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_MFD_SY7636A is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RT4831 is not set
+# CONFIG_MFD_RT5033 is not set
+# CONFIG_MFD_RT5120 is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_SI476X_CORE is not set
+CONFIG_MFD_SM501=m
+CONFIG_MFD_SM501_GPIO=y
+# CONFIG_MFD_SKY81452 is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_LP3943 is not set
+# CONFIG_MFD_LP8788 is not set
+# CONFIG_MFD_TI_LMU is not set
+# CONFIG_MFD_PALMAS is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS65086 is not set
+# CONFIG_MFD_TPS65090 is not set
+# CONFIG_MFD_TI_LP873X is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65910 is not set
+# CONFIG_MFD_TPS65912_I2C is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_LM3533 is not set
+# CONFIG_MFD_TQMX86 is not set
+CONFIG_MFD_VX855=m
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_ATC260X_I2C is not set
+# CONFIG_MFD_INTEL_M10_BMC is not set
+# end of Multifunction device drivers
+
+# CONFIG_REGULATOR is not set
+CONFIG_RC_CORE=m
+CONFIG_LIRC=y
+CONFIG_RC_MAP=m
+CONFIG_RC_DECODERS=y
+CONFIG_IR_IMON_DECODER=m
+CONFIG_IR_JVC_DECODER=m
+CONFIG_IR_MCE_KBD_DECODER=m
+CONFIG_IR_NEC_DECODER=m
+CONFIG_IR_RC5_DECODER=m
+CONFIG_IR_RC6_DECODER=m
+# CONFIG_IR_RCMM_DECODER is not set
+CONFIG_IR_SANYO_DECODER=m
+# CONFIG_IR_SHARP_DECODER is not set
+CONFIG_IR_SONY_DECODER=m
+# CONFIG_IR_XMP_DECODER is not set
+CONFIG_RC_DEVICES=y
+CONFIG_IR_ENE=m
+CONFIG_IR_FINTEK=m
+# CONFIG_IR_IGORPLUGUSB is not set
+CONFIG_IR_IGUANA=m
+CONFIG_IR_IMON=m
+CONFIG_IR_IMON_RAW=m
+CONFIG_IR_ITE_CIR=m
+CONFIG_IR_MCEUSB=m
+CONFIG_IR_NUVOTON=m
+CONFIG_IR_REDRAT3=m
+CONFIG_IR_SERIAL=m
+CONFIG_IR_SERIAL_TRANSMITTER=y
+CONFIG_IR_STREAMZAP=m
+# CONFIG_IR_TOY is not set
+CONFIG_IR_TTUSBIR=m
+CONFIG_IR_WINBOND_CIR=m
+CONFIG_RC_ATI_REMOTE=m
+# CONFIG_RC_LOOPBACK is not set
+# CONFIG_RC_XBOX_DVD is not set
+CONFIG_CEC_CORE=m
+
+#
+# CEC support
+#
+# CONFIG_MEDIA_CEC_RC is not set
+CONFIG_MEDIA_CEC_SUPPORT=y
+# CONFIG_CEC_CH7322 is not set
+# CONFIG_CEC_GPIO is not set
+# CONFIG_CEC_SECO is not set
+CONFIG_USB_PULSE8_CEC=m
+CONFIG_USB_RAINSHADOW_CEC=m
+# end of CEC support
+
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_SUPPORT_FILTER=y
+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
+
+#
+# Media device types
+#
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_RADIO_SUPPORT=y
+# CONFIG_MEDIA_SDR_SUPPORT is not set
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+# CONFIG_MEDIA_TEST_SUPPORT is not set
+# end of Media device types
+
+CONFIG_VIDEO_DEV=m
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_DVB_CORE=m
+
+#
+# Video4Linux options
+#
+CONFIG_VIDEO_V4L2_I2C=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_TUNER=m
+CONFIG_V4L2_ASYNC=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_DMA_SG=m
+CONFIG_VIDEOBUF_VMALLOC=m
+# end of Video4Linux options
+
+#
+# Media controller options
+#
+CONFIG_MEDIA_CONTROLLER_DVB=y
+# end of Media controller options
+
+#
+# Digital TV options
+#
+# CONFIG_DVB_MMAP is not set
+CONFIG_DVB_NET=y
+CONFIG_DVB_MAX_ADAPTERS=8
+CONFIG_DVB_DYNAMIC_MINORS=y
+# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set
+# CONFIG_DVB_ULE_DEBUG is not set
+# end of Digital TV options
+
+#
+# Media drivers
+#
+
+#
+# Drivers filtered as selected at 'Filter media drivers'
+#
+
+#
+# Media drivers
+#
+CONFIG_MEDIA_USB_SUPPORT=y
+
+#
+# Webcam devices
+#
+CONFIG_USB_GSPCA=m
+CONFIG_USB_GSPCA_BENQ=m
+CONFIG_USB_GSPCA_CONEX=m
+CONFIG_USB_GSPCA_CPIA1=m
+# CONFIG_USB_GSPCA_DTCS033 is not set
+CONFIG_USB_GSPCA_ETOMS=m
+CONFIG_USB_GSPCA_FINEPIX=m
+CONFIG_USB_GSPCA_JEILINJ=m
+CONFIG_USB_GSPCA_JL2005BCD=m
+# CONFIG_USB_GSPCA_KINECT is not set
+CONFIG_USB_GSPCA_KONICA=m
+CONFIG_USB_GSPCA_MARS=m
+CONFIG_USB_GSPCA_MR97310A=m
+CONFIG_USB_GSPCA_NW80X=m
+CONFIG_USB_GSPCA_OV519=m
+CONFIG_USB_GSPCA_OV534=m
+CONFIG_USB_GSPCA_OV534_9=m
+CONFIG_USB_GSPCA_PAC207=m
+CONFIG_USB_GSPCA_PAC7302=m
+CONFIG_USB_GSPCA_PAC7311=m
+CONFIG_USB_GSPCA_SE401=m
+CONFIG_USB_GSPCA_SN9C2028=m
+CONFIG_USB_GSPCA_SN9C20X=m
+CONFIG_USB_GSPCA_SONIXB=m
+CONFIG_USB_GSPCA_SONIXJ=m
+CONFIG_USB_GSPCA_SPCA1528=m
+CONFIG_USB_GSPCA_SPCA500=m
+CONFIG_USB_GSPCA_SPCA501=m
+CONFIG_USB_GSPCA_SPCA505=m
+CONFIG_USB_GSPCA_SPCA506=m
+CONFIG_USB_GSPCA_SPCA508=m
+CONFIG_USB_GSPCA_SPCA561=m
+CONFIG_USB_GSPCA_SQ905=m
+CONFIG_USB_GSPCA_SQ905C=m
+CONFIG_USB_GSPCA_SQ930X=m
+CONFIG_USB_GSPCA_STK014=m
+# CONFIG_USB_GSPCA_STK1135 is not set
+CONFIG_USB_GSPCA_STV0680=m
+CONFIG_USB_GSPCA_SUNPLUS=m
+CONFIG_USB_GSPCA_T613=m
+CONFIG_USB_GSPCA_TOPRO=m
+# CONFIG_USB_GSPCA_TOUPTEK is not set
+CONFIG_USB_GSPCA_TV8532=m
+CONFIG_USB_GSPCA_VC032X=m
+CONFIG_USB_GSPCA_VICAM=m
+CONFIG_USB_GSPCA_XIRLINK_CIT=m
+CONFIG_USB_GSPCA_ZC3XX=m
+CONFIG_USB_GL860=m
+CONFIG_USB_M5602=m
+CONFIG_USB_STV06XX=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
+CONFIG_USB_S2255=m
+# CONFIG_VIDEO_USBTV is not set
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+
+#
+# Analog TV USB devices
+#
+# CONFIG_VIDEO_GO7007 is not set
+CONFIG_VIDEO_HDPVR=m
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+CONFIG_VIDEO_PVRUSB2_DVB=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+# CONFIG_VIDEO_STK1160_COMMON is not set
+
+#
+# Analog/digital TV USB devices
+#
+CONFIG_VIDEO_AU0828=m
+CONFIG_VIDEO_AU0828_V4L2=y
+# CONFIG_VIDEO_AU0828_RC is not set
+CONFIG_VIDEO_CX231XX=m
+CONFIG_VIDEO_CX231XX_RC=y
+CONFIG_VIDEO_CX231XX_ALSA=m
+CONFIG_VIDEO_CX231XX_DVB=m
+
+#
+# Digital TV USB devices
+#
+# CONFIG_DVB_AS102 is not set
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set
+CONFIG_DVB_USB_V2=m
+CONFIG_DVB_USB_AF9015=m
+CONFIG_DVB_USB_AF9035=m
+CONFIG_DVB_USB_ANYSEE=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_AZ6007=m
+CONFIG_DVB_USB_CE6230=m
+# CONFIG_DVB_USB_DVBSKY is not set
+CONFIG_DVB_USB_EC168=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_LME2510=m
+CONFIG_DVB_USB_MXL111SF=m
+CONFIG_DVB_USB_RTL28XXU=m
+# CONFIG_DVB_USB_ZD1301 is not set
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_AF9005=m
+CONFIG_DVB_USB_AF9005_REMOTE=m
+CONFIG_DVB_USB_AZ6027=m
+CONFIG_DVB_USB_CINERGY_T2=m
+CONFIG_DVB_USB_CXUSB=m
+# CONFIG_DVB_USB_CXUSB_ANALOG is not set
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_DIB3000MC=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_USB_DTV5100=m
+CONFIG_DVB_USB_DW2102=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_OPERA1=m
+CONFIG_DVB_USB_PCTV452E=m
+CONFIG_DVB_USB_TECHNISAT_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_SMS_USB_DRV=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+
+#
+# Webcam, TV (analog/digital) USB devices
+#
+CONFIG_VIDEO_EM28XX=m
+# CONFIG_VIDEO_EM28XX_V4L2 is not set
+CONFIG_VIDEO_EM28XX_ALSA=m
+CONFIG_VIDEO_EM28XX_DVB=m
+CONFIG_VIDEO_EM28XX_RC=m
+CONFIG_MEDIA_PCI_SUPPORT=y
+
+#
+# Media capture support
+#
+# CONFIG_VIDEO_SOLO6X10 is not set
+# CONFIG_VIDEO_TW5864 is not set
+# CONFIG_VIDEO_TW68 is not set
+# CONFIG_VIDEO_TW686X is not set
+# CONFIG_VIDEO_ZORAN is not set
+
+#
+# Media capture/analog TV support
+#
+# CONFIG_VIDEO_DT3155 is not set
+CONFIG_VIDEO_IVTV=m
+# CONFIG_VIDEO_IVTV_ALSA is not set
+CONFIG_VIDEO_FB_IVTV=m
+# CONFIG_VIDEO_FB_IVTV_FORCE_PAT is not set
+
+#
+# Media capture/analog/hybrid TV support
+#
+CONFIG_VIDEO_BT848=m
+CONFIG_DVB_BT8XX=m
+CONFIG_VIDEO_CX18=m
+# CONFIG_VIDEO_CX18_ALSA is not set
+CONFIG_VIDEO_CX23885=m
+CONFIG_MEDIA_ALTERA_CI=m
+# CONFIG_VIDEO_CX25821 is not set
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+# CONFIG_VIDEO_CX88_ENABLE_VP3054 is not set
+CONFIG_VIDEO_CX88_MPEG=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_RC=y
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7164=m
+
+#
+# Media digital TV PCI Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set
+CONFIG_DVB_DDBRIDGE=m
+# CONFIG_DVB_DDBRIDGE_MSIENABLE is not set
+CONFIG_DVB_DM1105=m
+CONFIG_MANTIS_CORE=m
+CONFIG_DVB_MANTIS=m
+CONFIG_DVB_HOPPER=m
+# CONFIG_DVB_NETUP_UNIDVB is not set
+CONFIG_DVB_NGENE=m
+CONFIG_DVB_PLUTO2=m
+CONFIG_DVB_PT1=m
+# CONFIG_DVB_PT3 is not set
+# CONFIG_DVB_SMIPCIE is not set
+# CONFIG_VIDEO_IPU3_CIO2 is not set
+CONFIG_RADIO_ADAPTERS=m
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_SAA7706H is not set
+# CONFIG_RADIO_SHARK is not set
+# CONFIG_RADIO_SHARK2 is not set
+# CONFIG_RADIO_SI4713 is not set
+CONFIG_RADIO_TEA575X=m
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_TEF6862 is not set
+# CONFIG_RADIO_WL1273 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_KEENE is not set
+# CONFIG_USB_MA901 is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_USB_RAREMONO is not set
+# CONFIG_RADIO_SI470X is not set
+CONFIG_MEDIA_PLATFORM_DRIVERS=y
+# CONFIG_V4L_PLATFORM_DRIVERS is not set
+# CONFIG_DVB_PLATFORM_DRIVERS is not set
+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
+
+#
+# Allegro DVT media platform drivers
+#
+
+#
+# Amlogic media platform drivers
+#
+
+#
+# Amphion drivers
+#
+
+#
+# Aspeed media platform drivers
+#
+
+#
+# Atmel media platform drivers
+#
+
+#
+# Cadence media platform drivers
+#
+# CONFIG_VIDEO_CADENCE_CSI2RX is not set
+# CONFIG_VIDEO_CADENCE_CSI2TX is not set
+
+#
+# Chips&Media media platform drivers
+#
+
+#
+# Intel media platform drivers
+#
+
+#
+# Marvell media platform drivers
+#
+
+#
+# Mediatek media platform drivers
+#
+
+#
+# NVidia media platform drivers
+#
+
+#
+# NXP media platform drivers
+#
+
+#
+# Qualcomm media platform drivers
+#
+
+#
+# Renesas media platform drivers
+#
+
+#
+# Rockchip media platform drivers
+#
+
+#
+# Samsung media platform drivers
+#
+
+#
+# STMicroelectronics media platform drivers
+#
+
+#
+# Sunxi media platform drivers
+#
+
+#
+# Texas Instruments drivers
+#
+
+#
+# Verisilicon media platform drivers
+#
+
+#
+# VIA media platform drivers
+#
+
+#
+# Xilinx media platform drivers
+#
+
+#
+# MMC/SDIO DVB adapters
+#
+CONFIG_SMS_SDIO_DRV=m
+
+#
+# FireWire (IEEE 1394) Adapters
+#
+CONFIG_DVB_FIREDTV=m
+CONFIG_DVB_FIREDTV_INPUT=y
+CONFIG_MEDIA_COMMON_OPTIONS=y
+
+#
+# common driver options
+#
+CONFIG_CYPRESS_FIRMWARE=m
+CONFIG_TTPCI_EEPROM=m
+CONFIG_VIDEO_CX2341X=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_SMS_SIANO_MDTV=m
+CONFIG_SMS_SIANO_RC=y
+# CONFIG_SMS_SIANO_DEBUGFS is not set
+CONFIG_VIDEOBUF2_CORE=m
+CONFIG_VIDEOBUF2_V4L2=m
+CONFIG_VIDEOBUF2_MEMOPS=m
+CONFIG_VIDEOBUF2_VMALLOC=m
+CONFIG_VIDEOBUF2_DMA_SG=m
+CONFIG_VIDEOBUF2_DVB=m
+# end of Media drivers
+
+CONFIG_MEDIA_HIDE_ANCILLARY_SUBDRV=y
+
+#
+# Media ancillary drivers
+#
+CONFIG_MEDIA_ATTACH=y
+
+#
+# IR I2C driver auto-selected by 'Autoselect ancillary drivers'
+#
+CONFIG_VIDEO_IR_I2C=m
+
+#
+# Camera sensor devices
+#
+# CONFIG_VIDEO_AR0521 is not set
+# CONFIG_VIDEO_HI556 is not set
+# CONFIG_VIDEO_HI846 is not set
+# CONFIG_VIDEO_HI847 is not set
+# CONFIG_VIDEO_IMX208 is not set
+# CONFIG_VIDEO_IMX214 is not set
+# CONFIG_VIDEO_IMX219 is not set
+# CONFIG_VIDEO_IMX258 is not set
+# CONFIG_VIDEO_IMX274 is not set
+# CONFIG_VIDEO_IMX290 is not set
+# CONFIG_VIDEO_IMX319 is not set
+# CONFIG_VIDEO_IMX355 is not set
+# CONFIG_VIDEO_MT9M001 is not set
+# CONFIG_VIDEO_MT9M032 is not set
+# CONFIG_VIDEO_MT9M111 is not set
+# CONFIG_VIDEO_MT9P031 is not set
+# CONFIG_VIDEO_MT9T001 is not set
+# CONFIG_VIDEO_MT9T112 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_MT9V032 is not set
+# CONFIG_VIDEO_MT9V111 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_VIDEO_OG01A1B is not set
+# CONFIG_VIDEO_OV02A10 is not set
+# CONFIG_VIDEO_OV08D10 is not set
+# CONFIG_VIDEO_OV13858 is not set
+# CONFIG_VIDEO_OV13B10 is not set
+# CONFIG_VIDEO_OV2640 is not set
+# CONFIG_VIDEO_OV2659 is not set
+# CONFIG_VIDEO_OV2680 is not set
+# CONFIG_VIDEO_OV2685 is not set
+# CONFIG_VIDEO_OV2740 is not set
+# CONFIG_VIDEO_OV5647 is not set
+# CONFIG_VIDEO_OV5648 is not set
+# CONFIG_VIDEO_OV5670 is not set
+# CONFIG_VIDEO_OV5675 is not set
+# CONFIG_VIDEO_OV5693 is not set
+# CONFIG_VIDEO_OV5695 is not set
+# CONFIG_VIDEO_OV6650 is not set
+# CONFIG_VIDEO_OV7251 is not set
+# CONFIG_VIDEO_OV7640 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_OV772X is not set
+# CONFIG_VIDEO_OV7740 is not set
+# CONFIG_VIDEO_OV8856 is not set
+# CONFIG_VIDEO_OV8865 is not set
+# CONFIG_VIDEO_OV9640 is not set
+# CONFIG_VIDEO_OV9650 is not set
+# CONFIG_VIDEO_OV9734 is not set
+# CONFIG_VIDEO_RDACM20 is not set
+# CONFIG_VIDEO_RDACM21 is not set
+# CONFIG_VIDEO_RJ54N1 is not set
+# CONFIG_VIDEO_S5C73M3 is not set
+# CONFIG_VIDEO_S5K4ECGX is not set
+# CONFIG_VIDEO_S5K5BAF is not set
+# CONFIG_VIDEO_S5K6A3 is not set
+# CONFIG_VIDEO_S5K6AA is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_VS6624 is not set
+# CONFIG_VIDEO_CCS is not set
+# CONFIG_VIDEO_ET8EK8 is not set
+# CONFIG_VIDEO_M5MOLS is not set
+# end of Camera sensor devices
+
+#
+# Lens drivers
+#
+# CONFIG_VIDEO_AD5820 is not set
+# CONFIG_VIDEO_AK7375 is not set
+# CONFIG_VIDEO_DW9714 is not set
+# CONFIG_VIDEO_DW9768 is not set
+# CONFIG_VIDEO_DW9807_VCM is not set
+# end of Lens drivers
+
+#
+# Flash devices
+#
+# CONFIG_VIDEO_ADP1653 is not set
+# CONFIG_VIDEO_LM3560 is not set
+# CONFIG_VIDEO_LM3646 is not set
+# end of Flash devices
+
+#
+# audio, video and radio I2C drivers auto-selected by 'Autoselect ancillary drivers'
+#
+CONFIG_VIDEO_CS3308=m
+CONFIG_VIDEO_CS5345=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_TVAUDIO=m
+CONFIG_VIDEO_VP27SMPX=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_SAA711X=m
+
+#
+# Video and audio decoders
+#
+CONFIG_VIDEO_SAA717X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+CONFIG_VIDEO_SAA6752HS=m
+CONFIG_VIDEO_M52790=m
+
+#
+# SPI I2C drivers auto-selected by 'Autoselect ancillary drivers'
+#
+
+#
+# Media SPI Adapters
+#
+# CONFIG_CXD2880_SPI_DRV is not set
+# CONFIG_VIDEO_GS1662 is not set
+# end of Media SPI Adapters
+
+CONFIG_MEDIA_TUNER=m
+
+#
+# Tuner drivers auto-selected by 'Autoselect ancillary drivers'
+#
+CONFIG_MEDIA_TUNER_E4000=m
+CONFIG_MEDIA_TUNER_FC0011=m
+CONFIG_MEDIA_TUNER_FC0012=m
+CONFIG_MEDIA_TUNER_FC0013=m
+CONFIG_MEDIA_TUNER_FC2580=m
+CONFIG_MEDIA_TUNER_IT913X=m
+CONFIG_MEDIA_TUNER_M88RS6000T=m
+CONFIG_MEDIA_TUNER_MAX2165=m
+CONFIG_MEDIA_TUNER_MC44S803=m
+CONFIG_MEDIA_TUNER_MT2060=m
+CONFIG_MEDIA_TUNER_MT2063=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_MT2131=m
+CONFIG_MEDIA_TUNER_MT2266=m
+CONFIG_MEDIA_TUNER_MXL5005S=m
+CONFIG_MEDIA_TUNER_MXL5007T=m
+CONFIG_MEDIA_TUNER_QM1D1B0004=m
+CONFIG_MEDIA_TUNER_QM1D1C0042=m
+CONFIG_MEDIA_TUNER_QT1010=m
+CONFIG_MEDIA_TUNER_R820T=m
+CONFIG_MEDIA_TUNER_SI2157=m
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA18212=m
+CONFIG_MEDIA_TUNER_TDA18218=m
+CONFIG_MEDIA_TUNER_TDA18250=m
+CONFIG_MEDIA_TUNER_TDA18271=m
+CONFIG_MEDIA_TUNER_TDA827X=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_TUA9001=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC4000=m
+CONFIG_MEDIA_TUNER_XC5000=m
+
+#
+# DVB Frontend drivers auto-selected by 'Autoselect ancillary drivers'
+#
+
+#
+# Multistandard (satellite) frontends
+#
+CONFIG_DVB_M88DS3103=m
+CONFIG_DVB_MXL5XX=m
+CONFIG_DVB_STB0899=m
+CONFIG_DVB_STB6100=m
+CONFIG_DVB_STV090x=m
+CONFIG_DVB_STV0910=m
+CONFIG_DVB_STV6110x=m
+CONFIG_DVB_STV6111=m
+
+#
+# Multistandard (cable + terrestrial) frontends
+#
+CONFIG_DVB_DRXK=m
+CONFIG_DVB_MN88472=m
+CONFIG_DVB_MN88473=m
+CONFIG_DVB_SI2165=m
+CONFIG_DVB_TDA18271C2DD=m
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24116=m
+CONFIG_DVB_CX24117=m
+CONFIG_DVB_CX24120=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_DS3000=m
+CONFIG_DVB_MB86A16=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_S5H1420=m
+CONFIG_DVB_SI21XX=m
+CONFIG_DVB_STB6000=m
+CONFIG_DVB_STV0288=m
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_STV0900=m
+CONFIG_DVB_STV6110=m
+CONFIG_DVB_TDA10071=m
+CONFIG_DVB_TDA10086=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TS2020=m
+CONFIG_DVB_TUNER_CX24113=m
+CONFIG_DVB_TUNER_ITD1000=m
+CONFIG_DVB_ZL10036=m
+CONFIG_DVB_ZL10039=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_AF9013=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_CXD2820R=m
+CONFIG_DVB_CXD2841ER=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+CONFIG_DVB_DRXD=m
+CONFIG_DVB_EC100=m
+CONFIG_DVB_GP8PSK_FE=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_RTL2830=m
+CONFIG_DVB_RTL2832=m
+CONFIG_DVB_SI2168=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_STV0367=m
+CONFIG_DVB_TDA10048=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_ZL10353=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_STV0297=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_TDA10023=m
+CONFIG_DVB_VES1820=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_AU8522=m
+CONFIG_DVB_AU8522_DTV=m
+CONFIG_DVB_AU8522_V4L=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LG2160=m
+CONFIG_DVB_LGDT3305=m
+CONFIG_DVB_LGDT3306A=m
+CONFIG_DVB_LGDT330X=m
+CONFIG_DVB_MXL692=m
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_S5H1409=m
+CONFIG_DVB_S5H1411=m
+
+#
+# ISDB-T (terrestrial) frontends
+#
+CONFIG_DVB_DIB8000=m
+CONFIG_DVB_MB86A20S=m
+CONFIG_DVB_S921=m
+
+#
+# ISDB-S (satellite) & ISDB-T (terrestrial) frontends
+#
+CONFIG_DVB_TC90522=m
+
+#
+# Digital terrestrial only tuners/PLL
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TUNER_DIB0070=m
+CONFIG_DVB_TUNER_DIB0090=m
+
+#
+# SEC control devices for DVB-S
+#
+CONFIG_DVB_A8293=m
+CONFIG_DVB_AF9033=m
+CONFIG_DVB_ATBM8830=m
+CONFIG_DVB_ISL6405=m
+CONFIG_DVB_ISL6421=m
+CONFIG_DVB_ISL6423=m
+CONFIG_DVB_IX2505V=m
+CONFIG_DVB_LGS8GXX=m
+CONFIG_DVB_LNBH25=m
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_LNBP22=m
+CONFIG_DVB_M88RS2000=m
+CONFIG_DVB_TDA665x=m
+CONFIG_DVB_DRX39XYJ=m
+
+#
+# Common Interface (EN50221) controller drivers
+#
+CONFIG_DVB_CXD2099=m
+# end of Media ancillary drivers
+
+#
+# Graphics support
+#
+CONFIG_APERTURE_HELPERS=y
+# CONFIG_AGP is not set
+CONFIG_INTEL_GTT=m
+CONFIG_VGA_SWITCHEROO=y
+CONFIG_DRM=m
+CONFIG_DRM_MIPI_DSI=y
+CONFIG_DRM_USE_DYNAMIC_DEBUG=y
+CONFIG_DRM_KMS_HELPER=m
+CONFIG_DRM_FBDEV_EMULATION=y
+CONFIG_DRM_FBDEV_OVERALLOC=100
+CONFIG_DRM_LOAD_EDID_FIRMWARE=y
+CONFIG_DRM_DISPLAY_HELPER=m
+CONFIG_DRM_DISPLAY_DP_HELPER=y
+CONFIG_DRM_DISPLAY_HDCP_HELPER=y
+CONFIG_DRM_DISPLAY_HDMI_HELPER=y
+CONFIG_DRM_DP_AUX_CHARDEV=y
+CONFIG_DRM_DP_CEC=y
+CONFIG_DRM_TTM=m
+CONFIG_DRM_BUDDY=m
+CONFIG_DRM_VRAM_HELPER=m
+CONFIG_DRM_TTM_HELPER=m
+CONFIG_DRM_GEM_SHMEM_HELPER=m
+CONFIG_DRM_SCHED=m
+
+#
+# I2C encoder or helper chips
+#
+CONFIG_DRM_I2C_CH7006=m
+CONFIG_DRM_I2C_SIL164=m
+# CONFIG_DRM_I2C_NXP_TDA998X is not set
+# CONFIG_DRM_I2C_NXP_TDA9950 is not set
+# end of I2C encoder or helper chips
+
+#
+# ARM devices
+#
+# end of ARM devices
+
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_RADEON_USERPTR=y
+CONFIG_DRM_AMDGPU=m
+# CONFIG_DRM_AMDGPU_SI is not set
+# CONFIG_DRM_AMDGPU_CIK is not set
+# CONFIG_DRM_AMDGPU_USERPTR is not set
+
+#
+# ACP (Audio CoProcessor) Configuration
+#
+CONFIG_DRM_AMD_ACP=y
+# end of ACP (Audio CoProcessor) Configuration
+
+#
+# Display Engine Configuration
+#
+CONFIG_DRM_AMD_DC=y
+CONFIG_DRM_AMD_DC_DCN=y
+# CONFIG_DRM_AMD_DC_HDCP is not set
+# CONFIG_DEBUG_KERNEL_DC is not set
+# CONFIG_DRM_AMD_SECURE_DISPLAY is not set
+# end of Display Engine Configuration
+
+# CONFIG_HSA_AMD is not set
+CONFIG_DRM_NOUVEAU=m
+# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set
+CONFIG_NOUVEAU_DEBUG=5
+CONFIG_NOUVEAU_DEBUG_DEFAULT=3
+# CONFIG_NOUVEAU_DEBUG_MMU is not set
+# CONFIG_NOUVEAU_DEBUG_PUSH is not set
+CONFIG_DRM_NOUVEAU_BACKLIGHT=y
+CONFIG_DRM_I915=m
+CONFIG_DRM_I915_FORCE_PROBE=""
+CONFIG_DRM_I915_CAPTURE_ERROR=y
+CONFIG_DRM_I915_COMPRESS_ERROR=y
+CONFIG_DRM_I915_USERPTR=y
+CONFIG_DRM_I915_GVT=y
+CONFIG_DRM_I915_GVT_KVMGT=m
+CONFIG_DRM_I915_REQUEST_TIMEOUT=20000
+CONFIG_DRM_I915_FENCE_TIMEOUT=10000
+CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND=250
+CONFIG_DRM_I915_HEARTBEAT_INTERVAL=2500
+CONFIG_DRM_I915_PREEMPT_TIMEOUT=640
+CONFIG_DRM_I915_MAX_REQUEST_BUSYWAIT=8000
+CONFIG_DRM_I915_STOP_TIMEOUT=100
+CONFIG_DRM_I915_TIMESLICE_DURATION=1
+# CONFIG_DRM_VGEM is not set
+CONFIG_DRM_VKMS=m
+CONFIG_DRM_VMWGFX=m
+CONFIG_DRM_VMWGFX_FBCON=y
+# CONFIG_DRM_VMWGFX_MKSSTATS is not set
+CONFIG_DRM_GMA500=m
+CONFIG_DRM_UDL=m
+CONFIG_DRM_AST=m
+CONFIG_DRM_MGAG200=m
+CONFIG_DRM_QXL=m
+CONFIG_DRM_VIRTIO_GPU=m
+CONFIG_DRM_PANEL=y
+
+#
+# Display Panels
+#
+# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set
+# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set
+# end of Display Panels
+
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_PANEL_BRIDGE=y
+
+#
+# Display Interface Bridges
+#
+# CONFIG_DRM_ANALOGIX_ANX78XX is not set
+# end of Display Interface Bridges
+
+# CONFIG_DRM_ETNAVIV is not set
+CONFIG_DRM_BOCHS=m
+CONFIG_DRM_CIRRUS_QEMU=m
+# CONFIG_DRM_GM12U320 is not set
+# CONFIG_DRM_PANEL_MIPI_DBI is not set
+# CONFIG_DRM_SIMPLEDRM is not set
+# CONFIG_TINYDRM_HX8357D is not set
+# CONFIG_TINYDRM_ILI9163 is not set
+# CONFIG_TINYDRM_ILI9225 is not set
+# CONFIG_TINYDRM_ILI9341 is not set
+# CONFIG_TINYDRM_ILI9486 is not set
+# CONFIG_TINYDRM_MI0283QT is not set
+# CONFIG_TINYDRM_REPAPER is not set
+# CONFIG_TINYDRM_ST7586 is not set
+# CONFIG_TINYDRM_ST7735R is not set
+# CONFIG_DRM_XEN_FRONTEND is not set
+# CONFIG_DRM_VBOXVIDEO is not set
+# CONFIG_DRM_GUD is not set
+# CONFIG_DRM_SSD130X is not set
+# CONFIG_DRM_HYPERV is not set
+# CONFIG_DRM_LEGACY is not set
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DRM_NOMODESET=y
+CONFIG_DRM_PRIVACY_SCREEN=y
+
+#
+# Frame buffer Devices
+#
+CONFIG_FB_CMDLINE=y
+CONFIG_FB_NOTIFY=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_MODE_HELPERS is not set
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_UVESA is not set
+CONFIG_FB_VESA=y
+CONFIG_FB_EFI=y
+# CONFIG_FB_N411 is not set
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_OPENCORES is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I740 is not set
+# CONFIG_FB_LE80578 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_SM501 is not set
+# CONFIG_FB_SMSCUFX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_XEN_FBDEV_FRONTEND is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_FB_HYPERV=m
+# CONFIG_FB_SIMPLE is not set
+# CONFIG_FB_SSD1307 is not set
+# CONFIG_FB_SM712 is not set
+# end of Frame buffer Devices
+
+#
+# Backlight & LCD device support
+#
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_L4F00242T03 is not set
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI922X is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+CONFIG_LCD_PLATFORM=m
+# CONFIG_LCD_AMS369FG06 is not set
+# CONFIG_LCD_LMS501KF03 is not set
+# CONFIG_LCD_HX8357 is not set
+# CONFIG_LCD_OTM3225A is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_KTD253 is not set
+# CONFIG_BACKLIGHT_PWM is not set
+CONFIG_BACKLIGHT_APPLE=m
+# CONFIG_BACKLIGHT_QCOM_WLED is not set
+# CONFIG_BACKLIGHT_SAHARA is not set
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+# CONFIG_BACKLIGHT_LM3630A is not set
+# CONFIG_BACKLIGHT_LM3639 is not set
+CONFIG_BACKLIGHT_LP855X=m
+# CONFIG_BACKLIGHT_GPIO is not set
+# CONFIG_BACKLIGHT_LV5207LP is not set
+# CONFIG_BACKLIGHT_BD6107 is not set
+# CONFIG_BACKLIGHT_ARCXCNN is not set
+# end of Backlight & LCD device support
+
+CONFIG_HDMI=y
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_DUMMY_CONSOLE_COLUMNS=80
+CONFIG_DUMMY_CONSOLE_ROWS=25
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set
+# end of Console display driver support
+
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# end of Graphics support
+
+CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_PCM_ELD=y
+CONFIG_SND_HWDEP=m
+CONFIG_SND_SEQ_DEVICE=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_COMPRESS_OFFLOAD=m
+CONFIG_SND_JACK=y
+CONFIG_SND_JACK_INPUT_DEV=y
+CONFIG_SND_OSSEMUL=y
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+CONFIG_SND_PCM_TIMER=y
+CONFIG_SND_HRTIMER=m
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_MAX_CARDS=32
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_PROC_FS=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+CONFIG_SND_CTL_FAST_LOOKUP=y
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_CTL_INPUT_VALIDATION is not set
+CONFIG_SND_VMASTER=y
+CONFIG_SND_DMA_SGBUF=y
+CONFIG_SND_CTL_LED=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_SEQUENCER_OSS=m
+CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
+CONFIG_SND_SEQ_MIDI_EVENT=m
+CONFIG_SND_SEQ_MIDI=m
+CONFIG_SND_SEQ_MIDI_EMUL=m
+CONFIG_SND_SEQ_VIRMIDI=m
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL3_LIB_SEQ=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_PCSP=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_ALOOP=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+# CONFIG_SND_MTS64 is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+CONFIG_SND_MPU401=m
+# CONFIG_SND_PORTMAN2X4 is not set
+CONFIG_SND_AC97_POWER_SAVE=y
+CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
+CONFIG_SND_PCI=y
+CONFIG_SND_AD1889=m
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 is not set
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ASIHPI=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+# CONFIG_SND_AW2 is not set
+# CONFIG_SND_AZT3328 is not set
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_OXYGEN_LIB=m
+CONFIG_SND_OXYGEN=m
+# CONFIG_SND_CS4281 is not set
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CTXFI=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_INDIGOIOX=m
+CONFIG_SND_INDIGODJX=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1_SEQ=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+# CONFIG_SND_ES1938 is not set
+CONFIG_SND_ES1968=m
+CONFIG_SND_ES1968_INPUT=y
+CONFIG_SND_ES1968_RADIO=y
+# CONFIG_SND_FM801 is not set
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_LOLA=m
+CONFIG_SND_LX6464ES=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MAESTRO3_INPUT=y
+CONFIG_SND_MIXART=m
+# CONFIG_SND_NM256 is not set
+CONFIG_SND_PCXHR=m
+# CONFIG_SND_RIPTIDE is not set
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+# CONFIG_SND_SONICVIBES is not set
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VIRTUOSO=m
+CONFIG_SND_VX222=m
+# CONFIG_SND_YMFPCI is not set
+
+#
+# HD-Audio
+#
+CONFIG_SND_HDA=m
+CONFIG_SND_HDA_GENERIC_LEDS=y
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDA_HWDEP=y
+CONFIG_SND_HDA_RECONFIG=y
+CONFIG_SND_HDA_INPUT_BEEP=y
+CONFIG_SND_HDA_INPUT_BEEP_MODE=0
+CONFIG_SND_HDA_PATCH_LOADER=y
+# CONFIG_SND_HDA_SCODEC_CS35L41_I2C is not set
+# CONFIG_SND_HDA_SCODEC_CS35L41_SPI is not set
+CONFIG_SND_HDA_CODEC_REALTEK=m
+CONFIG_SND_HDA_CODEC_ANALOG=m
+CONFIG_SND_HDA_CODEC_SIGMATEL=m
+CONFIG_SND_HDA_CODEC_VIA=m
+CONFIG_SND_HDA_CODEC_HDMI=m
+CONFIG_SND_HDA_CODEC_CIRRUS=m
+# CONFIG_SND_HDA_CODEC_CS8409 is not set
+CONFIG_SND_HDA_CODEC_CONEXANT=m
+CONFIG_SND_HDA_CODEC_CA0110=m
+CONFIG_SND_HDA_CODEC_CA0132=m
+CONFIG_SND_HDA_CODEC_CA0132_DSP=y
+CONFIG_SND_HDA_CODEC_CMEDIA=m
+CONFIG_SND_HDA_CODEC_SI3054=m
+CONFIG_SND_HDA_GENERIC=m
+CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
+# CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM is not set
+# end of HD-Audio
+
+CONFIG_SND_HDA_CORE=m
+CONFIG_SND_HDA_DSP_LOADER=y
+CONFIG_SND_HDA_COMPONENT=y
+CONFIG_SND_HDA_I915=y
+CONFIG_SND_HDA_EXT_CORE=m
+CONFIG_SND_HDA_PREALLOC_SIZE=0
+CONFIG_SND_INTEL_NHLT=y
+CONFIG_SND_INTEL_DSP_CONFIG=m
+CONFIG_SND_INTEL_SOUNDWIRE_ACPI=m
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y
+CONFIG_SND_USB_UA101=m
+CONFIG_SND_USB_USX2Y=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_USB_US122L=m
+CONFIG_SND_USB_6FIRE=m
+CONFIG_SND_USB_HIFACE=m
+CONFIG_SND_BCD2000=m
+CONFIG_SND_USB_LINE6=m
+CONFIG_SND_USB_POD=m
+CONFIG_SND_USB_PODHD=m
+CONFIG_SND_USB_TONEPORT=m
+CONFIG_SND_USB_VARIAX=m
+CONFIG_SND_FIREWIRE=y
+CONFIG_SND_FIREWIRE_LIB=m
+CONFIG_SND_DICE=m
+CONFIG_SND_OXFW=m
+CONFIG_SND_ISIGHT=m
+CONFIG_SND_FIREWORKS=m
+CONFIG_SND_BEBOB=m
+CONFIG_SND_FIREWIRE_DIGI00X=m
+CONFIG_SND_FIREWIRE_TASCAM=m
+CONFIG_SND_FIREWIRE_MOTU=m
+CONFIG_SND_FIREFACE=m
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_COMPRESS=y
+CONFIG_SND_SOC_TOPOLOGY=y
+CONFIG_SND_SOC_ACPI=m
+# CONFIG_SND_SOC_ADI is not set
+# CONFIG_SND_SOC_AMD_ACP is not set
+# CONFIG_SND_SOC_AMD_ACP3x is not set
+# CONFIG_SND_SOC_AMD_RENOIR is not set
+# CONFIG_SND_SOC_AMD_ACP5x is not set
+# CONFIG_SND_SOC_AMD_ACP6x is not set
+# CONFIG_SND_AMD_ACP_CONFIG is not set
+# CONFIG_SND_SOC_AMD_ACP_COMMON is not set
+# CONFIG_SND_SOC_AMD_RPL_ACP6x is not set
+# CONFIG_SND_SOC_AMD_PS is not set
+# CONFIG_SND_ATMEL_SOC is not set
+# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set
+# CONFIG_SND_DESIGNWARE_I2S is not set
+
+#
+# SoC Audio for Freescale CPUs
+#
+
+#
+# Common SoC Audio options for Freescale CPUs:
+#
+# CONFIG_SND_SOC_FSL_ASRC is not set
+# CONFIG_SND_SOC_FSL_SAI is not set
+# CONFIG_SND_SOC_FSL_AUDMIX is not set
+# CONFIG_SND_SOC_FSL_SSI is not set
+# CONFIG_SND_SOC_FSL_SPDIF is not set
+# CONFIG_SND_SOC_FSL_ESAI is not set
+# CONFIG_SND_SOC_FSL_MICFIL is not set
+# CONFIG_SND_SOC_FSL_XCVR is not set
+# CONFIG_SND_SOC_IMX_AUDMUX is not set
+# end of SoC Audio for Freescale CPUs
+
+# CONFIG_SND_I2S_HI6210_I2S is not set
+# CONFIG_SND_SOC_IMG is not set
+CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
+CONFIG_SND_SOC_INTEL_SST=m
+# CONFIG_SND_SOC_INTEL_CATPT is not set
+CONFIG_SND_SST_ATOM_HIFI2_PLATFORM=m
+# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set
+CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI=m
+CONFIG_SND_SOC_INTEL_SKYLAKE=m
+CONFIG_SND_SOC_INTEL_SKL=m
+CONFIG_SND_SOC_INTEL_APL=m
+CONFIG_SND_SOC_INTEL_KBL=m
+CONFIG_SND_SOC_INTEL_GLK=m
+CONFIG_SND_SOC_INTEL_CNL=m
+CONFIG_SND_SOC_INTEL_CFL=m
+# CONFIG_SND_SOC_INTEL_CML_H is not set
+# CONFIG_SND_SOC_INTEL_CML_LP is not set
+CONFIG_SND_SOC_INTEL_SKYLAKE_FAMILY=m
+CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK=m
+# CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC is not set
+CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON=m
+CONFIG_SND_SOC_ACPI_INTEL_MATCH=m
+# CONFIG_SND_SOC_INTEL_AVS is not set
+CONFIG_SND_SOC_INTEL_MACH=y
+# CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES is not set
+CONFIG_SND_SOC_INTEL_HDA_DSP_COMMON=m
+CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH=m
+CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH=m
+CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH=m
+CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH=m
+CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH=m
+CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH=m
+# CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH is not set
+CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH=m
+CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH=m
+CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=m
+CONFIG_SND_SOC_INTEL_SKL_RT286_MACH=m
+CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH=m
+CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH=m
+CONFIG_SND_SOC_INTEL_DA7219_MAX98357A_GENERIC=m
+CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON=m
+CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH=m
+CONFIG_SND_SOC_INTEL_BXT_RT298_MACH=m
+CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH=m
+CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH=m
+CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH=m
+# CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH is not set
+# CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH is not set
+# CONFIG_SND_SOC_MTK_BTCVSD is not set
+# CONFIG_SND_SOC_SOF_TOPLEVEL is not set
+
+#
+# STMicroelectronics STM32 SOC audio support
+#
+# end of STMicroelectronics STM32 SOC audio support
+
+# CONFIG_SND_SOC_XILINX_I2S is not set
+# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set
+# CONFIG_SND_SOC_XILINX_SPDIF is not set
+# CONFIG_SND_SOC_XTFPGA_I2S is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
+
+#
+# CODEC drivers
+#
+# CONFIG_SND_SOC_AC97_CODEC is not set
+# CONFIG_SND_SOC_ADAU1372_I2C is not set
+# CONFIG_SND_SOC_ADAU1372_SPI is not set
+# CONFIG_SND_SOC_ADAU1701 is not set
+# CONFIG_SND_SOC_ADAU1761_I2C is not set
+# CONFIG_SND_SOC_ADAU1761_SPI is not set
+# CONFIG_SND_SOC_ADAU7002 is not set
+# CONFIG_SND_SOC_ADAU7118_HW is not set
+# CONFIG_SND_SOC_ADAU7118_I2C is not set
+# CONFIG_SND_SOC_AK4104 is not set
+# CONFIG_SND_SOC_AK4118 is not set
+# CONFIG_SND_SOC_AK4375 is not set
+# CONFIG_SND_SOC_AK4458 is not set
+# CONFIG_SND_SOC_AK4554 is not set
+# CONFIG_SND_SOC_AK4613 is not set
+# CONFIG_SND_SOC_AK4642 is not set
+# CONFIG_SND_SOC_AK5386 is not set
+# CONFIG_SND_SOC_AK5558 is not set
+# CONFIG_SND_SOC_ALC5623 is not set
+# CONFIG_SND_SOC_AW8738 is not set
+# CONFIG_SND_SOC_BD28623 is not set
+# CONFIG_SND_SOC_BT_SCO is not set
+# CONFIG_SND_SOC_CS35L32 is not set
+# CONFIG_SND_SOC_CS35L33 is not set
+# CONFIG_SND_SOC_CS35L34 is not set
+# CONFIG_SND_SOC_CS35L35 is not set
+# CONFIG_SND_SOC_CS35L36 is not set
+# CONFIG_SND_SOC_CS35L41_SPI is not set
+# CONFIG_SND_SOC_CS35L41_I2C is not set
+# CONFIG_SND_SOC_CS35L45_SPI is not set
+# CONFIG_SND_SOC_CS35L45_I2C is not set
+# CONFIG_SND_SOC_CS42L42 is not set
+# CONFIG_SND_SOC_CS42L51_I2C is not set
+# CONFIG_SND_SOC_CS42L52 is not set
+# CONFIG_SND_SOC_CS42L56 is not set
+# CONFIG_SND_SOC_CS42L73 is not set
+# CONFIG_SND_SOC_CS42L83 is not set
+# CONFIG_SND_SOC_CS4234 is not set
+# CONFIG_SND_SOC_CS4265 is not set
+# CONFIG_SND_SOC_CS4270 is not set
+# CONFIG_SND_SOC_CS4271_I2C is not set
+# CONFIG_SND_SOC_CS4271_SPI is not set
+# CONFIG_SND_SOC_CS42XX8_I2C is not set
+# CONFIG_SND_SOC_CS43130 is not set
+# CONFIG_SND_SOC_CS4341 is not set
+# CONFIG_SND_SOC_CS4349 is not set
+# CONFIG_SND_SOC_CS53L30 is not set
+# CONFIG_SND_SOC_CX2072X is not set
+CONFIG_SND_SOC_DA7213=m
+CONFIG_SND_SOC_DA7219=m
+CONFIG_SND_SOC_DMIC=m
+# CONFIG_SND_SOC_ES7134 is not set
+# CONFIG_SND_SOC_ES7241 is not set
+CONFIG_SND_SOC_ES8316=m
+# CONFIG_SND_SOC_ES8326 is not set
+# CONFIG_SND_SOC_ES8328_I2C is not set
+# CONFIG_SND_SOC_ES8328_SPI is not set
+# CONFIG_SND_SOC_GTM601 is not set
+CONFIG_SND_SOC_HDAC_HDMI=m
+# CONFIG_SND_SOC_HDA is not set
+# CONFIG_SND_SOC_ICS43432 is not set
+# CONFIG_SND_SOC_INNO_RK3036 is not set
+# CONFIG_SND_SOC_MAX98088 is not set
+CONFIG_SND_SOC_MAX98090=m
+CONFIG_SND_SOC_MAX98357A=m
+# CONFIG_SND_SOC_MAX98504 is not set
+# CONFIG_SND_SOC_MAX9867 is not set
+CONFIG_SND_SOC_MAX98927=m
+# CONFIG_SND_SOC_MAX98520 is not set
+# CONFIG_SND_SOC_MAX98373_I2C is not set
+CONFIG_SND_SOC_MAX98390=m
+# CONFIG_SND_SOC_MAX98396 is not set
+# CONFIG_SND_SOC_MAX9860 is not set
+# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set
+# CONFIG_SND_SOC_PCM1681 is not set
+# CONFIG_SND_SOC_PCM1789_I2C is not set
+# CONFIG_SND_SOC_PCM179X_I2C is not set
+# CONFIG_SND_SOC_PCM179X_SPI is not set
+# CONFIG_SND_SOC_PCM186X_I2C is not set
+# CONFIG_SND_SOC_PCM186X_SPI is not set
+# CONFIG_SND_SOC_PCM3060_I2C is not set
+# CONFIG_SND_SOC_PCM3060_SPI is not set
+# CONFIG_SND_SOC_PCM3168A_I2C is not set
+# CONFIG_SND_SOC_PCM3168A_SPI is not set
+# CONFIG_SND_SOC_PCM5102A is not set
+# CONFIG_SND_SOC_PCM512x_I2C is not set
+# CONFIG_SND_SOC_PCM512x_SPI is not set
+# CONFIG_SND_SOC_RK3328 is not set
+CONFIG_SND_SOC_RL6231=m
+CONFIG_SND_SOC_RL6347A=m
+CONFIG_SND_SOC_RT286=m
+CONFIG_SND_SOC_RT298=m
+CONFIG_SND_SOC_RT5514=m
+CONFIG_SND_SOC_RT5514_SPI=m
+# CONFIG_SND_SOC_RT5616 is not set
+# CONFIG_SND_SOC_RT5631 is not set
+CONFIG_SND_SOC_RT5640=m
+CONFIG_SND_SOC_RT5645=m
+CONFIG_SND_SOC_RT5651=m
+# CONFIG_SND_SOC_RT5659 is not set
+CONFIG_SND_SOC_RT5663=m
+CONFIG_SND_SOC_RT5670=m
+# CONFIG_SND_SOC_RT9120 is not set
+# CONFIG_SND_SOC_SGTL5000 is not set
+# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set
+# CONFIG_SND_SOC_SIMPLE_MUX is not set
+# CONFIG_SND_SOC_SPDIF is not set
+# CONFIG_SND_SOC_SRC4XXX_I2C is not set
+# CONFIG_SND_SOC_SSM2305 is not set
+# CONFIG_SND_SOC_SSM2518 is not set
+# CONFIG_SND_SOC_SSM2602_SPI is not set
+# CONFIG_SND_SOC_SSM2602_I2C is not set
+CONFIG_SND_SOC_SSM4567=m
+# CONFIG_SND_SOC_STA32X is not set
+# CONFIG_SND_SOC_STA350 is not set
+# CONFIG_SND_SOC_STI_SAS is not set
+# CONFIG_SND_SOC_TAS2552 is not set
+# CONFIG_SND_SOC_TAS2562 is not set
+# CONFIG_SND_SOC_TAS2764 is not set
+# CONFIG_SND_SOC_TAS2770 is not set
+# CONFIG_SND_SOC_TAS2780 is not set
+# CONFIG_SND_SOC_TAS5086 is not set
+# CONFIG_SND_SOC_TAS571X is not set
+# CONFIG_SND_SOC_TAS5720 is not set
+# CONFIG_SND_SOC_TAS5805M is not set
+# CONFIG_SND_SOC_TAS6424 is not set
+# CONFIG_SND_SOC_TDA7419 is not set
+# CONFIG_SND_SOC_TFA9879 is not set
+# CONFIG_SND_SOC_TFA989X is not set
+# CONFIG_SND_SOC_TLV320ADC3XXX is not set
+# CONFIG_SND_SOC_TLV320AIC23_I2C is not set
+# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
+# CONFIG_SND_SOC_TLV320AIC31XX is not set
+# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set
+# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set
+# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set
+# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set
+# CONFIG_SND_SOC_TLV320ADCX140 is not set
+CONFIG_SND_SOC_TS3A227E=m
+# CONFIG_SND_SOC_TSCS42XX is not set
+# CONFIG_SND_SOC_TSCS454 is not set
+# CONFIG_SND_SOC_UDA1334 is not set
+# CONFIG_SND_SOC_WM8510 is not set
+# CONFIG_SND_SOC_WM8523 is not set
+# CONFIG_SND_SOC_WM8524 is not set
+# CONFIG_SND_SOC_WM8580 is not set
+# CONFIG_SND_SOC_WM8711 is not set
+# CONFIG_SND_SOC_WM8728 is not set
+# CONFIG_SND_SOC_WM8731_I2C is not set
+# CONFIG_SND_SOC_WM8731_SPI is not set
+# CONFIG_SND_SOC_WM8737 is not set
+# CONFIG_SND_SOC_WM8741 is not set
+# CONFIG_SND_SOC_WM8750 is not set
+# CONFIG_SND_SOC_WM8753 is not set
+# CONFIG_SND_SOC_WM8770 is not set
+# CONFIG_SND_SOC_WM8776 is not set
+# CONFIG_SND_SOC_WM8782 is not set
+# CONFIG_SND_SOC_WM8804_I2C is not set
+# CONFIG_SND_SOC_WM8804_SPI is not set
+# CONFIG_SND_SOC_WM8903 is not set
+# CONFIG_SND_SOC_WM8904 is not set
+# CONFIG_SND_SOC_WM8940 is not set
+# CONFIG_SND_SOC_WM8960 is not set
+# CONFIG_SND_SOC_WM8962 is not set
+# CONFIG_SND_SOC_WM8974 is not set
+# CONFIG_SND_SOC_WM8978 is not set
+# CONFIG_SND_SOC_WM8985 is not set
+# CONFIG_SND_SOC_ZL38060 is not set
+# CONFIG_SND_SOC_MAX9759 is not set
+# CONFIG_SND_SOC_MT6351 is not set
+# CONFIG_SND_SOC_MT6358 is not set
+# CONFIG_SND_SOC_MT6660 is not set
+# CONFIG_SND_SOC_NAU8315 is not set
+# CONFIG_SND_SOC_NAU8540 is not set
+# CONFIG_SND_SOC_NAU8810 is not set
+# CONFIG_SND_SOC_NAU8821 is not set
+# CONFIG_SND_SOC_NAU8822 is not set
+CONFIG_SND_SOC_NAU8824=m
+CONFIG_SND_SOC_NAU8825=m
+# CONFIG_SND_SOC_TPA6130A2 is not set
+# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set
+# CONFIG_SND_SOC_LPASS_VA_MACRO is not set
+# CONFIG_SND_SOC_LPASS_RX_MACRO is not set
+# CONFIG_SND_SOC_LPASS_TX_MACRO is not set
+# end of CODEC drivers
+
+# CONFIG_SND_SIMPLE_CARD is not set
+CONFIG_SND_X86=y
+CONFIG_HDMI_LPE_AUDIO=m
+CONFIG_SND_SYNTH_EMUX=m
+CONFIG_SND_XEN_FRONTEND=m
+# CONFIG_SND_VIRTIO is not set
+CONFIG_AC97_BUS=m
+
+#
+# HID support
+#
+CONFIG_HID=y
+CONFIG_HID_BATTERY_STRENGTH=y
+CONFIG_HIDRAW=y
+CONFIG_UHID=m
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=m
+# CONFIG_HID_ACCUTOUCH is not set
+CONFIG_HID_ACRUX=m
+# CONFIG_HID_ACRUX_FF is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_APPLEIR=m
+CONFIG_HID_ASUS=m
+CONFIG_HID_AUREAL=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_BETOP_FF=m
+# CONFIG_HID_BIGBEN_FF is not set
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CORSAIR=m
+# CONFIG_HID_COUGAR is not set
+# CONFIG_HID_MACALLY is not set
+CONFIG_HID_PRODIKEYS=m
+CONFIG_HID_CMEDIA=m
+# CONFIG_HID_CP2112 is not set
+# CONFIG_HID_CREATIVE_SB0540 is not set
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_EMS_FF is not set
+CONFIG_HID_ELAN=m
+CONFIG_HID_ELECOM=m
+CONFIG_HID_ELO=m
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_FT260 is not set
+CONFIG_HID_GEMBIRD=m
+CONFIG_HID_GFRM=m
+# CONFIG_HID_GLORIOUS is not set
+CONFIG_HID_HOLTEK=m
+# CONFIG_HOLTEK_FF is not set
+# CONFIG_HID_VIVALDI is not set
+CONFIG_HID_GT683R=m
+CONFIG_HID_KEYTOUCH=m
+CONFIG_HID_KYE=m
+CONFIG_HID_UCLOGIC=m
+CONFIG_HID_WALTOP=m
+# CONFIG_HID_VIEWSONIC is not set
+# CONFIG_HID_VRC2 is not set
+# CONFIG_HID_XIAOMI is not set
+CONFIG_HID_GYRATION=m
+CONFIG_HID_ICADE=m
+CONFIG_HID_ITE=m
+CONFIG_HID_JABRA=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LCPOWER=m
+CONFIG_HID_LED=m
+CONFIG_HID_LENOVO=m
+# CONFIG_HID_LETSKETCH is not set
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_LOGITECH_DJ=m
+CONFIG_HID_LOGITECH_HIDPP=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+CONFIG_HID_MAGICMOUSE=y
+# CONFIG_HID_MALTRON is not set
+# CONFIG_HID_MAYFLASH is not set
+# CONFIG_HID_MEGAWORLD_FF is not set
+# CONFIG_HID_REDRAGON is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_MULTITOUCH=m
+# CONFIG_HID_NINTENDO is not set
+CONFIG_HID_NTI=m
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=m
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PENMOUNT=m
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_PICOLCD=m
+CONFIG_HID_PICOLCD_FB=y
+CONFIG_HID_PICOLCD_BACKLIGHT=y
+CONFIG_HID_PICOLCD_LCD=y
+CONFIG_HID_PICOLCD_LEDS=y
+CONFIG_HID_PICOLCD_CIR=y
+CONFIG_HID_PLANTRONICS=m
+# CONFIG_HID_PXRC is not set
+# CONFIG_HID_RAZER is not set
+CONFIG_HID_PRIMAX=m
+# CONFIG_HID_RETRODE is not set
+CONFIG_HID_ROCCAT=m
+CONFIG_HID_SAITEK=m
+CONFIG_HID_SAMSUNG=m
+# CONFIG_HID_SEMITEK is not set
+# CONFIG_HID_SIGMAMICRO is not set
+CONFIG_HID_SONY=m
+CONFIG_SONY_FF=y
+CONFIG_HID_SPEEDLINK=m
+# CONFIG_HID_STEAM is not set
+CONFIG_HID_STEELSERIES=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_RMI=m
+CONFIG_HID_GREENASIA=m
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_HYPERV_MOUSE=m
+CONFIG_HID_SMARTJOYPLUS=m
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TIVO=m
+CONFIG_HID_TOPSEED=m
+# CONFIG_HID_TOPRE is not set
+CONFIG_HID_THINGM=m
+CONFIG_HID_THRUSTMASTER=m
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_HID_UDRAW_PS3 is not set
+# CONFIG_HID_U2FZERO is not set
+CONFIG_HID_WACOM=m
+CONFIG_HID_WIIMOTE=m
+CONFIG_HID_XINMO=m
+CONFIG_HID_ZEROPLUS=m
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_HID_ZYDACRON=m
+CONFIG_HID_SENSOR_HUB=y
+CONFIG_HID_SENSOR_CUSTOM_SENSOR=m
+CONFIG_HID_ALPS=m
+# CONFIG_HID_MCP2221 is not set
+# end of Special HID drivers
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+# end of USB HID support
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID_ACPI is not set
+# end of I2C HID support
+
+#
+# Intel ISH HID support
+#
+CONFIG_INTEL_ISH_HID=m
+# CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER is not set
+# end of Intel ISH HID support
+
+#
+# AMD SFH HID Support
+#
+# CONFIG_AMD_SFH_HID is not set
+# end of AMD SFH HID Support
+# end of HID support
+
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_LED_TRIG=y
+# CONFIG_USB_ULPI_BUS is not set
+# CONFIG_USB_CONN_GPIO is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+CONFIG_USB_PCI=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_FEW_INIT_RETRIES is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_PRODUCTLIST is not set
+CONFIG_USB_LEDS_TRIGGER_USBPORT=m
+CONFIG_USB_AUTOSUSPEND_DELAY=2
+CONFIG_USB_MON=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DBGCAP=y
+CONFIG_USB_XHCI_PCI=y
+# CONFIG_USB_XHCI_PCI_RENESAS is not set
+CONFIG_USB_XHCI_PLATFORM=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_PCI=y
+# CONFIG_USB_EHCI_FSL is not set
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_FOTG210_HCD is not set
+# CONFIG_USB_MAX3421_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PCI=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_U132_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HCD_BCMA is not set
+# CONFIG_USB_HCD_TEST_MODE is not set
+# CONFIG_USB_XEN_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
+CONFIG_USB_TMC=m
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_REALTEK=m
+CONFIG_REALTEK_AUTOPM=y
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_STORAGE_ONETOUCH=m
+CONFIG_USB_STORAGE_KARMA=m
+CONFIG_USB_STORAGE_CYPRESS_ATACB=m
+CONFIG_USB_STORAGE_ENE_UB6250=m
+CONFIG_USB_UAS=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+# CONFIG_USBIP_CORE is not set
+# CONFIG_USB_CDNS_SUPPORT is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_DWC2 is not set
+# CONFIG_USB_CHIPIDEA is not set
+# CONFIG_USB_ISP1760 is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_SIMPLE is not set
+CONFIG_USB_SERIAL_AIRCABLE=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+# CONFIG_USB_SERIAL_F81232 is not set
+CONFIG_USB_SERIAL_F8153X=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_IUU=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_METRO is not set
+CONFIG_USB_SERIAL_MOS7720=m
+CONFIG_USB_SERIAL_MOS7715_PARPORT=y
+CONFIG_USB_SERIAL_MOS7840=m
+CONFIG_USB_SERIAL_MXUPORT=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OTI6858=m
+CONFIG_USB_SERIAL_QCAUX=m
+CONFIG_USB_SERIAL_QUALCOMM=m
+CONFIG_USB_SERIAL_SPCP8X5=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+CONFIG_USB_SERIAL_SYMBOL=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_WWAN=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_OPTICON=m
+CONFIG_USB_SERIAL_XSENS_MT=m
+# CONFIG_USB_SERIAL_WISHBONE is not set
+CONFIG_USB_SERIAL_SSU100=m
+CONFIG_USB_SERIAL_QT2=m
+CONFIG_USB_SERIAL_UPD78F0730=m
+# CONFIG_USB_SERIAL_XR is not set
+CONFIG_USB_SERIAL_DEBUG=m
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_SEVSEG=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
+# CONFIG_APPLE_MFI_FASTCHARGE is not set
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_LD=m
+# CONFIG_USB_TRANCEVIBRATOR is not set
+CONFIG_USB_IOWARRIOR=m
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
+CONFIG_USB_ISIGHTFW=m
+# CONFIG_USB_YUREX is not set
+CONFIG_USB_EZUSB_FX2=m
+# CONFIG_USB_HUB_USB251XB is not set
+CONFIG_USB_HSIC_USB3503=m
+# CONFIG_USB_HSIC_USB4604 is not set
+# CONFIG_USB_LINK_LAYER_TEST is not set
+# CONFIG_USB_CHAOSKEY is not set
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
+#
+# USB Physical Layer drivers
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ISP1301 is not set
+# end of USB Physical Layer drivers
+
+# CONFIG_USB_GADGET is not set
+CONFIG_TYPEC=m
+CONFIG_TYPEC_TCPM=m
+CONFIG_TYPEC_TCPCI=m
+CONFIG_TYPEC_RT1711H=m
+# CONFIG_TYPEC_TCPCI_MAXIM is not set
+CONFIG_TYPEC_FUSB302=m
+CONFIG_TYPEC_UCSI=m
+# CONFIG_UCSI_CCG is not set
+CONFIG_UCSI_ACPI=m
+# CONFIG_UCSI_STM32G0 is not set
+CONFIG_TYPEC_TPS6598X=m
+# CONFIG_TYPEC_ANX7411 is not set
+# CONFIG_TYPEC_RT1719 is not set
+# CONFIG_TYPEC_HD3SS3220 is not set
+# CONFIG_TYPEC_STUSB160X is not set
+# CONFIG_TYPEC_WUSB3801 is not set
+
+#
+# USB Type-C Multiplexer/DeMultiplexer Switch support
+#
+# CONFIG_TYPEC_MUX_FSA4480 is not set
+CONFIG_TYPEC_MUX_PI3USB30532=m
+# end of USB Type-C Multiplexer/DeMultiplexer Switch support
+
+#
+# USB Type-C Alternate Mode drivers
+#
+CONFIG_TYPEC_DP_ALTMODE=m
+# CONFIG_TYPEC_NVIDIA_ALTMODE is not set
+# end of USB Type-C Alternate Mode drivers
+
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_ROLES_INTEL_XHCI=y
+CONFIG_MMC=m
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_SDIO_UART=m
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PCI=m
+CONFIG_MMC_RICOH_MMC=y
+CONFIG_MMC_SDHCI_ACPI=m
+CONFIG_MMC_SDHCI_PLTFM=m
+# CONFIG_MMC_SDHCI_F_SDH30 is not set
+# CONFIG_MMC_WBSD is not set
+CONFIG_MMC_TIFM_SD=m
+# CONFIG_MMC_SPI is not set
+CONFIG_MMC_CB710=m
+CONFIG_MMC_VIA_SDMMC=m
+CONFIG_MMC_VUB300=m
+CONFIG_MMC_USHC=m
+# CONFIG_MMC_USDHI6ROL0 is not set
+CONFIG_MMC_REALTEK_PCI=m
+CONFIG_MMC_REALTEK_USB=m
+CONFIG_MMC_CQHCI=m
+# CONFIG_MMC_HSQ is not set
+# CONFIG_MMC_TOSHIBA_PCI is not set
+# CONFIG_MMC_MTK is not set
+CONFIG_MMC_SDHCI_XENON=m
+# CONFIG_SCSI_UFSHCD is not set
+CONFIG_MEMSTICK=m
+# CONFIG_MEMSTICK_DEBUG is not set
+
+#
+# MemoryStick drivers
+#
+# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
+CONFIG_MSPRO_BLOCK=m
+# CONFIG_MS_BLOCK is not set
+
+#
+# MemoryStick Host Controller Drivers
+#
+CONFIG_MEMSTICK_TIFM_MS=m
+CONFIG_MEMSTICK_JMICRON_38X=m
+CONFIG_MEMSTICK_R592=m
+CONFIG_MEMSTICK_REALTEK_PCI=m
+CONFIG_MEMSTICK_REALTEK_USB=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+# CONFIG_LEDS_CLASS_FLASH is not set
+# CONFIG_LEDS_CLASS_MULTICOLOR is not set
+# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_APU is not set
+CONFIG_LEDS_LM3530=m
+# CONFIG_LEDS_LM3532 is not set
+# CONFIG_LEDS_LM3642 is not set
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_LP3944=m
+# CONFIG_LEDS_LP3952 is not set
+# CONFIG_LEDS_LP50XX is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_PCA963X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_PWM is not set
+# CONFIG_LEDS_BD2802 is not set
+CONFIG_LEDS_INTEL_SS4200=m
+# CONFIG_LEDS_LT3593 is not set
+# CONFIG_LEDS_TCA6507 is not set
+# CONFIG_LEDS_TLC591XX is not set
+# CONFIG_LEDS_LM355x is not set
+# CONFIG_LEDS_IS31FL319X is not set
+
+#
+# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
+#
+CONFIG_LEDS_BLINKM=m
+CONFIG_LEDS_MLXCPLD=m
+# CONFIG_LEDS_MLXREG is not set
+# CONFIG_LEDS_USER is not set
+# CONFIG_LEDS_NIC78BX is not set
+# CONFIG_LEDS_TI_LMU_COMMON is not set
+
+#
+# Flash and Torch LED drivers
+#
+
+#
+# RGB LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
+CONFIG_LEDS_TRIGGER_DISK=y
+# CONFIG_LEDS_TRIGGER_MTD is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+# CONFIG_LEDS_TRIGGER_CPU is not set
+# CONFIG_LEDS_TRIGGER_ACTIVITY is not set
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
+CONFIG_LEDS_TRIGGER_CAMERA=m
+# CONFIG_LEDS_TRIGGER_PANIC is not set
+# CONFIG_LEDS_TRIGGER_NETDEV is not set
+# CONFIG_LEDS_TRIGGER_PATTERN is not set
+CONFIG_LEDS_TRIGGER_AUDIO=m
+# CONFIG_LEDS_TRIGGER_TTY is not set
+
+#
+# Simple LED drivers
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_USER_MEM=y
+CONFIG_INFINIBAND_ON_DEMAND_PAGING=y
+CONFIG_INFINIBAND_ADDR_TRANS=y
+CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y
+CONFIG_INFINIBAND_VIRT_DMA=y
+CONFIG_INFINIBAND_BNXT_RE=m
+CONFIG_INFINIBAND_CXGB4=m
+# CONFIG_INFINIBAND_EFA is not set
+# CONFIG_INFINIBAND_ERDMA is not set
+CONFIG_INFINIBAND_HFI1=m
+# CONFIG_HFI1_DEBUG_SDMA_ORDER is not set
+# CONFIG_SDMA_VERBOSITY is not set
+# CONFIG_INFINIBAND_IRDMA is not set
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_MLX5_INFINIBAND=m
+# CONFIG_INFINIBAND_MTHCA is not set
+# CONFIG_INFINIBAND_OCRDMA is not set
+CONFIG_INFINIBAND_QEDR=m
+# CONFIG_INFINIBAND_QIB is not set
+CONFIG_INFINIBAND_USNIC=m
+CONFIG_INFINIBAND_VMWARE_PVRDMA=m
+CONFIG_INFINIBAND_RDMAVT=m
+CONFIG_RDMA_RXE=m
+# CONFIG_RDMA_SIW is not set
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_CM=y
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_SRPT=m
+CONFIG_INFINIBAND_ISER=m
+CONFIG_INFINIBAND_ISERT=m
+# CONFIG_INFINIBAND_RTRS_CLIENT is not set
+# CONFIG_INFINIBAND_RTRS_SERVER is not set
+CONFIG_INFINIBAND_OPA_VNIC=m
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EDAC=y
+CONFIG_EDAC_LEGACY_SYSFS=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_DECODE_MCE=m
+CONFIG_EDAC_GHES=y
+CONFIG_EDAC_AMD64=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82975X=m
+CONFIG_EDAC_I3000=m
+CONFIG_EDAC_I3200=m
+CONFIG_EDAC_IE31200=m
+CONFIG_EDAC_X38=m
+CONFIG_EDAC_I5400=m
+CONFIG_EDAC_I7CORE=m
+CONFIG_EDAC_I5000=m
+CONFIG_EDAC_I5100=m
+CONFIG_EDAC_I7300=m
+CONFIG_EDAC_SBRIDGE=m
+CONFIG_EDAC_SKX=m
+CONFIG_EDAC_I10NM=m
+CONFIG_EDAC_PND2=m
+# CONFIG_EDAC_IGEN6 is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_SYSTOHC is not set
+# CONFIG_RTC_DEBUG is not set
+CONFIG_RTC_NVMEM=y
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_ABB5ZES3 is not set
+# CONFIG_RTC_DRV_ABEOZ9 is not set
+# CONFIG_RTC_DRV_ABX80X is not set
+CONFIG_RTC_DRV_DS1307=m
+# CONFIG_RTC_DRV_DS1307_CENTURY is not set
+CONFIG_RTC_DRV_DS1374=m
+# CONFIG_RTC_DRV_DS1374_WDT is not set
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_MAX6900=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_ISL12022=m
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_PCF8523=m
+# CONFIG_RTC_DRV_PCF85063 is not set
+# CONFIG_RTC_DRV_PCF85363 is not set
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_M41T80=m
+CONFIG_RTC_DRV_M41T80_WDT=y
+CONFIG_RTC_DRV_BQ32K=m
+# CONFIG_RTC_DRV_S35390A is not set
+CONFIG_RTC_DRV_FM3130=m
+# CONFIG_RTC_DRV_RX8010 is not set
+CONFIG_RTC_DRV_RX8581=m
+CONFIG_RTC_DRV_RX8025=m
+CONFIG_RTC_DRV_EM3027=m
+# CONFIG_RTC_DRV_RV3028 is not set
+# CONFIG_RTC_DRV_RV3032 is not set
+CONFIG_RTC_DRV_RV8803=m
+# CONFIG_RTC_DRV_SD3078 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1302 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1343 is not set
+# CONFIG_RTC_DRV_DS1347 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6916 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+CONFIG_RTC_DRV_RX4581=m
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+# CONFIG_RTC_DRV_MCP795 is not set
+CONFIG_RTC_I2C_AND_SPI=y
+
+#
+# SPI and I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS3232=m
+CONFIG_RTC_DRV_DS3232_HWMON=y
+# CONFIG_RTC_DRV_PCF2127 is not set
+CONFIG_RTC_DRV_RV3029C2=m
+# CONFIG_RTC_DRV_RV3029_HWMON is not set
+# CONFIG_RTC_DRV_RX6110 is not set
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+CONFIG_RTC_DRV_DS1286=m
+CONFIG_RTC_DRV_DS1511=m
+CONFIG_RTC_DRV_DS1553=m
+# CONFIG_RTC_DRV_DS1685_FAMILY is not set
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_DS2404=m
+CONFIG_RTC_DRV_STK17TA8=m
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_M48T35=m
+CONFIG_RTC_DRV_M48T59=m
+CONFIG_RTC_DRV_MSM6242=m
+CONFIG_RTC_DRV_BQ4802=m
+CONFIG_RTC_DRV_RP5C01=m
+CONFIG_RTC_DRV_V3020=m
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_FTRTC010 is not set
+
+#
+# HID Sensor RTC drivers
+#
+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+# CONFIG_RTC_DRV_GOLDFISH is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DMA_ACPI=y
+# CONFIG_ALTERA_MSGDMA is not set
+CONFIG_INTEL_IDMA64=m
+CONFIG_INTEL_IDXD_BUS=m
+CONFIG_INTEL_IDXD=m
+# CONFIG_INTEL_IDXD_COMPAT is not set
+CONFIG_INTEL_IDXD_SVM=y
+CONFIG_INTEL_IDXD_PERFMON=y
+CONFIG_INTEL_IOATDMA=m
+# CONFIG_PLX_DMA is not set
+# CONFIG_AMD_PTDMA is not set
+# CONFIG_QCOM_HIDMA_MGMT is not set
+# CONFIG_QCOM_HIDMA is not set
+CONFIG_DW_DMAC_CORE=y
+CONFIG_DW_DMAC=m
+CONFIG_DW_DMAC_PCI=y
+# CONFIG_DW_EDMA is not set
+# CONFIG_DW_EDMA_PCIE is not set
+CONFIG_HSU_DMA=y
+# CONFIG_SF_PDMA is not set
+# CONFIG_INTEL_LDMA is not set
+
+#
+# DMA Clients
+#
+CONFIG_ASYNC_TX_DMA=y
+CONFIG_DMATEST=m
+CONFIG_DMA_ENGINE_RAID=y
+
+#
+# DMABUF options
+#
+CONFIG_SYNC_FILE=y
+# CONFIG_SW_SYNC is not set
+# CONFIG_UDMABUF is not set
+# CONFIG_DMABUF_MOVE_NOTIFY is not set
+# CONFIG_DMABUF_DEBUG is not set
+# CONFIG_DMABUF_SELFTESTS is not set
+# CONFIG_DMABUF_HEAPS is not set
+# CONFIG_DMABUF_SYSFS_STATS is not set
+# end of DMABUF options
+
+CONFIG_DCA=m
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_PANEL is not set
+CONFIG_UIO=m
+CONFIG_UIO_CIF=m
+CONFIG_UIO_PDRV_GENIRQ=m
+# CONFIG_UIO_DMEM_GENIRQ is not set
+CONFIG_UIO_AEC=m
+CONFIG_UIO_SERCOS3=m
+CONFIG_UIO_PCI_GENERIC=m
+# CONFIG_UIO_NETX is not set
+# CONFIG_UIO_PRUSS is not set
+# CONFIG_UIO_MF624 is not set
+CONFIG_UIO_HV_GENERIC=m
+CONFIG_VFIO=m
+CONFIG_VFIO_IOMMU_TYPE1=m
+CONFIG_VFIO_VIRQFD=m
+CONFIG_VFIO_NOIOMMU=y
+CONFIG_VFIO_PCI_CORE=m
+CONFIG_VFIO_PCI_MMAP=y
+CONFIG_VFIO_PCI_INTX=y
+CONFIG_VFIO_PCI=m
+# CONFIG_VFIO_PCI_VGA is not set
+# CONFIG_VFIO_PCI_IGD is not set
+# CONFIG_MLX5_VFIO_PCI is not set
+CONFIG_VFIO_MDEV=m
+CONFIG_IRQ_BYPASS_MANAGER=m
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO_ANCHOR=y
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_PCI_LIB=y
+CONFIG_VIRTIO_PCI_LIB_LEGACY=y
+CONFIG_VIRTIO_MENU=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_PCI_LEGACY=y
+# CONFIG_VIRTIO_PMEM is not set
+CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_MEM=m
+CONFIG_VIRTIO_INPUT=m
+# CONFIG_VIRTIO_MMIO is not set
+CONFIG_VIRTIO_DMA_SHARED_BUFFER=m
+# CONFIG_VDPA is not set
+CONFIG_VHOST_IOTLB=m
+CONFIG_VHOST=m
+CONFIG_VHOST_MENU=y
+CONFIG_VHOST_NET=m
+# CONFIG_VHOST_SCSI is not set
+CONFIG_VHOST_VSOCK=m
+# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+CONFIG_HYPERV=m
+CONFIG_HYPERV_TIMER=y
+CONFIG_HYPERV_UTILS=m
+CONFIG_HYPERV_BALLOON=m
+# end of Microsoft Hyper-V guest support
+
+#
+# Xen driver support
+#
+CONFIG_XEN_BALLOON=y
+# CONFIG_XEN_BALLOON_MEMORY_HOTPLUG is not set
+CONFIG_XEN_SCRUB_PAGES_DEFAULT=y
+CONFIG_XEN_DEV_EVTCHN=m
+# CONFIG_XEN_BACKEND is not set
+CONFIG_XENFS=m
+CONFIG_XEN_COMPAT_XENFS=y
+CONFIG_XEN_SYS_HYPERVISOR=y
+CONFIG_XEN_XENBUS_FRONTEND=y
+# CONFIG_XEN_GNTDEV is not set
+# CONFIG_XEN_GRANT_DEV_ALLOC is not set
+# CONFIG_XEN_GRANT_DMA_ALLOC is not set
+# CONFIG_XEN_PVCALLS_FRONTEND is not set
+CONFIG_XEN_PRIVCMD=m
+CONFIG_XEN_EFI=y
+CONFIG_XEN_AUTO_XLATE=y
+CONFIG_XEN_ACPI=y
+CONFIG_XEN_FRONT_PGDIR_SHBUF=m
+# CONFIG_XEN_UNPOPULATED_ALLOC is not set
+# CONFIG_XEN_VIRTIO is not set
+# end of Xen driver support
+
+# CONFIG_GREYBUS is not set
+# CONFIG_COMEDI is not set
+# CONFIG_STAGING is not set
+# CONFIG_CHROME_PLATFORMS is not set
+CONFIG_MELLANOX_PLATFORM=y
+CONFIG_MLXREG_HOTPLUG=m
+# CONFIG_MLXREG_IO is not set
+# CONFIG_MLXREG_LC is not set
+# CONFIG_NVSW_SN2201 is not set
+CONFIG_SURFACE_PLATFORMS=y
+# CONFIG_SURFACE3_WMI is not set
+# CONFIG_SURFACE_3_POWER_OPREGION is not set
+# CONFIG_SURFACE_GPE is not set
+# CONFIG_SURFACE_HOTPLUG is not set
+# CONFIG_SURFACE_PRO3_BUTTON is not set
+CONFIG_X86_PLATFORM_DEVICES=y
+CONFIG_ACPI_WMI=m
+CONFIG_WMI_BMOF=m
+# CONFIG_HUAWEI_WMI is not set
+# CONFIG_UV_SYSFS is not set
+CONFIG_MXM_WMI=m
+# CONFIG_PEAQ_WMI is not set
+# CONFIG_NVIDIA_WMI_EC_BACKLIGHT is not set
+# CONFIG_XIAOMI_WMI is not set
+# CONFIG_GIGABYTE_WMI is not set
+# CONFIG_YOGABOOK_WMI is not set
+CONFIG_ACERHDF=m
+# CONFIG_ACER_WIRELESS is not set
+CONFIG_ACER_WMI=m
+# CONFIG_AMD_PMF is not set
+# CONFIG_AMD_PMC is not set
+CONFIG_AMD_HSMP=m
+# CONFIG_ADV_SWBUTTON is not set
+CONFIG_APPLE_GMUX=m
+CONFIG_ASUS_LAPTOP=m
+# CONFIG_ASUS_WIRELESS is not set
+CONFIG_ASUS_WMI=m
+CONFIG_ASUS_NB_WMI=m
+# CONFIG_ASUS_TF103C_DOCK is not set
+# CONFIG_MERAKI_MX100 is not set
+CONFIG_EEEPC_LAPTOP=m
+CONFIG_EEEPC_WMI=m
+# CONFIG_X86_PLATFORM_DRIVERS_DELL is not set
+CONFIG_AMILO_RFKILL=m
+CONFIG_FUJITSU_LAPTOP=m
+CONFIG_FUJITSU_TABLET=m
+# CONFIG_GPD_POCKET_FAN is not set
+CONFIG_HP_ACCEL=m
+# CONFIG_WIRELESS_HOTKEY is not set
+CONFIG_HP_WMI=m
+# CONFIG_IBM_RTL is not set
+CONFIG_IDEAPAD_LAPTOP=m
+CONFIG_SENSORS_HDAPS=m
+CONFIG_THINKPAD_ACPI=m
+CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y
+# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set
+# CONFIG_THINKPAD_ACPI_DEBUG is not set
+# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set
+CONFIG_THINKPAD_ACPI_VIDEO=y
+CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y
+# CONFIG_THINKPAD_LMI is not set
+# CONFIG_INTEL_ATOMISP2_PM is not set
+# CONFIG_INTEL_SAR_INT1092 is not set
+CONFIG_INTEL_PMC_CORE=m
+
+#
+# Intel Speed Select Technology interface support
+#
+CONFIG_INTEL_SPEED_SELECT_INTERFACE=m
+# end of Intel Speed Select Technology interface support
+
+CONFIG_INTEL_WMI=y
+# CONFIG_INTEL_WMI_SBL_FW_UPDATE is not set
+CONFIG_INTEL_WMI_THUNDERBOLT=m
+
+#
+# Intel Uncore Frequency Control
+#
+# CONFIG_INTEL_UNCORE_FREQ_CONTROL is not set
+# end of Intel Uncore Frequency Control
+
+CONFIG_INTEL_HID_EVENT=m
+CONFIG_INTEL_VBTN=m
+# CONFIG_INTEL_INT0002_VGPIO is not set
+CONFIG_INTEL_OAKTRAIL=m
+# CONFIG_INTEL_ISHTP_ECLITE is not set
+# CONFIG_INTEL_PUNIT_IPC is not set
+CONFIG_INTEL_RST=m
+# CONFIG_INTEL_SMARTCONNECT is not set
+CONFIG_INTEL_TURBO_MAX_3=y
+# CONFIG_INTEL_VSEC is not set
+CONFIG_MSI_LAPTOP=m
+CONFIG_MSI_WMI=m
+# CONFIG_PCENGINES_APU2 is not set
+# CONFIG_BARCO_P50_GPIO is not set
+CONFIG_SAMSUNG_LAPTOP=m
+CONFIG_SAMSUNG_Q10=m
+# CONFIG_ACPI_TOSHIBA is not set
+CONFIG_TOSHIBA_BT_RFKILL=m
+# CONFIG_TOSHIBA_HAPS is not set
+# CONFIG_TOSHIBA_WMI is not set
+CONFIG_ACPI_CMPC=m
+CONFIG_COMPAL_LAPTOP=m
+# CONFIG_LG_LAPTOP is not set
+CONFIG_PANASONIC_LAPTOP=m
+CONFIG_SONY_LAPTOP=m
+CONFIG_SONYPI_COMPAT=y
+# CONFIG_SYSTEM76_ACPI is not set
+CONFIG_TOPSTAR_LAPTOP=m
+# CONFIG_SERIAL_MULTI_INSTANTIATE is not set
+CONFIG_MLX_PLATFORM=m
+CONFIG_INTEL_IPS=m
+# CONFIG_INTEL_SCU_PCI is not set
+# CONFIG_INTEL_SCU_PLATFORM is not set
+# CONFIG_SIEMENS_SIMATIC_IPC is not set
+# CONFIG_WINMATE_FM07_KEYS is not set
+CONFIG_P2SB=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_COMMON_CLK=y
+# CONFIG_LMK04832 is not set
+# CONFIG_COMMON_CLK_MAX9485 is not set
+# CONFIG_COMMON_CLK_SI5341 is not set
+# CONFIG_COMMON_CLK_SI5351 is not set
+# CONFIG_COMMON_CLK_SI544 is not set
+# CONFIG_COMMON_CLK_CDCE706 is not set
+# CONFIG_COMMON_CLK_CS2000_CP is not set
+# CONFIG_COMMON_CLK_PWM is not set
+# CONFIG_XILINX_VCU is not set
+CONFIG_HWSPINLOCK=y
+
+#
+# Clock Source drivers
+#
+CONFIG_CLKEVT_I8253=y
+CONFIG_I8253_LOCK=y
+CONFIG_CLKBLD_I8253=y
+# end of Clock Source drivers
+
+CONFIG_MAILBOX=y
+CONFIG_PCC=y
+# CONFIG_ALTERA_MBOX is not set
+CONFIG_IOMMU_IOVA=y
+CONFIG_IOASID=y
+CONFIG_IOMMU_API=y
+CONFIG_IOMMU_SUPPORT=y
+
+#
+# Generic IOMMU Pagetable Support
+#
+CONFIG_IOMMU_IO_PGTABLE=y
+# end of Generic IOMMU Pagetable Support
+
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set
+# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
+CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y
+CONFIG_IOMMU_DMA=y
+CONFIG_IOMMU_SVA=y
+CONFIG_AMD_IOMMU=y
+CONFIG_AMD_IOMMU_V2=m
+CONFIG_DMAR_TABLE=y
+CONFIG_INTEL_IOMMU=y
+CONFIG_INTEL_IOMMU_SVM=y
+# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set
+CONFIG_INTEL_IOMMU_FLOPPY_WA=y
+# CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not set
+CONFIG_IRQ_REMAP=y
+CONFIG_HYPERV_IOMMU=y
+# CONFIG_VIRTIO_IOMMU is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_REMOTEPROC is not set
+# end of Remoteproc drivers
+
+#
+# Rpmsg drivers
+#
+# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
+# CONFIG_RPMSG_VIRTIO is not set
+# end of Rpmsg drivers
+
+# CONFIG_SOUNDWIRE is not set
+
+#
+# SOC (System On Chip) specific Drivers
+#
+
+#
+# Amlogic SoC drivers
+#
+# end of Amlogic SoC drivers
+
+#
+# Broadcom SoC drivers
+#
+# end of Broadcom SoC drivers
+
+#
+# NXP/Freescale QorIQ SoC drivers
+#
+# end of NXP/Freescale QorIQ SoC drivers
+
+#
+# fujitsu SoC drivers
+#
+# end of fujitsu SoC drivers
+
+#
+# i.MX SoC drivers
+#
+# end of i.MX SoC drivers
+
+#
+# Enable LiteX SoC Builder specific drivers
+#
+# end of Enable LiteX SoC Builder specific drivers
+
+#
+# Qualcomm SoC drivers
+#
+# end of Qualcomm SoC drivers
+
+# CONFIG_SOC_TI is not set
+
+#
+# Xilinx SoC drivers
+#
+# end of Xilinx SoC drivers
+# end of SOC (System On Chip) specific Drivers
+
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+CONFIG_IIO=m
+CONFIG_IIO_BUFFER=y
+# CONFIG_IIO_BUFFER_CB is not set
+# CONFIG_IIO_BUFFER_DMA is not set
+# CONFIG_IIO_BUFFER_DMAENGINE is not set
+# CONFIG_IIO_BUFFER_HW_CONSUMER is not set
+CONFIG_IIO_KFIFO_BUF=m
+CONFIG_IIO_TRIGGERED_BUFFER=m
+# CONFIG_IIO_CONFIGFS is not set
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
+# CONFIG_IIO_SW_DEVICE is not set
+# CONFIG_IIO_SW_TRIGGER is not set
+# CONFIG_IIO_TRIGGERED_EVENT is not set
+
+#
+# Accelerometers
+#
+# CONFIG_ADIS16201 is not set
+# CONFIG_ADIS16209 is not set
+# CONFIG_ADXL313_I2C is not set
+# CONFIG_ADXL313_SPI is not set
+# CONFIG_ADXL345_I2C is not set
+# CONFIG_ADXL345_SPI is not set
+# CONFIG_ADXL355_I2C is not set
+# CONFIG_ADXL355_SPI is not set
+# CONFIG_ADXL367_SPI is not set
+# CONFIG_ADXL367_I2C is not set
+# CONFIG_ADXL372_SPI is not set
+# CONFIG_ADXL372_I2C is not set
+# CONFIG_BMA180 is not set
+# CONFIG_BMA220 is not set
+# CONFIG_BMA400 is not set
+# CONFIG_BMC150_ACCEL is not set
+# CONFIG_BMI088_ACCEL is not set
+# CONFIG_DA280 is not set
+# CONFIG_DA311 is not set
+# CONFIG_DMARD06 is not set
+# CONFIG_DMARD09 is not set
+# CONFIG_DMARD10 is not set
+# CONFIG_FXLS8962AF_I2C is not set
+# CONFIG_FXLS8962AF_SPI is not set
+CONFIG_HID_SENSOR_ACCEL_3D=m
+# CONFIG_IIO_ST_ACCEL_3AXIS is not set
+# CONFIG_KXSD9 is not set
+# CONFIG_KXCJK1013 is not set
+# CONFIG_MC3230 is not set
+# CONFIG_MMA7455_I2C is not set
+# CONFIG_MMA7455_SPI is not set
+# CONFIG_MMA7660 is not set
+# CONFIG_MMA8452 is not set
+# CONFIG_MMA9551 is not set
+# CONFIG_MMA9553 is not set
+# CONFIG_MSA311 is not set
+# CONFIG_MXC4005 is not set
+# CONFIG_MXC6255 is not set
+# CONFIG_SCA3000 is not set
+# CONFIG_SCA3300 is not set
+# CONFIG_STK8312 is not set
+# CONFIG_STK8BA50 is not set
+# end of Accelerometers
+
+#
+# Analog to digital converters
+#
+# CONFIG_AD7091R5 is not set
+# CONFIG_AD7124 is not set
+# CONFIG_AD7192 is not set
+# CONFIG_AD7266 is not set
+# CONFIG_AD7280 is not set
+# CONFIG_AD7291 is not set
+# CONFIG_AD7292 is not set
+# CONFIG_AD7298 is not set
+# CONFIG_AD7476 is not set
+# CONFIG_AD7606_IFACE_PARALLEL is not set
+# CONFIG_AD7606_IFACE_SPI is not set
+# CONFIG_AD7766 is not set
+# CONFIG_AD7768_1 is not set
+# CONFIG_AD7780 is not set
+# CONFIG_AD7791 is not set
+# CONFIG_AD7793 is not set
+# CONFIG_AD7887 is not set
+# CONFIG_AD7923 is not set
+# CONFIG_AD7949 is not set
+# CONFIG_AD799X is not set
+# CONFIG_ENVELOPE_DETECTOR is not set
+# CONFIG_HI8435 is not set
+# CONFIG_HX711 is not set
+# CONFIG_INA2XX_ADC is not set
+# CONFIG_LTC2471 is not set
+# CONFIG_LTC2485 is not set
+# CONFIG_LTC2496 is not set
+# CONFIG_LTC2497 is not set
+# CONFIG_MAX1027 is not set
+# CONFIG_MAX11100 is not set
+# CONFIG_MAX1118 is not set
+# CONFIG_MAX11205 is not set
+# CONFIG_MAX1241 is not set
+# CONFIG_MAX1363 is not set
+# CONFIG_MAX9611 is not set
+# CONFIG_MCP320X is not set
+# CONFIG_MCP3422 is not set
+# CONFIG_MCP3911 is not set
+# CONFIG_NAU7802 is not set
+# CONFIG_RICHTEK_RTQ6056 is not set
+# CONFIG_SD_ADC_MODULATOR is not set
+# CONFIG_TI_ADC081C is not set
+# CONFIG_TI_ADC0832 is not set
+# CONFIG_TI_ADC084S021 is not set
+# CONFIG_TI_ADC12138 is not set
+# CONFIG_TI_ADC108S102 is not set
+# CONFIG_TI_ADC128S052 is not set
+# CONFIG_TI_ADC161S626 is not set
+# CONFIG_TI_ADS1015 is not set
+# CONFIG_TI_ADS7950 is not set
+# CONFIG_TI_ADS8344 is not set
+# CONFIG_TI_ADS8688 is not set
+# CONFIG_TI_ADS124S08 is not set
+# CONFIG_TI_ADS131E08 is not set
+# CONFIG_TI_TLC4541 is not set
+# CONFIG_TI_TSC2046 is not set
+# CONFIG_VF610_ADC is not set
+# CONFIG_VIPERBOARD_ADC is not set
+# CONFIG_XILINX_XADC is not set
+# end of Analog to digital converters
+
+#
+# Analog to digital and digital to analog converters
+#
+# CONFIG_AD74413R is not set
+# end of Analog to digital and digital to analog converters
+
+#
+# Analog Front Ends
+#
+# CONFIG_IIO_RESCALE is not set
+# end of Analog Front Ends
+
+#
+# Amplifiers
+#
+# CONFIG_AD8366 is not set
+# CONFIG_ADA4250 is not set
+# CONFIG_HMC425 is not set
+# end of Amplifiers
+
+#
+# Capacitance to digital converters
+#
+# CONFIG_AD7150 is not set
+# CONFIG_AD7746 is not set
+# end of Capacitance to digital converters
+
+#
+# Chemical Sensors
+#
+# CONFIG_ATLAS_PH_SENSOR is not set
+# CONFIG_ATLAS_EZO_SENSOR is not set
+# CONFIG_BME680 is not set
+# CONFIG_CCS811 is not set
+# CONFIG_IAQCORE is not set
+# CONFIG_SCD30_CORE is not set
+# CONFIG_SCD4X is not set
+# CONFIG_SENSIRION_SGP30 is not set
+# CONFIG_SENSIRION_SGP40 is not set
+# CONFIG_SPS30_I2C is not set
+# CONFIG_SENSEAIR_SUNRISE_CO2 is not set
+# CONFIG_VZ89X is not set
+# end of Chemical Sensors
+
+#
+# Hid Sensor IIO Common
+#
+CONFIG_HID_SENSOR_IIO_COMMON=m
+CONFIG_HID_SENSOR_IIO_TRIGGER=m
+# end of Hid Sensor IIO Common
+
+#
+# IIO SCMI Sensors
+#
+# end of IIO SCMI Sensors
+
+#
+# SSP Sensor Common
+#
+# CONFIG_IIO_SSP_SENSORHUB is not set
+# end of SSP Sensor Common
+
+#
+# Digital to analog converters
+#
+# CONFIG_AD3552R is not set
+# CONFIG_AD5064 is not set
+# CONFIG_AD5360 is not set
+# CONFIG_AD5380 is not set
+# CONFIG_AD5421 is not set
+# CONFIG_AD5446 is not set
+# CONFIG_AD5449 is not set
+# CONFIG_AD5592R is not set
+# CONFIG_AD5593R is not set
+# CONFIG_AD5504 is not set
+# CONFIG_AD5624R_SPI is not set
+# CONFIG_LTC2688 is not set
+# CONFIG_AD5686_SPI is not set
+# CONFIG_AD5696_I2C is not set
+# CONFIG_AD5755 is not set
+# CONFIG_AD5758 is not set
+# CONFIG_AD5761 is not set
+# CONFIG_AD5764 is not set
+# CONFIG_AD5766 is not set
+# CONFIG_AD5770R is not set
+# CONFIG_AD5791 is not set
+# CONFIG_AD7293 is not set
+# CONFIG_AD7303 is not set
+# CONFIG_AD8801 is not set
+# CONFIG_DPOT_DAC is not set
+# CONFIG_DS4424 is not set
+# CONFIG_LTC1660 is not set
+# CONFIG_LTC2632 is not set
+# CONFIG_M62332 is not set
+# CONFIG_MAX517 is not set
+# CONFIG_MAX5821 is not set
+# CONFIG_MCP4725 is not set
+# CONFIG_MCP4922 is not set
+# CONFIG_TI_DAC082S085 is not set
+# CONFIG_TI_DAC5571 is not set
+# CONFIG_TI_DAC7311 is not set
+# CONFIG_TI_DAC7612 is not set
+# CONFIG_VF610_DAC is not set
+# end of Digital to analog converters
+
+#
+# IIO dummy driver
+#
+# end of IIO dummy driver
+
+#
+# Filters
+#
+# CONFIG_ADMV8818 is not set
+# end of Filters
+
+#
+# Frequency Synthesizers DDS/PLL
+#
+
+#
+# Clock Generator/Distribution
+#
+# CONFIG_AD9523 is not set
+# end of Clock Generator/Distribution
+
+#
+# Phase-Locked Loop (PLL) frequency synthesizers
+#
+# CONFIG_ADF4350 is not set
+# CONFIG_ADF4371 is not set
+# CONFIG_ADMV1013 is not set
+# CONFIG_ADMV1014 is not set
+# CONFIG_ADMV4420 is not set
+# CONFIG_ADRF6780 is not set
+# end of Phase-Locked Loop (PLL) frequency synthesizers
+# end of Frequency Synthesizers DDS/PLL
+
+#
+# Digital gyroscope sensors
+#
+# CONFIG_ADIS16080 is not set
+# CONFIG_ADIS16130 is not set
+# CONFIG_ADIS16136 is not set
+# CONFIG_ADIS16260 is not set
+# CONFIG_ADXRS290 is not set
+# CONFIG_ADXRS450 is not set
+# CONFIG_BMG160 is not set
+# CONFIG_FXAS21002C is not set
+CONFIG_HID_SENSOR_GYRO_3D=m
+# CONFIG_MPU3050_I2C is not set
+# CONFIG_IIO_ST_GYRO_3AXIS is not set
+# CONFIG_ITG3200 is not set
+# end of Digital gyroscope sensors
+
+#
+# Health Sensors
+#
+
+#
+# Heart Rate Monitors
+#
+# CONFIG_AFE4403 is not set
+# CONFIG_AFE4404 is not set
+# CONFIG_MAX30100 is not set
+# CONFIG_MAX30102 is not set
+# end of Heart Rate Monitors
+# end of Health Sensors
+
+#
+# Humidity sensors
+#
+# CONFIG_AM2315 is not set
+# CONFIG_DHT11 is not set
+# CONFIG_HDC100X is not set
+# CONFIG_HDC2010 is not set
+CONFIG_HID_SENSOR_HUMIDITY=m
+# CONFIG_HTS221 is not set
+# CONFIG_HTU21 is not set
+# CONFIG_SI7005 is not set
+# CONFIG_SI7020 is not set
+# end of Humidity sensors
+
+#
+# Inertial measurement units
+#
+# CONFIG_ADIS16400 is not set
+# CONFIG_ADIS16460 is not set
+# CONFIG_ADIS16475 is not set
+# CONFIG_ADIS16480 is not set
+# CONFIG_BMI160_I2C is not set
+# CONFIG_BMI160_SPI is not set
+# CONFIG_BOSCH_BNO055_I2C is not set
+# CONFIG_FXOS8700_I2C is not set
+# CONFIG_FXOS8700_SPI is not set
+# CONFIG_KMX61 is not set
+# CONFIG_INV_ICM42600_I2C is not set
+# CONFIG_INV_ICM42600_SPI is not set
+# CONFIG_INV_MPU6050_I2C is not set
+# CONFIG_INV_MPU6050_SPI is not set
+# CONFIG_IIO_ST_LSM6DSX is not set
+# CONFIG_IIO_ST_LSM9DS0 is not set
+# end of Inertial measurement units
+
+#
+# Light sensors
+#
+# CONFIG_ACPI_ALS is not set
+# CONFIG_ADJD_S311 is not set
+# CONFIG_ADUX1020 is not set
+# CONFIG_AL3010 is not set
+# CONFIG_AL3320A is not set
+# CONFIG_APDS9300 is not set
+# CONFIG_APDS9960 is not set
+# CONFIG_AS73211 is not set
+# CONFIG_BH1750 is not set
+# CONFIG_BH1780 is not set
+# CONFIG_CM32181 is not set
+# CONFIG_CM3232 is not set
+# CONFIG_CM3323 is not set
+# CONFIG_CM3605 is not set
+# CONFIG_CM36651 is not set
+# CONFIG_GP2AP002 is not set
+# CONFIG_GP2AP020A00F is not set
+# CONFIG_SENSORS_ISL29018 is not set
+# CONFIG_SENSORS_ISL29028 is not set
+# CONFIG_ISL29125 is not set
+CONFIG_HID_SENSOR_ALS=m
+CONFIG_HID_SENSOR_PROX=m
+# CONFIG_JSA1212 is not set
+# CONFIG_RPR0521 is not set
+# CONFIG_LTR501 is not set
+# CONFIG_LTRF216A is not set
+# CONFIG_LV0104CS is not set
+# CONFIG_MAX44000 is not set
+# CONFIG_MAX44009 is not set
+# CONFIG_NOA1305 is not set
+# CONFIG_OPT3001 is not set
+# CONFIG_PA12203001 is not set
+# CONFIG_SI1133 is not set
+# CONFIG_SI1145 is not set
+# CONFIG_STK3310 is not set
+# CONFIG_ST_UVIS25 is not set
+# CONFIG_TCS3414 is not set
+# CONFIG_TCS3472 is not set
+# CONFIG_SENSORS_TSL2563 is not set
+# CONFIG_TSL2583 is not set
+# CONFIG_TSL2591 is not set
+# CONFIG_TSL2772 is not set
+# CONFIG_TSL4531 is not set
+# CONFIG_US5182D is not set
+# CONFIG_VCNL4000 is not set
+# CONFIG_VCNL4035 is not set
+# CONFIG_VEML6030 is not set
+# CONFIG_VEML6070 is not set
+# CONFIG_VL6180 is not set
+# CONFIG_ZOPT2201 is not set
+# end of Light sensors
+
+#
+# Magnetometer sensors
+#
+# CONFIG_AK8974 is not set
+# CONFIG_AK8975 is not set
+# CONFIG_AK09911 is not set
+# CONFIG_BMC150_MAGN_I2C is not set
+# CONFIG_BMC150_MAGN_SPI is not set
+# CONFIG_MAG3110 is not set
+CONFIG_HID_SENSOR_MAGNETOMETER_3D=m
+# CONFIG_MMC35240 is not set
+# CONFIG_IIO_ST_MAGN_3AXIS is not set
+# CONFIG_SENSORS_HMC5843_I2C is not set
+# CONFIG_SENSORS_HMC5843_SPI is not set
+# CONFIG_SENSORS_RM3100_I2C is not set
+# CONFIG_SENSORS_RM3100_SPI is not set
+# CONFIG_YAMAHA_YAS530 is not set
+# end of Magnetometer sensors
+
+#
+# Multiplexers
+#
+# CONFIG_IIO_MUX is not set
+# end of Multiplexers
+
+#
+# Inclinometer sensors
+#
+CONFIG_HID_SENSOR_INCLINOMETER_3D=m
+CONFIG_HID_SENSOR_DEVICE_ROTATION=m
+# end of Inclinometer sensors
+
+#
+# Triggers - standalone
+#
+# CONFIG_IIO_INTERRUPT_TRIGGER is not set
+# CONFIG_IIO_SYSFS_TRIGGER is not set
+# end of Triggers - standalone
+
+#
+# Linear and angular position sensors
+#
+# CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE is not set
+# end of Linear and angular position sensors
+
+#
+# Digital potentiometers
+#
+# CONFIG_AD5110 is not set
+# CONFIG_AD5272 is not set
+# CONFIG_DS1803 is not set
+# CONFIG_MAX5432 is not set
+# CONFIG_MAX5481 is not set
+# CONFIG_MAX5487 is not set
+# CONFIG_MCP4018 is not set
+# CONFIG_MCP4131 is not set
+# CONFIG_MCP4531 is not set
+# CONFIG_MCP41010 is not set
+# CONFIG_TPL0102 is not set
+# end of Digital potentiometers
+
+#
+# Digital potentiostats
+#
+# CONFIG_LMP91000 is not set
+# end of Digital potentiostats
+
+#
+# Pressure sensors
+#
+# CONFIG_ABP060MG is not set
+# CONFIG_BMP280 is not set
+# CONFIG_DLHL60D is not set
+# CONFIG_DPS310 is not set
+CONFIG_HID_SENSOR_PRESS=m
+# CONFIG_HP03 is not set
+# CONFIG_ICP10100 is not set
+# CONFIG_MPL115_I2C is not set
+# CONFIG_MPL115_SPI is not set
+# CONFIG_MPL3115 is not set
+# CONFIG_MS5611 is not set
+# CONFIG_MS5637 is not set
+# CONFIG_IIO_ST_PRESS is not set
+# CONFIG_T5403 is not set
+# CONFIG_HP206C is not set
+# CONFIG_ZPA2326 is not set
+# end of Pressure sensors
+
+#
+# Lightning sensors
+#
+# CONFIG_AS3935 is not set
+# end of Lightning sensors
+
+#
+# Proximity and distance sensors
+#
+# CONFIG_ISL29501 is not set
+# CONFIG_LIDAR_LITE_V2 is not set
+# CONFIG_MB1232 is not set
+# CONFIG_PING is not set
+# CONFIG_RFD77402 is not set
+# CONFIG_SRF04 is not set
+# CONFIG_SX9310 is not set
+# CONFIG_SX9324 is not set
+# CONFIG_SX9360 is not set
+# CONFIG_SX9500 is not set
+# CONFIG_SRF08 is not set
+# CONFIG_VCNL3020 is not set
+# CONFIG_VL53L0X_I2C is not set
+# end of Proximity and distance sensors
+
+#
+# Resolver to digital converters
+#
+# CONFIG_AD2S90 is not set
+# CONFIG_AD2S1200 is not set
+# end of Resolver to digital converters
+
+#
+# Temperature sensors
+#
+# CONFIG_LTC2983 is not set
+# CONFIG_MAXIM_THERMOCOUPLE is not set
+CONFIG_HID_SENSOR_TEMP=m
+# CONFIG_MLX90614 is not set
+# CONFIG_MLX90632 is not set
+# CONFIG_TMP006 is not set
+# CONFIG_TMP007 is not set
+# CONFIG_TMP117 is not set
+# CONFIG_TSYS01 is not set
+# CONFIG_TSYS02D is not set
+# CONFIG_MAX31856 is not set
+# CONFIG_MAX31865 is not set
+# end of Temperature sensors
+
+CONFIG_NTB=m
+# CONFIG_NTB_MSI is not set
+# CONFIG_NTB_AMD is not set
+# CONFIG_NTB_IDT is not set
+CONFIG_NTB_INTEL=m
+# CONFIG_NTB_EPF is not set
+# CONFIG_NTB_SWITCHTEC is not set
+CONFIG_NTB_PINGPONG=m
+CONFIG_NTB_TOOL=m
+CONFIG_NTB_PERF=m
+CONFIG_NTB_TRANSPORT=m
+CONFIG_PWM=y
+CONFIG_PWM_SYSFS=y
+# CONFIG_PWM_DEBUG is not set
+# CONFIG_PWM_CLK is not set
+# CONFIG_PWM_DWC is not set
+CONFIG_PWM_LPSS=m
+CONFIG_PWM_LPSS_PCI=m
+CONFIG_PWM_LPSS_PLATFORM=m
+# CONFIG_PWM_PCA9685 is not set
+
+#
+# IRQ chip support
+#
+# end of IRQ chip support
+
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+
+#
+# PHY Subsystem
+#
+# CONFIG_GENERIC_PHY is not set
+# CONFIG_USB_LGM_PHY is not set
+# CONFIG_PHY_CAN_TRANSCEIVER is not set
+
+#
+# PHY drivers for Broadcom platforms
+#
+# CONFIG_BCM_KONA_USB2_PHY is not set
+# end of PHY drivers for Broadcom platforms
+
+# CONFIG_PHY_PXA_28NM_HSIC is not set
+# CONFIG_PHY_PXA_28NM_USB2 is not set
+# CONFIG_PHY_CPCAP_USB is not set
+# CONFIG_PHY_INTEL_LGM_EMMC is not set
+# end of PHY Subsystem
+
+CONFIG_POWERCAP=y
+CONFIG_INTEL_RAPL_CORE=m
+CONFIG_INTEL_RAPL=m
+# CONFIG_IDLE_INJECT is not set
+# CONFIG_MCB is not set
+
+#
+# Performance monitor support
+#
+# end of Performance monitor support
+
+CONFIG_RAS=y
+# CONFIG_RAS_CEC is not set
+CONFIG_USB4=m
+# CONFIG_USB4_DEBUGFS_WRITE is not set
+# CONFIG_USB4_DMA_TEST is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID_BINDER_IPC is not set
+# end of Android
+
+CONFIG_LIBNVDIMM=m
+CONFIG_BLK_DEV_PMEM=m
+CONFIG_ND_CLAIM=y
+CONFIG_ND_BTT=m
+CONFIG_BTT=y
+CONFIG_ND_PFN=m
+CONFIG_NVDIMM_PFN=y
+CONFIG_NVDIMM_DAX=y
+CONFIG_NVDIMM_KEYS=y
+CONFIG_DAX=y
+CONFIG_DEV_DAX=m
+CONFIG_DEV_DAX_PMEM=m
+CONFIG_DEV_DAX_HMEM=m
+CONFIG_DEV_DAX_HMEM_DEVICES=y
+CONFIG_DEV_DAX_KMEM=m
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SYSFS=y
+# CONFIG_NVMEM_RMEM is not set
+
+#
+# HW tracing support
+#
+# CONFIG_STM is not set
+CONFIG_INTEL_TH=m
+CONFIG_INTEL_TH_PCI=m
+CONFIG_INTEL_TH_ACPI=m
+CONFIG_INTEL_TH_GTH=m
+CONFIG_INTEL_TH_MSU=m
+CONFIG_INTEL_TH_PTI=m
+# CONFIG_INTEL_TH_DEBUG is not set
+# end of HW tracing support
+
+# CONFIG_FPGA is not set
+# CONFIG_TEE is not set
+# CONFIG_SIOX is not set
+# CONFIG_SLIMBUS is not set
+# CONFIG_INTERCONNECT is not set
+# CONFIG_COUNTER is not set
+# CONFIG_MOST is not set
+# CONFIG_PECI is not set
+# CONFIG_HTE is not set
+# end of Device Drivers
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_VALIDATE_FS_PARSER is not set
+CONFIG_FS_IOMAP=y
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_USE_FOR_EXT2=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_SUPPORT_V4=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_ONLINE_SCRUB is not set
+# CONFIG_XFS_WARN is not set
+# CONFIG_XFS_DEBUG is not set
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+# CONFIG_OCFS2_FS is not set
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
+# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
+# CONFIG_BTRFS_DEBUG is not set
+# CONFIG_BTRFS_ASSERT is not set
+# CONFIG_BTRFS_FS_REF_VERIFY is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_F2FS_FS is not set
+# CONFIG_ZONEFS_FS is not set
+CONFIG_FS_DAX=y
+CONFIG_FS_DAX_PMD=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_EXPORTFS_BLOCK_OPS=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_FS_ENCRYPTION is not set
+# CONFIG_FS_VERITY is not set
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QUOTA_DEBUG is not set
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_AUTOFS_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_VIRTIO_FS=m
+CONFIG_FUSE_DAX=y
+CONFIG_OVERLAY_FS=m
+# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
+# CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW is not set
+# CONFIG_OVERLAY_FS_INDEX is not set
+# CONFIG_OVERLAY_FS_XINO_AUTO is not set
+# CONFIG_OVERLAY_FS_METACOPY is not set
+
+#
+# Caches
+#
+CONFIG_NETFS_SUPPORT=m
+CONFIG_NETFS_STATS=y
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+# CONFIG_FSCACHE_DEBUG is not set
+CONFIG_CACHEFILES=m
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_ERROR_INJECTION is not set
+# CONFIG_CACHEFILES_ONDEMAND is not set
+# end of Caches
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+# end of CD-ROM/DVD Filesystems
+
+#
+# DOS/FAT/EXFAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_FAT_DEFAULT_UTF8 is not set
+CONFIG_EXFAT_FS=m
+CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+CONFIG_NTFS3_FS=m
+# CONFIG_NTFS3_64BIT_CLUSTER is not set
+CONFIG_NTFS3_LZX_XPRESS=y
+CONFIG_NTFS3_FS_POSIX_ACL=y
+# end of DOS/FAT/EXFAT/NT Filesystems
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_VMCORE=y
+CONFIG_PROC_VMCORE_DEVICE_DUMP=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_PROC_CHILDREN=y
+CONFIG_PROC_PID_ARCH_STATUS=y
+CONFIG_PROC_CPU_RESCTRL=y
+CONFIG_KERNFS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_TMPFS_INODE64 is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set
+CONFIG_MEMFD_CREATE=y
+CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_EFIVAR_FS=y
+# end of Pseudo filesystems
+
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ORANGEFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_UBIFS_FS is not set
+CONFIG_CRAMFS=m
+CONFIG_CRAMFS_BLOCKDEV=y
+# CONFIG_CRAMFS_MTD is not set
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_FILE_CACHE is not set
+CONFIG_SQUASHFS_FILE_DIRECT=y
+# CONFIG_SQUASHFS_DECOMP_SINGLE is not set
+# CONFIG_SQUASHFS_DECOMP_MULTI is not set
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_ZLIB=y
+# CONFIG_SQUASHFS_LZ4 is not set
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+# CONFIG_SQUASHFS_ZSTD is not set
+# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_PSTORE=y
+CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
+CONFIG_PSTORE_DEFLATE_COMPRESS=y
+# CONFIG_PSTORE_LZO_COMPRESS is not set
+# CONFIG_PSTORE_LZ4_COMPRESS is not set
+# CONFIG_PSTORE_LZ4HC_COMPRESS is not set
+# CONFIG_PSTORE_842_COMPRESS is not set
+# CONFIG_PSTORE_ZSTD_COMPRESS is not set
+CONFIG_PSTORE_COMPRESS=y
+CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y
+CONFIG_PSTORE_COMPRESS_DEFAULT="deflate"
+# CONFIG_PSTORE_CONSOLE is not set
+# CONFIG_PSTORE_PMSG is not set
+# CONFIG_PSTORE_FTRACE is not set
+CONFIG_PSTORE_RAM=m
+# CONFIG_PSTORE_BLK is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_EROFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+# CONFIG_NFS_V2 is not set
+CONFIG_NFS_V3=m
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=m
+# CONFIG_NFS_SWAP is not set
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_PNFS_FILE_LAYOUT=m
+CONFIG_PNFS_BLOCK=m
+CONFIG_PNFS_FLEXFILE_LAYOUT=m
+CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
+# CONFIG_NFS_V4_1_MIGRATION is not set
+CONFIG_NFS_V4_SECURITY_LABEL=y
+CONFIG_NFS_FSCACHE=y
+# CONFIG_NFS_USE_LEGACY_DNS is not set
+CONFIG_NFS_USE_KERNEL_DNS=y
+CONFIG_NFS_DEBUG=y
+# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set
+# CONFIG_NFS_V4_2_READ_PLUS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_PNFS=y
+CONFIG_NFSD_BLOCKLAYOUT=y
+CONFIG_NFSD_SCSILAYOUT=y
+CONFIG_NFSD_FLEXFILELAYOUT=y
+CONFIG_NFSD_V4_2_INTER_SSC=y
+CONFIG_NFSD_V4_SECURITY_LABEL=y
+CONFIG_GRACE_PERIOD=m
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_NFS_V4_2_SSC_HELPER=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_SUNRPC_BACKCHANNEL=y
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES is not set
+CONFIG_SUNRPC_DEBUG=y
+CONFIG_SUNRPC_XPRT_RDMA=m
+CONFIG_CEPH_FS=m
+# CONFIG_CEPH_FSCACHE is not set
+CONFIG_CEPH_FS_POSIX_ACL=y
+# CONFIG_CEPH_FS_SECURITY_LABEL is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS2 is not set
+CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DEBUG=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set
+CONFIG_CIFS_DFS_UPCALL=y
+# CONFIG_CIFS_SWN_UPCALL is not set
+# CONFIG_CIFS_SMB_DIRECT is not set
+# CONFIG_CIFS_FSCACHE is not set
+# CONFIG_SMB_SERVER is not set
+CONFIG_SMBFS_COMMON=m
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+# CONFIG_DLM_DEPRECATED_API is not set
+CONFIG_DLM_DEBUG=y
+# CONFIG_UNICODE is not set
+CONFIG_IO_WQ=y
+# end of File systems
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_REQUEST_CACHE is not set
+CONFIG_PERSISTENT_KEYRINGS=y
+CONFIG_TRUSTED_KEYS=y
+CONFIG_TRUSTED_KEYS_TPM=y
+CONFIG_ENCRYPTED_KEYS=y
+# CONFIG_USER_DECRYPTED_DATA is not set
+# CONFIG_KEY_DH_OPERATIONS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+CONFIG_SECURITY=y
+CONFIG_SECURITY_WRITABLE_HOOKS=y
+CONFIG_SECURITYFS=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_INFINIBAND=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+CONFIG_SECURITY_PATH=y
+CONFIG_INTEL_TXT=y
+CONFIG_LSM_MMAP_MIN_ADDR=65535
+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
+# CONFIG_STATIC_USERMODEHELPER is not set
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9
+CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256
+# CONFIG_SECURITY_SMACK is not set
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_SECURITY_APPARMOR=y
+# CONFIG_SECURITY_APPARMOR_DEBUG is not set
+CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY=y
+CONFIG_SECURITY_APPARMOR_HASH=y
+CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y
+CONFIG_SECURITY_APPARMOR_EXPORT_BINARY=y
+CONFIG_SECURITY_APPARMOR_PARANOID_LOAD=y
+# CONFIG_SECURITY_LOADPIN is not set
+CONFIG_SECURITY_YAMA=y
+# CONFIG_SECURITY_SAFESETID is not set
+CONFIG_SECURITY_LOCKDOWN_LSM=y
+CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
+CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y
+# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set
+# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set
+# CONFIG_SECURITY_LANDLOCK is not set
+CONFIG_INTEGRITY=y
+CONFIG_INTEGRITY_SIGNATURE=y
+CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
+CONFIG_INTEGRITY_TRUSTED_KEYRING=y
+CONFIG_INTEGRITY_PLATFORM_KEYRING=y
+# CONFIG_INTEGRITY_MACHINE_KEYRING is not set
+CONFIG_LOAD_UEFI_KEYS=y
+CONFIG_INTEGRITY_AUDIT=y
+CONFIG_IMA=y
+# CONFIG_IMA_KEXEC is not set
+CONFIG_IMA_MEASURE_PCR_IDX=10
+CONFIG_IMA_LSM_RULES=y
+CONFIG_IMA_NG_TEMPLATE=y
+# CONFIG_IMA_SIG_TEMPLATE is not set
+CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng"
+# CONFIG_IMA_DEFAULT_HASH_SHA1 is not set
+CONFIG_IMA_DEFAULT_HASH_SHA256=y
+# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set
+# CONFIG_IMA_DEFAULT_HASH_SM3 is not set
+CONFIG_IMA_DEFAULT_HASH="sha256"
+# CONFIG_IMA_WRITE_POLICY is not set
+CONFIG_IMA_READ_POLICY=y
+CONFIG_IMA_APPRAISE=y
+# CONFIG_IMA_ARCH_POLICY is not set
+# CONFIG_IMA_APPRAISE_BUILD_POLICY is not set
+CONFIG_IMA_APPRAISE_BOOTPARAM=y
+# CONFIG_IMA_APPRAISE_MODSIG is not set
+CONFIG_IMA_TRUSTED_KEYRING=y
+# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set
+# CONFIG_IMA_BLACKLIST_KEYRING is not set
+CONFIG_IMA_LOAD_X509=y
+CONFIG_IMA_X509_PATH="/etc/keys/x509_ima.der"
+# CONFIG_IMA_APPRAISE_SIGNED_INIT is not set
+CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y
+CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y
+# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set
+# CONFIG_IMA_DISABLE_HTABLE is not set
+CONFIG_EVM=y
+CONFIG_EVM_ATTR_FSUUID=y
+# CONFIG_EVM_ADD_XATTRS is not set
+CONFIG_EVM_LOAD_X509=y
+CONFIG_EVM_X509_PATH="/etc/keys/x509_evm.der"
+CONFIG_DEFAULT_SECURITY_SELINUX=y
+# CONFIG_DEFAULT_SECURITY_APPARMOR is not set
+# CONFIG_DEFAULT_SECURITY_DAC is not set
+CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
+
+#
+# Kernel hardening options
+#
+
+#
+# Memory initialization
+#
+CONFIG_INIT_STACK_NONE=y
+# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
+# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
+# end of Memory initialization
+
+CONFIG_RANDSTRUCT_NONE=y
+# end of Kernel hardening options
+# end of Security options
+
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_ASYNC_PQ=m
+CONFIG_ASYNC_RAID6_RECOV=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_FIPS_NAME="Linux Kernel Cryptographic API"
+# CONFIG_CRYPTO_FIPS_CUSTOM_VERSION is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_SKCIPHER=y
+CONFIG_CRYPTO_SKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_AKCIPHER2=y
+CONFIG_CRYPTO_AKCIPHER=y
+CONFIG_CRYPTO_KPP2=y
+CONFIG_CRYPTO_KPP=m
+CONFIG_CRYPTO_ACOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_USER=m
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+# CONFIG_CRYPTO_MANAGER_EXTRA_TESTS is not set
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_NULL2=y
+CONFIG_CRYPTO_PCRYPT=m
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_SIMD=y
+# end of Crypto core or helper
+
+#
+# Public-key cryptography
+#
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_DH=m
+# CONFIG_CRYPTO_DH_RFC7919_GROUPS is not set
+CONFIG_CRYPTO_ECC=m
+CONFIG_CRYPTO_ECDH=m
+# CONFIG_CRYPTO_ECDSA is not set
+# CONFIG_CRYPTO_ECRDSA is not set
+CONFIG_CRYPTO_SM2=y
+# CONFIG_CRYPTO_CURVE25519 is not set
+# end of Public-key cryptography
+
+#
+# Block ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_AES_TI is not set
+CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_ARIA is not set
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_BLOWFISH_COMMON=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST_COMMON=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_SM4=m
+CONFIG_CRYPTO_SM4_GENERIC=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+# end of Block ciphers
+
+#
+# Length-preserving ciphers and modes
+#
+# CONFIG_CRYPTO_ADIANTUM is not set
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_CHACHA20=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CFB=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_HCTR2 is not set
+# CONFIG_CRYPTO_KEYWRAP is not set
+CONFIG_CRYPTO_LRW=m
+# CONFIG_CRYPTO_OFB is not set
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+# end of Length-preserving ciphers and modes
+
+#
+# AEAD (authenticated encryption with associated data) ciphers
+#
+# CONFIG_CRYPTO_AEGIS128 is not set
+CONFIG_CRYPTO_CHACHA20POLY1305=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SEQIV=y
+CONFIG_CRYPTO_ECHAINIV=m
+CONFIG_CRYPTO_ESSIV=m
+# end of AEAD (authenticated encryption with associated data) ciphers
+
+#
+# Hashes, digests, and MACs
+#
+CONFIG_CRYPTO_BLAKE2B=y
+CONFIG_CRYPTO_CMAC=m
+CONFIG_CRYPTO_GHASH=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_POLY1305=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SHA3=m
+CONFIG_CRYPTO_SM3=y
+CONFIG_CRYPTO_SM3_GENERIC=y
+# CONFIG_CRYPTO_STREEBOG is not set
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_XXHASH=y
+# end of Hashes, digests, and MACs
+
+#
+# CRCs (cyclic redundancy checks)
+#
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_CRCT10DIF=y
+CONFIG_CRYPTO_CRC64_ROCKSOFT=m
+# end of CRCs (cyclic redundancy checks)
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_842 is not set
+# CONFIG_CRYPTO_LZ4 is not set
+# CONFIG_CRYPTO_LZ4HC is not set
+CONFIG_CRYPTO_ZSTD=y
+# end of Compression
+
+#
+# Random number generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_HASH=y
+CONFIG_CRYPTO_DRBG_CTR=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+# end of Random number generation
+
+#
+# Userspace interface
+#
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_USER_API_RNG=y
+# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set
+CONFIG_CRYPTO_USER_API_AEAD=y
+CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y
+# CONFIG_CRYPTO_STATS is not set
+# end of Userspace interface
+
+CONFIG_CRYPTO_HASH_INFO=y
+
+#
+# Accelerated Cryptographic Algorithms for CPU (x86)
+#
+# CONFIG_CRYPTO_CURVE25519_X86 is not set
+CONFIG_CRYPTO_AES_NI_INTEL=y
+CONFIG_CRYPTO_BLOWFISH_X86_64=m
+CONFIG_CRYPTO_CAMELLIA_X86_64=m
+CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m
+CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=m
+CONFIG_CRYPTO_CAST5_AVX_X86_64=m
+CONFIG_CRYPTO_CAST6_AVX_X86_64=m
+CONFIG_CRYPTO_DES3_EDE_X86_64=m
+CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m
+CONFIG_CRYPTO_SERPENT_AVX_X86_64=m
+CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m
+CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64=m
+CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64=m
+CONFIG_CRYPTO_TWOFISH_X86_64=m
+CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m
+CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m
+# CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64 is not set
+CONFIG_CRYPTO_CHACHA20_X86_64=m
+# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set
+# CONFIG_CRYPTO_NHPOLY1305_SSE2 is not set
+# CONFIG_CRYPTO_NHPOLY1305_AVX2 is not set
+# CONFIG_CRYPTO_BLAKE2S_X86 is not set
+# CONFIG_CRYPTO_POLYVAL_CLMUL_NI is not set
+CONFIG_CRYPTO_POLY1305_X86_64=m
+CONFIG_CRYPTO_SHA1_SSSE3=y
+CONFIG_CRYPTO_SHA256_SSSE3=y
+CONFIG_CRYPTO_SHA512_SSSE3=m
+CONFIG_CRYPTO_SM3_AVX_X86_64=m
+CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m
+CONFIG_CRYPTO_CRC32C_INTEL=m
+CONFIG_CRYPTO_CRC32_PCLMUL=m
+CONFIG_CRYPTO_CRCT10DIF_PCLMUL=m
+# end of Accelerated Cryptographic Algorithms for CPU (x86)
+
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=m
+CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
+# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
+# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
+CONFIG_CRYPTO_DEV_CCP=y
+CONFIG_CRYPTO_DEV_CCP_DD=m
+CONFIG_CRYPTO_DEV_SP_CCP=y
+CONFIG_CRYPTO_DEV_CCP_CRYPTO=m
+CONFIG_CRYPTO_DEV_SP_PSP=y
+# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set
+CONFIG_CRYPTO_DEV_QAT=m
+CONFIG_CRYPTO_DEV_QAT_DH895xCC=m
+CONFIG_CRYPTO_DEV_QAT_C3XXX=m
+CONFIG_CRYPTO_DEV_QAT_C62X=m
+# CONFIG_CRYPTO_DEV_QAT_4XXX is not set
+CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m
+CONFIG_CRYPTO_DEV_QAT_C3XXXVF=m
+CONFIG_CRYPTO_DEV_QAT_C62XVF=m
+CONFIG_CRYPTO_DEV_NITROX=m
+CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m
+CONFIG_CRYPTO_DEV_CHELSIO=m
+# CONFIG_CRYPTO_DEV_VIRTIO is not set
+# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
+# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set
+CONFIG_ASYMMETRIC_KEY_TYPE=y
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+CONFIG_X509_CERTIFICATE_PARSER=y
+# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set
+CONFIG_PKCS7_MESSAGE_PARSER=y
+# CONFIG_PKCS7_TEST_KEY is not set
+CONFIG_SIGNED_PE_FILE_VERIFICATION=y
+# CONFIG_FIPS_SIGNATURE_SELFTEST is not set
+
+#
+# Certificates for signature checking
+#
+CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
+CONFIG_MODULE_SIG_KEY_TYPE_RSA=y
+# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set
+CONFIG_SYSTEM_TRUSTED_KEYRING=y
+CONFIG_SYSTEM_TRUSTED_KEYS=""
+# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set
+CONFIG_SECONDARY_TRUSTED_KEYRING=y
+CONFIG_SYSTEM_BLACKLIST_KEYRING=y
+CONFIG_SYSTEM_BLACKLIST_HASH_LIST=""
+CONFIG_SYSTEM_REVOCATION_LIST=y
+CONFIG_SYSTEM_REVOCATION_KEYS=""
+# CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE is not set
+# end of Certificates for signature checking
+
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_RAID6_PQ=m
+CONFIG_RAID6_PQ_BENCHMARK=y
+# CONFIG_PACKING is not set
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_CORDIC=m
+# CONFIG_PRIME_NUMBERS is not set
+CONFIG_RATIONAL=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
+CONFIG_ARCH_USE_SYM_ANNOTATIONS=y
+
+#
+# Crypto library routines
+#
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LIB_AES=y
+CONFIG_CRYPTO_LIB_ARC4=m
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m
+CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m
+# CONFIG_CRYPTO_LIB_CHACHA is not set
+# CONFIG_CRYPTO_LIB_CURVE25519 is not set
+CONFIG_CRYPTO_LIB_DES=m
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11
+CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m
+CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m
+# CONFIG_CRYPTO_LIB_POLY1305 is not set
+# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+# end of Crypto library routines
+
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC64_ROCKSOFT=m
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+CONFIG_CRC64=m
+# CONFIG_CRC4 is not set
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_CRC8=m
+CONFIG_XXHASH=y
+# CONFIG_RANDOM32_SELFTEST is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+# CONFIG_XZ_DEC_MICROLZMA is not set
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_DECOMPRESS_LZ4=y
+CONFIG_DECOMPRESS_ZSTD=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_ENC8=y
+CONFIG_REED_SOLOMON_DEC8=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_BTREE=y
+CONFIG_INTERVAL_TREE=y
+CONFIG_XARRAY_MULTI=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAS_DMA=y
+CONFIG_DMA_OPS=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED=y
+CONFIG_SWIOTLB=y
+CONFIG_DMA_COHERENT_POOL=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_DMA_MAP_BENCHMARK is not set
+CONFIG_SGL_ALLOC=y
+CONFIG_CHECK_SIGNATURE=y
+CONFIG_CPUMASK_OFFSTACK=y
+# CONFIG_FORCE_NR_CPUS is not set
+CONFIG_CPU_RMAP=y
+CONFIG_DQL=y
+CONFIG_GLOB=y
+# CONFIG_GLOB_SELFTEST is not set
+CONFIG_NLATTR=y
+CONFIG_CLZ_TAB=y
+CONFIG_IRQ_POLL=y
+CONFIG_MPILIB=y
+CONFIG_SIGNATURE=y
+CONFIG_DIMLIB=y
+CONFIG_OID_REGISTRY=y
+CONFIG_UCS2_STRING=y
+CONFIG_HAVE_GENERIC_VDSO=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_VDSO_TIME_NS=y
+CONFIG_FONT_SUPPORT=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_SG_POOL=y
+CONFIG_ARCH_HAS_PMEM_API=y
+CONFIG_MEMREGION=y
+CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y
+CONFIG_ARCH_HAS_COPY_MC=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_STACKDEPOT=y
+CONFIG_SBITMAP=y
+CONFIG_PARMAN=m
+CONFIG_OBJAGG=m
+# end of Library routines
+
+CONFIG_PLDMFW=y
+CONFIG_ASN1_ENCODER=y
+
+#
+# Kernel hacking
+#
+
+#
+# printk and dmesg options
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_CALLER=y
+# CONFIG_STACKTRACE_BUILD_ID is not set
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
+CONFIG_CONSOLE_LOGLEVEL_QUIET=4
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
+CONFIG_BOOT_PRINTK_DELAY=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DYNAMIC_DEBUG_CORE=y
+CONFIG_SYMBOLIC_ERRNAME=y
+CONFIG_DEBUG_BUGVERBOSE=y
+# end of printk and dmesg options
+
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MISC=y
+
+#
+# Compile-time checks and compiler options
+#
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_NONE is not set
+# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
+CONFIG_DEBUG_INFO_DWARF4=y
+# CONFIG_DEBUG_INFO_DWARF5 is not set
+# CONFIG_DEBUG_INFO_REDUCED is not set
+# CONFIG_DEBUG_INFO_COMPRESSED is not set
+# CONFIG_DEBUG_INFO_SPLIT is not set
+CONFIG_DEBUG_INFO_BTF=y
+# CONFIG_GDB_SCRIPTS is not set
+CONFIG_FRAME_WARN=2048
+CONFIG_STRIP_ASM_SYMS=y
+# CONFIG_READABLE_ASM is not set
+# CONFIG_HEADERS_INSTALL is not set
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
+CONFIG_OBJTOOL=y
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# end of Compile-time checks and compiler options
+
+#
+# Generic Kernel Debugging Instruments
+#
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
+CONFIG_MAGIC_SYSRQ_SERIAL=y
+CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_FS_ALLOW_ALL=y
+# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set
+# CONFIG_DEBUG_FS_ALLOW_NONE is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_KGDB=y
+CONFIG_KGDB_HONOUR_BLOCKLIST=y
+CONFIG_KGDB_SERIAL_CONSOLE=y
+CONFIG_KGDB_TESTS=y
+# CONFIG_KGDB_TESTS_ON_BOOT is not set
+CONFIG_KGDB_LOW_LEVEL_TRAP=y
+CONFIG_KGDB_KDB=y
+CONFIG_KDB_DEFAULT_ENABLE=0x0
+CONFIG_KDB_KEYBOARD=y
+CONFIG_KDB_CONTINUE_CATASTROPHIC=0
+CONFIG_ARCH_HAS_EARLY_DEBUG=y
+CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
+# CONFIG_UBSAN is not set
+CONFIG_HAVE_ARCH_KCSAN=y
+# end of Generic Kernel Debugging Instruments
+
+#
+# Networking Debugging
+#
+# CONFIG_NET_DEV_REFCNT_TRACKER is not set
+# CONFIG_NET_NS_REFCNT_TRACKER is not set
+# CONFIG_DEBUG_NET is not set
+# end of Networking Debugging
+
+#
+# Memory Debugging
+#
+# CONFIG_PAGE_EXTENSION is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_PAGE_OWNER is not set
+# CONFIG_PAGE_TABLE_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+# CONFIG_DEBUG_PAGE_REF is not set
+# CONFIG_DEBUG_RODATA_TEST is not set
+CONFIG_ARCH_HAS_DEBUG_WX=y
+# CONFIG_DEBUG_WX is not set
+CONFIG_GENERIC_PTDUMP=y
+# CONFIG_PTDUMP_DEBUGFS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SHRINKER_DEBUG is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_SCHED_STACK_END_CHECK is not set
+CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VM_PGTABLE is not set
+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
+# CONFIG_DEBUG_VIRTUAL is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+CONFIG_HAVE_ARCH_KASAN=y
+CONFIG_HAVE_ARCH_KASAN_VMALLOC=y
+# CONFIG_KASAN is not set
+CONFIG_HAVE_ARCH_KFENCE=y
+# CONFIG_KFENCE is not set
+CONFIG_HAVE_ARCH_KMSAN=y
+# end of Memory Debugging
+
+CONFIG_DEBUG_SHIRQ=y
+
+#
+# Debug Oops, Lockups and Hangs
+#
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_PANIC_ON_OOPS_VALUE=1
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_HARDLOCKUP_DETECTOR_PERF=y
+CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y
+CONFIG_HARDLOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+# CONFIG_WQ_WATCHDOG is not set
+# CONFIG_TEST_LOCKUP is not set
+# end of Debug Oops, Lockups and Hangs
+
+#
+# Scheduler Debugging
+#
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHED_INFO=y
+CONFIG_SCHEDSTATS=y
+# end of Scheduler Debugging
+
+# CONFIG_DEBUG_TIMEKEEPING is not set
+CONFIG_DEBUG_PREEMPT=y
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_LOCK_TORTURE_TEST is not set
+# CONFIG_WW_MUTEX_SELFTEST is not set
+# CONFIG_SCF_TORTURE_TEST is not set
+# CONFIG_CSD_LOCK_WAIT_DEBUG is not set
+# end of Lock Debugging (spinlocks, mutexes, etc...)
+
+# CONFIG_DEBUG_IRQFLAGS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
+# CONFIG_DEBUG_KOBJECT is not set
+
+#
+# Debug kernel data structures
+#
+CONFIG_DEBUG_LIST=y
+# CONFIG_DEBUG_PLIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BUG_ON_DATA_CORRUPTION is not set
+# CONFIG_DEBUG_MAPLE_TREE is not set
+# end of Debug kernel data structures
+
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_RCU_SCALE_TEST is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_REF_SCALE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0
+# CONFIG_RCU_TRACE is not set
+# CONFIG_RCU_EQS_DEBUG is not set
+# end of RCU Debugging
+
+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_RETHOOK=y
+CONFIG_RETHOOK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y
+CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_FENTRY=y
+CONFIG_HAVE_OBJTOOL_MCOUNT=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y
+CONFIG_BUILDTIME_MCOUNT_SORT=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_TRACE_CLOCK=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+CONFIG_BOOTTIME_TRACING=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_FUNCTION_GRAPH_TRACER=y
+CONFIG_DYNAMIC_FTRACE=y
+CONFIG_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
+CONFIG_DYNAMIC_FTRACE_WITH_ARGS=y
+# CONFIG_FPROBE is not set
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_STACK_TRACER=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+CONFIG_SCHED_TRACER=y
+CONFIG_HWLAT_TRACER=y
+CONFIG_OSNOISE_TRACER=y
+CONFIG_TIMERLAT_TRACER=y
+# CONFIG_MMIOTRACE is not set
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_TRACER_SNAPSHOT=y
+# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_KPROBE_EVENTS=y
+# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set
+CONFIG_UPROBE_EVENTS=y
+CONFIG_BPF_EVENTS=y
+CONFIG_DYNAMIC_EVENTS=y
+CONFIG_PROBE_EVENTS=y
+# CONFIG_BPF_KPROBE_OVERRIDE is not set
+CONFIG_FTRACE_MCOUNT_RECORD=y
+CONFIG_FTRACE_MCOUNT_USE_CC=y
+CONFIG_TRACING_MAP=y
+CONFIG_SYNTH_EVENTS=y
+CONFIG_HIST_TRIGGERS=y
+# CONFIG_TRACE_EVENT_INJECT is not set
+# CONFIG_TRACEPOINT_BENCHMARK is not set
+CONFIG_RING_BUFFER_BENCHMARK=m
+# CONFIG_TRACE_EVAL_MAP_FILE is not set
+# CONFIG_FTRACE_RECORD_RECURSION is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_FTRACE_SORT_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set
+# CONFIG_PREEMPTIRQ_DELAY_TEST is not set
+# CONFIG_SYNTH_EVENT_GEN_TEST is not set
+# CONFIG_KPROBE_EVENT_GEN_TEST is not set
+# CONFIG_HIST_TRIGGERS_DEBUG is not set
+# CONFIG_RV is not set
+CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y
+CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y
+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
+CONFIG_STRICT_DEVMEM=y
+# CONFIG_IO_STRICT_DEVMEM is not set
+
+#
+# x86 Debugging
+#
+CONFIG_EARLY_PRINTK_USB=y
+# CONFIG_X86_VERBOSE_BOOTUP is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_EARLY_PRINTK_DBGP=y
+CONFIG_EARLY_PRINTK_USB_XDBC=y
+# CONFIG_EFI_PGT_DUMP is not set
+# CONFIG_DEBUG_TLBFLUSH is not set
+CONFIG_HAVE_MMIOTRACE_SUPPORT=y
+CONFIG_X86_DECODER_SELFTEST=y
+CONFIG_IO_DELAY_0X80=y
+# CONFIG_IO_DELAY_0XED is not set
+# CONFIG_IO_DELAY_UDELAY is not set
+# CONFIG_IO_DELAY_NONE is not set
+CONFIG_DEBUG_BOOT_PARAMS=y
+# CONFIG_CPA_DEBUG is not set
+# CONFIG_DEBUG_ENTRY is not set
+# CONFIG_DEBUG_NMI_SELFTEST is not set
+# CONFIG_X86_DEBUG_FPU is not set
+# CONFIG_PUNIT_ATOM_DEBUG is not set
+CONFIG_UNWINDER_ORC=y
+# CONFIG_UNWINDER_FRAME_POINTER is not set
+# end of x86 Debugging
+
+#
+# Kernel Testing and Coverage
+#
+# CONFIG_KUNIT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+CONFIG_FUNCTION_ERROR_INJECTION=y
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_ARCH_HAS_KCOV=y
+# CONFIG_KCOV is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_ARCH_USE_MEMTEST=y
+# CONFIG_MEMTEST is not set
+# CONFIG_HYPERV_TESTING is not set
+# end of Kernel Testing and Coverage
+
+#
+# Rust hacking
+#
+# end of Rust hacking
+# end of Kernel hacking
--
2.20.1
1
0
Prepare initial configs for devel-6.1 branch.
Liu Chao (1):
kconfig: Add script to update openeuler_defconfig
Xie XiuQi (2):
config: add initial openeuler_defconfig for arm64
config: add initial openeuler_defconfig for x86_64
arch/arm64/configs/openeuler_defconfig | 7732 ++++++++++++++++++++
arch/x86/configs/openeuler_defconfig | 8938 ++++++++++++++++++++++++
scripts/kconfig/Makefile | 10 +
scripts/kconfig/makeconfig.sh | 24 +
4 files changed, 16704 insertions(+)
create mode 100644 arch/arm64/configs/openeuler_defconfig
create mode 100644 arch/x86/configs/openeuler_defconfig
create mode 100644 scripts/kconfig/makeconfig.sh
--
2.20.1
1
3

[PATCH openEuler-5.10 01/45] block: fix crash on cmpxchg for request_wrapper
by Zheng Zengkai 04 Jan '23
by Zheng Zengkai 04 Jan '23
04 Jan '23
From: Yu Kuai <yukuai3(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I65K8D
CVE: NA
--------------------------------
Now that address of request_wrapper is caculated by address of request
plus cmd_size, if cmd_size is not aligned to 8 bytes, request_wrapper
will end up not aligned to 8 bytes as well, which will crash in arm64
because assembly instruction casal requires that operand address is
aligned to 8 bytes:
Internal error: Oops: 96000021 [#1] SMP
pc : blk_account_io_latency+0x54/0x134
Call trace:
blk_account_io_latency+0x54/0x134
blk_account_io_done+0x3c/0x4c
__blk_mq_end_request+0x78/0x134
scsi_end_request+0xcc/0x1f0
scsi_io_completion+0x88/0x240
scsi_finish_command+0x104/0x140
scsi_softirq_done+0x90/0x180
blk_mq_complete_request+0x5c/0x70
scsi_mq_done+0x4c/0x100
Fix the problem by declaring request_wrapper as aligned to cachline, and
placing it before request.
Fixes: 82327165da5c ("blk-mq: don't access request_wrapper if request is not allocated from block layer")
Signed-off-by: Yu Kuai <yukuai3(a)huawei.com>
Reviewed-by: Hou Tao <houtao1(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
block/blk-flush.c | 8 +++++---
block/blk-mq.c | 2 +-
block/blk-mq.h | 9 +++------
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 65753f781c20..093c581a2651 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -470,6 +470,7 @@ struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size,
gfp_t flags)
{
struct blk_flush_queue *fq;
+ struct request_wrapper *wrapper;
int rq_sz = sizeof(struct request) + sizeof(struct request_wrapper);
fq = kzalloc_node(sizeof(*fq), flags, node);
@@ -479,10 +480,11 @@ struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size,
spin_lock_init(&fq->mq_flush_lock);
rq_sz = round_up(rq_sz + cmd_size, cache_line_size());
- fq->flush_rq = kzalloc_node(rq_sz, flags, node);
- if (!fq->flush_rq)
+ wrapper = kzalloc_node(rq_sz, flags, node);
+ if (!wrapper)
goto fail_rq;
+ fq->flush_rq = (struct request *)(wrapper + 1);
INIT_LIST_HEAD(&fq->flush_queue[0]);
INIT_LIST_HEAD(&fq->flush_queue[1]);
INIT_LIST_HEAD(&fq->flush_data_in_flight);
@@ -501,7 +503,7 @@ void blk_free_flush_queue(struct blk_flush_queue *fq)
if (!fq)
return;
- kfree(fq->flush_rq);
+ kfree(request_to_wrapper(fq->flush_rq));
kfree(fq);
}
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1c4a4e197e65..ffabe9c3de31 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2642,7 +2642,7 @@ static int blk_mq_alloc_rqs(struct blk_mq_tag_set *set,
to_do = min(entries_per_page, depth - i);
left -= to_do * rq_size;
for (j = 0; j < to_do; j++) {
- struct request *rq = p;
+ struct request *rq = p + sizeof(struct request_wrapper);
tags->static_rqs[i] = rq;
if (blk_mq_init_request(set, rq, hctx_idx, node)) {
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 6254abe9c112..dcb2077e4db6 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -40,14 +40,11 @@ struct blk_mq_ctx {
struct request_wrapper {
/* Time that I/O was counted in part_get_stat_info(). */
u64 stat_time_ns;
-};
+} ____cacheline_aligned_in_smp;
-static inline struct request_wrapper *request_to_wrapper(struct request *rq)
+static inline struct request_wrapper *request_to_wrapper(void *rq)
{
- unsigned long addr = (unsigned long)rq;
-
- addr += sizeof(*rq) + rq->q->tag_set->cmd_size;
- return (struct request_wrapper *)addr;
+ return rq - sizeof(struct request_wrapper);
}
void blk_mq_exit_queue(struct request_queue *q);
--
2.20.1
1
44

[PATCH openEuler-5.10 01/31] drm/amdkfd: Check for null pointer after calling kmemdup
by Zheng Zengkai 04 Jan '23
by Zheng Zengkai 04 Jan '23
04 Jan '23
From: Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
stable inclusion
from stable-v6.0.14
commit abfaf0eee97925905e742aa3b0b72e04a918fa9e
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6694U
CVE: CVE-2022-3108
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
As the possible failure of the allocation, kmemdup() may return NULL
pointer.
Therefore, it should be better to check the 'props2' in order to prevent
the dereference of NULL pointer.
Fixes: 3a87177eb141 ("drm/amdkfd: Add topology support for dGPUs")
Signed-off-by: Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
Reviewed-by: Felix Kuehling <Felix.Kuehling(a)amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling(a)amd.com>
Signed-off-by: Alex Deucher <alexander.deucher(a)amd.com>
Signed-off-by: Ren Zhijie <renzhijie2(a)huawei.com>
Reviewed-by: songping yu <yusongping(a)huawei.com>
Reviewed-by: Chen Hui <judy.chenhui(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
index 86b4dadf772e..02e3c650ed1c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
@@ -408,6 +408,9 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink,
return -ENODEV;
/* same everything but the other direction */
props2 = kmemdup(props, sizeof(*props2), GFP_KERNEL);
+ if (!props2)
+ return -ENOMEM;
+
props2->node_from = id_to;
props2->node_to = id_from;
props2->kobj = NULL;
--
2.20.1
1
30

[PATCH openEuler-5.10-LTS 01/30] Bluetooth: L2CAP: Fix build errors in some archs
by Zheng Zengkai 04 Jan '23
by Zheng Zengkai 04 Jan '23
04 Jan '23
From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
stable inclusion
from stable-v5.10.141
commit 38267d266336a7fb9eae9be23567a44776c6e4ca
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I64WCC
CVE: CVE-2022-20566
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
-------------------------------
commit b840304fb46cdf7012722f456bce06f151b3e81b upstream.
This attempts to fix the follow errors:
In function 'memcmp',
inlined from 'bacmp' at ./include/net/bluetooth/bluetooth.h:347:9,
inlined from 'l2cap_global_chan_by_psm' at
net/bluetooth/l2cap_core.c:2003:15:
./include/linux/fortify-string.h:44:33: error: '__builtin_memcmp'
specified bound 6 exceeds source size 0 [-Werror=stringop-overread]
44 | #define __underlying_memcmp __builtin_memcmp
| ^
./include/linux/fortify-string.h:420:16: note: in expansion of macro
'__underlying_memcmp'
420 | return __underlying_memcmp(p, q, size);
| ^~~~~~~~~~~~~~~~~~~
In function 'memcmp',
inlined from 'bacmp' at ./include/net/bluetooth/bluetooth.h:347:9,
inlined from 'l2cap_global_chan_by_psm' at
net/bluetooth/l2cap_core.c:2004:15:
./include/linux/fortify-string.h:44:33: error: '__builtin_memcmp'
specified bound 6 exceeds source size 0 [-Werror=stringop-overread]
44 | #define __underlying_memcmp __builtin_memcmp
| ^
./include/linux/fortify-string.h:420:16: note: in expansion of macro
'__underlying_memcmp'
420 | return __underlying_memcmp(p, q, size);
| ^~~~~~~~~~~~~~~~~~~
Fixes: 332f1795ca20 ("Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm regression")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
Cc: Sudip Mukherjee <sudipm.mukherjee(a)gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Lu Jialin <lujialin4(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
net/bluetooth/l2cap_core.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 70bfd9e8913e..f78ad8f536f7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1988,11 +1988,11 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
src_match = !bacmp(&c->src, src);
dst_match = !bacmp(&c->dst, dst);
if (src_match && dst_match) {
- c = l2cap_chan_hold_unless_zero(c);
- if (c) {
- read_unlock(&chan_list_lock);
- return c;
- }
+ if (!l2cap_chan_hold_unless_zero(c))
+ continue;
+
+ read_unlock(&chan_list_lock);
+ return c;
}
/* Closest match */
--
2.20.1
1
29

30 Dec '22
From: Zhou Guanghui <zhouguanghui1(a)huawei.com>
ascend inclusion
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I67NC1
CVE: NA
------------------------------------------
Charge Buddy hugepage to memcg when kmemcg is disabled. If kmemcg
is enabled, we can alse use kmemcg to charge buddy hugepages.
Signed-off-by: Zhou Guanghui <zhouguanghui1(a)huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
include/linux/share_pool.h | 30 ++++++++++++++++++++++++++++++
mm/hugetlb.c | 3 +++
mm/share_pool.c | 28 +++++++++++++++++++++++-----
3 files changed, 56 insertions(+), 5 deletions(-)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h
index c58f0dce0b20..2ebfb3d5be13 100644
--- a/include/linux/share_pool.h
+++ b/include/linux/share_pool.h
@@ -8,6 +8,8 @@
#include <linux/printk.h>
#include <linux/hashtable.h>
#include <linux/numa.h>
+#include <linux/hugetlb.h>
+#include <linux/memcontrol.h>
#define SP_HUGEPAGE (1 << 0)
#define SP_HUGEPAGE_ONLY (1 << 1)
@@ -411,6 +413,26 @@ extern bool sp_check_mmap_addr(unsigned long addr, unsigned long flags);
extern int sp_id_of_current(void);
extern int mg_sp_id_of_current(void);
+
+static inline void sp_kmemcg_uncharge_hpage(struct page *page)
+{
+ if (!sp_is_enabled())
+ return;
+
+ if (memcg_kmem_enabled() && PageKmemcg(page)) {
+ int order = huge_page_order(page_hstate(page));
+
+ __memcg_kmem_uncharge(page, order);
+ }
+}
+
+static inline void sp_memcg_uncharge_hpage(struct page *page)
+{
+ if (!sp_is_enabled())
+ return;
+
+ mem_cgroup_uncharge(page);
+}
#else
static inline int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)
@@ -684,6 +706,14 @@ static inline int mg_sp_id_of_current(void)
return -EPERM;
}
+static inline void sp_kmemcg_uncharge_hpage(struct page *page)
+{
+}
+
+static inline void sp_memcg_uncharge_hpage(struct page *page)
+{
+}
+
#endif
#endif /* LINUX_SHARE_POOL_H */
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index fb1f90eed7fc..495d8b5b38fc 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -38,6 +38,7 @@
#include <linux/node.h>
#include <linux/userfaultfd_k.h>
#include <linux/page_owner.h>
+#include <linux/share_pool.h>
#include "internal.h"
int hugetlb_max_hstate __read_mostly;
@@ -1311,6 +1312,7 @@ void free_huge_page(struct page *page)
(struct hugepage_subpool *)page_private(page);
bool restore_reserve;
+ sp_kmemcg_uncharge_hpage(page);
set_page_private(page, 0);
page->mapping = NULL;
VM_BUG_ON_PAGE(page_count(page), page);
@@ -1345,6 +1347,7 @@ void free_huge_page(struct page *page)
h->resv_huge_pages++;
if (PageHugeTemporary(page)) {
+ sp_memcg_uncharge_hpage(page);
list_del(&page->lru);
ClearPageHugeTemporary(page);
update_and_free_page(h, page);
diff --git a/mm/share_pool.c b/mm/share_pool.c
index d2591c73a503..5d8344fe805a 100644
--- a/mm/share_pool.c
+++ b/mm/share_pool.c
@@ -4555,6 +4555,8 @@ vm_fault_t sharepool_no_page(struct mm_struct *mm,
int err;
int node_id;
struct sp_area *spa;
+ bool charge_hpage = false;
+ struct mem_cgroup *memcg;
spa = vma->vm_private_data;
if (!spa) {
@@ -4572,10 +4574,11 @@ vm_fault_t sharepool_no_page(struct mm_struct *mm,
page = alloc_huge_page(vma, haddr, 0);
if (IS_ERR(page)) {
- page = alloc_huge_page_node(hstate_file(vma->vm_file),
- node_id);
+ page = hugetlb_alloc_hugepage(node_id, HUGETLB_ALLOC_BUDDY);
if (!page)
page = ERR_PTR(-ENOMEM);
+ else if (!PageKmemcg(page))
+ charge_hpage = true;
}
if (IS_ERR(page)) {
ptl = huge_pte_lock(h, mm, ptep);
@@ -4588,12 +4591,24 @@ vm_fault_t sharepool_no_page(struct mm_struct *mm,
ret = vmf_error(PTR_ERR(page));
goto out;
}
+
+ if (charge_hpage &&
+ mem_cgroup_try_charge_delay(page, vma->vm_mm, GFP_KERNEL, &memcg, true)) {
+ put_page(page);
+ ret = vmf_error(-ENOMEM);
+ goto out;
+ }
+
__SetPageUptodate(page);
new_page = true;
/* sharepool pages are all shared */
err = huge_add_to_page_cache(page, mapping, idx);
if (err) {
+ if (charge_hpage) {
+ mem_cgroup_cancel_charge(page, memcg, true);
+ charge_hpage = false;
+ }
put_page(page);
if (err == -EEXIST)
goto retry;
@@ -4601,7 +4616,6 @@ vm_fault_t sharepool_no_page(struct mm_struct *mm,
}
}
-
ptl = huge_pte_lock(h, mm, ptep);
size = i_size_read(mapping->host) >> huge_page_shift(h);
if (idx >= size)
@@ -4618,11 +4632,13 @@ vm_fault_t sharepool_no_page(struct mm_struct *mm,
hugetlb_count_add(pages_per_huge_page(h), mm);
+ if (charge_hpage)
+ mem_cgroup_commit_charge(page, memcg, false, true);
+
spin_unlock(ptl);
- if (new_page) {
+ if (new_page)
SetPagePrivate(&page[1]);
- }
unlock_page(page);
out:
@@ -4631,6 +4647,8 @@ vm_fault_t sharepool_no_page(struct mm_struct *mm,
backout:
spin_unlock(ptl);
unlock_page(page);
+ if (charge_hpage)
+ mem_cgroup_cancel_charge(page, memcg, true);
put_page(page);
goto out;
}
--
2.25.1
1
0
您好!
Kernel SIG 邀请您参加 2022-12-30 14:00 召开的Zoom会议(自动录制)
会议主题:openEuler Kernel SIG双周例会
会议内容:
1. 进展update
2. 议题征集中
欢迎大家积极申报议题(新增议题可以回复邮件反馈,或者录入会议看板)
会议链接:https://us06web.zoom.us/j/84061666239?pwd=ZGNrZUo0RW5DWWhOQTRaVW53Y0gyUT09
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
温馨提醒:建议接入会议后修改参会人的姓名,也可以使用您在gitee.com的ID
更多资讯尽在:https://openeuler.org/zh/
Hello!
openEuler Kernel SIG invites you to attend the Zoom conference(auto recording) will be held at 2022-12-30 14:00,
The subject of the conference is openEuler Kernel SIG双周例会,
Summary:
1. 进展update
2. 议题征集中
欢迎大家积极申报议题(新增议题可以回复邮件反馈,或者录入会议看板)
You can join the meeting at https://us06web.zoom.us/j/84061666239?pwd=ZGNrZUo0RW5DWWhOQTRaVW53Y0gyUT09.
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings.
Note: You are advised to change the participant name after joining the conference or use your ID at gitee.com.
More information: https://openeuler.org/en/
2
1

30 Dec '22
3SNIC inclusion
category: features
bugzilla: https://gitee.com/openeuler/kernel/issues/I64M90
CVE: NA
v1->v2:
1. Update openEuler/MAINTAINERS
This commit is to suppport 3SNIC 3S5XX RAID/HBA controllers.
RAID controllers support RAID 0/1/5/6/10/50/60 modes;
HBA controlllers support RAID 0/1/10 modes.
RAID/HBA support SAS/SATA HDD/SSD.
Signed-off-by: liangry <liangry1(a)3snic.com>
Reviewed-by: Jiang Yu<yujiang(a)3snic.com>
Reviewed-by: Steven Song <steven.song(a)3snic.com>
---
Documentation/scsi/sssraid.rst | 83 +
MAINTAINERS | 7 +
arch/arm64/configs/openeuler_defconfig | 1 +
arch/x86/configs/openeuler_defconfig | 1 +
drivers/scsi/Kconfig | 1 +
drivers/scsi/Makefile | 1 +
drivers/scsi/sssraid/Kconfig | 14 +
drivers/scsi/sssraid/Makefile | 7 +
drivers/scsi/sssraid/sssraid.h | 971 ++++++++++
drivers/scsi/sssraid/sssraid_debug.h | 34 +
drivers/scsi/sssraid/sssraid_fw.c | 1724 +++++++++++++++++
drivers/scsi/sssraid/sssraid_os.c | 2337 ++++++++++++++++++++++++
openEuler/MAINTAINERS | 6 +
13 files changed, 5187 insertions(+)
create mode 100644 Documentation/scsi/sssraid.rst
create mode 100644 drivers/scsi/sssraid/Kconfig
create mode 100644 drivers/scsi/sssraid/Makefile
create mode 100644 drivers/scsi/sssraid/sssraid.h
create mode 100644 drivers/scsi/sssraid/sssraid_debug.h
create mode 100644 drivers/scsi/sssraid/sssraid_fw.c
create mode 100644 drivers/scsi/sssraid/sssraid_os.c
diff --git a/Documentation/scsi/sssraid.rst b/Documentation/scsi/sssraid.rst
new file mode 100644
index 000000000000..d56e5f7c478c
--- /dev/null
+++ b/Documentation/scsi/sssraid.rst
@@ -0,0 +1,83 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==============================================
+SSSRAID - 3SNIC SCSI RAID Controller driver
+==============================================
+
+This file describes the SSSRAID SCSI driver for 3SNIC
+(http://www.3snic.com) RAID controllers. The SSSRAID
+driver is the first generation RAID driver for 3SNIC Corp.
+
+For 3SNIC SSSRAID controller support, enable the SSSRAID driver
+when configuring the kernel.
+
+SSSRAID specific entries in /sys
+=================================
+
+SSSRAID host attributes
+------------------------
+ - /sys/class/scsi_host/host*/csts_pp
+ - /sys/class/scsi_host/host*/csts_shst
+ - /sys/class/scsi_host/host*/csts_cfs
+ - /sys/class/scsi_host/host*/csts_rdy
+ - /sys/class/scsi_host/host*/fw_version
+
+ The host csts_pp attribute is a read only attribute. This attribute
+ indicates whether the controller is processing commands. If this attribute
+ is set to ‘1’, then the controller is processing commands normally. If
+ this attribute is cleared to ‘0’, then the controller has temporarily stopped
+ processing commands in order to handle an event (e.g., firmware activation).
+
+ The host csts_shst attribute is a read only attribute. This attribute
+ indicates status of shutdown processing.The shutdown status values are defined
+ as:
+ ====== ==============================
+ Value Definition
+ ====== ==============================
+ 00b Normal operation
+ 01b Shutdown processing occurring
+ 10b Shutdown processing complete
+ 11b Reserved
+ ====== ==============================
+ The host csts_cfs attribute is a read only attribute. This attribute is set to
+ ’1’ when a fatal controller error occurred that could not be communicated in the
+ appropriate Completion Queue. This bit is cleared to ‘0’ when a fatal controller
+ error has not occurred.
+
+ The host csts_rdy attribute is a read only attribute. This attribute is set to
+ ‘1’ when the controller is ready to process submission queue entries.
+
+ The fw_version attribute is read-only and will return the driver version and the
+ controller firmware version.
+
+SSSRAID scsi device attributes
+------------------------------
+ - /sys/class/scsi_device/X\:X\:X\:X/device/raid_level
+ - /sys/class/scsi_device/X\:X\:X\:X/device/raid_state
+ - /sys/class/scsi_device/X\:X\:X\:X/device/raid_resync
+
+ The device raid_level attribute is a read only attribute. This attribute indicates
+ RAID level of scsi device(will dispaly "NA" if scsi device is not virtual disk type).
+
+ The device raid_state attribute is read-only and indicates RAID status of scsi
+ device(will dispaly "NA" if scsi device is not virtual disk type).
+
+ The device raid_resync attribute is read-only and indicates RAID rebuild processing
+ of scsi device(will dispaly "NA" if scsi device is not virtual disk type).
+
+Supported devices
+=================
+
+ =================== ======= =======================================
+ PCI ID (pci.ids) OEM Product
+ =================== ======= =======================================
+ 1F3F:2100 3SNIC 3S510(HBA:8Ports,1G DDR)
+ 1F3F:2100 3SNIC 3S520(HBA:16Ports,1G DDR)
+ 1F3F:2100 3SNIC 3S530(HBA:32Ports,1G DDR)
+ 1F3F:2100 3SNIC 3S540(HBA:40Ports,1G DDR)
+ 1F3F:2200 3SNIC 3S580(RAID:16Ports,2G cache)
+ 1F3F:2200 3SNIC 3S585(RAID:16Ports,4G cache)
+ 1F3F:2200 3SNIC 3S590(RAID:32Ports,4G cache)
+ 1F3F:2200 3SNIC 3S5A0(RAID:40Ports,2G cache)
+ 1F3F:2200 3SNIC 3S5A5(RAID:40Ports,4G cache)
+ =================== ======= =======================================
diff --git a/MAINTAINERS b/MAINTAINERS
index 9ae209633628..e6470640f764 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16669,6 +16669,13 @@ M: Jan-Benedict Glaw <jbglaw(a)lug-owl.de>
S: Maintained
F: arch/alpha/kernel/srm_env.c
+SSSRAID SCSI/Raid DRIVERS
+M: Steven Song <steven.song(a)3snic.com>
+L: linux-scsi(a)vger.kernel.org
+S: Maintained
+F: Documentation/scsi/sssraid.rst
+F: drivers/scsi/sssraid/
+
ST LSM6DSx IMU IIO DRIVER
M: Lorenzo Bianconi <lorenzo.bianconi83(a)gmail.com>
L: linux-iio(a)vger.kernel.org
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index 30384eacad4f..dc4ba0d2b694 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -2394,6 +2394,7 @@ CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_3SNIC_SSSRAID=m
CONFIG_SCSI_MPT3SAS=m
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
CONFIG_SCSI_MPT3SAS_MAX_SGE=128
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index 5ada612f1d75..df16f123515b 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -2355,6 +2355,7 @@ CONFIG_SCSI_AACRAID=m
# CONFIG_MEGARAID_LEGACY is not set
CONFIG_MEGARAID_SAS=m
CONFIG_SCSI_MPT3SAS=m
+CONFIG_SCSI_3SNIC_SSSRAID=m
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
CONFIG_SCSI_MPT3SAS_MAX_SGE=128
CONFIG_SCSI_MPT2SAS=m
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 0fbe4edeccd0..7339d6179e5a 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -481,6 +481,7 @@ config SCSI_ARCMSR
source "drivers/scsi/esas2r/Kconfig"
source "drivers/scsi/megaraid/Kconfig.megaraid"
+source "drivers/scsi/sssraid/Kconfig"
source "drivers/scsi/mpt3sas/Kconfig"
source "drivers/scsi/smartpqi/Kconfig"
source "drivers/scsi/ufs/Kconfig"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 78a3c832394c..01bb908fb832 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor/
obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
obj-$(CONFIG_SCSI_HPSA) += hpsa.o
obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi/
+obj-$(CONFIG_SCSI_3SNIC_SSSRAID) += sssraid/
obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/
obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o
obj-$(CONFIG_SCSI_DC395x) += dc395x.o
diff --git a/drivers/scsi/sssraid/Kconfig b/drivers/scsi/sssraid/Kconfig
new file mode 100644
index 000000000000..769f68732bf3
--- /dev/null
+++ b/drivers/scsi/sssraid/Kconfig
@@ -0,0 +1,14 @@
+#
+# Kernel configuration file for the 3SNIC
+#
+
+config SCSI_3SNIC_SSSRAID
+ tristate "3SNIC sssraid Adapter"
+ depends on PCI && SCSI
+ select BLK_DEV_BSGLIB
+ depends on ARM64 || X86_64
+ help
+ This driver supports 3SNIC 3S5xx serial RAID controller, which has
+ PCI Express Gen4 interface with host and supports SAS/SATA HDD/SSD.
+ To compile this driver as a module, choose M here: the module will
+ be called sssraid.
diff --git a/drivers/scsi/sssraid/Makefile b/drivers/scsi/sssraid/Makefile
new file mode 100644
index 000000000000..c80605866b42
--- /dev/null
+++ b/drivers/scsi/sssraid/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the 3SNIC sssraid drivers.
+#
+
+obj-$(CONFIG_SCSI_3SNIC_SSSRAID) += sssraid.o
+
+sssraid-objs := sssraid_os.o sssraid_fw.o
diff --git a/drivers/scsi/sssraid/sssraid.h b/drivers/scsi/sssraid/sssraid.h
new file mode 100644
index 000000000000..bae668ef9c98
--- /dev/null
+++ b/drivers/scsi/sssraid/sssraid.h
@@ -0,0 +1,971 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2022 3SNIC Information Technology, Ltd */
+
+/* 3SNIC RAID SSSXXX Series Linux Driver */
+
+#ifndef __SSSRAID_H_
+#define __SSSRAID_H_
+
+#define SSSRAID_DRIVER_VERSION "1.0.0.0"
+#define SSSRAID_DRIVER_RELDATE "12-December-2022"
+
+#define SSSRAID_DRIVER_NAME "sssraid"
+
+#define SSSRAID_NAME_LENGTH 32
+
+/*
+ * SSSRAID Vendor ID and Device IDs
+ */
+#define PCI_VENDOR_ID_3SNIC_LOGIC 0x1F3F
+
+#define SSSRAID_SERVER_DEVICE_HBA_DID 0x2100
+#define SSSRAID_SERVER_DEVICE_RAID_DID 0x2200
+
+#define SSSRAID_CAP_MQES(cap) ((cap) & 0xffff)
+#define SSSRAID_CAP_STRIDE(cap) (((cap) >> 32) & 0xf)
+#define SSSRAID_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf)
+#define SSSRAID_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf)
+#define SSSRAID_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff)
+#define SSSRAID_CAP_DMAMASK(cap) (((cap) >> 37) & 0xff)
+
+#define SSSRAID_DEFAULT_MAX_CHANNEL 4
+#define SSSRAID_DEFAULT_MAX_ID 240
+#define SSSRAID_DEFAULT_MAX_LUN_PER_HOST 8
+#define MAX_SECTORS 2048
+
+/*
+ * Time define
+ */
+#define SSSRAID_WATCHDOG_INTERVAL 1000 /* in milli seconds */
+#define SSSRAID_PORTENABLE_TIMEOUT 300
+
+/*
+ * SSSRAID queue and entry size for Admin and I/O type
+ */
+#define IO_SQE_SIZE sizeof(struct sssraid_ioq_command)
+#define ADMIN_SQE_SIZE sizeof(struct sssraid_admin_command)
+#define SQE_SIZE(qid) (((qid) > 0) ? IO_SQE_SIZE : ADMIN_SQE_SIZE)
+#define CQ_SIZE(depth) ((depth) * sizeof(struct sssraid_completion))
+#define SQ_SIZE(qid, depth) ((depth) * SQE_SIZE(qid))
+
+#define SENSE_SIZE(depth) ((depth) * SCSI_SENSE_BUFFERSIZE)
+
+#define SSSRAID_AQ_DEPTH 128
+#define SSSRAID_NR_AEN_COMMANDS 16
+#define SSSRAID_AQ_BLK_MQ_DEPTH (SSSRAID_AQ_DEPTH - SSSRAID_NR_AEN_COMMANDS)
+#define SSSRAID_AQ_MQ_TAG_DEPTH (SSSRAID_AQ_BLK_MQ_DEPTH - 1)
+
+#define SSSRAID_ADMIN_QUEUE_NUM 1
+#define SSSRAID_PTCMDS_PERQ 1
+#define SSSRAID_IO_BLK_MQ_DEPTH (hdev->scsi_qd)
+#define SSSRAID_NR_IOQ_PTCMDS (SSSRAID_PTCMDS_PERQ * hdev->shost->nr_hw_queues)
+
+#define FUA_MASK 0x08
+#define SSSRAID_MINORS BIT(MINORBITS)
+#define SSSRAID_RW_FUA BIT(14)
+
+#define COMMAND_IS_WRITE(cmd) ((cmd)->common.opcode & 1)
+
+#define SSSRAID_IO_IOSQES 7
+#define SSSRAID_IO_IOCQES 4
+#define PRP_ENTRY_SIZE 8
+
+#define SMALL_POOL_SIZE 256
+#define MAX_SMALL_POOL_NUM 16
+#define MAX_CMD_PER_DEV 64
+#define MAX_CDB_LEN 16
+
+#define SSSRAID_UP_TO_MULTY4(x) (((x) + 4) & (~0x03))
+
+#define CQE_STATUS_SUCCESS (0x0)
+
+#define IO_6_DEFAULT_TX_LEN 256
+
+#define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct sssraid_sgl_desc))
+
+#define SSSRAID_CAP_TIMEOUT_UNIT_MS (HZ / 2)
+
+extern u32 admin_tmout;
+#define ADMIN_TIMEOUT (admin_tmout * HZ)
+
+#define SSSRAID_WAIT_ABNL_CMD_TIMEOUT 6
+
+#define SSSRAID_DMA_MSK_BIT_MAX 64
+
+enum {
+ SSSRAID_SGL_FMT_DATA_DESC = 0x00,
+ SSSRAID_SGL_FMT_SEG_DESC = 0x02,
+ SSSRAID_SGL_FMT_LAST_SEG_DESC = 0x03,
+ SSSRAID_KEY_SGL_FMT_DATA_DESC = 0x04,
+ SSSRAID_TRANSPORT_SGL_DATA_DESC = 0x05
+};
+
+
+enum {
+ SSSRAID_REQ_CANCELLED = (1 << 0),
+ SSSRAID_REQ_USERCMD = (1 << 1),
+};
+
+enum {
+ SSSRAID_SC_SUCCESS = 0x0,
+ SSSRAID_SC_INVALID_OPCODE = 0x1,
+ SSSRAID_SC_INVALID_FIELD = 0x2,
+
+ SSSRAID_SC_ABORT_LIMIT = 0x103,
+ SSSRAID_SC_ABORT_MISSING = 0x104,
+ SSSRAID_SC_ASYNC_LIMIT = 0x105,
+
+ SSSRAID_SC_DNR = 0x4000,
+};
+
+enum {
+ SSSRAID_REG_CAP = 0x0000,
+ SSSRAID_REG_CC = 0x0014,
+ SSSRAID_REG_CSTS = 0x001c,
+ SSSRAID_REG_AQA = 0x0024,
+ SSSRAID_REG_ASQ = 0x0028,
+ SSSRAID_REG_ACQ = 0x0030,
+ SSSRAID_REG_DBS = 0x1000,
+};
+
+enum {
+ SSSRAID_CC_ENABLE = 1 << 0,
+ SSSRAID_CC_CSS_NVM = 0 << 4,
+ SSSRAID_CC_MPS_SHIFT = 7,
+ SSSRAID_CC_AMS_SHIFT = 11,
+ SSSRAID_CC_SHN_SHIFT = 14,
+ SSSRAID_CC_IOSQES_SHIFT = 16,
+ SSSRAID_CC_IOCQES_SHIFT = 20,
+ SSSRAID_CC_AMS_RR = 0 << SSSRAID_CC_AMS_SHIFT,
+ SSSRAID_CC_SHN_NONE = 0 << SSSRAID_CC_SHN_SHIFT,
+ SSSRAID_CC_IOSQES = SSSRAID_IO_IOSQES << SSSRAID_CC_IOSQES_SHIFT,
+ SSSRAID_CC_IOCQES = SSSRAID_IO_IOCQES << SSSRAID_CC_IOCQES_SHIFT,
+ SSSRAID_CC_SHN_NORMAL = 1 << SSSRAID_CC_SHN_SHIFT,
+ SSSRAID_CC_SHN_MASK = 3 << SSSRAID_CC_SHN_SHIFT,
+ SSSRAID_CSTS_CFS_SHIFT = 1,
+ SSSRAID_CSTS_SHST_SHIFT = 2,
+ SSSRAID_CSTS_PP_SHIFT = 5,
+ SSSRAID_CSTS_RDY = 1 << 0,
+ SSSRAID_CSTS_SHST_CMPLT = 2 << 2,
+ SSSRAID_CSTS_SHST_MASK = 3 << 2,
+ SSSRAID_CSTS_CFS_MASK = 1 << SSSRAID_CSTS_CFS_SHIFT,
+ SSSRAID_CSTS_PP_MASK = 1 << SSSRAID_CSTS_PP_SHIFT,
+};
+
+enum {
+ SSSRAID_ADMIN_DELETE_SQ = 0x00,
+ SSSRAID_ADMIN_CREATE_SQ = 0x01,
+ SSSRAID_ADMIN_DELETE_CQ = 0x04,
+ SSSRAID_ADMIN_CREATE_CQ = 0x05,
+ SSSRAID_ADMIN_ABORT_CMD = 0x08,
+ SSSRAID_ADMIN_SET_FEATURES = 0x09,
+ SSSRAID_ADMIN_ASYNC_EVENT = 0x0c,
+ SSSRAID_ADMIN_GET_INFO = 0xc6,
+ SSSRAID_ADMIN_RESET = 0xc8,
+};
+
+enum {
+ SSSRAID_GET_INFO_CTRL = 0,
+ SSSRAID_GET_INFO_DEV_LIST = 1,
+};
+
+enum sssraid_scsi_rst_type {
+ SSSRAID_RESET_TARGET = 0,
+ SSSRAID_RESET_BUS = 1,
+};
+
+enum {
+ SSSRAID_AEN_ERROR = 0,
+ SSSRAID_AEN_NOTICE = 2,
+ SSSRAID_AEN_VS = 7,
+};
+
+enum {
+ SSSRAID_AEN_DEV_CHANGED = 0x00,
+ SSSRAID_AEN_FW_ACT_START = 0x01,
+ SSSRAID_AEN_HOST_PROBING = 0x10,
+};
+
+enum {
+ SSSRAID_AEN_TIMESYN = 0x00,
+ SSSRAID_AEN_FW_ACT_FINISH = 0x02,
+ SSSRAID_AEN_EVENT_MIN = 0x80,
+ SSSRAID_AEN_EVENT_MAX = 0xff,
+};
+
+enum {
+ SSSRAID_CMD_WRITE = 0x01,
+ SSSRAID_CMD_READ = 0x02,
+
+ SSSRAID_CMD_NONIO_NONE = 0x80,
+ SSSRAID_CMD_NONIO_TODEV = 0x81,
+ SSSRAID_CMD_NONIO_FROMDEV = 0x82,
+};
+
+enum {
+ SSSRAID_QUEUE_PHYS_CONTIG = (1 << 0),
+ SSSRAID_CQ_IRQ_ENABLED = (1 << 1),
+
+ SSSRAID_FEAT_NUM_QUEUES = 0x07,
+ SSSRAID_FEAT_ASYNC_EVENT = 0x0b,
+ SSSRAID_FEAT_TIMESTAMP = 0x0e,
+};
+
+enum sssraid_state {
+ SSSRAID_NEW,
+ SSSRAID_LIVE,
+ SSSRAID_RESETTING,
+ SSSRAID_DELETING,
+ SSSRAID_DEAD,
+};
+
+enum {
+ SSSRAID_CARD_HBA,
+ SSSRAID_CARD_RAID,
+};
+
+enum sssraid_cmd_type {
+ SSSRAID_CMD_ADM,
+ SSSRAID_CMD_IOPT,
+};
+
+/*
+ * SSSRAID completion queue entry struct
+ */
+struct sssraid_completion {
+ __le32 result;
+ union {
+ struct {
+ __u8 sense_len;
+ __u8 resv[3];
+ };
+ __le32 result1;
+ };
+ __le16 sq_head;
+ __le16 sq_id;
+ __le16 cmd_id;
+ __le16 status;
+};
+
+/*
+ * SSSRAID firmware controller properties
+ */
+struct sssraid_ctrl_info {
+ __le32 nd;
+ __le16 max_cmds;
+ __le16 max_channel;
+ __le32 max_tgt_id;
+ __le16 max_lun;
+ __le16 max_num_sge;
+ __le16 lun_num_in_boot;
+ __u8 mdts;
+ __u8 acl;
+ __u8 aerl;
+ __u8 card_type;
+ __u16 rsvd;
+ __le32 rtd3e;
+ __u8 sn[32];
+ __u8 fr[16];
+ __u8 rsvd1[4020];
+};
+
+struct sssraid_intr_info {
+ struct sssraid_dev *hdev;
+ u16 msix_index;
+ struct sssraid_cqueue *cqinfo;
+ char name[SSSRAID_NAME_LENGTH];
+};
+
+struct sssraid_fwevt {
+ struct list_head list;
+ struct work_struct work;
+ struct sssraid_dev *hdev;
+ u16 event_id;
+ bool send_ack;
+ bool process_evt;
+ u32 evt_ctx;
+ struct kref ref_count;
+ char event_data[0] __aligned(4);
+};
+
+/*
+ * SSSRAID private device struct definition
+ */
+struct sssraid_dev {
+ struct pci_dev *pdev;
+ struct Scsi_Host *shost;
+ struct sssraid_squeue *sqinfo;
+ struct sssraid_cqueue *cqinfo;
+ struct dma_pool *prp_page_pool;
+ struct dma_pool *prp_small_pool[MAX_SMALL_POOL_NUM];
+ void __iomem *bar;
+
+ u32 init_done_queue_cnt;
+ u32 ioq_depth;
+ u32 db_stride;
+ u32 __iomem *dbs;
+ struct rw_semaphore devices_rwsem;
+ int numa_node;
+ u32 page_size;
+ u32 ctrl_config;
+ u64 cap;
+ u32 instance;
+ u32 scsi_qd;
+ struct sssraid_ctrl_info *ctrl_info;
+ struct sssraid_dev_info *devices;
+
+ int logging_level;
+
+ char name[SSSRAID_NAME_LENGTH];
+ int cpu_count;
+ /*
+ * before_affinity_msix_cnt is
+ * min("FW support IO Queue count", num_online_cpus)+1
+ */
+ u16 before_affinity_msix_cnt;
+
+ struct sssraid_cmd *adm_cmds;
+ struct list_head adm_cmd_list;
+ spinlock_t adm_cmd_lock;
+
+ struct sssraid_cmd *ioq_ptcmds;
+ struct list_head ioq_pt_list;
+ spinlock_t ioq_pt_lock;
+
+ int reset_flag;
+
+ enum sssraid_state state;
+ spinlock_t state_lock;
+
+ struct request_queue *bsg_queue;
+
+ u8 intr_enabled;
+
+ struct sssraid_intr_info *intr_info;
+ u32 intr_info_count;
+
+ char watchdog_work_q_name[20];
+ struct workqueue_struct *watchdog_work_q;
+ struct delayed_work watchdog_work;
+ spinlock_t watchdog_lock;
+
+ char fwevt_worker_name[SSSRAID_NAME_LENGTH];
+ struct workqueue_struct *fwevt_worker_thread;
+ spinlock_t fwevt_lock;
+ struct list_head fwevt_list;
+
+ struct sssraid_fwevt *current_event;
+};
+
+/*
+ * SSSRAID scatter list descriptor
+ */
+struct sssraid_sgl_desc {
+ __le64 addr;
+ __le32 length;
+ __u8 rsvd[3];
+ __u8 type;
+};
+
+union sssraid_data_ptr {
+ struct {
+ __le64 prp1;
+ __le64 prp2;
+ };
+ struct sssraid_sgl_desc sgl;
+};
+
+/*
+ * SSSRAID general admin class command format struct
+ */
+struct sssraid_admin_common_command {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __le32 cdw2[4];
+ union sssraid_data_ptr dptr;
+ __le32 cdw10;
+ __le32 cdw11;
+ __le32 cdw12;
+ __le32 cdw13;
+ __le32 cdw14;
+ __le32 cdw15;
+};
+
+struct sssraid_features {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __u64 rsvd2[2];
+ union sssraid_data_ptr dptr;
+ __le32 fid;
+ __le32 dword11;
+ __le32 dword12;
+ __le32 dword13;
+ __le32 dword14;
+ __le32 dword15;
+};
+
+/*
+ * SSSRAID create completion queue command struct
+ */
+struct sssraid_create_cq {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __u32 rsvd1[5];
+ __le64 prp1;
+ __u64 rsvd8;
+ __le16 cqid;
+ __le16 qsize;
+ __le16 cq_flags;
+ __le16 irq_vector;
+ __u32 rsvd12[4];
+};
+
+/*
+ * SSSRAID create submission queue command struct
+ */
+struct sssraid_create_sq {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __u32 rsvd1[5];
+ __le64 prp1;
+ __u64 rsvd8;
+ __le16 sqid;
+ __le16 qsize;
+ __le16 sq_flags;
+ __le16 cqid;
+ __u32 rsvd12[4];
+};
+
+/*
+ * SSSRAID delete submission queue command struct
+ */
+struct sssraid_delete_queue {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __u32 rsvd1[9];
+ __le16 qid;
+ __u16 rsvd10;
+ __u32 rsvd11[5];
+};
+
+/*
+ * SSSRAID access to information command struct
+ */
+struct sssraid_get_info {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __u32 rsvd2[4];
+ union sssraid_data_ptr dptr;
+ __u8 type;
+ __u8 rsvd10[3];
+ __le32 cdw11;
+ __u32 rsvd12[4];
+};
+
+/*
+ * User command struct
+ */
+struct sssraid_usr_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ union {
+ struct {
+ __le16 subopcode;
+ __le16 rsvd1;
+ } info_0;
+ __le32 cdw2;
+ };
+ union {
+ struct {
+ __le16 data_len;
+ __le16 param_len;
+ } info_1;
+ __le32 cdw3;
+ };
+ __u64 metadata;
+ union sssraid_data_ptr dptr;
+ __le32 cdw10;
+ __le32 cdw11;
+ __le32 cdw12;
+ __le32 cdw13;
+ __le32 cdw14;
+ __le32 cdw15;
+};
+
+enum {
+ SSSRAID_CMD_FLAG_SGL_METABUF = (1 << 6),
+ SSSRAID_CMD_FLAG_SGL_METASEG = (1 << 7),
+ SSSRAID_CMD_FLAG_SGL_ALL = SSSRAID_CMD_FLAG_SGL_METABUF | SSSRAID_CMD_FLAG_SGL_METASEG,
+};
+
+enum sssraid_cmd_state {
+ SSSRAID_CMD_IDLE = 0,
+ SSSRAID_CMD_IN_FLIGHT = 1,
+ SSSRAID_CMD_COMPLETE = 2,
+ SSSRAID_CMD_TIMEOUT = 3,
+ SSSRAID_CMD_TMO_COMPLETE = 4,
+};
+
+/*
+ * SSSRAID abort command struct
+ */
+struct sssraid_abort_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __u64 rsvd2[4];
+ __le16 sqid;
+ __le16 cid;
+ __u32 rsvd11[5];
+};
+
+/*
+ * SSSRAID reset command struct
+ */
+struct sssraid_reset_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __u64 rsvd2[4];
+ __u8 type;
+ __u8 rsvd10[3];
+ __u32 rsvd11[5];
+};
+
+/*
+ * SSSRAID admin class command set struct
+ */
+struct sssraid_admin_command {
+ union {
+ struct sssraid_admin_common_command common;
+ struct sssraid_features features;
+ struct sssraid_create_cq create_cq;
+ struct sssraid_create_sq create_sq;
+ struct sssraid_delete_queue delete_queue;
+ struct sssraid_get_info get_info;
+ struct sssraid_abort_cmd abort;
+ struct sssraid_reset_cmd reset;
+ struct sssraid_usr_cmd usr_cmd;
+ };
+};
+
+/*
+ * SSSRAID general IO class command format struct
+ */
+struct sssraid_ioq_common_command {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __le16 sense_len;
+ __u8 cdb_len;
+ __u8 rsvd2;
+ __le32 cdw3[3];
+ union sssraid_data_ptr dptr;
+ __le32 cdw10[6];
+ __u8 cdb[32];
+ __le64 sense_addr;
+ __le32 cdw26[6];
+};
+
+/*
+ * SSSRAID read or write command struct
+ */
+struct sssraid_rw_command {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __le16 sense_len;
+ __u8 cdb_len;
+ __u8 rsvd2;
+ __u32 rsvd3[3];
+ union sssraid_data_ptr dptr;
+ __le64 slba;
+ __le16 nlb;
+ __le16 control;
+ __u32 rsvd13[3];
+ __u8 cdb[32];
+ __le64 sense_addr;
+ __u32 rsvd26[6];
+};
+
+struct sssraid_scsi_nonio {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __le16 sense_len;
+ __u8 cdb_length;
+ __u8 rsvd2;
+ __u32 rsvd3[3];
+ union sssraid_data_ptr dptr;
+ __u32 rsvd10[5];
+ __le32 buffer_len;
+ __u8 cdb[32];
+ __le64 sense_addr;
+ __u32 rsvd26[6];
+};
+
+/*
+ * SSSRAID IO class command struct
+ */
+struct sssraid_ioq_command {
+ union {
+ struct sssraid_ioq_common_command common;
+ struct sssraid_rw_command rw;
+ struct sssraid_scsi_nonio scsi_nonio;
+ };
+};
+
+/*
+ * SSSRAID passthru command struct
+ */
+struct sssraid_passthru_common_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 rsvd0;
+ __u32 nsid;
+ union {
+ struct {
+ __u16 subopcode;
+ __u16 rsvd1;
+ } info_0;
+ __u32 cdw2;
+ };
+ union {
+ struct {
+ __u16 data_len;
+ __u16 param_len;
+ } info_1;
+ __u32 cdw3;
+ };
+ __u64 metadata;
+
+ __u64 addr;
+ __u64 prp2;
+
+ __u32 cdw10;
+ __u32 cdw11;
+ __u32 cdw12;
+ __u32 cdw13;
+ __u32 cdw14;
+ __u32 cdw15;
+ __u32 timeout_ms;
+ __u32 result0;
+ __u32 result1;
+};
+
+struct sssraid_ioq_passthru_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 rsvd0;
+ __u32 nsid;
+ union {
+ struct {
+ __u16 res_sense_len;
+ __u8 cdb_len;
+ __u8 rsvd0;
+ } info_0;
+ __u32 cdw2;
+ };
+ union {
+ struct {
+ __u16 subopcode;
+ __u16 rsvd1;
+ } info_1;
+ __u32 cdw3;
+ };
+ union {
+ struct {
+ __u16 rsvd;
+ __u16 param_len;
+ } info_2;
+ __u32 cdw4;
+ };
+ __u32 cdw5;
+ __u64 addr;
+ __u64 prp2;
+ union {
+ struct {
+ __u16 eid;
+ __u16 sid;
+ } info_3;
+ __u32 cdw10;
+ };
+ union {
+ struct {
+ __u16 did;
+ __u8 did_flag;
+ __u8 rsvd2;
+ } info_4;
+ __u32 cdw11;
+ };
+ __u32 cdw12;
+ __u32 cdw13;
+ __u32 cdw14;
+ __u32 data_len;
+ __u32 cdw16;
+ __u32 cdw17;
+ __u32 cdw18;
+ __u32 cdw19;
+ __u32 cdw20;
+ __u32 cdw21;
+ __u32 cdw22;
+ __u32 cdw23;
+ __u64 sense_addr;
+ __u32 cdw26[4];
+ __u32 timeout_ms;
+ __u32 result0;
+ __u32 result1;
+};
+
+struct sssraid_bsg_request {
+ u32 msgcode;
+ u32 control;
+ union {
+ struct sssraid_passthru_common_cmd admcmd;
+ struct sssraid_ioq_passthru_cmd ioqcmd;
+ };
+};
+
+enum {
+ SSSRAID_BSG_ADM,
+ SSSRAID_BSG_IOQ,
+};
+
+/*
+ * define the transfer command struct
+ */
+struct sssraid_cmd {
+ u16 qid;
+ u16 cid;
+ u32 result0;
+ u32 result1;
+ u16 status;
+ void *priv;
+ enum sssraid_cmd_state state;
+ struct completion cmd_done;
+ struct list_head list;
+};
+
+/*
+ * define the SSSRAID physical queue struct
+ */
+struct sssraid_squeue {
+ struct sssraid_dev *hdev;
+ spinlock_t sq_lock; /* spinlock for lock handling */
+
+ void *sq_cmds;
+
+ dma_addr_t sq_dma_addr;
+ u32 __iomem *q_db;
+ u8 cq_phase;
+ u8 sqes;
+ u16 qidx;
+ u16 sq_tail;
+ u16 last_cq_head;
+ u16 q_depth;
+ void *sense;
+ dma_addr_t sense_dma_addr;
+ struct dma_pool *prp_small_pool;
+};
+
+struct sssraid_cqueue {
+ struct sssraid_dev *hdev;
+
+ spinlock_t cq_lock ____cacheline_aligned_in_smp; /* spinlock for lock handling */
+
+ struct sssraid_completion *cqes;
+
+ dma_addr_t cq_dma_addr;
+ u8 cq_phase;
+ u16 cq_head;
+ u16 last_cq_head;
+};
+
+/*
+ * define the SSSRAID IO queue descriptor struct
+ */
+struct sssraid_iod {
+ struct sssraid_squeue *sqinfo;
+ enum sssraid_cmd_state state;
+ int npages;
+ u32 nsge;
+ u32 length;
+ bool use_sgl;
+ dma_addr_t first_dma;
+ void *sense;
+ dma_addr_t sense_dma;
+ struct scatterlist *sg;
+ void *list[0];
+};
+
+/*
+ * define the SSSRAID scsi device attribution and information
+ */
+#define SSSRAID_DEV_INFO_ATTR_BOOT(attr) ((attr) & 0x01)
+#define SSSRAID_DEV_INFO_ATTR_VD(attr) (((attr) & 0x02) == 0x0)
+#define SSSRAID_DEV_INFO_ATTR_PT(attr) (((attr) & 0x22) == 0x02)
+#define SSSRAID_DEV_INFO_ATTR_RAWDISK(attr) ((attr) & 0x20)
+#define SSSRAID_DEV_DISK_TYPE(attr) ((attr) & 0x1e)
+
+#define SSSRAID_DEV_INFO_FLAG_VALID(flag) ((flag) & 0x01)
+#define SSSRAID_DEV_INFO_FLAG_CHANGE(flag) ((flag) & 0x02)
+
+/*
+ * define the SSSRAID scsi device identifier
+ */
+enum {
+ SSSRAID_SAS_HDD_VD = 0x04,
+ SSSRAID_SATA_HDD_VD = 0x08,
+ SSSRAID_SAS_SSD_VD = 0x0c,
+ SSSRAID_SATA_SSD_VD = 0x10,
+ SSSRAID_NVME_SSD_VD = 0x14,
+ SSSRAID_SAS_HDD_PD = 0x06,
+ SSSRAID_SATA_HDD_PD = 0x0a,
+ SSSRAID_SAS_SSD_PD = 0x0e,
+ SSSRAID_SATA_SSD_PD = 0x12,
+ SSSRAID_NVME_SSD_PD = 0x16,
+};
+
+/*
+ * define the SSSRAID scsi device queue depth
+ */
+#define SSSRAID_HDD_PD_QD 64
+#define SSSRAID_HDD_VD_QD 256
+#define SSSRAID_SSD_PD_QD 64
+#define SSSRAID_SSD_VD_QD 256
+
+#define BGTASK_TYPE_REBUILD 4
+#define USR_CMD_READ 0xc2
+#define USR_CMD_RDLEN 0x1000
+#define USR_CMD_VDINFO 0x704
+#define USR_CMD_BGTASK 0x504
+#define VDINFO_PARAM_LEN 0x04
+
+/*
+ * SSSRAID virtual device information struct
+ */
+struct sssraid_vd_info {
+ __u8 name[32];
+ __le16 id;
+ __u8 rg_id;
+ __u8 rg_level;
+ __u8 sg_num;
+ __u8 sg_disk_num;
+ __u8 vd_status;
+ __u8 vd_type;
+ __u8 rsvd1[4056];
+};
+
+#define MAX_REALTIME_BGTASK_NUM 32
+
+struct bgtask_info {
+ __u8 type;
+ __u8 progress;
+ __u8 rate;
+ __u8 rsvd0;
+ __le16 vd_id;
+ __le16 time_left;
+ __u8 rsvd1[4];
+};
+
+struct sssraid_bgtask {
+ __u8 sw;
+ __u8 task_num;
+ __u8 rsvd[6];
+ struct bgtask_info bgtask[MAX_REALTIME_BGTASK_NUM];
+};
+
+/*
+ * SSSRAID scsi device information struct
+ */
+struct sssraid_dev_info {
+ __le32 hdid;
+ __le16 target;
+ __u8 channel;
+ __u8 lun;
+ __u8 attr;
+ __u8 flag;
+ __le16 max_io_kb;
+};
+
+#define IOQ_PT_DATA_LEN 4096
+#define MAX_DEV_ENTRY_PER_PAGE_4K 340
+struct sssraid_dev_list {
+ __le32 dev_num;
+ __u32 rsvd0[3];
+ struct sssraid_dev_info devices[MAX_DEV_ENTRY_PER_PAGE_4K];
+};
+
+/*
+ * SSSRAID scsi device host data struct
+ */
+struct sssraid_sdev_hostdata {
+ u32 hdid;
+ u16 max_io_kb;
+ u8 attr;
+ u8 flag;
+ u8 rg_id;
+ u8 rsvd[3];
+};
+
+extern unsigned char small_pool_num;
+extern u32 io_queue_depth;
+irqreturn_t sssraid_isr_poll(int irq, void *privdata);
+bool sssraid_poll_cq(struct sssraid_dev *hdev, u16 qidx, int cid);
+void sssraid_submit_cmd(struct sssraid_squeue *sqinfo, const void *cmd);
+int sssraid_get_dev_list(struct sssraid_dev *hdev, struct sssraid_dev_info *devices);
+int sssraid_submit_admin_sync_cmd(struct sssraid_dev *hdev, struct sssraid_admin_command *cmd,
+ u32 *result0, u32 *result1, u32 timeout);
+int sssraid_send_abort_cmd(struct sssraid_dev *hdev, u32 hdid, u16 qidx, u16 cid);
+int sssraid_send_reset_cmd(struct sssraid_dev *hdev, u8 type, u32 hdid);
+void sssraid_adm_timeout(struct sssraid_dev *hdev, struct sssraid_cmd *cmd);
+int sssraid_init_ioc(struct sssraid_dev *hdev, u8 re_init);
+void sssraid_cleanup_ioc(struct sssraid_dev *hdev, u8 re_init);
+int sssraid_soft_reset_handler(struct sssraid_dev *hdev);
+void sssraid_free_iod_res(struct sssraid_dev *hdev, struct sssraid_iod *iod);
+bool sssraid_change_host_state(struct sssraid_dev *hdev, enum sssraid_state newstate);
+int sssraid_configure_timestamp(struct sssraid_dev *hdev);
+int sssraid_init_ctrl_info(struct sssraid_dev *hdev);
+struct sssraid_cmd *sssraid_get_cmd(struct sssraid_dev *hdev, enum sssraid_cmd_type type);
+void sssraid_put_cmd(struct sssraid_dev *hdev, struct sssraid_cmd *cmd,
+ enum sssraid_cmd_type type);
+int sssraid_send_event_ack(struct sssraid_dev *hdev, u8 event,
+ u32 event_ctx, u16 cid);
+struct sssraid_fwevt *sssraid_alloc_fwevt(int len);
+void sssraid_fwevt_add_to_list(struct sssraid_dev *hdev,
+ struct sssraid_fwevt *fwevt);
+void sssraid_cleanup_fwevt_list(struct sssraid_dev *hdev);
+void sssraid_ioc_enable_intr(struct sssraid_dev *hdev);
+void sssraid_ioc_disable_intr(struct sssraid_dev *hdev);
+void sssraid_cleanup_resources(struct sssraid_dev *hdev);
+void sssraid_complete_cqes(struct sssraid_dev *hdev, u16 qidx, u16 start, u16 end);
+int sssraid_io_map_data(struct sssraid_dev *hdev, struct sssraid_iod *iod,
+ struct scsi_cmnd *scmd, struct sssraid_ioq_command *ioq_cmd);
+void sssraid_map_status(struct sssraid_iod *iod, struct scsi_cmnd *scmd,
+ struct sssraid_completion *cqe);
+void sssraid_scan_disk(struct sssraid_dev *hdev);
+void sssraid_complete_aen(struct sssraid_dev *hdev, struct sssraid_completion *cqe);
+void sssraid_back_all_io(struct sssraid_dev *hdev);
+
+static inline void **sssraid_iod_list(struct sssraid_iod *iod)
+{
+ return iod->list;
+}
+
+#end
diff --git a/drivers/scsi/sssraid/sssraid_debug.h b/drivers/scsi/sssraid/sssraid_debug.h
new file mode 100644
index 000000000000..d48c57e275f7
--- /dev/null
+++ b/drivers/scsi/sssraid/sssraid_debug.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2022 3SNIC Information Technology, Ltd */
+
+/* 3SNIC RAID SSSXXX Series Linux Driver */
+
+#ifndef SSSRAID_DEBUG_H_INCLUDED
+#define SSSRAID_DEBUG_H_INCLUDED
+
+/*
+ * debug levels
+ */
+#define SSSRAID_DEBUG 0x00000001
+
+/*
+ * debug macros
+ */
+
+#define ioc_err(ioc, fmt, ...) \
+ pr_err("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
+#define ioc_notice(ioc, fmt, ...) \
+ pr_notice("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
+#define ioc_warn(ioc, fmt, ...) \
+ pr_warn("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
+#define ioc_info(ioc, fmt, ...) \
+ pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
+
+
+#define dbgprint(IOC, FMT, ...) \
+ do { \
+ if (unlikely(IOC->logging_level & SSSRAID_DEBUG)) \
+ pr_info("%s: " FMT, (IOC)->name, ##__VA_ARGS__); \
+ } while (0)
+
+#endif /* SSSRAID_DEBUG_H_INCLUDED */
diff --git a/drivers/scsi/sssraid/sssraid_fw.c b/drivers/scsi/sssraid/sssraid_fw.c
new file mode 100644
index 000000000000..54287cf70558
--- /dev/null
+++ b/drivers/scsi/sssraid/sssraid_fw.c
@@ -0,0 +1,1724 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2022 3SNIC Information Technology, Ltd */
+
+/* 3SNIC RAID SSSXXX Series Linux Driver */
+
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/sysfs.h>
+#include <linux/gfp.h>
+#include <linux/types.h>
+#include <linux/ratelimit.h>
+#include <linux/debugfs.h>
+#include <linux/blkdev.h>
+#include <linux/bsg-lib.h>
+#include <linux/sort.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_dbg.h>
+
+#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/once.h>
+#include <linux/sched/signal.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
+
+#include "sssraid.h"
+#include "sssraid_debug.h"
+
+static int sssraid_wait_ready(struct sssraid_dev *hdev, u64 cap, bool enabled)
+{
+ unsigned long timeout =
+ ((SSSRAID_CAP_TIMEOUT(cap) + 1) * SSSRAID_CAP_TIMEOUT_UNIT_MS) + jiffies;
+ u32 bit = enabled ? SSSRAID_CSTS_RDY : 0;
+
+ while ((readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_RDY) != bit) {
+ usleep_range(1000, 2000);
+ if (fatal_signal_pending(current))
+ return -EINTR;
+
+ if (time_after(jiffies, timeout)) {
+ ioc_err(hdev, "Device not ready; aborting %s\n",
+ enabled ? "initialisation" : "reset");
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+static int sssraid_enable_ctrl(struct sssraid_dev *hdev)
+{
+ u64 cap = hdev->cap;
+ u32 dev_page_min = SSSRAID_CAP_MPSMIN(cap) + 12;
+ u32 page_shift = PAGE_SHIFT;
+
+ if (page_shift < dev_page_min) {
+ ioc_err(hdev, "Minimum device page size[%u], too large for host[%u]\n",
+ 1U << dev_page_min, 1U << page_shift);
+ return -ENODEV;
+ }
+
+ page_shift = min_t(unsigned int, SSSRAID_CAP_MPSMAX(cap) + 12, PAGE_SHIFT);
+ hdev->page_size = 1U << page_shift;
+
+ hdev->ctrl_config = SSSRAID_CC_CSS_NVM;
+ hdev->ctrl_config |= (page_shift - 12) << SSSRAID_CC_MPS_SHIFT;
+ hdev->ctrl_config |= SSSRAID_CC_AMS_RR | SSSRAID_CC_SHN_NONE;
+ hdev->ctrl_config |= SSSRAID_CC_IOSQES | SSSRAID_CC_IOCQES;
+ hdev->ctrl_config |= SSSRAID_CC_ENABLE;
+ writel(hdev->ctrl_config, hdev->bar + SSSRAID_REG_CC);
+
+ return sssraid_wait_ready(hdev, cap, true);
+}
+
+static int sssraid_disable_ctrl(struct sssraid_dev *hdev)
+{
+ hdev->ctrl_config &= ~SSSRAID_CC_SHN_MASK;
+ hdev->ctrl_config &= ~SSSRAID_CC_ENABLE;
+ writel(hdev->ctrl_config, hdev->bar + SSSRAID_REG_CC);
+
+ return sssraid_wait_ready(hdev, hdev->cap, false);
+}
+
+static int sssraid_shutdown_ctrl(struct sssraid_dev *hdev)
+{
+ unsigned long timeout = le32_to_cpu(hdev->ctrl_info->rtd3e) / 1000000 * HZ + jiffies;
+
+ hdev->ctrl_config &= ~SSSRAID_CC_SHN_MASK;
+ hdev->ctrl_config |= SSSRAID_CC_SHN_NORMAL;
+ writel(hdev->ctrl_config, hdev->bar + SSSRAID_REG_CC);
+
+ while ((readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_SHST_MASK) !=
+ SSSRAID_CSTS_SHST_CMPLT) {
+ msleep(100);
+ if (fatal_signal_pending(current))
+ return -EINTR;
+ if (time_after(jiffies, timeout)) {
+ ioc_err(hdev, "Device shutdown incomplete; abort shutdown\n");
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+static int sssraid_remap_bar(struct sssraid_dev *hdev, u32 size)
+{
+ struct pci_dev *pdev = hdev->pdev;
+
+ if (size > pci_resource_len(pdev, 0)) {
+ ioc_err(hdev, "Input size[%u] exceed bar0 length[%llu]\n",
+ size, pci_resource_len(pdev, 0));
+ return -ENODEV;
+ }
+
+ if (hdev->bar)
+ iounmap(hdev->bar);
+
+ hdev->bar = ioremap(pci_resource_start(pdev, 0), size);
+ if (!hdev->bar) {
+ ioc_err(hdev, "ioremap for bar0 failed\n");
+ return -ENODEV;
+ }
+ hdev->dbs = hdev->bar + SSSRAID_REG_DBS;
+
+ return 0;
+}
+
+static int sssraid_create_dma_pools(struct sssraid_dev *hdev)
+{
+ int i;
+ char poolname[20] = { 0 };
+
+ hdev->prp_page_pool = dma_pool_create("prp list page", &hdev->pdev->dev,
+ PAGE_SIZE, PAGE_SIZE, 0);
+
+ if (!hdev->prp_page_pool) {
+ ioc_err(hdev, "create prp_page_pool failed\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < small_pool_num; i++) {
+ sprintf(poolname, "prp_list_256_%d", i);
+ hdev->prp_small_pool[i] = dma_pool_create(poolname, &hdev->pdev->dev,
+ SMALL_POOL_SIZE,
+ SMALL_POOL_SIZE, 0);
+
+ if (!hdev->prp_small_pool[i]) {
+ ioc_err(hdev, "create prp_small_pool %d failed\n", i);
+ goto destroy_prp_small_pool;
+ }
+ }
+
+ return 0;
+
+destroy_prp_small_pool:
+ while (i > 0)
+ dma_pool_destroy(hdev->prp_small_pool[--i]);
+ dma_pool_destroy(hdev->prp_page_pool);
+
+ return -ENOMEM;
+}
+
+static void sssraid_destroy_dma_pools(struct sssraid_dev *hdev)
+{
+ int i;
+
+ for (i = 0; i < small_pool_num; i++)
+ dma_pool_destroy(hdev->prp_small_pool[i]);
+ dma_pool_destroy(hdev->prp_page_pool);
+}
+
+static int sssraid_alloc_resources(struct sssraid_dev *hdev)
+{
+ int retval, nqueue;
+
+ hdev->ctrl_info = kzalloc_node(sizeof(*hdev->ctrl_info), GFP_KERNEL, hdev->numa_node);
+ if (!hdev->ctrl_info)
+ return -ENOMEM;
+
+ retval = sssraid_create_dma_pools(hdev);
+ if (retval)
+ goto free_ctrl_info;
+ /* not num_online_cpus */
+ nqueue = num_possible_cpus() + 1;
+ hdev->cqinfo = kcalloc_node(nqueue, sizeof(struct sssraid_cqueue),
+ GFP_KERNEL, hdev->numa_node);
+ if (!hdev->cqinfo) {
+ retval = -ENOMEM;
+ goto destroy_dma_pools;
+ }
+
+ hdev->sqinfo = kcalloc_node(nqueue, sizeof(struct sssraid_squeue),
+ GFP_KERNEL, hdev->numa_node);
+ if (!hdev->sqinfo) {
+ retval = -ENOMEM;
+ goto free_cqueues;
+ }
+
+ /* sssraid_alloc_admin_cmds moved to sssraid_init_ioc */
+
+ ioc_info(hdev, "queues num: %d\n", nqueue);
+
+ return 0;
+
+free_cqueues:
+ kfree(hdev->cqinfo);
+destroy_dma_pools:
+ sssraid_destroy_dma_pools(hdev);
+free_ctrl_info:
+ kfree(hdev->ctrl_info);
+
+ return retval;
+}
+
+void sssraid_ioc_enable_intr(struct sssraid_dev *hdev)
+{
+ hdev->intr_enabled = 1;
+}
+
+void sssraid_ioc_disable_intr(struct sssraid_dev *hdev)
+{
+ u16 i, max_vectors;
+
+ hdev->intr_enabled = 0;
+ max_vectors = hdev->intr_info_count;
+
+ for (i = 0; i < max_vectors; i++)
+ synchronize_irq(pci_irq_vector(hdev->pdev, i));
+}
+
+static int sssraid_setup_resources(struct sssraid_dev *hdev)
+{
+ struct pci_dev *pdev = hdev->pdev;
+ int retval = 0;
+ u64 maskbit = SSSRAID_DMA_MSK_BIT_MAX;
+
+ if (pci_enable_device_mem(pdev)) {
+ ioc_err(hdev, "pci_enable_device_mem: failed\n");
+ retval = -ENODEV;
+ goto out_failed;
+ }
+
+ retval = pci_request_mem_regions(pdev, SSSRAID_DRIVER_NAME);
+ if (retval) {
+ ioc_err(hdev, "fail to request memory regions\n");
+ retval = -ENODEV;
+ goto out_failed;
+ }
+
+ /* get cap value at first, so keep
+ * sssraid_remap_bar(hdev, SSSRAID_REG_DBS + 4096)
+ * ioremap(pci_resource_start(..)) still in sssraid_remap_bar
+ */
+ retval = sssraid_remap_bar(hdev, SSSRAID_REG_DBS + 4096);
+ if (retval) {
+ retval = -ENODEV;
+ goto out_failed;
+ }
+
+ pci_set_master(pdev);
+
+ if (readl(hdev->bar + SSSRAID_REG_CSTS) == U32_MAX) {
+ retval = -ENODEV;
+ ioc_err(hdev, "Read csts register failed\n");
+ goto out_failed;
+ }
+
+ hdev->cap = lo_hi_readq(hdev->bar + SSSRAID_REG_CAP);
+ hdev->ioq_depth = min_t(u32, SSSRAID_CAP_MQES(hdev->cap) + 1, io_queue_depth);
+ hdev->scsi_qd = hdev->ioq_depth - SSSRAID_PTCMDS_PERQ;
+ hdev->db_stride = 1 << SSSRAID_CAP_STRIDE(hdev->cap);
+
+ maskbit = SSSRAID_CAP_DMAMASK(hdev->cap);
+ if (maskbit < 32 || maskbit > SSSRAID_DMA_MSK_BIT_MAX) {
+ ioc_err(hdev, "err, dma mask invalid[%llu], set to default\n", maskbit);
+ maskbit = SSSRAID_DMA_MSK_BIT_MAX;
+ }
+
+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(maskbit))) {
+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+ ioc_err(hdev, "set dma mask[32] and coherent failed\n");
+ retval = -ENODEV;
+ goto out_failed;
+ }
+ ioc_info(hdev, "set dma mask[32] success\n");
+ } else {
+ ioc_info(hdev, "set dma mask[%llu] success\n", maskbit);
+ }
+
+ /* pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES) moved to setup_isr */
+
+ pci_set_drvdata(pdev, hdev->shost);
+
+ pci_enable_pcie_error_reporting(pdev);
+ pci_save_state(pdev);
+
+ sssraid_ioc_disable_intr(hdev);
+
+ return retval;
+
+out_failed:
+ sssraid_cleanup_resources(hdev);
+ return retval;
+}
+
+static int sssraid_alloc_admin_cmds(struct sssraid_dev *hdev)
+{
+ u16 i;
+
+ INIT_LIST_HEAD(&hdev->adm_cmd_list);
+ spin_lock_init(&hdev->adm_cmd_lock);
+
+ hdev->adm_cmds = kcalloc_node(SSSRAID_AQ_BLK_MQ_DEPTH, sizeof(struct sssraid_cmd),
+ GFP_KERNEL, hdev->numa_node);
+
+ if (!hdev->adm_cmds) {
+ ioc_err(hdev, "Alloc admin cmds failed\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < SSSRAID_AQ_BLK_MQ_DEPTH; i++) {
+ hdev->adm_cmds[i].qid = 0;
+ hdev->adm_cmds[i].cid = i;
+ list_add_tail(&(hdev->adm_cmds[i].list), &hdev->adm_cmd_list);
+ }
+
+ ioc_info(hdev, "Alloc admin cmds success, num[%d]\n", SSSRAID_AQ_BLK_MQ_DEPTH);
+
+ return 0;
+}
+
+static int sssraid_alloc_qpair(struct sssraid_dev *hdev, u16 qidx, u16 depth)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+ int retval = 0;
+
+ if (hdev->init_done_queue_cnt > qidx) {
+ ioc_info(hdev, "warn: queue[%d] is exist\n", qidx);
+ return 0;
+ }
+
+ cqinfo->cqes = dma_alloc_coherent(&hdev->pdev->dev, CQ_SIZE(depth),
+ &cqinfo->cq_dma_addr, GFP_KERNEL | __GFP_ZERO);
+ if (!cqinfo->cqes)
+ return -ENOMEM;
+
+ sqinfo->sq_cmds = dma_alloc_coherent(&hdev->pdev->dev, SQ_SIZE(qidx, depth),
+ &sqinfo->sq_dma_addr, GFP_KERNEL);
+ if (!sqinfo->sq_cmds) {
+ retval = -ENOMEM;
+ goto free_cqes;
+ }
+
+ /* alloc sense buffer */
+ sqinfo->sense = dma_alloc_coherent(&hdev->pdev->dev, SENSE_SIZE(depth),
+ &sqinfo->sense_dma_addr, GFP_KERNEL | __GFP_ZERO);
+ if (!sqinfo->sense) {
+ retval = -ENOMEM;
+ goto free_sq_cmds;
+ }
+
+ spin_lock_init(&sqinfo->sq_lock);
+ spin_lock_init(&cqinfo->cq_lock);
+ cqinfo->hdev = hdev;
+ sqinfo->hdev = hdev;
+ sqinfo->q_depth = depth;
+ sqinfo->qidx = qidx;
+ /* cq_vector replaced by msix_index */
+
+ /*
+ * online_queues: completely initialized queue count: sssraid_init_queue
+ * queue_count: allocated but not completely initialized queue count: sssraid_alloc_queue
+ * online_queues/queue_count replaced by init_done_queue_cnt.
+ */
+ hdev->init_done_queue_cnt++;
+
+ return 0;
+
+free_sq_cmds:
+ dma_free_coherent(&hdev->pdev->dev, SQ_SIZE(qidx, depth), (void *)sqinfo->sq_cmds,
+ sqinfo->sq_dma_addr);
+free_cqes:
+ dma_free_coherent(&hdev->pdev->dev, CQ_SIZE(depth), (void *)cqinfo->cqes,
+ cqinfo->cq_dma_addr);
+ return retval;
+}
+
+static void sssraid_init_queue(struct sssraid_dev *hdev, u16 qidx)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ memset((void *)cqinfo->cqes, 0, CQ_SIZE(sqinfo->q_depth));
+
+ sqinfo->sq_tail = 0;
+ cqinfo->cq_head = 0;
+ cqinfo->cq_phase = 1;
+ sqinfo->q_db = &hdev->dbs[qidx * 2 * hdev->db_stride];
+ sqinfo->prp_small_pool = hdev->prp_small_pool[qidx % small_pool_num];
+}
+
+static int sssraid_setup_admin_qpair(struct sssraid_dev *hdev)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[0];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[0];
+ u32 aqa;
+ int retval;
+
+ ioc_info(hdev, "start disable ctrl\n");
+
+ retval = sssraid_disable_ctrl(hdev);
+ if (retval)
+ return retval;
+
+ /* this func don't alloc admin queue */
+
+ aqa = sqinfo->q_depth - 1;
+ aqa |= aqa << 16;
+ writel(aqa, hdev->bar + SSSRAID_REG_AQA);
+ lo_hi_writeq(sqinfo->sq_dma_addr, hdev->bar + SSSRAID_REG_ASQ);
+ lo_hi_writeq(cqinfo->cq_dma_addr, hdev->bar + SSSRAID_REG_ACQ);
+
+ ioc_info(hdev, "start enable ctrl\n");
+
+ retval = sssraid_enable_ctrl(hdev);
+ if (retval) {
+ retval = -ENODEV;
+ return retval;
+ }
+
+ /* interrupt registry not here */
+ /* cq_vector replaced by msix_index */
+
+ sssraid_init_queue(hdev, 0);
+
+ ioc_info(hdev, "success, queuecount:[%d], pagesize[%d]\n",
+ hdev->init_done_queue_cnt, hdev->page_size);
+
+ return 0;
+}
+
+static void sssraid_cleanup_isr(struct sssraid_dev *hdev)
+{
+ u16 i;
+
+ sssraid_ioc_disable_intr(hdev);
+
+ if (!hdev->intr_info)
+ return;
+
+ for (i = 0; i < hdev->intr_info_count; i++)
+ free_irq(pci_irq_vector(hdev->pdev, i),
+ (hdev->intr_info + i));
+
+ kfree(hdev->intr_info);
+ hdev->intr_info = NULL;
+ hdev->intr_info_count = 0;
+ pci_free_irq_vectors(hdev->pdev);
+}
+
+static void sssraid_complete_adminq_cmnd(struct sssraid_dev *hdev, u16 qidx,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_cmd *adm_cmd;
+
+ adm_cmd = hdev->adm_cmds + le16_to_cpu(cqe->cmd_id);
+ if (unlikely(adm_cmd->state == SSSRAID_CMD_IDLE)) {
+ ioc_warn(hdev, "Invalid id %d completed on queue %d\n",
+ le16_to_cpu(cqe->cmd_id), le16_to_cpu(cqe->sq_id));
+ return;
+ }
+
+ adm_cmd->status = le16_to_cpu(cqe->status) >> 1;
+ adm_cmd->result0 = le32_to_cpu(cqe->result);
+ adm_cmd->result1 = le32_to_cpu(cqe->result1);
+
+ complete(&adm_cmd->cmd_done);
+}
+
+static inline bool sssraid_cqe_pending(struct sssraid_cqueue *cqinfo)
+{
+ return (le16_to_cpu(cqinfo->cqes[cqinfo->cq_head].status) & 1) ==
+ cqinfo->cq_phase;
+}
+
+static inline void sssraid_update_cq_head(struct sssraid_dev *hdev, u16 qidx)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ if (++cqinfo->cq_head == sqinfo->q_depth) {
+ cqinfo->cq_head = 0;
+ cqinfo->cq_phase = !cqinfo->cq_phase;
+ }
+}
+
+static inline bool sssraid_process_cq(struct sssraid_dev *hdev, u16 qidx, u16 *start,
+ u16 *end, int tag)
+{
+ bool found = false;
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ *start = cqinfo->cq_head;
+ while (!found && sssraid_cqe_pending(cqinfo)) {
+ if (le16_to_cpu(cqinfo->cqes[cqinfo->cq_head].cmd_id) == tag)
+ found = true;
+ sssraid_update_cq_head(hdev, qidx);
+ }
+ *end = cqinfo->cq_head;
+
+ if (*start != *end)
+ writel(cqinfo->cq_head, sqinfo->q_db + sqinfo->hdev->db_stride);
+
+ return found;
+}
+
+static irqreturn_t sssraid_isr(int irq, void *privdata)
+{
+ struct sssraid_intr_info *intr_info = privdata;
+ struct sssraid_dev *hdev = intr_info->hdev;
+ irqreturn_t ret = IRQ_NONE;
+ struct sssraid_cqueue *cqinfo;
+ u16 midx, start, end;
+
+ if (!intr_info)
+ return IRQ_NONE;
+
+ if (!hdev->intr_enabled)
+ return IRQ_NONE;
+
+ midx = intr_info->msix_index;
+ cqinfo = &hdev->cqinfo[midx];
+
+ spin_lock(&cqinfo->cq_lock);
+ if (cqinfo->cq_head != cqinfo->last_cq_head)
+ ret = IRQ_HANDLED;
+
+ sssraid_process_cq(hdev, midx, &start, &end, -1);
+ cqinfo->last_cq_head = cqinfo->cq_head;
+ spin_unlock(&cqinfo->cq_lock);
+
+ if (start != end) {
+ sssraid_complete_cqes(hdev, midx, start, end);
+ ret = IRQ_HANDLED;
+ }
+ return ret;
+}
+
+irqreturn_t sssraid_isr_poll(int irq, void *privdata)
+{
+ return IRQ_NONE;
+}
+
+bool sssraid_poll_cq(struct sssraid_dev *hdev, u16 qidx, int cid)
+{
+ u16 start, end;
+ bool found;
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+
+ if (!sssraid_cqe_pending(cqinfo))
+ return 0;
+
+ spin_lock_irq(&cqinfo->cq_lock);
+ found = sssraid_process_cq(hdev, qidx, &start, &end, cid);
+ spin_unlock_irq(&cqinfo->cq_lock);
+
+ sssraid_complete_cqes(hdev, qidx, start, end);
+ return found;
+}
+
+static inline int sssraid_request_irq(struct sssraid_dev *hdev, u16 index)
+{
+ struct pci_dev *pdev = hdev->pdev;
+ struct sssraid_intr_info *intr_info = hdev->intr_info + index;
+ int retval = 0;
+
+ intr_info->hdev = hdev;
+ intr_info->msix_index = index;
+ intr_info->cqinfo = NULL;
+
+ snprintf(intr_info->name, SSSRAID_NAME_LENGTH, "%s%d-msix%d",
+ SSSRAID_DRIVER_NAME, hdev->instance, index);
+
+ retval = request_threaded_irq(pci_irq_vector(pdev, index), sssraid_isr,
+ sssraid_isr_poll, IRQF_SHARED, intr_info->name, intr_info);
+
+ if (retval) {
+ ioc_err(hdev, "%s: Unable to allocate interrupt %d!\n",
+ intr_info->name, pci_irq_vector(pdev, index));
+ return retval;
+ }
+
+ return retval;
+}
+
+static int sssraid_setup_isr(struct sssraid_dev *hdev, u8 setup_one)
+{
+ unsigned int irq_flags = PCI_IRQ_MSIX;
+ u16 max_vectors = 0, i;
+ int retval = 0;
+
+ struct irq_affinity desc = { .pre_vectors = 1};
+
+ sssraid_cleanup_isr(hdev);
+
+ if (setup_one)
+ max_vectors = 1;
+ else {
+ max_vectors = hdev->before_affinity_msix_cnt;
+
+ ioc_info(hdev, "MSI-x vectors requested: %d\n", max_vectors);
+ }
+
+ irq_flags |= PCI_IRQ_AFFINITY | PCI_IRQ_ALL_TYPES;
+
+ i = pci_alloc_irq_vectors_affinity(hdev->pdev,
+ 1, max_vectors, irq_flags, &desc);
+
+ if (i <= 0) {
+ ioc_err(hdev, "Cannot alloc irq vectors\n");
+ goto out_failed;
+ }
+ if (i != max_vectors) {
+ ioc_info(hdev,
+ "allocated vectors (%d) are less than configured (%d)\n",
+ i, max_vectors);
+
+ max_vectors = i;
+ }
+
+ hdev->intr_info = kzalloc(sizeof(struct sssraid_intr_info) * max_vectors,
+ GFP_KERNEL);
+ if (!hdev->intr_info) {
+ retval = -1;
+ pci_free_irq_vectors(hdev->pdev);
+ goto out_failed;
+ }
+
+ for (i = 0; i < max_vectors; i++) {
+ retval = sssraid_request_irq(hdev, i);
+ if (retval) {
+ hdev->intr_info_count = i; /* =i is for offload interrupt loop counter */
+ goto out_failed;
+ }
+ }
+
+ /* intr_info_count replace max_qid */
+ hdev->intr_info_count = max_vectors;
+ sssraid_ioc_enable_intr(hdev);
+ return retval;
+out_failed:
+ sssraid_cleanup_isr(hdev);
+
+ return retval;
+}
+
+static bool sssraid_adm_need_reset(struct sssraid_admin_command *cmd)
+{
+ switch (cmd->common.opcode) {
+ case SSSRAID_ADMIN_DELETE_SQ:
+ case SSSRAID_ADMIN_CREATE_SQ:
+ case SSSRAID_ADMIN_DELETE_CQ:
+ case SSSRAID_ADMIN_CREATE_CQ:
+ case SSSRAID_ADMIN_SET_FEATURES:
+ return false;
+ default:
+ return true;
+ }
+}
+
+void sssraid_submit_cmd(struct sssraid_squeue *sqinfo, const void *cmd)
+{
+ u32 sqes = SQE_SIZE(sqinfo->qidx);
+ unsigned long flags;
+ struct sssraid_admin_common_command *acd = (struct sssraid_admin_common_command *)cmd;
+
+ spin_lock_irqsave(&sqinfo->sq_lock, flags);
+ memcpy((sqinfo->sq_cmds + sqes * sqinfo->sq_tail), cmd, sqes);
+ if (++sqinfo->sq_tail == sqinfo->q_depth)
+ sqinfo->sq_tail = 0;
+
+ writel(sqinfo->sq_tail, sqinfo->q_db);
+ spin_unlock_irqrestore(&sqinfo->sq_lock, flags);
+
+ dbgprint(sqinfo->hdev, "cid[%d] qidx[%d], opcode[0x%x], flags[0x%x], hdid[%u]\n",
+ le16_to_cpu(acd->command_id), sqinfo->qidx, acd->opcode, acd->flags,
+ le32_to_cpu(acd->hdid));
+}
+
+int sssraid_submit_admin_sync_cmd(struct sssraid_dev *hdev, struct sssraid_admin_command *cmd,
+ u32 *result0, u32 *result1, u32 timeout)
+{
+ struct sssraid_cmd *adm_cmd = sssraid_get_cmd(hdev, SSSRAID_CMD_ADM);
+
+ if (!adm_cmd) {
+ ioc_err(hdev, "err, get admin cmd failed\n");
+ return -EFAULT;
+ }
+
+ timeout = timeout ? timeout : ADMIN_TIMEOUT;
+
+ /*
+ * watch dog not as optimized as
+ * init_completion/complete
+ */
+ init_completion(&adm_cmd->cmd_done);
+
+ cmd->common.command_id = cpu_to_le16(adm_cmd->cid);
+ sssraid_submit_cmd(&hdev->sqinfo[0], cmd);
+
+ if (!wait_for_completion_timeout(&adm_cmd->cmd_done, timeout)) {
+ ioc_err(hdev, "cid[%d] qidx[%d] timeout, opcode[0x%x] subopcode[0x%x]\n",
+ adm_cmd->cid, adm_cmd->qid, cmd->usr_cmd.opcode,
+ cmd->usr_cmd.info_0.subopcode);
+
+ /* reset controller if admin timeout */
+ if (sssraid_adm_need_reset(cmd))
+ sssraid_adm_timeout(hdev, adm_cmd);
+
+ sssraid_put_cmd(hdev, adm_cmd, SSSRAID_CMD_ADM);
+ return -ETIME;
+ }
+
+ if (result0)
+ *result0 = adm_cmd->result0;
+ if (result1)
+ *result1 = adm_cmd->result1;
+
+ sssraid_put_cmd(hdev, adm_cmd, SSSRAID_CMD_ADM);
+
+ return adm_cmd->status;
+}
+
+static int sssraid_get_ctrl_info(struct sssraid_dev *hdev, struct sssraid_ctrl_info *ctrl_info)
+{
+ struct sssraid_admin_command admin_cmd;
+ u8 *data_ptr = NULL;
+ dma_addr_t data_dma = 0;
+ int retval;
+
+ data_ptr = dma_alloc_coherent(&hdev->pdev->dev, PAGE_SIZE, &data_dma, GFP_KERNEL);
+ if (!data_ptr)
+ return -ENOMEM;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.get_info.opcode = SSSRAID_ADMIN_GET_INFO;
+ admin_cmd.get_info.type = SSSRAID_GET_INFO_CTRL;
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ retval = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+ if (!retval)
+ memcpy(ctrl_info, data_ptr, sizeof(struct sssraid_ctrl_info));
+
+ dma_free_coherent(&hdev->pdev->dev, PAGE_SIZE, data_ptr, data_dma);
+
+ return retval;
+}
+
+int sssraid_init_ctrl_info(struct sssraid_dev *hdev)
+{
+ int retval;
+
+ hdev->ctrl_info->nd = cpu_to_le32(240);
+ hdev->ctrl_info->mdts = 8;
+ hdev->ctrl_info->max_cmds = cpu_to_le16(4096);
+ hdev->ctrl_info->max_num_sge = cpu_to_le16(128);
+ hdev->ctrl_info->max_channel = cpu_to_le16(4);
+ hdev->ctrl_info->max_tgt_id = cpu_to_le32(3239);
+ hdev->ctrl_info->max_lun = cpu_to_le16(2);
+
+ retval = sssraid_get_ctrl_info(hdev, hdev->ctrl_info);
+ if (retval)
+ ioc_err(hdev, "init controller info failed: %d\n", retval);
+
+ ioc_info(hdev, "nd = %d\n", le32_to_cpu(hdev->ctrl_info->nd));
+ ioc_info(hdev, "max_cmd = %d\n", le16_to_cpu(hdev->ctrl_info->max_cmds));
+ ioc_info(hdev, "max_channel = %d\n", le16_to_cpu(hdev->ctrl_info->max_channel));
+ ioc_info(hdev, "max_tgt_id = %d\n", le32_to_cpu(hdev->ctrl_info->max_tgt_id));
+ ioc_info(hdev, "max_lun = %d\n", le16_to_cpu(hdev->ctrl_info->max_lun));
+ ioc_info(hdev, "max_num_sge = %d\n", le16_to_cpu(hdev->ctrl_info->max_num_sge));
+ ioc_info(hdev, "lun_num_boot = %d\n", le16_to_cpu(hdev->ctrl_info->lun_num_in_boot));
+ ioc_info(hdev, "mdts = %d\n", hdev->ctrl_info->mdts);
+ ioc_info(hdev, "acl = %d\n", hdev->ctrl_info->acl);
+ ioc_info(hdev, "aer1 = %d\n", hdev->ctrl_info->aerl);
+ ioc_info(hdev, "card_type = %d\n", hdev->ctrl_info->card_type);
+ ioc_info(hdev, "rtd3e = %d\n", le32_to_cpu(hdev->ctrl_info->rtd3e));
+ ioc_info(hdev, "sn = %s\n", hdev->ctrl_info->sn);
+ ioc_info(hdev, "fr = %s\n", hdev->ctrl_info->fr);
+
+ if (!hdev->ctrl_info->aerl)
+ hdev->ctrl_info->aerl = 1;
+ if (hdev->ctrl_info->aerl > SSSRAID_NR_AEN_COMMANDS)
+ hdev->ctrl_info->aerl = SSSRAID_NR_AEN_COMMANDS;
+
+ return 0;
+}
+
+static int sssraid_set_features(struct sssraid_dev *hdev, u32 fid, u32 dword11, void *buffer,
+ size_t buflen, u32 *result)
+{
+ struct sssraid_admin_command admin_cmd;
+ int ret;
+ u8 *data_ptr = NULL;
+ dma_addr_t data_dma = 0;
+
+ if (buffer && buflen) {
+ data_ptr = dma_alloc_coherent(&hdev->pdev->dev, buflen, &data_dma, GFP_KERNEL);
+ if (!data_ptr)
+ return -ENOMEM;
+
+ memcpy(data_ptr, buffer, buflen);
+ }
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.features.opcode = SSSRAID_ADMIN_SET_FEATURES;
+ admin_cmd.features.fid = cpu_to_le32(fid);
+ admin_cmd.features.dword11 = cpu_to_le32(dword11);
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ ret = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, result, NULL, 0);
+
+ if (data_ptr)
+ dma_free_coherent(&hdev->pdev->dev, buflen, data_ptr, data_dma);
+
+ return ret;
+}
+
+static int sssraid_set_queue_cnt(struct sssraid_dev *hdev, u32 *cnt)
+{
+ u32 q_cnt = (*cnt - 1) | ((*cnt - 1) << 16);
+ u32 nr_ioqs, result;
+ int status;
+
+ status = sssraid_set_features(hdev, SSSRAID_FEAT_NUM_QUEUES, q_cnt, NULL, 0, &result);
+ if (status) {
+ ioc_err(hdev, "Set queue count failed, status: %d\n",
+ status);
+ return -EIO;
+ }
+
+ nr_ioqs = min(result & 0xffff, result >> 16) + 1;
+ *cnt = min(*cnt, nr_ioqs);
+ if (*cnt == 0) {
+ ioc_err(hdev, "Illegal queue count: zero\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int sssraid_create_cq(struct sssraid_dev *hdev, u16 qidx)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+ struct sssraid_admin_command admin_cmd;
+ int flags = SSSRAID_QUEUE_PHYS_CONTIG | SSSRAID_CQ_IRQ_ENABLED;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.create_cq.opcode = SSSRAID_ADMIN_CREATE_CQ;
+ admin_cmd.create_cq.prp1 = cpu_to_le64(cqinfo->cq_dma_addr);
+ admin_cmd.create_cq.cqid = cpu_to_le16(qidx);
+ admin_cmd.create_cq.qsize = cpu_to_le16(sqinfo->q_depth - 1);
+ admin_cmd.create_cq.cq_flags = cpu_to_le16(flags);
+ admin_cmd.create_cq.irq_vector = cpu_to_le16(qidx);
+
+ return sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+}
+
+static int sssraid_create_io_cq(struct sssraid_dev *hdev, u16 qidx)
+{
+ int retval;
+ struct sssraid_cqueue *cqinfo = hdev->cqinfo + qidx;
+ u16 midx = qidx;
+
+ retval = sssraid_create_cq(hdev, qidx);
+ if (retval)
+ return retval;
+
+ /*
+ * cqinfo initialization at sssraid_init_queue
+ */
+ hdev->intr_info[midx].cqinfo = cqinfo;
+
+ return retval;
+}
+
+static int sssraid_create_sq(struct sssraid_dev *hdev, u16 qidx)
+{
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+ struct sssraid_admin_command admin_cmd;
+ int flags = SSSRAID_QUEUE_PHYS_CONTIG;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.create_sq.opcode = SSSRAID_ADMIN_CREATE_SQ;
+ admin_cmd.create_sq.prp1 = cpu_to_le64(sqinfo->sq_dma_addr);
+ admin_cmd.create_sq.sqid = cpu_to_le16(qidx);
+ admin_cmd.create_sq.qsize = cpu_to_le16(sqinfo->q_depth - 1);
+ admin_cmd.create_sq.sq_flags = cpu_to_le16(flags);
+ admin_cmd.create_sq.cqid = cpu_to_le16(qidx);
+
+ return sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+}
+
+static int sssraid_create_io_sq(struct sssraid_dev *hdev, u16 qidx)
+{
+ return sssraid_create_sq(hdev, qidx);
+}
+
+int sssraid_get_dev_list(struct sssraid_dev *hdev, struct sssraid_dev_info *devices)
+{
+ u32 nd = le32_to_cpu(hdev->ctrl_info->nd);
+ struct sssraid_admin_command admin_cmd;
+ struct sssraid_dev_list *list_buf;
+ dma_addr_t data_dma = 0;
+ u32 i, idx, hdid, ndev;
+ int ret = 0;
+
+ list_buf = dma_alloc_coherent(&hdev->pdev->dev, PAGE_SIZE, &data_dma, GFP_KERNEL);
+ if (!list_buf)
+ return -ENOMEM;
+
+ for (idx = 0; idx < nd;) {
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.get_info.opcode = SSSRAID_ADMIN_GET_INFO;
+ admin_cmd.get_info.type = SSSRAID_GET_INFO_DEV_LIST;
+ admin_cmd.get_info.cdw11 = cpu_to_le32(idx);
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ ret = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+
+ if (ret) {
+ ioc_err(hdev, "Get device list failed, nd: %u, idx: %u, ret: %d\n",
+ nd, idx, ret);
+ goto out;
+ }
+ ndev = le32_to_cpu(list_buf->dev_num);
+
+ ioc_info(hdev, "ndev numbers: %u\n", ndev);
+
+ for (i = 0; i < ndev; i++) {
+ hdid = le32_to_cpu(list_buf->devices[i].hdid);
+ ioc_info(hdev, "list_buf->devices[%d], hdid: %u target: %d, channel: %d, lun: %d, attr[0x%x]\n",
+ i, hdid, le16_to_cpu(list_buf->devices[i].target),
+ list_buf->devices[i].channel,
+ list_buf->devices[i].lun,
+ list_buf->devices[i].attr);
+ if (hdid > nd || hdid == 0) {
+ ioc_err(hdev, "err, hdid[%d] invalid\n", hdid);
+ continue;
+ }
+ memcpy(&devices[hdid - 1], &list_buf->devices[i],
+ sizeof(struct sssraid_dev_info));
+ }
+ idx += ndev;
+
+ if (ndev < MAX_DEV_ENTRY_PER_PAGE_4K)
+ break;
+ }
+
+out:
+ dma_free_coherent(&hdev->pdev->dev, PAGE_SIZE, list_buf, data_dma);
+ return ret;
+}
+
+/* send abort command by admin queue temporary */
+int sssraid_send_abort_cmd(struct sssraid_dev *hdev, u32 hdid, u16 qidx, u16 cid)
+{
+ struct sssraid_admin_command admin_cmd;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.abort.opcode = SSSRAID_ADMIN_ABORT_CMD;
+ admin_cmd.abort.hdid = cpu_to_le32(hdid);
+ admin_cmd.abort.sqid = cpu_to_le16(qidx);
+ admin_cmd.abort.cid = cpu_to_le16(cid);
+
+ return sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+}
+
+/* send reset command by admin quueue temporary */
+int sssraid_send_reset_cmd(struct sssraid_dev *hdev, u8 type, u32 hdid)
+{
+ struct sssraid_admin_command admin_cmd;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.reset.opcode = SSSRAID_ADMIN_RESET;
+ admin_cmd.reset.hdid = cpu_to_le32(hdid);
+ admin_cmd.reset.type = type;
+
+ return sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+}
+
+static int sssraid_delete_queue(struct sssraid_dev *hdev, u8 op, u16 qidx)
+{
+ struct sssraid_admin_command admin_cmd;
+ int retval;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.delete_queue.opcode = op;
+ admin_cmd.delete_queue.qid = cpu_to_le16(qidx);
+
+ retval = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+
+ if (retval)
+ ioc_err(hdev, "Delete %s:[%d] failed\n",
+ (op == SSSRAID_ADMIN_DELETE_CQ) ? "cq" : "sq", qidx);
+
+ return retval;
+}
+
+static int sssraid_delete_cq(struct sssraid_dev *hdev, u16 qidx)
+{
+ return sssraid_delete_queue(hdev, SSSRAID_ADMIN_DELETE_CQ, qidx);
+}
+
+void sssraid_adm_timeout(struct sssraid_dev *hdev, struct sssraid_cmd *cmd)
+{
+ /* command may be returned because controller reset */
+ if (READ_ONCE(cmd->state) == SSSRAID_CMD_COMPLETE)
+ return;
+
+ if (!sssraid_change_host_state(hdev, SSSRAID_RESETTING)) {
+ ioc_info(hdev, "can't change to reset state\n");
+ return;
+ }
+ sssraid_soft_reset_handler(hdev);
+}
+
+static int sssraid_create_io_qpair(struct sssraid_dev *hdev, u16 qidx)
+{
+ int retval;
+
+ retval = sssraid_create_io_cq(hdev, qidx);
+ if (retval)
+ return retval;
+
+ retval = sssraid_create_io_sq(hdev, qidx);
+ if (retval)
+ goto delete_cq;
+
+ /* intr_info.msix_index substitute cq_vector */
+
+ /* io interrupt registry:
+ * not here, put above
+ */
+
+ sssraid_init_queue(hdev, qidx);
+
+ return 0;
+
+delete_cq:
+ sssraid_delete_cq(hdev, qidx);
+
+ return retval;
+}
+
+static int sssraid_setup_io_qpair(struct sssraid_dev *hdev)
+{
+ u32 i, num_queues;
+ int retval = 0;
+
+ num_queues = min(hdev->intr_info_count, hdev->init_done_queue_cnt - 1);
+ for (i = 1; i <= num_queues; i++) {
+ retval = sssraid_create_io_qpair(hdev, i);
+ if (retval) {
+ ioc_err(hdev, "Create queue[%d] failed\n", i);
+ break;
+ }
+ }
+
+ ioc_info(hdev, "init_done_queue_cnt[%d], intr_info_count[%d] num_queues[%d]",
+ hdev->init_done_queue_cnt, /*hdev->online_queues,*/
+ hdev->intr_info_count, num_queues);
+
+ return retval >= 0 ? 0 : retval;
+}
+
+static int sssraid_alloc_ioq_ptcmds(struct sssraid_dev *hdev)
+{
+ int i;
+ int ptnum = SSSRAID_NR_IOQ_PTCMDS;
+
+ INIT_LIST_HEAD(&hdev->ioq_pt_list);
+ spin_lock_init(&hdev->ioq_pt_lock);
+
+ hdev->ioq_ptcmds = kcalloc_node(ptnum, sizeof(struct sssraid_cmd),
+ GFP_KERNEL, hdev->numa_node);
+
+ if (!hdev->ioq_ptcmds) {
+ ioc_err(hdev, "Alloc ioq_ptcmds failed\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < ptnum; i++) {
+ hdev->ioq_ptcmds[i].qid = i / SSSRAID_PTCMDS_PERQ + 1;
+ hdev->ioq_ptcmds[i].cid = i % SSSRAID_PTCMDS_PERQ + SSSRAID_IO_BLK_MQ_DEPTH;
+ list_add_tail(&(hdev->ioq_ptcmds[i].list), &hdev->ioq_pt_list);
+ }
+
+ ioc_info(hdev, "Alloc ioq_ptcmds success, ptnum[%d]\n", ptnum);
+
+ return 0;
+}
+
+int sssraid_send_event_ack(struct sssraid_dev *hdev, u8 event,
+ u32 event_ctx, u16 cid)
+{
+ /* event,event_ctx no use at this time */
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[0];
+ struct sssraid_admin_command admin_cmd;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.common.opcode = SSSRAID_ADMIN_ASYNC_EVENT;
+ admin_cmd.common.command_id = cpu_to_le16(cid);
+
+ sssraid_submit_cmd(sqinfo, &admin_cmd);
+ ioc_info(hdev, "send aen, cid[%d]\n", cid);
+
+ return 0;
+}
+
+static void sssraid_handle_aen_notice(struct sssraid_dev *hdev, u32 result)
+{
+ switch ((result & 0xff00) >> 8) {
+ case SSSRAID_AEN_DEV_CHANGED:
+ sssraid_scan_disk(hdev);
+ break;
+ case SSSRAID_AEN_FW_ACT_START:
+ ioc_info(hdev, "fw activation starting\n");
+ break;
+ case SSSRAID_AEN_HOST_PROBING:
+ break;
+ default:
+ ioc_warn(hdev, "async event result %08x\n", result);
+ }
+}
+
+static void sssraid_handle_aen_vs(struct sssraid_dev *hdev, u32 result, u32 result1)
+{
+ switch ((result & 0xff00) >> 8) {
+ case SSSRAID_AEN_TIMESYN:
+ sssraid_configure_timestamp(hdev);
+ break;
+ case SSSRAID_AEN_FW_ACT_FINISH:
+ ioc_info(hdev, "fw activation finish\n");
+ if (sssraid_init_ctrl_info(hdev))
+ ioc_err(hdev, "get ctrl info failed after fw act\n");
+ break;
+ case SSSRAID_AEN_EVENT_MIN ... SSSRAID_AEN_EVENT_MAX:
+ ioc_info(hdev, "rcv card event[%d], param1[0x%x] param2[0x%x]\n",
+ (result & 0xff00) >> 8, result, result1);
+ break;
+ default:
+ ioc_warn(hdev, "async event result: 0x%x\n", result);
+ }
+}
+
+static inline void sssraid_send_all_aen(struct sssraid_dev *hdev)
+{
+ u16 i;
+
+ for (i = 0; i < hdev->ctrl_info->aerl; i++)
+ sssraid_send_event_ack(hdev, 0, 0, i + SSSRAID_AQ_BLK_MQ_DEPTH);
+}
+
+static int sssraid_dev_list_init(struct sssraid_dev *hdev)
+{
+ u32 nd = le32_to_cpu(hdev->ctrl_info->nd);
+
+ hdev->devices = kzalloc_node(nd * sizeof(struct sssraid_dev_info),
+ GFP_KERNEL, hdev->numa_node);
+ if (!hdev->devices)
+ return -ENOMEM;
+
+ return 0;
+}
+
+int sssraid_configure_timestamp(struct sssraid_dev *hdev)
+{
+ __le64 ts;
+ int retval;
+
+ ts = cpu_to_le64(ktime_to_ms(ktime_get_real()));
+ retval = sssraid_set_features(hdev, SSSRAID_FEAT_TIMESTAMP, 0, &ts, sizeof(ts), NULL);
+
+ if (retval)
+ ioc_err(hdev, "set timestamp failed: %d\n", retval);
+ return retval;
+}
+
+int sssraid_init_ioc(struct sssraid_dev *hdev, u8 re_init)
+{
+ int retval = 0;
+ int i;
+ u32 nr_ioqs, bar_size;
+
+ if (!re_init) {
+ hdev->cpu_count = num_online_cpus();
+
+ retval = sssraid_alloc_resources(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc resources:error %d\n",
+ retval);
+ goto out_nocleanup;
+ }
+ }
+
+ /* reset need re-setup */
+ retval = sssraid_setup_resources(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to setup resources:error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ if (!re_init) {
+ retval = sssraid_alloc_admin_cmds(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc admin cmds:error %d\n",
+ retval);
+ goto out_failed;
+ }
+ /* put here:
+ * alloc admin queue
+ */
+ retval = sssraid_alloc_qpair(hdev, 0, SSSRAID_AQ_DEPTH);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc admin queue:error %d\n",
+ retval);
+ goto out_failed;
+ }
+ }
+
+ retval = sssraid_setup_admin_qpair(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to setup admin queue:error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ /* 1. unregister all interrupt
+ * 2. admin interrupt registry
+ */
+ retval = sssraid_setup_isr(hdev, 1);
+ if (retval) {
+ ioc_err(hdev, "Failed to setup ISR error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ retval = sssraid_init_ctrl_info(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to get ctrl info error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ nr_ioqs = hdev->cpu_count;
+ retval = sssraid_set_queue_cnt(hdev, &nr_ioqs);
+ if (retval) {
+ ioc_err(hdev, "Failed to set queue cnt error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ hdev->before_affinity_msix_cnt = nr_ioqs + 1;
+
+ /* 1. unregister all interrupt
+ * 2. admin interrupt re-registry
+ * 3. io interrupt registry
+ */
+ retval = sssraid_setup_isr(hdev, 0);
+ if (retval) {
+ ioc_err(hdev, "Failed to re-setup ISR, error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ /* remap */
+ bar_size = SSSRAID_REG_DBS + ((nr_ioqs + 1) * 8 * hdev->db_stride);
+ retval = sssraid_remap_bar(hdev, bar_size);
+ if (retval) {
+ ioc_err(hdev, "Failed to re-map bar, error %d\n",
+ retval);
+ goto out_failed;
+ }
+ hdev->sqinfo[0].q_db = hdev->dbs;
+
+ /* num_vecs no sense, abandon */
+
+ if (!re_init) {
+ for (i = hdev->init_done_queue_cnt; i <= hdev->intr_info_count; i++) {
+ retval = sssraid_alloc_qpair(hdev, i, hdev->ioq_depth);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc io queue:error %d\n",
+ retval);
+ goto out_failed;
+ }
+ }
+ ioc_info(hdev, "intr_info_count: %d, init_done_queue_cnt: %d, ioq_depth: %d\n",
+ hdev->intr_info_count, hdev->init_done_queue_cnt, hdev->ioq_depth);
+ }
+
+ retval = sssraid_setup_io_qpair(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to setup io qpair, error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ if (!re_init) {
+ retval = sssraid_alloc_ioq_ptcmds(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc ioq ptcmds, error %d\n",
+ retval);
+ goto out_failed;
+ }
+ }
+
+ sssraid_send_all_aen(hdev);
+
+ if (!re_init) {
+ retval = sssraid_dev_list_init(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to init device list, error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ retval = sssraid_configure_timestamp(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to configure timestamp, error %d\n",
+ retval);
+ goto out_failed;
+ }
+ }
+
+ return retval;
+
+out_failed:
+ sssraid_cleanup_ioc(hdev, re_init);
+out_nocleanup:
+ return retval;
+}
+
+void sssraid_cleanup_resources(struct sssraid_dev *hdev)
+{
+ struct pci_dev *pdev = hdev->pdev;
+
+ sssraid_cleanup_isr(hdev);
+
+ if (hdev->bar) {
+ iounmap(hdev->bar);
+ hdev->bar = NULL;
+ }
+
+ if (pci_is_enabled(pdev)) {
+ pci_disable_pcie_error_reporting(pdev);
+ pci_release_mem_regions(pdev);
+ pci_disable_device(pdev);
+ }
+}
+
+static void sssraid_free_ioq_ptcmds(struct sssraid_dev *hdev)
+{
+ kfree(hdev->ioq_ptcmds);
+ hdev->ioq_ptcmds = NULL;
+
+ INIT_LIST_HEAD(&hdev->ioq_pt_list);
+}
+
+static void sssraid_delete_io_queues(struct sssraid_dev *hdev)
+{
+ u16 queues = hdev->init_done_queue_cnt - 1;
+ u8 opcode = SSSRAID_ADMIN_DELETE_SQ;
+ u16 i, pass;
+
+ if (!pci_device_is_present(hdev->pdev)) {
+ ioc_err(hdev, "pci_device is not present, skip disable io queues\n");
+ return;
+ }
+
+ if (hdev->init_done_queue_cnt < 2) {
+ ioc_err(hdev, "err, io queue has been delete\n");
+ return;
+ }
+
+ for (pass = 0; pass < 2; pass++) {
+ for (i = queues; i > 0; i--)
+ if (sssraid_delete_queue(hdev, opcode, i))
+ break;
+
+ opcode = SSSRAID_ADMIN_DELETE_CQ;
+ }
+}
+
+void sssraid_complete_aen(struct sssraid_dev *hdev, struct sssraid_completion *cqe)
+{
+ u32 result = le32_to_cpu(cqe->result);
+
+ ioc_info(hdev, "rcv aen, cid[%d], status[0x%x], result[0x%x]\n",
+ le16_to_cpu(cqe->cmd_id), le16_to_cpu(cqe->status) >> 1, result);
+
+ /*
+ * The response to event moved from this func.
+ * sssraid_send_aen changed to name sssraid_send_event_ack
+ */
+
+ if ((le16_to_cpu(cqe->status) >> 1) != SSSRAID_SC_SUCCESS)
+ return;
+ switch (result & 0x7) {
+ case SSSRAID_AEN_NOTICE:
+ sssraid_handle_aen_notice(hdev, result);
+ break;
+ case SSSRAID_AEN_VS:
+ sssraid_handle_aen_vs(hdev, result, le32_to_cpu(cqe->result1));
+ break;
+ default:
+ ioc_warn(hdev, "Unsupported async event type: %u\n",
+ result & 0x7);
+ break;
+ }
+}
+
+void sssraid_free_iod_res(struct sssraid_dev *hdev, struct sssraid_iod *iod)
+{
+ const int last_prp = hdev->page_size / sizeof(__le64) - 1;
+ dma_addr_t dma_addr, next_dma_addr;
+ struct sssraid_sgl_desc *sg_list;
+ __le64 *prp_list;
+ void *addr;
+ int i;
+
+ dma_addr = iod->first_dma;
+ if (iod->npages == 0)
+ dma_pool_free(iod->sqinfo->prp_small_pool, sssraid_iod_list(iod)[0], dma_addr);
+
+ for (i = 0; i < iod->npages; i++) {
+ addr = sssraid_iod_list(iod)[i];
+
+ if (iod->use_sgl) {
+ sg_list = addr;
+ next_dma_addr =
+ le64_to_cpu((sg_list[SGES_PER_PAGE - 1]).addr);
+ } else {
+ prp_list = addr;
+ next_dma_addr = le64_to_cpu(prp_list[last_prp]);
+ }
+
+ dma_pool_free(hdev->prp_page_pool, addr, dma_addr);
+ dma_addr = next_dma_addr;
+ }
+
+ iod->sense = NULL;
+ iod->npages = -1;
+}
+
+static void sssraid_complete_ioq_sync_cmnd(struct sssraid_dev *hdev, u16 qidx,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_cmd *ptcmd;
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ ptcmd = hdev->ioq_ptcmds + (sqinfo->qidx - 1) * SSSRAID_PTCMDS_PERQ +
+ le16_to_cpu(cqe->cmd_id) - SSSRAID_IO_BLK_MQ_DEPTH;
+
+ ptcmd->status = le16_to_cpu(cqe->status) >> 1;
+ ptcmd->result0 = le32_to_cpu(cqe->result);
+ ptcmd->result1 = le32_to_cpu(cqe->result1);
+
+ complete(&ptcmd->cmd_done);
+}
+
+static void sssraid_complete_ioq_cmnd(struct sssraid_dev *hdev, u16 qidx,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ struct blk_mq_tags *tags;
+ struct scsi_cmnd *scmd;
+ struct sssraid_iod *iod;
+ struct request *req;
+ unsigned long elapsed;
+
+ tags = hdev->shost->tag_set.tags[sqinfo->qidx - 1];
+
+ req = blk_mq_tag_to_rq(tags, le16_to_cpu(cqe->cmd_id));
+ if (unlikely(!req || !blk_mq_request_started(req))) {
+ ioc_warn(hdev, "Invalid id %d completed on queue %d\n",
+ le16_to_cpu(cqe->cmd_id), sqinfo->qidx);
+ return;
+ }
+
+ scmd = blk_mq_rq_to_pdu(req);
+ iod = scsi_cmd_priv(scmd);
+
+ elapsed = jiffies - scmd->jiffies_at_alloc;
+ dbgprint(hdev, "cid[%d] qidx[%d] finish IO cost %3ld.%3ld seconds\n",
+ le16_to_cpu(cqe->cmd_id), sqinfo->qidx, elapsed / HZ, elapsed % HZ);
+
+ if (cmpxchg(&iod->state, SSSRAID_CMD_IN_FLIGHT, SSSRAID_CMD_COMPLETE) !=
+ SSSRAID_CMD_IN_FLIGHT) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] enters abnormal handler, cost %3ld.%3ld seconds\n",
+ le16_to_cpu(cqe->cmd_id), sqinfo->qidx, elapsed / HZ, elapsed % HZ);
+ WRITE_ONCE(iod->state, SSSRAID_CMD_TMO_COMPLETE);
+
+ if (iod->nsge) {
+ iod->nsge = 0;
+ scsi_dma_unmap(scmd);
+ }
+ sssraid_free_iod_res(hdev, iod);
+
+ return;
+ }
+
+ sssraid_map_status(iod, scmd, cqe);
+ if (iod->nsge) {
+ iod->nsge = 0;
+ scsi_dma_unmap(scmd);
+ }
+ sssraid_free_iod_res(hdev, iod);
+ scmd->scsi_done(scmd);
+}
+
+static void sssraid_process_admin_cq(struct sssraid_dev *hdev,
+ struct sssraid_squeue *sqinfo,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_fwevt *fwevt = NULL;
+ u16 cid = le16_to_cpu(cqe->cmd_id), sz;
+
+ if (likely(cid < SSSRAID_AQ_BLK_MQ_DEPTH))
+ sssraid_complete_adminq_cmnd(hdev, sqinfo->qidx, cqe);
+ else {
+ sz = sizeof(*cqe);
+ fwevt = sssraid_alloc_fwevt(sz);
+ if (!fwevt) {
+ ioc_info(hdev, "%s :failure at %s:%d/%s()!\n",
+ __func__, __FILE__, __LINE__, __func__);
+ return;
+ }
+
+ memcpy(fwevt->event_data, cqe, sz);
+ fwevt->hdev = hdev;
+ fwevt->event_id = 0; /* evt_type:0 */
+ fwevt->send_ack = 1; /* ack_req:1 */
+ fwevt->process_evt = 1; /* process_evt_bh:1 */
+ fwevt->evt_ctx = 0; /* 0 */
+ sssraid_fwevt_add_to_list(hdev, fwevt);
+ }
+}
+
+static void sssraid_process_io_cq(struct sssraid_dev *hdev,
+ struct sssraid_squeue *sqinfo,
+ struct sssraid_completion *cqe)
+{
+ u16 cid = le16_to_cpu(cqe->cmd_id);
+
+ if (likely(cid < SSSRAID_IO_BLK_MQ_DEPTH))
+ sssraid_complete_ioq_cmnd(hdev, sqinfo->qidx, cqe);
+ else /* io sync handle */
+ sssraid_complete_ioq_sync_cmnd(hdev, sqinfo->qidx, cqe);
+}
+
+static inline void sssraid_handle_cqe(struct sssraid_dev *hdev, u16 mdix, u16 didx)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[mdix];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[mdix];
+
+ struct sssraid_completion *cqe = &cqinfo->cqes[didx];
+ u16 cid = le16_to_cpu(cqe->cmd_id);
+
+ if (unlikely(cid >= sqinfo->q_depth)) {
+ ioc_err(hdev, "Invalid command id[%d] completed on queue %d\n",
+ cid, cqe->sq_id);
+ return;
+ }
+
+ dbgprint(hdev, "cid[%d] mdix[%d], result[0x%x], sq_id[%d], status[0x%x]\n",
+ cid, sqinfo->qidx, le32_to_cpu(cqe->result),
+ le16_to_cpu(cqe->sq_id), le16_to_cpu(cqe->status));
+
+ if (!mdix) /* admin */
+ sssraid_process_admin_cq(hdev, sqinfo, cqe);
+ else /* io */
+ sssraid_process_io_cq(hdev, sqinfo, cqe);
+}
+
+void sssraid_complete_cqes(struct sssraid_dev *hdev, u16 midx, u16 start, u16 end)
+{
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[midx];
+
+ while (start != end) {
+ sssraid_handle_cqe(hdev, midx, start);
+ if (++start == sqinfo->q_depth)
+ start = 0;
+ }
+}
+
+static void sssraid_disable_admin_queue(struct sssraid_dev *hdev, bool shutdown)
+{
+ struct sssraid_cqueue *adm_cqinfo = &hdev->cqinfo[0];
+ u16 start, end;
+
+ if (pci_device_is_present(hdev->pdev)) {
+ if (shutdown)
+ sssraid_shutdown_ctrl(hdev);
+ else
+ sssraid_disable_ctrl(hdev);
+ }
+
+ if (hdev->init_done_queue_cnt == 0) {
+ ioc_err(hdev, "err, admin queue has been delete\n");
+ return;
+ }
+
+ spin_lock_irq(&adm_cqinfo->cq_lock);
+ sssraid_process_cq(hdev, 0, &start, &end, -1);
+ spin_unlock_irq(&adm_cqinfo->cq_lock);
+ sssraid_complete_cqes(hdev, 0, start, end);
+}
+
+static void sssraid_free_all_queues(struct sssraid_dev *hdev)
+{
+ int i;
+ struct sssraid_cqueue *cqinfo;
+ struct sssraid_squeue *sqinfo;
+
+ for (i = 0; i < hdev->init_done_queue_cnt; i++) {
+ cqinfo = &hdev->cqinfo[i];
+ sqinfo = &hdev->sqinfo[i];
+ dma_free_coherent(&hdev->pdev->dev, CQ_SIZE(sqinfo->q_depth),
+ (void *)cqinfo->cqes, cqinfo->cq_dma_addr);
+ dma_free_coherent(&hdev->pdev->dev, SQ_SIZE(sqinfo->qidx, sqinfo->q_depth),
+ sqinfo->sq_cmds, sqinfo->sq_dma_addr);
+ dma_free_coherent(&hdev->pdev->dev, SENSE_SIZE(sqinfo->q_depth),
+ sqinfo->sense, sqinfo->sense_dma_addr);
+ }
+
+ hdev->init_done_queue_cnt = 0;
+}
+
+static void sssraid_free_admin_cmds(struct sssraid_dev *hdev)
+{
+ kfree(hdev->adm_cmds);
+ hdev->adm_cmds = NULL;
+ INIT_LIST_HEAD(&hdev->adm_cmd_list);
+}
+
+static void sssraid_free_resources(struct sssraid_dev *hdev)
+{
+ sssraid_free_admin_cmds(hdev);
+ kfree(hdev->sqinfo);
+ kfree(hdev->cqinfo);
+ sssraid_destroy_dma_pools(hdev);
+ kfree(hdev->ctrl_info);
+}
+
+void sssraid_cleanup_ioc(struct sssraid_dev *hdev, u8 re_init)
+{
+ if (!re_init)
+ sssraid_free_ioq_ptcmds(hdev);
+
+ sssraid_delete_io_queues(hdev);
+ sssraid_disable_admin_queue(hdev, !re_init);
+
+ if (!re_init)
+ sssraid_free_all_queues(hdev);
+
+ sssraid_ioc_disable_intr(hdev);
+ sssraid_cleanup_resources(hdev);
+
+ if (!re_init)
+ sssraid_free_resources(hdev);
+
+}
+
+int sssraid_soft_reset_handler(struct sssraid_dev *hdev)
+{
+ int retval = 0;
+
+ if (hdev->state != SSSRAID_RESETTING) {
+ ioc_err(hdev, "err, host is not reset state\n");
+ return retval;
+ }
+
+ ioc_info(hdev, "enter host reset\n");
+
+ sssraid_ioc_disable_intr(hdev);
+ sssraid_cleanup_fwevt_list(hdev);
+
+ /* realize above here:
+ * sssraid_dev_disable -> sssraid_back_all_io
+ */
+ sssraid_back_all_io(hdev);
+ /*
+ * realize sssraid_dev_disable,
+ * i.e. sssraid_cleanup_ioc(1)
+ */
+ if (hdev->ctrl_config & SSSRAID_CC_ENABLE) {
+ ioc_info(hdev, "start dev_disable\n");
+ sssraid_cleanup_ioc(hdev, 1);
+ }
+
+ retval = sssraid_init_ioc(hdev, 1);
+ if (retval) {
+ ioc_err(hdev, "init ioc fail.\n");
+ return retval;
+ }
+
+ sssraid_change_host_state(hdev, SSSRAID_LIVE);
+
+ return retval;
+}
diff --git a/drivers/scsi/sssraid/sssraid_os.c b/drivers/scsi/sssraid/sssraid_os.c
new file mode 100644
index 000000000000..16d2b94d78f3
--- /dev/null
+++ b/drivers/scsi/sssraid/sssraid_os.c
@@ -0,0 +1,2337 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2022 3SNIC Information Technology, Ltd */
+
+/* 3SNIC RAID SSSXXX Series Linux Driver */
+
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/sysfs.h>
+#include <linux/gfp.h>
+#include <linux/types.h>
+#include <linux/ratelimit.h>
+#include <linux/debugfs.h>
+#include <linux/blkdev.h>
+#include <linux/bsg-lib.h>
+#include <linux/sort.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_dbg.h>
+
+#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/once.h>
+#include <linux/sched/signal.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
+
+#include "sssraid.h"
+#include "sssraid_debug.h"
+
+u32 admin_tmout = 60;
+module_param(admin_tmout, uint, 0644);
+MODULE_PARM_DESC(admin_tmout, "admin commands timeout (seconds)");
+
+static u32 scmd_tmout_rawdisk = 180;
+module_param(scmd_tmout_rawdisk, uint, 0644);
+MODULE_PARM_DESC(scmd_tmout_rawdisk, "scsi commands timeout for rawdisk(seconds)");
+
+static u32 scmd_tmout_vd = 180;
+module_param(scmd_tmout_vd, uint, 0644);
+MODULE_PARM_DESC(scmd_tmout_vd, "scsi commands timeout for vd(seconds)");
+
+static int ioq_depth_set(const char *val, const struct kernel_param *kp);
+static const struct kernel_param_ops ioq_depth_ops = {
+ .set = ioq_depth_set,
+ .get = param_get_uint,
+};
+
+u32 io_queue_depth = 1024;
+module_param_cb(io_queue_depth, &ioq_depth_ops, &io_queue_depth, 0644);
+MODULE_PARM_DESC(io_queue_depth, "set io queue depth, should >= 2");
+
+static int logging_level_set(const char *val, const struct kernel_param *kp)
+{
+ u8 n = 0;
+ int ret;
+
+ ret = kstrtou8(val, 10, &n);
+ if (ret != 0)
+ return -EINVAL;
+
+ return param_set_byte(val, kp);
+}
+
+static const struct kernel_param_ops logging_level_ops = {
+ .set = logging_level_set,
+ .get = param_get_byte,
+};
+
+static unsigned char logging_level;
+module_param_cb(logging_level, &logging_level_ops, &logging_level, 0644);
+MODULE_PARM_DESC(logging_level, "set log level, default zero for switch off");
+
+static int small_pool_num_set(const char *val, const struct kernel_param *kp)
+{
+ u8 n = 0;
+ int ret;
+
+ ret = kstrtou8(val, 10, &n);
+ if (ret != 0)
+ return -EINVAL;
+ if (n > MAX_SMALL_POOL_NUM)
+ n = MAX_SMALL_POOL_NUM;
+ if (n < 1)
+ n = 1;
+ *((u8 *)kp->arg) = n;
+
+ return 0;
+}
+
+static const struct kernel_param_ops small_pool_num_ops = {
+ .set = small_pool_num_set,
+ .get = param_get_byte,
+};
+
+/* Small pools are used to save PRP for small IOs.It was
+ * found that the spinlock of a single pool conflicts a
+ * lot with multiple CPUs.So multiple pools are introduced
+ * to reduce the conflictions.
+ */
+unsigned char small_pool_num = 4;
+module_param_cb(small_pool_num, &small_pool_num_ops, &small_pool_num, 0644);
+MODULE_PARM_DESC(small_pool_num, "set prp small pool num, default 4, MAX 16");
+
+//static struct class *sssraid_class;
+
+enum FW_STAT_CODE {
+ FW_STAT_OK = 0,
+ FW_STAT_NEED_CHECK,
+ FW_STAT_ERROR,
+ FW_STAT_EP_PCIE_ERROR,
+ FW_STAT_NAC_DMA_ERROR,
+ FW_STAT_ABORTED,
+ FW_STAT_NEED_RETRY
+};
+
+static const char * const raid_levels[] = {"0", "1", "5", "6", "10", "50", "60", "NA"};
+
+static const char * const raid_states[] = {
+ "NA", "NORMAL", "FAULT", "DEGRADE", "NOT_FORMATTED", "FORMATTING", "SANITIZING",
+ "INITIALIZING", "INITIALIZE_FAIL", "DELETING", "DELETE_FAIL", "WRITE_PROTECT"
+};
+
+static int ioq_depth_set(const char *val, const struct kernel_param *kp)
+{
+ int n = 0;
+ int ret;
+
+ ret = kstrtoint(val, 10, &n);
+ if (ret != 0 || n < 2)
+ return -EINVAL;
+
+ return param_set_int(val, kp);
+}
+
+/*
+ * common
+ */
+static struct class *sssraid_class;
+
+struct sssraid_fwevt *sssraid_alloc_fwevt(int len)
+{
+ struct sssraid_fwevt *fwevt;
+
+ fwevt = kzalloc(sizeof(*fwevt) + len, GFP_ATOMIC);
+ if (!fwevt)
+ return NULL;
+
+ kref_init(&fwevt->ref_count);
+ return fwevt;
+
+}
+
+static void sssraid_fwevt_free(struct kref *r)
+{
+ kfree(container_of(r, struct sssraid_fwevt, ref_count));
+}
+
+static void sssraid_fwevt_get(struct sssraid_fwevt *fwevt)
+{
+ kref_get(&fwevt->ref_count);
+}
+
+static void sssraid_fwevt_put(struct sssraid_fwevt *fwevt)
+{
+ kref_put(&fwevt->ref_count, sssraid_fwevt_free);
+}
+
+static void sssraid_fwevt_del_from_list(struct sssraid_dev *hdev,
+ struct sssraid_fwevt *fwevt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdev->fwevt_lock, flags);
+ if (!list_empty(&fwevt->list)) {
+ list_del_init(&fwevt->list);
+ /*
+ * Put fwevt reference count after
+ * removing it from fwevt_list
+ */
+ sssraid_fwevt_put(fwevt);
+ }
+ spin_unlock_irqrestore(&hdev->fwevt_lock, flags);
+}
+
+static void sssraid_fwevt_bh(struct sssraid_dev *hdev,
+ struct sssraid_fwevt *fwevt)
+{
+ struct sssraid_completion *cqe;
+
+ hdev->current_event = fwevt;
+ sssraid_fwevt_del_from_list(hdev, fwevt);
+
+ cqe = (struct sssraid_completion *)fwevt->event_data;
+
+ if (!fwevt->process_evt)
+ goto evt_ack;
+
+ sssraid_complete_aen(hdev, cqe);
+
+evt_ack:
+ /* event response put here: event has been handled. */
+ sssraid_send_event_ack(hdev, fwevt->event_id,
+ fwevt->evt_ctx, le16_to_cpu(cqe->cmd_id));
+ sssraid_fwevt_put(fwevt);
+ hdev->current_event = NULL;
+}
+
+static void sssraid_fwevt_worker(struct work_struct *work)
+{
+ struct sssraid_fwevt *fwevt = container_of(work, struct sssraid_fwevt,
+ work);
+ sssraid_fwevt_bh(fwevt->hdev, fwevt);
+ /*
+ * Put fwevt reference count after
+ * dequeuing it from worker queue
+ */
+ sssraid_fwevt_put(fwevt);
+}
+
+void sssraid_fwevt_add_to_list(struct sssraid_dev *hdev,
+ struct sssraid_fwevt *fwevt)
+{
+ unsigned long flags;
+
+ if (!hdev->fwevt_worker_thread)
+ return;
+
+ spin_lock_irqsave(&hdev->fwevt_lock, flags);
+ /* get fwevt reference count while adding it to fwevt_list */
+ sssraid_fwevt_get(fwevt);
+ INIT_LIST_HEAD(&fwevt->list);
+ list_add_tail(&fwevt->list, &hdev->fwevt_list);
+ INIT_WORK(&fwevt->work, sssraid_fwevt_worker);
+ /* get fwevt reference count while enqueueing it to worker queue */
+ sssraid_fwevt_get(fwevt);
+ queue_work(hdev->fwevt_worker_thread, &fwevt->work);
+ spin_unlock_irqrestore(&hdev->fwevt_lock, flags);
+}
+
+static struct sssraid_fwevt *sssraid_dequeue_fwevt(
+ struct sssraid_dev *hdev)
+{
+ unsigned long flags;
+ struct sssraid_fwevt *fwevt = NULL;
+
+ spin_lock_irqsave(&hdev->fwevt_lock, flags);
+ if (!list_empty(&hdev->fwevt_list)) {
+ fwevt = list_first_entry(&hdev->fwevt_list,
+ struct sssraid_fwevt, list);
+ list_del_init(&fwevt->list);
+ /*
+ * Put fwevt reference count after
+ * removing it from fwevt_list
+ */
+ sssraid_fwevt_put(fwevt);
+ }
+ spin_unlock_irqrestore(&hdev->fwevt_lock, flags);
+
+ return fwevt;
+}
+
+void sssraid_cleanup_fwevt_list(struct sssraid_dev *hdev)
+{
+ struct sssraid_fwevt *fwevt = NULL;
+
+ if ((list_empty(&hdev->fwevt_list) && !hdev->current_event) ||
+ !hdev->fwevt_worker_thread)
+ return;
+
+ while ((fwevt = sssraid_dequeue_fwevt(hdev)) ||
+ (fwevt = hdev->current_event)) {
+ /*
+ * Wait on the fwevt to complete. If this returns 1, then
+ * the event was never executed, and we need a put for the
+ * reference the work had on the fwevt.
+ *
+ * If it did execute, we wait for it to finish, and the put will
+ * happen from sssraid_process_fwevt()
+ */
+ if (cancel_work_sync(&fwevt->work)) {
+ /*
+ * Put fwevt reference count after
+ * dequeuing it from worker queue
+ */
+ sssraid_fwevt_put(fwevt);
+ /*
+ * Put fwevt reference count to neutralize
+ * kref_init increment
+ */
+ sssraid_fwevt_put(fwevt);
+ }
+ }
+}
+
+/*
+ * common 1
+ */
+static int sssraid_npages_prp(struct sssraid_dev *hdev)
+{
+ u32 size = 1U << ((hdev->ctrl_info->mdts) * 1U) << 12;
+ u32 nprps = DIV_ROUND_UP(size + hdev->page_size, hdev->page_size);
+
+ return DIV_ROUND_UP(PRP_ENTRY_SIZE * nprps, hdev->page_size - PRP_ENTRY_SIZE);
+}
+
+static int sssraid_npages_sgl(struct sssraid_dev *hdev)
+{
+ u32 nsge = le16_to_cpu(hdev->ctrl_info->max_num_sge);
+
+ return DIV_ROUND_UP(nsge * sizeof(struct sssraid_sgl_desc), hdev->page_size);
+}
+
+static u32 sssraid_cmd_size(struct sssraid_dev *hdev)
+{
+ u32 alloc_size = sizeof(__le64 *) * max(sssraid_npages_prp(hdev), sssraid_npages_sgl(hdev));
+
+ ioc_info(hdev, "iod size: %lu, alloc_size: %u\n",
+ sizeof(struct sssraid_iod), alloc_size);
+
+ return sizeof(struct sssraid_iod) + alloc_size;
+}
+
+static int sssraid_setup_prps(struct sssraid_dev *hdev, struct sssraid_iod *iod)
+{
+ struct scatterlist *sg = iod->sg;
+ u64 dma_addr = sg_dma_address(sg);
+ int dma_len = sg_dma_len(sg);
+ __le64 *prp_list, *old_prp_list;
+ int page_size = hdev->page_size;
+ int offset = dma_addr & (page_size - 1);
+ void **list = sssraid_iod_list(iod);
+ int length = iod->length;
+ struct dma_pool *pool;
+ dma_addr_t prp_dma;
+ int nprps, i;
+
+ length -= (page_size - offset);
+ if (length <= 0) {
+ iod->first_dma = 0;
+ return 0;
+ }
+
+ dma_len -= (page_size - offset);
+ if (dma_len) {
+ dma_addr += (page_size - offset);
+ } else {
+ sg = sg_next(sg);
+ dma_addr = sg_dma_address(sg);
+ dma_len = sg_dma_len(sg);
+ }
+
+ if (length <= page_size) {
+ iod->first_dma = dma_addr;
+ return 0;
+ }
+
+ nprps = DIV_ROUND_UP(length, page_size);
+ if (nprps <= (SMALL_POOL_SIZE / PRP_ENTRY_SIZE)) {
+ pool = iod->sqinfo->prp_small_pool;
+ iod->npages = 0;
+ } else {
+ pool = hdev->prp_page_pool;
+ iod->npages = 1;
+ }
+
+ prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
+ if (!prp_list) {
+ dev_err_ratelimited(&hdev->pdev->dev, "Allocate first prp_list memory failed\n");
+ iod->first_dma = dma_addr;
+ iod->npages = -1;
+ return -ENOMEM;
+ }
+ list[0] = prp_list;
+ iod->first_dma = prp_dma;
+ i = 0;
+ for (;;) {
+ if (i == page_size / PRP_ENTRY_SIZE) {
+ old_prp_list = prp_list;
+
+ prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
+ if (!prp_list) {
+ dev_err_ratelimited(&hdev->pdev->dev, "Allocate %dth prp_list memory failed\n",
+ iod->npages + 1);
+ return -ENOMEM;
+ }
+ list[iod->npages++] = prp_list;
+ prp_list[0] = old_prp_list[i - 1];
+ old_prp_list[i - 1] = cpu_to_le64(prp_dma);
+ i = 1;
+ }
+ prp_list[i++] = cpu_to_le64(dma_addr);
+ dma_len -= page_size;
+ dma_addr += page_size;
+ length -= page_size;
+ if (length <= 0)
+ break;
+ if (dma_len > 0)
+ continue;
+ if (unlikely(dma_len < 0))
+ goto bad_sgl;
+ sg = sg_next(sg);
+ dma_addr = sg_dma_address(sg);
+ dma_len = sg_dma_len(sg);
+ }
+
+ return 0;
+
+bad_sgl:
+ ioc_err(hdev, "Setup prps, invalid SGL for payload: %d nents: %d\n",
+ iod->length, iod->nsge);
+ return -EIO;
+}
+
+static inline bool sssraid_is_rw_scmd(struct scsi_cmnd *scmd)
+{
+ switch (scmd->cmnd[0]) {
+ case READ_6:
+ case READ_10:
+ case READ_12:
+ case READ_16:
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_12:
+ case WRITE_16:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool sssraid_is_prp(struct sssraid_dev *hdev, struct scsi_cmnd *scmd, u32 nsge)
+{
+ struct scatterlist *sg = scsi_sglist(scmd);
+ u32 page_mask = hdev->page_size - 1;
+ bool is_prp = true;
+ int i = 0;
+
+ scsi_for_each_sg(scmd, sg, nsge, i) {
+ if (i != 0 && i != nsge - 1) {
+ if ((sg_dma_len(sg) & page_mask) ||
+ (sg_dma_address(sg) & page_mask)) {
+ is_prp = false;
+ break;
+ }
+ }
+
+ if (nsge > 1 && i == 0) {
+ if ((sg_dma_address(sg) + sg_dma_len(sg)) & page_mask) {
+ is_prp = false;
+ break;
+ }
+ }
+
+ if (nsge > 1 && i == (nsge - 1)) {
+ if (sg_dma_address(sg) & page_mask) {
+ is_prp = false;
+ break;
+ }
+ }
+ }
+
+ return is_prp;
+}
+
+static void sssraid_sgl_set_data(struct sssraid_sgl_desc *sge, struct scatterlist *sg)
+{
+ sge->addr = cpu_to_le64(sg_dma_address(sg));
+ sge->length = cpu_to_le32(sg_dma_len(sg));
+ sge->type = SSSRAID_SGL_FMT_DATA_DESC << 4;
+}
+
+static void sssraid_sgl_set_seg(struct sssraid_sgl_desc *sge, dma_addr_t dma_addr, int entries)
+{
+ sge->addr = cpu_to_le64(dma_addr);
+ if (entries <= SGES_PER_PAGE) {
+ sge->length = cpu_to_le32(entries * sizeof(*sge));
+ sge->type = SSSRAID_SGL_FMT_LAST_SEG_DESC << 4;
+ } else {
+ sge->length = cpu_to_le32(PAGE_SIZE);
+ sge->type = SSSRAID_SGL_FMT_SEG_DESC << 4;
+ }
+}
+
+
+static int sssraid_setup_ioq_cmd_sgl(struct sssraid_dev *hdev,
+ struct scsi_cmnd *scmd, struct sssraid_ioq_command *ioq_cmd,
+ struct sssraid_iod *iod)
+{
+ struct sssraid_sgl_desc *sg_list, *link, *old_sg_list;
+ struct scatterlist *sg = scsi_sglist(scmd);
+ void **list = sssraid_iod_list(iod);
+ struct dma_pool *pool;
+ int nsge = iod->nsge;
+ dma_addr_t sgl_dma;
+ int i = 0;
+
+ ioq_cmd->common.flags |= SSSRAID_CMD_FLAG_SGL_METABUF;
+
+ if (nsge == 1) {
+ sssraid_sgl_set_data(&ioq_cmd->common.dptr.sgl, sg);
+ return 0;
+ }
+
+ if (nsge <= (SMALL_POOL_SIZE / sizeof(struct sssraid_sgl_desc))) {
+ pool = iod->sqinfo->prp_small_pool;
+ iod->npages = 0;
+ } else {
+ pool = hdev->prp_page_pool;
+ iod->npages = 1;
+ }
+
+ sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma);
+ if (!sg_list) {
+ dev_err_ratelimited(&hdev->pdev->dev, "Allocate first sgl_list failed\n");
+ iod->npages = -1;
+ return -ENOMEM;
+ }
+
+ list[0] = sg_list;
+ iod->first_dma = sgl_dma;
+ sssraid_sgl_set_seg(&ioq_cmd->common.dptr.sgl, sgl_dma, nsge);
+ do {
+ if (i == SGES_PER_PAGE) {
+ old_sg_list = sg_list;
+ link = &old_sg_list[SGES_PER_PAGE - 1];
+
+ sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma);
+ if (!sg_list) {
+ dev_err_ratelimited(&hdev->pdev->dev, "Allocate %dth sgl_list failed\n",
+ iod->npages + 1);
+ return -ENOMEM;
+ }
+ list[iod->npages++] = sg_list;
+
+ i = 0;
+ memcpy(&sg_list[i++], link, sizeof(*link));
+ sssraid_sgl_set_seg(link, sgl_dma, nsge);
+ }
+
+ sssraid_sgl_set_data(&sg_list[i++], sg);
+ sg = sg_next(sg);
+ } while (--nsge > 0);
+
+ return 0;
+}
+
+static void sssraid_shost_init(struct sssraid_dev *hdev)
+{
+ struct pci_dev *pdev = hdev->pdev;
+ u8 domain, bus;
+ u32 dev_func;
+
+ domain = pci_domain_nr(pdev->bus);
+ bus = pdev->bus->number;
+ dev_func = pdev->devfn;
+
+ hdev->shost->nr_hw_queues = hdev->init_done_queue_cnt - 1;
+ hdev->shost->can_queue = (hdev->ioq_depth - SSSRAID_PTCMDS_PERQ);
+
+ hdev->shost->sg_tablesize = le16_to_cpu(hdev->ctrl_info->max_num_sge);
+ /* 512B per sector */
+ hdev->shost->max_sectors = (1U << ((hdev->ctrl_info->mdts) * 1U) << 12) / 512;
+ hdev->shost->cmd_per_lun = MAX_CMD_PER_DEV;
+ hdev->shost->max_channel = le16_to_cpu(hdev->ctrl_info->max_channel) - 1;
+ hdev->shost->max_id = le32_to_cpu(hdev->ctrl_info->max_tgt_id);
+ hdev->shost->max_lun = le16_to_cpu(hdev->ctrl_info->max_lun);
+
+ hdev->shost->this_id = -1;
+ hdev->shost->unique_id = (domain << 16) | (bus << 8) | dev_func;
+ hdev->shost->max_cmd_len = MAX_CDB_LEN;
+ hdev->shost->hostt->cmd_size = sssraid_cmd_size(hdev);
+}
+
+static inline void sssraid_get_tag_from_scmd(struct scsi_cmnd *scmd, u16 *qidx, u16 *cid)
+{
+ u32 tag = blk_mq_unique_tag(scmd->request);
+
+ *qidx = blk_mq_unique_tag_to_hwq(tag) + 1;
+ *cid = blk_mq_unique_tag_to_tag(tag);
+}
+
+static inline uint32_t get_unaligned_be24(const uint8_t *const p)
+{
+ return get_unaligned_be32(p - 1) & 0xffffffU;
+}
+
+static int sssraid_setup_rw_cmd(struct sssraid_dev *hdev,
+ struct sssraid_rw_command *rw,
+ struct scsi_cmnd *scmd)
+{
+ u32 start_lba_lo, start_lba_hi;
+ u32 datalength = 0;
+ u16 control = 0;
+
+ start_lba_lo = 0;
+ start_lba_hi = 0;
+
+ if (scmd->sc_data_direction == DMA_TO_DEVICE) {
+ rw->opcode = SSSRAID_CMD_WRITE;
+ } else if (scmd->sc_data_direction == DMA_FROM_DEVICE) {
+ rw->opcode = SSSRAID_CMD_READ;
+ } else {
+ ioc_err(hdev, "Invalid RW_IO for unsupported data direction: %d\n",
+ scmd->sc_data_direction);
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ /* 6-byte READ(0x08) or WRITE(0x0A) cdb */
+ if (scmd->cmd_len == 6) {
+ datalength = (u32)(scmd->cmnd[4] == 0 ?
+ IO_6_DEFAULT_TX_LEN : scmd->cmnd[4]);
+ start_lba_lo = (u32)get_unaligned_be24(&scmd->cmnd[1]);
+
+ start_lba_lo &= 0x1FFFFF;
+ }
+
+ /* 10-byte READ(0x28) or WRITE(0x2A) cdb */
+ else if (scmd->cmd_len == 10) {
+ datalength = (u32)get_unaligned_be16(&scmd->cmnd[7]);
+ start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]);
+
+ if (scmd->cmnd[1] & FUA_MASK)
+ control |= SSSRAID_RW_FUA;
+ }
+
+ /* 12-byte READ(0xA8) or WRITE(0xAA) cdb */
+ else if (scmd->cmd_len == 12) {
+ datalength = get_unaligned_be32(&scmd->cmnd[6]);
+ start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]);
+
+ if (scmd->cmnd[1] & FUA_MASK)
+ control |= SSSRAID_RW_FUA;
+ }
+ /* 16-byte READ(0x88) or WRITE(0x8A) cdb */
+ else if (scmd->cmd_len == 16) {
+ datalength = get_unaligned_be32(&scmd->cmnd[10]);
+ start_lba_lo = get_unaligned_be32(&scmd->cmnd[6]);
+ start_lba_hi = get_unaligned_be32(&scmd->cmnd[2]);
+
+ if (scmd->cmnd[1] & FUA_MASK)
+ control |= SSSRAID_RW_FUA;
+ }
+
+ if (unlikely(datalength > U16_MAX || datalength == 0)) {
+ ioc_err(hdev, "Invalid IO for illegal transfer data length: %u\n", datalength);
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ rw->slba = cpu_to_le64(((u64)start_lba_hi << 32) | start_lba_lo);
+ /* 0base for nlb */
+ rw->nlb = cpu_to_le16((u16)(datalength - 1));
+ rw->control = cpu_to_le16(control);
+
+ return 0;
+}
+
+static int sssraid_setup_nonio_cmd(struct sssraid_dev *hdev,
+ struct sssraid_scsi_nonio *scsi_nonio, struct scsi_cmnd *scmd)
+{
+ scsi_nonio->buffer_len = cpu_to_le32(scsi_bufflen(scmd));
+
+ switch (scmd->sc_data_direction) {
+ case DMA_NONE:
+ scsi_nonio->opcode = SSSRAID_CMD_NONIO_NONE;
+ break;
+ case DMA_TO_DEVICE:
+ scsi_nonio->opcode = SSSRAID_CMD_NONIO_TODEV;
+ break;
+ case DMA_FROM_DEVICE:
+ scsi_nonio->opcode = SSSRAID_CMD_NONIO_FROMDEV;
+ break;
+ default:
+ ioc_err(hdev, "Invalid NON_IO for unsupported data direction: %d\n",
+ scmd->sc_data_direction);
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int sssraid_setup_ioq_cmd(struct sssraid_dev *hdev,
+ struct sssraid_ioq_command *ioq_cmd, struct scsi_cmnd *scmd)
+{
+ memcpy(ioq_cmd->common.cdb, scmd->cmnd, scmd->cmd_len);
+ ioq_cmd->common.cdb_len = scmd->cmd_len;
+
+ if (sssraid_is_rw_scmd(scmd))
+ return sssraid_setup_rw_cmd(hdev, &ioq_cmd->rw, scmd);
+ else
+ return sssraid_setup_nonio_cmd(hdev, &ioq_cmd->scsi_nonio, scmd);
+}
+
+static inline void sssraid_init_iod(struct sssraid_iod *iod)
+{
+ iod->nsge = 0;
+ iod->npages = -1;
+ iod->use_sgl = false;
+ WRITE_ONCE(iod->state, SSSRAID_CMD_IDLE);
+}
+
+int sssraid_io_map_data(struct sssraid_dev *hdev, struct sssraid_iod *iod,
+ struct scsi_cmnd *scmd, struct sssraid_ioq_command *ioq_cmd)
+{
+ int retval;
+
+ retval = scsi_dma_map(scmd);
+ if (unlikely(retval < 0))
+ return retval;
+ iod->nsge = retval;
+ /* No data to DMA, it may be scsi no-rw command */
+ if (unlikely(iod->nsge == 0))
+ return 0;
+
+ iod->length = scsi_bufflen(scmd);
+ iod->sg = scsi_sglist(scmd);
+ iod->use_sgl = !sssraid_is_prp(hdev, scmd, iod->nsge);
+
+ if (iod->use_sgl) {
+ retval = sssraid_setup_ioq_cmd_sgl(hdev, scmd, ioq_cmd, iod);
+ } else {
+ retval = sssraid_setup_prps(hdev, iod);
+ ioq_cmd->common.dptr.prp1 =
+ cpu_to_le64(sg_dma_address(iod->sg));
+ ioq_cmd->common.dptr.prp2 = cpu_to_le64(iod->first_dma);
+ }
+
+ if (retval)
+ scsi_dma_unmap(scmd);
+
+ return retval;
+}
+
+void sssraid_map_status(struct sssraid_iod *iod, struct scsi_cmnd *scmd,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_dev *hdev = iod->sqinfo->hdev;
+
+ scsi_set_resid(scmd, 0);
+
+ switch ((le16_to_cpu(cqe->status) >> 1) & 0x7f) {
+ case FW_STAT_OK:
+ set_host_byte(scmd, DID_OK);
+ break;
+ case FW_STAT_NEED_CHECK:
+ set_host_byte(scmd, DID_OK);
+ scmd->result |= le16_to_cpu(cqe->status) >> 8;
+ if (scmd->result & SAM_STAT_CHECK_CONDITION) {
+ memset(scmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ memcpy(scmd->sense_buffer, iod->sense, SCSI_SENSE_BUFFERSIZE);
+ scmd->result = (scmd->result & 0x00ffffff) | (DRIVER_SENSE << 24);
+ }
+ break;
+ case FW_STAT_ABORTED:
+ set_host_byte(scmd, DID_ABORT);
+ break;
+ case FW_STAT_NEED_RETRY:
+ set_host_byte(scmd, DID_REQUEUE);
+ break;
+ default:
+ set_host_byte(scmd, DID_BAD_TARGET);
+ ioc_warn(hdev, "cid[%d] qid[%d] bad status[0x%x]\n",
+ le16_to_cpu(cqe->cmd_id), le16_to_cpu(cqe->sq_id),
+ le16_to_cpu(cqe->status));
+ break;
+ }
+}
+
+
+struct sssraid_cmd *sssraid_get_cmd(struct sssraid_dev *hdev, enum sssraid_cmd_type type)
+{
+ struct sssraid_cmd *cmd = NULL;
+ unsigned long flags;
+ struct list_head *head = &hdev->adm_cmd_list;
+ spinlock_t *slock = &hdev->adm_cmd_lock;
+
+ if (type == SSSRAID_CMD_IOPT) {
+ head = &hdev->ioq_pt_list;
+ slock = &hdev->ioq_pt_lock;
+ }
+
+ spin_lock_irqsave(slock, flags);
+ if (list_empty(head)) {
+ spin_unlock_irqrestore(slock, flags);
+ ioc_err(hdev, "err, cmd[%d] list empty\n", type);
+ return NULL;
+ }
+ cmd = list_entry(head->next, struct sssraid_cmd, list);
+ list_del_init(&cmd->list);
+ spin_unlock_irqrestore(slock, flags);
+
+ WRITE_ONCE(cmd->state, SSSRAID_CMD_IN_FLIGHT);
+
+ return cmd;
+}
+
+static int sssraid_add_device(struct sssraid_dev *hdev, struct sssraid_dev_info *device)
+{
+ struct Scsi_Host *shost = hdev->shost;
+ struct scsi_device *sdev;
+
+ ioc_info(hdev, "add device, hdid: %u target: %d, channel: %d, lun: %d, attr[0x%x]\n",
+ le32_to_cpu(device->hdid), le16_to_cpu(device->target),
+ device->channel, device->lun, device->attr);
+
+ sdev = scsi_device_lookup(shost, device->channel, le16_to_cpu(device->target), 0);
+ if (sdev) {
+ ioc_warn(hdev, "Device is already exist, channel: %d, target_id: %d, lun: %d\n",
+ device->channel, le16_to_cpu(device->target), 0);
+ scsi_device_put(sdev);
+ return -EEXIST;
+ }
+ scsi_add_device(shost, device->channel, le16_to_cpu(device->target), 0);
+ return 0;
+}
+
+static int sssraid_rescan_device(struct sssraid_dev *hdev, struct sssraid_dev_info *device)
+{
+ struct Scsi_Host *shost = hdev->shost;
+ struct scsi_device *sdev;
+
+ ioc_info(hdev, "rescan device, hdid: %u target: %d, channel: %d, lun: %d, attr[0x%x]\n",
+ le32_to_cpu(device->hdid), le16_to_cpu(device->target),
+ device->channel, device->lun, device->attr);
+
+ sdev = scsi_device_lookup(shost, device->channel, le16_to_cpu(device->target), 0);
+ if (!sdev) {
+ ioc_warn(hdev, "device is not exit rescan it, channel: %d, target_id: %d, lun: %d\n",
+ device->channel, le16_to_cpu(device->target), 0);
+ return -ENODEV;
+ }
+
+ scsi_rescan_device(&sdev->sdev_gendev);
+ scsi_device_put(sdev);
+ return 0;
+}
+
+static int sssraid_remove_device(struct sssraid_dev *hdev, struct sssraid_dev_info *org_device)
+{
+ struct Scsi_Host *shost = hdev->shost;
+ struct scsi_device *sdev;
+
+ ioc_info(hdev, "remove device, hdid: %u target: %d, channel: %d, lun: %d, attr[0x%x]\n",
+ le32_to_cpu(org_device->hdid), le16_to_cpu(org_device->target),
+ org_device->channel, org_device->lun, org_device->attr);
+
+ sdev = scsi_device_lookup(shost, org_device->channel, le16_to_cpu(org_device->target), 0);
+ if (!sdev) {
+ ioc_warn(hdev, "device is not exit remove it, channel: %d, target_id: %d, lun: %d\n",
+ org_device->channel, le16_to_cpu(org_device->target), 0);
+ return -ENODEV;
+ }
+
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ return 0;
+}
+
+static int luntarget_cmp_func(const void *l, const void *r)
+{
+ const struct sssraid_dev_info *ln = l;
+ const struct sssraid_dev_info *rn = r;
+ int l_attr = SSSRAID_DEV_INFO_ATTR_BOOT(ln->attr);
+ int r_attr = SSSRAID_DEV_INFO_ATTR_BOOT(rn->attr);
+
+ /* boot first */
+ if (l_attr != r_attr)
+ return (r_attr - l_attr);
+
+ if (ln->channel == rn->channel)
+ return le16_to_cpu(ln->target) - le16_to_cpu(rn->target);
+
+ return ln->channel - rn->channel;
+}
+
+void sssraid_scan_disk(struct sssraid_dev *hdev)
+{
+ struct sssraid_dev_info *devices, *org_devices;
+ struct sssraid_dev_info *sortdevice;
+ u32 nd = le32_to_cpu(hdev->ctrl_info->nd);
+ u8 flag, org_flag;
+ int i, ret;
+ int count = 0;
+
+ devices = kcalloc(nd, sizeof(struct sssraid_dev_info), GFP_KERNEL);
+ if (!devices)
+ return;
+
+ sortdevice = kcalloc(nd, sizeof(struct sssraid_dev_info), GFP_KERNEL);
+ if (!sortdevice)
+ goto free_list;
+
+ ret = sssraid_get_dev_list(hdev, devices);
+ if (ret)
+ goto free_all;
+ org_devices = hdev->devices;
+ for (i = 0; i < nd; i++) {
+ org_flag = org_devices[i].flag;
+ flag = devices[i].flag;
+
+ dbgprint(hdev, "i: %d, org_flag: 0x%x, flag: 0x%x\n", i, org_flag, flag);
+
+ if (SSSRAID_DEV_INFO_FLAG_VALID(flag)) {
+ if (!SSSRAID_DEV_INFO_FLAG_VALID(org_flag)) {
+ down_write(&hdev->devices_rwsem);
+ memcpy(&org_devices[i], &devices[i],
+ sizeof(struct sssraid_dev_info));
+ memcpy(&sortdevice[count++], &devices[i],
+ sizeof(struct sssraid_dev_info));
+ up_write(&hdev->devices_rwsem);
+ } else if (SSSRAID_DEV_INFO_FLAG_CHANGE(flag)) {
+ sssraid_rescan_device(hdev, &devices[i]);
+ }
+ } else {
+ if (SSSRAID_DEV_INFO_FLAG_VALID(org_flag)) {
+ down_write(&hdev->devices_rwsem);
+ org_devices[i].flag &= 0xfe;
+ up_write(&hdev->devices_rwsem);
+ sssraid_remove_device(hdev, &org_devices[i]);
+ }
+ }
+ }
+
+ ioc_info(hdev, "scan work add device count = %d\n", count);
+
+ sort(sortdevice, count, sizeof(sortdevice[0]), luntarget_cmp_func, NULL);
+
+ for (i = 0; i < count; i++)
+ sssraid_add_device(hdev, &sortdevice[i]);
+
+free_all:
+ kfree(sortdevice);
+free_list:
+ kfree(devices);
+}
+
+static int sssraid_wait_abnl_cmd_done(struct sssraid_iod *iod)
+{
+ u16 times = 0;
+
+ do {
+ if (READ_ONCE(iod->state) == SSSRAID_CMD_TMO_COMPLETE)
+ break;
+ msleep(500);
+ times++;
+ } while (times <= SSSRAID_WAIT_ABNL_CMD_TIMEOUT);
+
+ /* wait command completion timeout after abort/reset success */
+ if (times >= SSSRAID_WAIT_ABNL_CMD_TIMEOUT)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static bool sssraid_check_scmd_completed(struct scsi_cmnd *scmd)
+{
+ struct sssraid_dev *hdev = shost_priv(scmd->device->host);
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ struct sssraid_squeue *sqinfo;
+ u16 hwq, cid;
+
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+ sqinfo = &hdev->sqinfo[hwq];
+ if (READ_ONCE(iod->state) == SSSRAID_CMD_COMPLETE || sssraid_poll_cq(hdev, hwq, cid)) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] has been completed\n",
+ cid, sqinfo->qidx);
+ return true;
+ }
+ return false;
+}
+
+static int sssraid_scsi_reset(struct scsi_cmnd *scmd, enum sssraid_scsi_rst_type rst)
+{
+ struct sssraid_dev *hdev = shost_priv(scmd->device->host);
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ struct sssraid_sdev_hostdata *hostdata;
+ u16 hwq, cid;
+ int ret;
+
+ scsi_print_command(scmd);
+
+ if (hdev->state != SSSRAID_LIVE || !sssraid_wait_abnl_cmd_done(iod) ||
+ sssraid_check_scmd_completed(scmd))
+ return SUCCESS;
+
+ hostdata = scmd->device->hostdata;
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] timeout, %s reset\n", cid, hwq,
+ rst ? "bus" : "target");
+ ret = sssraid_send_reset_cmd(hdev, rst, hostdata->hdid);
+ if (ret == 0) {
+ ret = sssraid_wait_abnl_cmd_done(iod);
+ if (ret) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] %s reset failed, not found\n",
+ cid, hwq, rst ? "bus" : "target");
+ return FAILED;
+ }
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] %s reset success\n", cid, hwq,
+ rst ? "bus" : "target");
+ return SUCCESS;
+ }
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] ret[%d] %s reset failed\n", cid, hwq, ret,
+ rst ? "bus" : "target");
+ return FAILED;
+}
+
+bool sssraid_change_host_state(struct sssraid_dev *hdev, enum sssraid_state newstate)
+{
+ unsigned long flags;
+ enum sssraid_state oldstate;
+ bool change = false;
+
+ spin_lock_irqsave(&hdev->state_lock, flags);
+
+ oldstate = hdev->state;
+ switch (newstate) {
+ case SSSRAID_LIVE:
+ switch (oldstate) {
+ case SSSRAID_NEW:
+ case SSSRAID_RESETTING:
+ change = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SSSRAID_RESETTING:
+ switch (oldstate) {
+ case SSSRAID_LIVE:
+ change = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SSSRAID_DELETING:
+ if (oldstate != SSSRAID_DELETING)
+ change = true;
+ break;
+ case SSSRAID_DEAD:
+ switch (oldstate) {
+ case SSSRAID_NEW:
+ case SSSRAID_LIVE:
+ case SSSRAID_RESETTING:
+ change = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ if (change)
+ hdev->state = newstate;
+ spin_unlock_irqrestore(&hdev->state_lock, flags);
+
+ ioc_info(hdev, "[%d]->[%d], change[%d]\n", oldstate, newstate, change);
+
+ return change;
+}
+
+static int sssraid_get_qd_by_disk(u8 attr)
+{
+ switch (SSSRAID_DEV_DISK_TYPE(attr)) {
+ case SSSRAID_SAS_HDD_VD:
+ case SSSRAID_SATA_HDD_VD:
+ return SSSRAID_HDD_VD_QD;
+ case SSSRAID_SAS_SSD_VD:
+ case SSSRAID_SATA_SSD_VD:
+ case SSSRAID_NVME_SSD_VD:
+ return SSSRAID_SSD_VD_QD;
+ case SSSRAID_SAS_HDD_PD:
+ case SSSRAID_SATA_HDD_PD:
+ return SSSRAID_HDD_PD_QD;
+ case SSSRAID_SAS_SSD_PD:
+ case SSSRAID_SATA_SSD_PD:
+ case SSSRAID_NVME_SSD_PD:
+ return SSSRAID_SSD_PD_QD;
+ default:
+ return MAX_CMD_PER_DEV;
+ }
+}
+
+static int sssraid_match_dev(struct sssraid_dev *hdev, u16 idx, struct scsi_device *sdev)
+{
+ if (SSSRAID_DEV_INFO_FLAG_VALID(hdev->devices[idx].flag)) {
+ if (sdev->channel == hdev->devices[idx].channel &&
+ sdev->id == le16_to_cpu(hdev->devices[idx].target) &&
+ sdev->lun < hdev->devices[idx].lun) {
+ ioc_info(hdev, "Match device success, channel:target:lun[%d:%d:%d]\n",
+ hdev->devices[idx].channel,
+ hdev->devices[idx].target,
+ hdev->devices[idx].lun);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int sssraid_bsg_map_data(struct sssraid_dev *hdev, struct bsg_job *job,
+ struct sssraid_admin_command *cmd)
+{
+ struct request *rq = blk_mq_rq_from_pdu(job);
+ struct sssraid_iod *iod = job->dd_data;
+ enum dma_data_direction dma_dir = rq_data_dir(rq) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ int ret = 0;
+
+ iod->sg = job->request_payload.sg_list;
+ iod->nsge = job->request_payload.sg_cnt;
+ iod->length = job->request_payload.payload_len;
+ iod->use_sgl = false;
+ iod->npages = -1;
+
+ if (!iod->nsge)
+ goto out;
+
+ ret = dma_map_sg_attrs(&hdev->pdev->dev, iod->sg, iod->nsge, dma_dir, DMA_ATTR_NO_WARN);
+ if (!ret)
+ goto out;
+
+ ret = sssraid_setup_prps(hdev, iod);
+ if (ret)
+ goto unmap;
+
+ cmd->common.dptr.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
+ cmd->common.dptr.prp2 = cpu_to_le64(iod->first_dma);
+
+ return 0;
+
+unmap:
+ dma_unmap_sg(&hdev->pdev->dev, iod->sg, iod->nsge, dma_dir);
+out:
+ return ret;
+}
+
+static void sssraid_bsg_unmap_data(struct sssraid_dev *hdev, struct bsg_job *job)
+{
+ struct request *rq = blk_mq_rq_from_pdu(job);
+ struct sssraid_iod *iod = job->dd_data;
+ enum dma_data_direction dma_dir = rq_data_dir(rq) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+ if (iod->nsge)
+ dma_unmap_sg(&hdev->pdev->dev, iod->sg, iod->nsge, dma_dir);
+
+ sssraid_free_iod_res(hdev, iod);
+}
+
+void sssraid_put_cmd(struct sssraid_dev *hdev, struct sssraid_cmd *cmd,
+ enum sssraid_cmd_type type)
+{
+ unsigned long flags;
+ struct list_head *head = &hdev->adm_cmd_list;
+ spinlock_t *slock = &hdev->adm_cmd_lock;
+
+ if (type == SSSRAID_CMD_IOPT) {
+ head = &hdev->ioq_pt_list;
+ slock = &hdev->ioq_pt_lock;
+ }
+
+ spin_lock_irqsave(slock, flags);
+ WRITE_ONCE(cmd->state, SSSRAID_CMD_IDLE);
+ list_add_tail(&cmd->list, head);
+ spin_unlock_irqrestore(slock, flags);
+}
+
+static int sssraid_user_admin_cmd(struct sssraid_dev *hdev, struct bsg_job *job)
+{
+ struct sssraid_bsg_request *bsg_req = job->request;
+ struct sssraid_passthru_common_cmd *cmd = &(bsg_req->admcmd);
+ struct sssraid_admin_command admin_cmd;
+ u32 timeout = msecs_to_jiffies(cmd->timeout_ms);
+ u32 result[2] = {0};
+ int status;
+
+ if (hdev->state >= SSSRAID_RESETTING) {
+ ioc_err(hdev, "err, host state:[%d] is not right\n",
+ hdev->state);
+ return -EBUSY;
+ }
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.common.opcode = cmd->opcode;
+ admin_cmd.common.flags = cmd->flags;
+ admin_cmd.common.hdid = cpu_to_le32(cmd->nsid);
+ admin_cmd.common.cdw2[0] = cpu_to_le32(cmd->cdw2);
+ admin_cmd.common.cdw2[1] = cpu_to_le32(cmd->cdw3);
+ admin_cmd.common.cdw10 = cpu_to_le32(cmd->cdw10);
+ admin_cmd.common.cdw11 = cpu_to_le32(cmd->cdw11);
+ admin_cmd.common.cdw12 = cpu_to_le32(cmd->cdw12);
+ admin_cmd.common.cdw13 = cpu_to_le32(cmd->cdw13);
+ admin_cmd.common.cdw14 = cpu_to_le32(cmd->cdw14);
+ admin_cmd.common.cdw15 = cpu_to_le32(cmd->cdw15);
+
+ status = sssraid_bsg_map_data(hdev, job, &admin_cmd);
+ if (status) {
+ ioc_err(hdev, "err, map data failed\n");
+ return status;
+ }
+
+ status = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, &result[0], &result[1], timeout);
+ if (status >= 0) {
+ job->reply_len = sizeof(result);
+ memcpy(job->reply, result, sizeof(result));
+ }
+
+ if (status)
+ ioc_info(hdev, "opcode[0x%x] subopcode[0x%x], status[0x%x] result0[0x%x] result1[0x%x]\n",
+ cmd->opcode, cmd->info_0.subopcode, status, result[0], result[1]);
+
+ sssraid_bsg_unmap_data(hdev, job);
+
+ return status;
+}
+
+static int sssraid_submit_ioq_sync_cmd(struct sssraid_dev *hdev, struct sssraid_ioq_command *cmd,
+ u32 *result, u32 *reslen, u32 timeout)
+{
+ int ret;
+ dma_addr_t sense_dma;
+ struct sssraid_squeue *sqinfo;
+ void *sense_addr = NULL;
+ struct sssraid_cmd *pt_cmd = sssraid_get_cmd(hdev, SSSRAID_CMD_IOPT);
+
+ if (!pt_cmd) {
+ ioc_err(hdev, "err, get sqinfo cmd failed\n");
+ return -EFAULT;
+ }
+
+ timeout = timeout ? timeout : ADMIN_TIMEOUT;
+
+ init_completion(&pt_cmd->cmd_done);
+
+ sqinfo = &hdev->sqinfo[pt_cmd->qid];
+ ret = pt_cmd->cid * SCSI_SENSE_BUFFERSIZE;
+ sense_addr = sqinfo->sense + ret;
+ sense_dma = sqinfo->sense_dma_addr + ret;
+
+ cmd->common.sense_addr = cpu_to_le64(sense_dma);
+ cmd->common.sense_len = cpu_to_le16(SCSI_SENSE_BUFFERSIZE);
+ cmd->common.command_id = cpu_to_le16(pt_cmd->cid);
+
+ sssraid_submit_cmd(sqinfo, cmd);
+
+ if (!wait_for_completion_timeout(&pt_cmd->cmd_done, timeout)) {
+ ioc_err(hdev, "cid[%d] qid[%d] timeout, opcode[0x%x] subopcode[0x%x]\n",
+ pt_cmd->cid, pt_cmd->qid, cmd->common.opcode,
+ (le32_to_cpu(cmd->common.cdw3[0]) & 0xffff));
+
+ /* reset controller if admin timeout */
+ sssraid_adm_timeout(hdev, pt_cmd);
+
+ sssraid_put_cmd(hdev, pt_cmd, SSSRAID_CMD_IOPT);
+ return -ETIME;
+ }
+
+ if (result && reslen) {
+ if ((pt_cmd->status & 0x17f) == 0x101) {
+ memcpy(result, sense_addr, SCSI_SENSE_BUFFERSIZE);
+ *reslen = SCSI_SENSE_BUFFERSIZE;
+ }
+ }
+
+ sssraid_put_cmd(hdev, pt_cmd, SSSRAID_CMD_IOPT);
+
+ return pt_cmd->status;
+}
+
+static int sssraid_user_ioq_cmd(struct sssraid_dev *hdev, struct bsg_job *job)
+{
+ struct sssraid_bsg_request *bsg_req = (struct sssraid_bsg_request *)(job->request);
+ struct sssraid_ioq_passthru_cmd *cmd = &(bsg_req->ioqcmd);
+ struct sssraid_ioq_command ioq_cmd;
+ int status = 0;
+ u32 timeout = msecs_to_jiffies(cmd->timeout_ms);
+
+ if (cmd->data_len > IOQ_PT_DATA_LEN) {
+ ioc_err(hdev, "data len bigger than 4k\n");
+ return -EFAULT;
+ }
+
+ if (hdev->state != SSSRAID_LIVE) {
+ ioc_err(hdev, "err, host state:[%d] is not live\n",
+ hdev->state);
+ return -EBUSY;
+ }
+
+ ioc_info(hdev, "opcode[0x%x] subopcode[0x%x] init, datalen[%d]\n",
+ cmd->opcode, cmd->info_1.subopcode, cmd->data_len);
+
+ memset(&ioq_cmd, 0, sizeof(ioq_cmd));
+ ioq_cmd.common.opcode = cmd->opcode;
+ ioq_cmd.common.flags = cmd->flags;
+ ioq_cmd.common.hdid = cpu_to_le32(cmd->nsid);
+ ioq_cmd.common.sense_len = cpu_to_le16(cmd->info_0.res_sense_len);
+ ioq_cmd.common.cdb_len = cmd->info_0.cdb_len;
+ ioq_cmd.common.rsvd2 = cmd->info_0.rsvd0;
+ ioq_cmd.common.cdw3[0] = cpu_to_le32(cmd->cdw3);
+ ioq_cmd.common.cdw3[1] = cpu_to_le32(cmd->cdw4);
+ ioq_cmd.common.cdw3[2] = cpu_to_le32(cmd->cdw5);
+
+ ioq_cmd.common.cdw10[0] = cpu_to_le32(cmd->cdw10);
+ ioq_cmd.common.cdw10[1] = cpu_to_le32(cmd->cdw11);
+ ioq_cmd.common.cdw10[2] = cpu_to_le32(cmd->cdw12);
+ ioq_cmd.common.cdw10[3] = cpu_to_le32(cmd->cdw13);
+ ioq_cmd.common.cdw10[4] = cpu_to_le32(cmd->cdw14);
+ ioq_cmd.common.cdw10[5] = cpu_to_le32(cmd->data_len);
+
+ memcpy(ioq_cmd.common.cdb, &cmd->cdw16, cmd->info_0.cdb_len);
+
+ ioq_cmd.common.cdw26[0] = cpu_to_le32(cmd->cdw26[0]);
+ ioq_cmd.common.cdw26[1] = cpu_to_le32(cmd->cdw26[1]);
+ ioq_cmd.common.cdw26[2] = cpu_to_le32(cmd->cdw26[2]);
+ ioq_cmd.common.cdw26[3] = cpu_to_le32(cmd->cdw26[3]);
+
+ status = sssraid_bsg_map_data(hdev, job, (struct sssraid_admin_command *)&ioq_cmd);
+ if (status) {
+ ioc_err(hdev, "err, map data failed\n");
+ return status;
+ }
+
+ status = sssraid_submit_ioq_sync_cmd(hdev, &ioq_cmd, job->reply, &job->reply_len, timeout);
+ if (status)
+ ioc_info(hdev, "opcode[0x%x] subopcode[0x%x], status[0x%x], reply_len[%d]\n",
+ cmd->opcode, cmd->info_1.subopcode, status, job->reply_len);
+
+ sssraid_bsg_unmap_data(hdev, job);
+
+ return status;
+}
+
+
+/* bsg dispatch user command */
+static int sssraid_bsg_host_dispatch(struct bsg_job *job)
+{
+ struct Scsi_Host *shost = dev_to_shost(job->dev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ struct request *rq = blk_mq_rq_from_pdu(job);
+ struct sssraid_bsg_request *bsg_req = job->request;
+ int ret = -ENOMSG;
+
+ job->reply_len = 0;
+
+ if (bsg_req == NULL || job->request_len != sizeof(struct sssraid_bsg_request)) {
+ bsg_job_done(job, ret, 0);
+ return 0;
+ }
+ dbgprint(hdev, "bsg msgcode[%d] msglen[%d] timeout[%d];"
+ "reqnsge[%d], reqlen[%d]\n",
+ bsg_req->msgcode, job->request_len, rq->timeout,
+ job->request_payload.sg_cnt, job->request_payload.payload_len);
+
+ switch (bsg_req->msgcode) {
+ case SSSRAID_BSG_ADM:
+ ret = sssraid_user_admin_cmd(hdev, job);
+ break;
+ case SSSRAID_BSG_IOQ:
+ ret = sssraid_user_ioq_cmd(hdev, job);
+ break;
+ default:
+ ioc_info(hdev, "unsupport msgcode[%d]\n", bsg_req->msgcode);
+ break;
+ }
+
+ if (ret > 0)
+ ret = ret | (ret << 8);
+
+ bsg_job_done(job, ret, 0);
+ return 0;
+}
+
+static inline void sssraid_remove_bsg(struct sssraid_dev *hdev)
+{
+ if (hdev->bsg_queue) {
+ bsg_unregister_queue(hdev->bsg_queue);
+ blk_cleanup_queue(hdev->bsg_queue);
+ }
+}
+
+static void sssraid_back_fault_cqe(struct sssraid_squeue *sqinfo, struct sssraid_completion *cqe)
+{
+ struct sssraid_dev *hdev = sqinfo->hdev;
+ struct blk_mq_tags *tags;
+ struct scsi_cmnd *scmd;
+ struct sssraid_iod *iod;
+ struct request *req;
+
+ tags = hdev->shost->tag_set.tags[sqinfo->qidx - 1];
+ req = blk_mq_tag_to_rq(tags, le16_to_cpu(cqe->cmd_id));
+ if (unlikely(!req || !blk_mq_request_started(req)))
+ return;
+
+ scmd = blk_mq_rq_to_pdu(req);
+ iod = scsi_cmd_priv(scmd);
+
+ if (READ_ONCE(iod->state) != SSSRAID_CMD_IN_FLIGHT &&
+ READ_ONCE(iod->state) != SSSRAID_CMD_TIMEOUT)
+ return;
+
+ WRITE_ONCE(iod->state, SSSRAID_CMD_TMO_COMPLETE);
+ set_host_byte(scmd, DID_NO_CONNECT);
+ if (iod->nsge)
+ scsi_dma_unmap(scmd);
+ sssraid_free_iod_res(hdev, iod);
+ scmd->scsi_done(scmd);
+ ioc_warn(hdev, "Back fault CQE, cid[%d] qidx[%d]\n",
+ le16_to_cpu(cqe->cmd_id), sqinfo->qidx);
+}
+
+void sssraid_back_all_io(struct sssraid_dev *hdev)
+{
+ int i, j;
+ struct sssraid_squeue *sqinfo;
+ struct sssraid_completion cqe = { 0 };
+
+ scsi_block_requests(hdev->shost);
+
+ for (i = 1; i <= hdev->shost->nr_hw_queues; i++) {
+ sqinfo = &hdev->sqinfo[i];
+ for (j = 0; j < hdev->scsi_qd; j++) {
+ cqe.cmd_id = cpu_to_le16(j);
+ sssraid_back_fault_cqe(sqinfo, &cqe);
+ }
+ }
+
+ scsi_unblock_requests(hdev->shost);
+
+ j = SSSRAID_AQ_BLK_MQ_DEPTH;
+ for (i = 0; i < j; i++) {
+ if (READ_ONCE(hdev->adm_cmds[i].state) == SSSRAID_CMD_IN_FLIGHT) {
+ ioc_info(hdev, "Back adm, cid[%d]\n", i);
+ hdev->adm_cmds[i].status = 0xFFFF;
+ WRITE_ONCE(hdev->adm_cmds[i].state, SSSRAID_CMD_COMPLETE);
+ complete(&(hdev->adm_cmds[i].cmd_done));
+ }
+ }
+
+ j = SSSRAID_NR_IOQ_PTCMDS;
+ for (i = 0; i < j; i++) {
+ if (READ_ONCE(hdev->ioq_ptcmds[i].state) == SSSRAID_CMD_IN_FLIGHT) {
+ hdev->ioq_ptcmds[i].status = 0xFFFF;
+ WRITE_ONCE(hdev->ioq_ptcmds[i].state, SSSRAID_CMD_COMPLETE);
+ complete(&(hdev->ioq_ptcmds[i].cmd_done));
+ }
+ }
+}
+
+/**
+ * static struct scsi_host_template sssraid_driver_template
+ */
+static int sssraid_scan_finished(struct Scsi_Host *shost,
+ unsigned long time)
+{
+ struct sssraid_dev *hdev = shost_priv(shost);
+
+ sssraid_scan_disk(hdev);
+
+ return 1;
+}
+
+/* eh_target_reset_handler call back */
+static int sssraid_eh_target_reset(struct scsi_cmnd *scmd)
+{
+ return sssraid_scsi_reset(scmd, SSSRAID_RESET_TARGET);
+}
+
+/* eh_bus_reset_handler call back */
+static int sssraid_bus_reset_handler(struct scsi_cmnd *scmd)
+{
+ return sssraid_scsi_reset(scmd, SSSRAID_RESET_BUS);
+}
+
+/* eh_host_reset_handler call back */
+static int sssraid_eh_host_reset(struct scsi_cmnd *scmd)
+{
+ u16 hwq, cid;
+ struct sssraid_dev *hdev = shost_priv(scmd->device->host);
+
+ scsi_print_command(scmd);
+ if (hdev->state != SSSRAID_LIVE || sssraid_check_scmd_completed(scmd))
+ return SUCCESS;
+
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+ ioc_warn(hdev, "cid[%d] qidx[%d] host reset\n", cid, hwq);
+
+ /* It's useless:
+ * old code sssraid_reset_work_sync
+ * queue_work(reset_work) at first,
+ * then flush_work to synchronize.
+ */
+ if (!sssraid_change_host_state(hdev, SSSRAID_RESETTING)) {
+ ioc_info(hdev, "can't change to reset state\n");
+ return FAILED;
+ }
+ if (sssraid_soft_reset_handler(hdev)) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] host reset failed\n", cid, hwq);
+ return FAILED;
+ }
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] host reset success\n", cid, hwq);
+
+ return SUCCESS;
+}
+
+/* host_reset call back */
+static int sssraid_sysfs_host_reset(struct Scsi_Host *shost, int reset_type)
+{
+ int ret;
+ struct sssraid_dev *hdev = shost_priv(shost);
+
+ ioc_info(hdev, "start sysfs host reset cmd\n");
+ if (!sssraid_change_host_state(hdev, SSSRAID_RESETTING)) {
+ ioc_info(hdev, "can't change to reset state\n");
+ return -EBUSY;
+ }
+ ret = sssraid_soft_reset_handler(hdev);
+ ioc_info(hdev, "stop sysfs host reset cmd[%d]\n", ret);
+
+ return ret;
+}
+
+/* queuecommand call back */
+static int sssraid_qcmd(struct Scsi_Host *shost,
+ struct scsi_cmnd *scmd)
+{
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ struct scsi_device *sdev = scmd->device;
+ struct sssraid_sdev_hostdata *hostdata = sdev->hostdata;
+ u16 hwq, cid;
+ struct sssraid_squeue *sq;
+ struct sssraid_ioq_command ioq_cmd;
+ int retval;
+
+ if (unlikely(hdev->state == SSSRAID_RESETTING))
+ return SCSI_MLQUEUE_HOST_BUSY;
+
+ if (unlikely(hdev->state != SSSRAID_LIVE)) {
+ set_host_byte(scmd, DID_NO_CONNECT);
+ scmd->scsi_done(scmd);
+ return 0;
+ }
+
+ if (unlikely(hdev->logging_level & SSSRAID_DEBUG))
+ scsi_print_command(scmd);
+
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+ hostdata = sdev->hostdata;
+ sq = &hdev->sqinfo[hwq];
+
+ memset(&ioq_cmd, 0, sizeof(ioq_cmd));
+ ioq_cmd.rw.hdid = cpu_to_le32(hostdata->hdid);
+ ioq_cmd.rw.command_id = cpu_to_le16(cid);
+
+ retval = sssraid_setup_ioq_cmd(hdev, &ioq_cmd, scmd);
+ if (unlikely(retval)) {
+ set_host_byte(scmd, DID_ERROR);
+ scmd->scsi_done(scmd);
+ return 0;
+ }
+
+ iod->sense = sq->sense + retval;
+ iod->sense_dma = sq->sense_dma_addr + retval;
+ ioq_cmd.common.sense_addr = cpu_to_le64(iod->sense_dma);
+ ioq_cmd.common.sense_len = cpu_to_le16(SCSI_SENSE_BUFFERSIZE);
+
+ sssraid_init_iod(iod);
+
+ iod->sqinfo = sq;
+ sssraid_io_map_data(hdev, iod, scmd, &ioq_cmd);
+ if (unlikely(retval)) {
+ ioc_err(hdev, "sssraid_io_map_data Err.\n");
+ set_host_byte(scmd, DID_ERROR);
+ scmd->scsi_done(scmd);
+ retval = 0;
+ goto deinit_iod;
+ }
+
+ WRITE_ONCE(iod->state, SSSRAID_CMD_IN_FLIGHT);
+ sssraid_submit_cmd(sq, &ioq_cmd);
+
+ return 0;
+
+deinit_iod:
+ sssraid_free_iod_res(hdev, iod);
+ return retval;
+}
+
+/* change_queue_depth call back:
+ * keep as old
+ */
+
+/* slave_configure call back */
+static int sssraid_slave_configure(struct scsi_device *sdev)
+{
+ int qd = MAX_CMD_PER_DEV;
+ unsigned int timeout = scmd_tmout_rawdisk * HZ;
+ struct sssraid_dev *hdev = shost_priv(sdev->host);
+ struct sssraid_sdev_hostdata *hostdata = sdev->hostdata;
+ u32 max_sec = sdev->host->max_sectors;
+
+ if (hostdata) {
+ if (SSSRAID_DEV_INFO_ATTR_VD(hostdata->attr))
+ timeout = scmd_tmout_vd * HZ;
+ else if (SSSRAID_DEV_INFO_ATTR_RAWDISK(hostdata->attr))
+ timeout = scmd_tmout_rawdisk * HZ;
+ max_sec = hostdata->max_io_kb << 1;
+ qd = sssraid_get_qd_by_disk(hostdata->attr);
+ } else {
+ ioc_err(hdev, "err, sdev->hostdata is null\n");
+ }
+
+ blk_queue_rq_timeout(sdev->request_queue, timeout);
+ sdev->eh_timeout = timeout;
+ scsi_change_queue_depth(sdev, qd);
+
+ if ((max_sec == 0) || (max_sec > sdev->host->max_sectors))
+ max_sec = sdev->host->max_sectors;
+
+ blk_queue_max_hw_sectors(sdev->request_queue, max_sec);
+
+ ioc_info(hdev, "sdev->channel:id:lun[%d:%d:%lld], scmd_timeout[%d]s, maxsec[%d]\n",
+ sdev->channel, sdev->id, sdev->lun, timeout / HZ, max_sec);
+
+ return 0;
+}
+
+/* slave_alloc call back */
+static int sssraid_slave_alloc(struct scsi_device *sdev)
+{
+ struct sssraid_sdev_hostdata *hostdata;
+ struct sssraid_dev *hdev;
+ u16 idx;
+
+ hdev = shost_priv(sdev->host);
+ hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL);
+ if (!hostdata) {
+ ioc_err(hdev, "Alloc scsi host data memory failed\n");
+ return -ENOMEM;
+ }
+
+ down_read(&hdev->devices_rwsem);
+ for (idx = 0; idx < le32_to_cpu(hdev->ctrl_info->nd); idx++) {
+ if (sssraid_match_dev(hdev, idx, sdev))
+ goto scan_host;
+ }
+ up_read(&hdev->devices_rwsem);
+
+ kfree(hostdata);
+ return -ENXIO;
+
+scan_host:
+ hostdata->hdid = le32_to_cpu(hdev->devices[idx].hdid);
+ hostdata->max_io_kb = le16_to_cpu(hdev->devices[idx].max_io_kb);
+ hostdata->attr = hdev->devices[idx].attr;
+ hostdata->flag = hdev->devices[idx].flag;
+ hostdata->rg_id = 0xff;
+ sdev->hostdata = hostdata;
+ up_read(&hdev->devices_rwsem);
+ return 0;
+}
+
+/* slave_destroy call back */
+static void sssraid_slave_destroy(struct scsi_device *sdev)
+{
+ kfree(sdev->hostdata);
+ sdev->hostdata = NULL;
+}
+
+/* eh_timed_out call back */
+static enum blk_eh_timer_return sssraid_scmd_timeout(struct scsi_cmnd *scmd)
+{
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ unsigned int timeout = scmd->device->request_queue->rq_timeout;
+
+ if (sssraid_check_scmd_completed(scmd))
+ goto out;
+
+ if (time_after(jiffies, scmd->jiffies_at_alloc + timeout)) {
+ if (cmpxchg(&iod->state, SSSRAID_CMD_IN_FLIGHT, SSSRAID_CMD_TIMEOUT) ==
+ SSSRAID_CMD_IN_FLIGHT) {
+ return BLK_EH_DONE;
+ }
+ }
+out:
+ return BLK_EH_RESET_TIMER;
+}
+
+/* eh_abort_handler call back */
+static int sssraid_abort_handler(struct scsi_cmnd *scmd)
+{
+ struct sssraid_dev *hdev = shost_priv(scmd->device->host);
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ struct sssraid_sdev_hostdata *hostdata;
+ u16 hwq, cid;
+ int ret;
+
+ scsi_print_command(scmd);
+
+ if (hdev->state != SSSRAID_LIVE || !sssraid_wait_abnl_cmd_done(iod) ||
+ sssraid_check_scmd_completed(scmd))
+ return SUCCESS;
+
+ hostdata = scmd->device->hostdata;
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] timeout, aborting\n", cid, hwq);
+ ret = sssraid_send_abort_cmd(hdev, hostdata->hdid, hwq, cid);
+ if (ret != -ETIME) {
+ ret = sssraid_wait_abnl_cmd_done(iod);
+ if (ret) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] abort failed, not found\n", cid, hwq);
+ return FAILED;
+ }
+ ioc_warn(hdev, "cid[%d] qidx[%d] abort succ\n", cid, hwq);
+ return SUCCESS;
+ }
+ ioc_warn(hdev, "cid[%d] qidx[%d] abort failed, timeout\n", cid, hwq);
+ return FAILED;
+}
+
+static ssize_t csts_pp_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ int ret = -1;
+
+ if (pci_device_is_present(hdev->pdev)) {
+ ret = (readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_PP_MASK);
+ ret >>= SSSRAID_CSTS_PP_SHIFT;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t csts_shst_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ int ret = -1;
+
+ if (pci_device_is_present(hdev->pdev)) {
+ ret = (readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_SHST_MASK);
+ ret >>= SSSRAID_CSTS_SHST_SHIFT;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t csts_cfs_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ int ret = -1;
+
+ if (pci_device_is_present(hdev->pdev)) {
+ ret = (readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_CFS_MASK);
+ ret >>= SSSRAID_CSTS_CFS_SHIFT;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t csts_rdy_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ int ret = -1;
+
+ if (pci_device_is_present(hdev->pdev))
+ ret = (readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_RDY);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t fw_version_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", hdev->ctrl_info->fr);
+}
+
+static DEVICE_ATTR_RO(csts_pp);
+static DEVICE_ATTR_RO(csts_shst);
+static DEVICE_ATTR_RO(csts_cfs);
+static DEVICE_ATTR_RO(csts_rdy);
+static DEVICE_ATTR_RO(fw_version);
+
+static struct device_attribute *sssraid_host_attrs[] = {
+ &dev_attr_csts_pp,
+ &dev_attr_csts_shst,
+ &dev_attr_csts_cfs,
+ &dev_attr_csts_rdy,
+ &dev_attr_fw_version,
+ NULL,
+};
+
+static int sssraid_get_vd_info(struct sssraid_dev *hdev, struct sssraid_vd_info *vd_info, u16 vid)
+{
+ struct sssraid_admin_command admin_cmd;
+ u8 *data_ptr = NULL;
+ dma_addr_t data_dma = 0;
+ int ret;
+
+ if (hdev->state >= SSSRAID_RESETTING) {
+ ioc_err(hdev, "err, host state[%d] is not right\n", hdev->state);
+ return -EBUSY;
+ }
+
+ data_ptr = dma_alloc_coherent(&hdev->pdev->dev, PAGE_SIZE, &data_dma, GFP_KERNEL);
+ if (!data_ptr)
+ return -ENOMEM;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.usr_cmd.opcode = USR_CMD_READ;
+ admin_cmd.usr_cmd.info_0.subopcode = cpu_to_le16(USR_CMD_VDINFO);
+ admin_cmd.usr_cmd.info_1.data_len = cpu_to_le16(USR_CMD_RDLEN);
+ admin_cmd.usr_cmd.info_1.param_len = cpu_to_le16(VDINFO_PARAM_LEN);
+ admin_cmd.usr_cmd.cdw10 = cpu_to_le32(vid);
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ ret = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+ if (!ret)
+ memcpy(vd_info, data_ptr, sizeof(struct sssraid_vd_info));
+
+ dma_free_coherent(&hdev->pdev->dev, PAGE_SIZE, data_ptr, data_dma);
+
+ return ret;
+}
+
+static int sssraid_get_bgtask(struct sssraid_dev *hdev, struct sssraid_bgtask *bgtask)
+{
+ struct sssraid_admin_command admin_cmd;
+ u8 *data_ptr = NULL;
+ dma_addr_t data_dma = 0;
+ int ret;
+
+ if (hdev->state >= SSSRAID_RESETTING) {
+ ioc_err(hdev, "err, host state[%d] is not right\n", hdev->state);
+ return -EBUSY;
+ }
+
+ data_ptr = dma_alloc_coherent(&hdev->pdev->dev, PAGE_SIZE, &data_dma, GFP_KERNEL);
+ if (!data_ptr)
+ return -ENOMEM;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.usr_cmd.opcode = USR_CMD_READ;
+ admin_cmd.usr_cmd.info_0.subopcode = cpu_to_le16(USR_CMD_BGTASK);
+ admin_cmd.usr_cmd.info_1.data_len = cpu_to_le16(USR_CMD_RDLEN);
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ ret = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+ if (!ret)
+ memcpy(bgtask, data_ptr, sizeof(struct sssraid_bgtask));
+
+ dma_free_coherent(&hdev->pdev->dev, PAGE_SIZE, data_ptr, data_dma);
+
+ return ret;
+}
+
+static ssize_t raid_level_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev;
+ struct sssraid_dev *hdev;
+ struct sssraid_vd_info *vd_info;
+ struct sssraid_sdev_hostdata *hostdata;
+ int ret;
+
+ sdev = to_scsi_device(dev);
+ hdev = shost_priv(sdev->host);
+ hostdata = sdev->hostdata;
+
+ vd_info = kmalloc(sizeof(*vd_info), GFP_KERNEL);
+ if (!vd_info || !SSSRAID_DEV_INFO_ATTR_VD(hostdata->attr))
+ return snprintf(buf, PAGE_SIZE, "NA\n");
+
+ ret = sssraid_get_vd_info(hdev, vd_info, sdev->id);
+ if (ret)
+ vd_info->rg_level = ARRAY_SIZE(raid_levels) - 1;
+
+ ret = (vd_info->rg_level < ARRAY_SIZE(raid_levels)) ?
+ vd_info->rg_level : (ARRAY_SIZE(raid_levels) - 1);
+
+ kfree(vd_info);
+
+ return snprintf(buf, PAGE_SIZE, "RAID-%s\n", raid_levels[ret]);
+}
+
+static ssize_t raid_state_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev;
+ struct sssraid_dev *hdev;
+ struct sssraid_vd_info *vd_info;
+ struct sssraid_sdev_hostdata *hostdata;
+ int ret;
+
+ sdev = to_scsi_device(dev);
+ hdev = shost_priv(sdev->host);
+ hostdata = sdev->hostdata;
+
+ vd_info = kmalloc(sizeof(*vd_info), GFP_KERNEL);
+ if (!vd_info || !SSSRAID_DEV_INFO_ATTR_VD(hostdata->attr))
+ return snprintf(buf, PAGE_SIZE, "NA\n");
+
+ ret = sssraid_get_vd_info(hdev, vd_info, sdev->id);
+ if (ret) {
+ vd_info->vd_status = 0;
+ vd_info->rg_id = 0xff;
+ }
+
+ ret = (vd_info->vd_status < ARRAY_SIZE(raid_states)) ? vd_info->vd_status : 0;
+
+ kfree(vd_info);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", raid_states[ret]);
+}
+
+static ssize_t raid_resync_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev;
+ struct sssraid_dev *hdev;
+ struct sssraid_vd_info *vd_info;
+ struct sssraid_bgtask *bgtask;
+ struct sssraid_sdev_hostdata *hostdata;
+ u8 rg_id, i, progress = 0;
+ int ret;
+
+ sdev = to_scsi_device(dev);
+ hdev = shost_priv(sdev->host);
+ hostdata = sdev->hostdata;
+
+ vd_info = kmalloc(sizeof(*vd_info), GFP_KERNEL);
+ if (!vd_info || !SSSRAID_DEV_INFO_ATTR_VD(hostdata->attr))
+ return snprintf(buf, PAGE_SIZE, "NA\n");
+
+ ret = sssraid_get_vd_info(hdev, vd_info, sdev->id);
+ if (ret)
+ goto out;
+
+ rg_id = vd_info->rg_id;
+
+ bgtask = (struct sssraid_bgtask *)vd_info;
+ ret = sssraid_get_bgtask(hdev, bgtask);
+ if (ret)
+ goto out;
+ for (i = 0; i < bgtask->task_num; i++) {
+ if ((bgtask->bgtask[i].type == BGTASK_TYPE_REBUILD) &&
+ (le16_to_cpu(bgtask->bgtask[i].vd_id) == rg_id))
+ progress = bgtask->bgtask[i].progress;
+ }
+
+out:
+ kfree(vd_info);
+ return snprintf(buf, PAGE_SIZE, "%d\n", progress);
+}
+
+static DEVICE_ATTR_RO(raid_level);
+static DEVICE_ATTR_RO(raid_state);
+static DEVICE_ATTR_RO(raid_resync);
+
+static struct device_attribute *sssraid_dev_attrs[] = {
+ &dev_attr_raid_level,
+ &dev_attr_raid_state,
+ &dev_attr_raid_resync,
+ NULL,
+};
+
+static struct scsi_host_template sssraid_driver_template = {
+ .module = THIS_MODULE,
+ .name = "3SNIC Logic sssraid driver",
+ .proc_name = "sssraid",
+ .queuecommand = sssraid_qcmd,
+ .slave_alloc = sssraid_slave_alloc,
+ .slave_destroy = sssraid_slave_destroy,
+ .slave_configure = sssraid_slave_configure,
+ .scan_finished = sssraid_scan_finished,
+ .eh_timed_out = sssraid_scmd_timeout,
+ .eh_abort_handler = sssraid_abort_handler,
+ .eh_target_reset_handler = sssraid_eh_target_reset,
+ .eh_bus_reset_handler = sssraid_bus_reset_handler,
+ .eh_host_reset_handler = sssraid_eh_host_reset,
+ .change_queue_depth = scsi_change_queue_depth,
+ .host_tagset = 0,
+ .this_id = -1,
+ .unchecked_isa_dma = 0,
+ .shost_attrs = sssraid_host_attrs,
+ .sdev_attrs = sssraid_dev_attrs,
+ .host_reset = sssraid_sysfs_host_reset,
+};
+
+/**
+ * sssraid_probe - PCI probe callback
+ * @pdev: PCI device instance
+ * @id: PCI device ID details
+ *
+ * controller initialization routine.
+ * Allocate per adapter instance through shost_priv and
+ * initialize controller specific data structures, initializae
+ * the controller hardware, add shost to the SCSI subsystem.
+ *
+ * Return: 0 on success, non-zero on failure.
+ */
+
+static int
+sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct sssraid_dev *hdev;
+ struct Scsi_Host *shost;
+ int node;
+ char bsg_name[15];
+ int retval = 0;
+
+ node = dev_to_node(&pdev->dev);
+ if (node == NUMA_NO_NODE) {
+ node = first_memory_node;
+ set_dev_node(&pdev->dev, node);
+ }
+
+ shost = scsi_host_alloc(&sssraid_driver_template, sizeof(*hdev));
+ if (!shost) {
+ retval = -ENODEV;
+ ioc_err(hdev, "Failed to allocate scsi host\n");
+ goto shost_failed;
+ }
+
+ hdev = shost_priv(shost);
+ hdev->numa_node = node;
+ hdev->instance = shost->host_no; /* for device instance */
+ sprintf(hdev->name, "%s%d", SSSRAID_DRIVER_NAME, hdev->instance);
+
+ init_rwsem(&hdev->devices_rwsem);
+ spin_lock_init(&hdev->state_lock);
+
+ spin_lock_init(&hdev->fwevt_lock);
+ spin_lock_init(&hdev->watchdog_lock);
+
+ INIT_LIST_HEAD(&hdev->fwevt_list);
+
+// logging_level = 1; //garden test
+ hdev->logging_level = logging_level; /* according to log_debug_switch*/
+
+ snprintf(hdev->fwevt_worker_name, sizeof(hdev->fwevt_worker_name),
+ "%s%d_fwevt_wrkr", SSSRAID_DRIVER_NAME, hdev->instance);
+ hdev->fwevt_worker_thread = alloc_ordered_workqueue(
+ hdev->fwevt_worker_name, WQ_MEM_RECLAIM);
+ if (!hdev->fwevt_worker_thread) {
+ ioc_err(hdev, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
+ retval = -ENODEV;
+ goto out_fwevtthread_failed;
+ }
+
+ hdev->shost = shost;
+ hdev->pdev = pdev;
+
+ if (sssraid_init_ioc(hdev, 0)) {
+ ioc_err(hdev, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
+ retval = -ENODEV;
+ goto out_iocinit_failed;
+ }
+
+ sssraid_shost_init(hdev);
+
+ retval = scsi_add_host(shost, &pdev->dev);
+ if (retval) {
+ ioc_err(hdev, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
+ goto addhost_failed;
+ }
+
+ snprintf(bsg_name, sizeof(bsg_name), "%s%d", SSSRAID_DRIVER_NAME, shost->host_no);
+ hdev->bsg_queue = bsg_setup_queue(&shost->shost_gendev, bsg_name,
+ sssraid_bsg_host_dispatch, NULL, sssraid_cmd_size(hdev));
+ if (IS_ERR(hdev->bsg_queue)) {
+ ioc_err(hdev, "err, setup bsg failed\n");
+ hdev->bsg_queue = NULL;
+ goto bsg_setup_failed;
+ }
+
+ sssraid_change_host_state(hdev, SSSRAID_LIVE);
+
+ scsi_scan_host(shost);
+ return retval;
+
+bsg_setup_failed:
+ scsi_remove_host(shost);
+addhost_failed:
+ sssraid_cleanup_ioc(hdev, 0);
+out_iocinit_failed:
+ destroy_workqueue(hdev->fwevt_worker_thread);
+out_fwevtthread_failed:
+ scsi_host_put(shost);
+shost_failed:
+ return retval;
+}
+
+static void sssraid_remove(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return;
+
+ ioc_info(hdev, "enter sssraid remove\n");
+
+ hdev = shost_priv(shost);
+
+ sssraid_change_host_state(hdev, SSSRAID_DELETING);
+
+ if (!pci_device_is_present(pdev))
+ sssraid_back_all_io(hdev);
+
+ sssraid_cleanup_fwevt_list(hdev);
+ destroy_workqueue(hdev->fwevt_worker_thread);
+
+ sssraid_remove_bsg(hdev);
+ scsi_remove_host(shost);
+ sssraid_cleanup_ioc(hdev, 0);
+
+ scsi_host_put(shost);
+}
+
+static void sssraid_shutdown(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return;
+
+ hdev = shost_priv(shost);
+
+ sssraid_cleanup_fwevt_list(hdev);
+ destroy_workqueue(hdev->fwevt_worker_thread);
+ sssraid_cleanup_ioc(hdev, 0);
+}
+
+#ifdef CONFIG_PM
+static int sssraid_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+ pci_power_t device_state;
+
+ if (!shost)
+ return 0;
+
+ hdev = shost_priv(shost);
+
+ while (hdev->state == SSSRAID_RESETTING)
+ ssleep(1);
+ sssraid_cleanup_fwevt_list(hdev);
+ scsi_block_requests(shost);
+ sssraid_cleanup_ioc(hdev, 1);
+
+ device_state = pci_choose_state(pdev, state);
+ pci_save_state(pdev);
+ pci_set_power_state(pdev, device_state);
+
+ return 0;
+}
+
+static int sssraid_resume(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+ pci_power_t device_state = pdev->current_state;
+
+ if (!shost)
+ return 0;
+
+ hdev = shost_priv(shost);
+
+ ioc_info(hdev, "pdev=0x%p, slot=%s, previous operating state [D%d]\n",
+ pdev, pci_name(pdev), device_state);
+ pci_set_power_state(pdev, PCI_D0);
+ pci_enable_wake(pdev, PCI_D0, 0);
+ pci_restore_state(pdev);
+ hdev->pdev = pdev;
+ hdev->cpu_count = num_online_cpus();
+
+ /* sssraid_setup_resources in sssraid_init_ioc */
+ sssraid_init_ioc(hdev, 1);
+ scsi_unblock_requests(shost);
+
+ return 0;
+}
+#endif
+
+static pci_ers_result_t sssraid_pci_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return PCI_ERS_RESULT_NONE;
+
+ hdev = shost_priv(shost);
+
+ ioc_info(hdev, "enter pci error detect, state:%d\n", state);
+
+ switch (state) {
+ case pci_channel_io_normal:
+ ioc_warn(hdev, "channel is normal, do nothing\n");
+
+ return PCI_ERS_RESULT_CAN_RECOVER;
+ case pci_channel_io_frozen:
+ ioc_warn(hdev, "channel io frozen, need reset controller\n");
+
+ scsi_block_requests(hdev->shost);
+
+ sssraid_change_host_state(hdev, SSSRAID_RESETTING);
+
+ return PCI_ERS_RESULT_NEED_RESET;
+ case pci_channel_io_perm_failure:
+ ioc_warn(hdev, "channel io failure, request disconnect\n");
+
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t sssraid_pci_slot_reset(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return PCI_ERS_RESULT_NONE;
+
+ hdev = shost_priv(shost);
+
+ ioc_info(hdev, "restart after slot reset\n");
+
+ pci_restore_state(pdev);
+
+ sssraid_soft_reset_handler(hdev);
+
+ scsi_unblock_requests(hdev->shost);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void sssraid_reset_done(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return;
+
+ hdev = shost_priv(shost);
+
+ ioc_info(hdev, "enter sssraid reset done\n");
+}
+
+static struct pci_error_handlers sssraid_err_handler = {
+ .error_detected = sssraid_pci_error_detected,
+ .slot_reset = sssraid_pci_slot_reset,
+ .reset_done = sssraid_reset_done,
+};
+
+static const struct pci_device_id sssraid_pci_id_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_3SNIC_LOGIC, SSSRAID_SERVER_DEVICE_HBA_DID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_3SNIC_LOGIC, SSSRAID_SERVER_DEVICE_RAID_DID) },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, sssraid_pci_id_table);
+
+static struct pci_driver sssraid_pci_driver = {
+ .name = SSSRAID_DRIVER_NAME,
+ .id_table = sssraid_pci_id_table,
+ .probe = sssraid_probe,
+ .remove = sssraid_remove,
+ .shutdown = sssraid_shutdown,
+#ifdef CONFIG_PM
+ .suspend = sssraid_suspend,
+ .resume = sssraid_resume,
+#endif
+ .err_handler = &sssraid_err_handler,
+};
+
+static int __init sssraid_init(void)
+{
+ int ret_val;
+
+ pr_info("Loading %s version %s\n", SSSRAID_DRIVER_NAME,
+ SSSRAID_DRIVER_VERSION);
+
+ sssraid_class = class_create(THIS_MODULE, "sssraid");
+ if (IS_ERR(sssraid_class)) {
+ ret_val = PTR_ERR(sssraid_class);
+ return ret_val;
+ }
+
+ ret_val = pci_register_driver(&sssraid_pci_driver);
+
+ return ret_val;
+}
+
+static void __exit sssraid_exit(void)
+{
+ pr_info("Unloading %s version %s\n", SSSRAID_DRIVER_NAME,
+ SSSRAID_DRIVER_VERSION);
+
+ class_destroy(sssraid_class);
+ pci_unregister_driver(&sssraid_pci_driver);
+}
+
+MODULE_AUTHOR("liangry1(a)3snic.com");
+MODULE_DESCRIPTION("3SNIC Information Technology SSSRAID Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(SSSRAID_DRIVER_VERSION);
+module_init(sssraid_init);
+module_exit(sssraid_exit);
diff --git a/openEuler/MAINTAINERS b/openEuler/MAINTAINERS
index 35b5a8f81fed..fc8b6e06fc04 100644
--- a/openEuler/MAINTAINERS
+++ b/openEuler/MAINTAINERS
@@ -76,6 +76,12 @@ F: include/linux/wait.h
F: include/uapi/linux/sched.h
F: kernel/sched/
+SSSRAID SCSI/Raid DRIVERS
+M: Steven Song <steven.song(a)3snic.com>
+S: Maintained
+F: Documentation/scsi/sssraid.rst
+F: drivers/scsi/sssraid/
+
THE REST
M: xiexiuqi(a)huawei.com
M: zhengzengkai(a)huawei.com
--
2.25.1
1
0
3SNIC inclusion
category: features
bugzilla: https://gitee.com/openeuler/kernel/issues/I64M90
CVE: NA
This commit is to suppport 3SNIC 3S5XX RAID/HBA controllers.
RAID controllers support RAID 0/1/5/6/10/50/60 modes;
HBA controlllers support RAID 0/1/10 modes.
RAID/HBA support SAS/SATA HDD/SSD.
Signed-off-by: liangry <liangry1(a)3snic.com>
Reviewed-by: Jiang Yu<yujiang(a)3snic.com>
Reviewed-by: Steven Song <steven.song(a)3snic.com>
---
Documentation/scsi/sssraid.rst | 83 +
MAINTAINERS | 7 +
arch/arm64/configs/openeuler_defconfig | 1 +
arch/x86/configs/openeuler_defconfig | 1 +
drivers/scsi/Kconfig | 1 +
drivers/scsi/Makefile | 1 +
drivers/scsi/sssraid/Kconfig | 14 +
drivers/scsi/sssraid/Makefile | 7 +
drivers/scsi/sssraid/sssraid.h | 971 ++++++++++
drivers/scsi/sssraid/sssraid_debug.h | 34 +
drivers/scsi/sssraid/sssraid_fw.c | 1724 +++++++++++++++++
drivers/scsi/sssraid/sssraid_os.c | 2337 ++++++++++++++++++++++++
12 files changed, 5181 insertions(+)
create mode 100644 Documentation/scsi/sssraid.rst
create mode 100644 drivers/scsi/sssraid/Kconfig
create mode 100644 drivers/scsi/sssraid/Makefile
create mode 100644 drivers/scsi/sssraid/sssraid.h
create mode 100644 drivers/scsi/sssraid/sssraid_debug.h
create mode 100644 drivers/scsi/sssraid/sssraid_fw.c
create mode 100644 drivers/scsi/sssraid/sssraid_os.c
diff --git a/Documentation/scsi/sssraid.rst b/Documentation/scsi/sssraid.rst
new file mode 100644
index 000000000000..d56e5f7c478c
--- /dev/null
+++ b/Documentation/scsi/sssraid.rst
@@ -0,0 +1,83 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==============================================
+SSSRAID - 3SNIC SCSI RAID Controller driver
+==============================================
+
+This file describes the SSSRAID SCSI driver for 3SNIC
+(http://www.3snic.com) RAID controllers. The SSSRAID
+driver is the first generation RAID driver for 3SNIC Corp.
+
+For 3SNIC SSSRAID controller support, enable the SSSRAID driver
+when configuring the kernel.
+
+SSSRAID specific entries in /sys
+=================================
+
+SSSRAID host attributes
+------------------------
+ - /sys/class/scsi_host/host*/csts_pp
+ - /sys/class/scsi_host/host*/csts_shst
+ - /sys/class/scsi_host/host*/csts_cfs
+ - /sys/class/scsi_host/host*/csts_rdy
+ - /sys/class/scsi_host/host*/fw_version
+
+ The host csts_pp attribute is a read only attribute. This attribute
+ indicates whether the controller is processing commands. If this attribute
+ is set to ‘1’, then the controller is processing commands normally. If
+ this attribute is cleared to ‘0’, then the controller has temporarily stopped
+ processing commands in order to handle an event (e.g., firmware activation).
+
+ The host csts_shst attribute is a read only attribute. This attribute
+ indicates status of shutdown processing.The shutdown status values are defined
+ as:
+ ====== ==============================
+ Value Definition
+ ====== ==============================
+ 00b Normal operation
+ 01b Shutdown processing occurring
+ 10b Shutdown processing complete
+ 11b Reserved
+ ====== ==============================
+ The host csts_cfs attribute is a read only attribute. This attribute is set to
+ ’1’ when a fatal controller error occurred that could not be communicated in the
+ appropriate Completion Queue. This bit is cleared to ‘0’ when a fatal controller
+ error has not occurred.
+
+ The host csts_rdy attribute is a read only attribute. This attribute is set to
+ ‘1’ when the controller is ready to process submission queue entries.
+
+ The fw_version attribute is read-only and will return the driver version and the
+ controller firmware version.
+
+SSSRAID scsi device attributes
+------------------------------
+ - /sys/class/scsi_device/X\:X\:X\:X/device/raid_level
+ - /sys/class/scsi_device/X\:X\:X\:X/device/raid_state
+ - /sys/class/scsi_device/X\:X\:X\:X/device/raid_resync
+
+ The device raid_level attribute is a read only attribute. This attribute indicates
+ RAID level of scsi device(will dispaly "NA" if scsi device is not virtual disk type).
+
+ The device raid_state attribute is read-only and indicates RAID status of scsi
+ device(will dispaly "NA" if scsi device is not virtual disk type).
+
+ The device raid_resync attribute is read-only and indicates RAID rebuild processing
+ of scsi device(will dispaly "NA" if scsi device is not virtual disk type).
+
+Supported devices
+=================
+
+ =================== ======= =======================================
+ PCI ID (pci.ids) OEM Product
+ =================== ======= =======================================
+ 1F3F:2100 3SNIC 3S510(HBA:8Ports,1G DDR)
+ 1F3F:2100 3SNIC 3S520(HBA:16Ports,1G DDR)
+ 1F3F:2100 3SNIC 3S530(HBA:32Ports,1G DDR)
+ 1F3F:2100 3SNIC 3S540(HBA:40Ports,1G DDR)
+ 1F3F:2200 3SNIC 3S580(RAID:16Ports,2G cache)
+ 1F3F:2200 3SNIC 3S585(RAID:16Ports,4G cache)
+ 1F3F:2200 3SNIC 3S590(RAID:32Ports,4G cache)
+ 1F3F:2200 3SNIC 3S5A0(RAID:40Ports,2G cache)
+ 1F3F:2200 3SNIC 3S5A5(RAID:40Ports,4G cache)
+ =================== ======= =======================================
diff --git a/MAINTAINERS b/MAINTAINERS
index 9ae209633628..e6470640f764 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16669,6 +16669,13 @@ M: Jan-Benedict Glaw <jbglaw(a)lug-owl.de>
S: Maintained
F: arch/alpha/kernel/srm_env.c
+SSSRAID SCSI/Raid DRIVERS
+M: Steven Song <steven.song(a)3snic.com>
+L: linux-scsi(a)vger.kernel.org
+S: Maintained
+F: Documentation/scsi/sssraid.rst
+F: drivers/scsi/sssraid/
+
ST LSM6DSx IMU IIO DRIVER
M: Lorenzo Bianconi <lorenzo.bianconi83(a)gmail.com>
L: linux-iio(a)vger.kernel.org
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index 30384eacad4f..dc4ba0d2b694 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -2394,6 +2394,7 @@ CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_3SNIC_SSSRAID=m
CONFIG_SCSI_MPT3SAS=m
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
CONFIG_SCSI_MPT3SAS_MAX_SGE=128
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index 5ada612f1d75..df16f123515b 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -2355,6 +2355,7 @@ CONFIG_SCSI_AACRAID=m
# CONFIG_MEGARAID_LEGACY is not set
CONFIG_MEGARAID_SAS=m
CONFIG_SCSI_MPT3SAS=m
+CONFIG_SCSI_3SNIC_SSSRAID=m
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
CONFIG_SCSI_MPT3SAS_MAX_SGE=128
CONFIG_SCSI_MPT2SAS=m
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 0fbe4edeccd0..7339d6179e5a 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -481,6 +481,7 @@ config SCSI_ARCMSR
source "drivers/scsi/esas2r/Kconfig"
source "drivers/scsi/megaraid/Kconfig.megaraid"
+source "drivers/scsi/sssraid/Kconfig"
source "drivers/scsi/mpt3sas/Kconfig"
source "drivers/scsi/smartpqi/Kconfig"
source "drivers/scsi/ufs/Kconfig"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 78a3c832394c..01bb908fb832 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor/
obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
obj-$(CONFIG_SCSI_HPSA) += hpsa.o
obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi/
+obj-$(CONFIG_SCSI_3SNIC_SSSRAID) += sssraid/
obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/
obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o
obj-$(CONFIG_SCSI_DC395x) += dc395x.o
diff --git a/drivers/scsi/sssraid/Kconfig b/drivers/scsi/sssraid/Kconfig
new file mode 100644
index 000000000000..769f68732bf3
--- /dev/null
+++ b/drivers/scsi/sssraid/Kconfig
@@ -0,0 +1,14 @@
+#
+# Kernel configuration file for the 3SNIC
+#
+
+config SCSI_3SNIC_SSSRAID
+ tristate "3SNIC sssraid Adapter"
+ depends on PCI && SCSI
+ select BLK_DEV_BSGLIB
+ depends on ARM64 || X86_64
+ help
+ This driver supports 3SNIC 3S5xx serial RAID controller, which has
+ PCI Express Gen4 interface with host and supports SAS/SATA HDD/SSD.
+ To compile this driver as a module, choose M here: the module will
+ be called sssraid.
diff --git a/drivers/scsi/sssraid/Makefile b/drivers/scsi/sssraid/Makefile
new file mode 100644
index 000000000000..c80605866b42
--- /dev/null
+++ b/drivers/scsi/sssraid/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the 3SNIC sssraid drivers.
+#
+
+obj-$(CONFIG_SCSI_3SNIC_SSSRAID) += sssraid.o
+
+sssraid-objs := sssraid_os.o sssraid_fw.o
diff --git a/drivers/scsi/sssraid/sssraid.h b/drivers/scsi/sssraid/sssraid.h
new file mode 100644
index 000000000000..bae668ef9c98
--- /dev/null
+++ b/drivers/scsi/sssraid/sssraid.h
@@ -0,0 +1,971 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2022 3SNIC Information Technology, Ltd */
+
+/* 3SNIC RAID SSSXXX Series Linux Driver */
+
+#ifndef __SSSRAID_H_
+#define __SSSRAID_H_
+
+#define SSSRAID_DRIVER_VERSION "1.0.0.0"
+#define SSSRAID_DRIVER_RELDATE "12-December-2022"
+
+#define SSSRAID_DRIVER_NAME "sssraid"
+
+#define SSSRAID_NAME_LENGTH 32
+
+/*
+ * SSSRAID Vendor ID and Device IDs
+ */
+#define PCI_VENDOR_ID_3SNIC_LOGIC 0x1F3F
+
+#define SSSRAID_SERVER_DEVICE_HBA_DID 0x2100
+#define SSSRAID_SERVER_DEVICE_RAID_DID 0x2200
+
+#define SSSRAID_CAP_MQES(cap) ((cap) & 0xffff)
+#define SSSRAID_CAP_STRIDE(cap) (((cap) >> 32) & 0xf)
+#define SSSRAID_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf)
+#define SSSRAID_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf)
+#define SSSRAID_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff)
+#define SSSRAID_CAP_DMAMASK(cap) (((cap) >> 37) & 0xff)
+
+#define SSSRAID_DEFAULT_MAX_CHANNEL 4
+#define SSSRAID_DEFAULT_MAX_ID 240
+#define SSSRAID_DEFAULT_MAX_LUN_PER_HOST 8
+#define MAX_SECTORS 2048
+
+/*
+ * Time define
+ */
+#define SSSRAID_WATCHDOG_INTERVAL 1000 /* in milli seconds */
+#define SSSRAID_PORTENABLE_TIMEOUT 300
+
+/*
+ * SSSRAID queue and entry size for Admin and I/O type
+ */
+#define IO_SQE_SIZE sizeof(struct sssraid_ioq_command)
+#define ADMIN_SQE_SIZE sizeof(struct sssraid_admin_command)
+#define SQE_SIZE(qid) (((qid) > 0) ? IO_SQE_SIZE : ADMIN_SQE_SIZE)
+#define CQ_SIZE(depth) ((depth) * sizeof(struct sssraid_completion))
+#define SQ_SIZE(qid, depth) ((depth) * SQE_SIZE(qid))
+
+#define SENSE_SIZE(depth) ((depth) * SCSI_SENSE_BUFFERSIZE)
+
+#define SSSRAID_AQ_DEPTH 128
+#define SSSRAID_NR_AEN_COMMANDS 16
+#define SSSRAID_AQ_BLK_MQ_DEPTH (SSSRAID_AQ_DEPTH - SSSRAID_NR_AEN_COMMANDS)
+#define SSSRAID_AQ_MQ_TAG_DEPTH (SSSRAID_AQ_BLK_MQ_DEPTH - 1)
+
+#define SSSRAID_ADMIN_QUEUE_NUM 1
+#define SSSRAID_PTCMDS_PERQ 1
+#define SSSRAID_IO_BLK_MQ_DEPTH (hdev->scsi_qd)
+#define SSSRAID_NR_IOQ_PTCMDS (SSSRAID_PTCMDS_PERQ * hdev->shost->nr_hw_queues)
+
+#define FUA_MASK 0x08
+#define SSSRAID_MINORS BIT(MINORBITS)
+#define SSSRAID_RW_FUA BIT(14)
+
+#define COMMAND_IS_WRITE(cmd) ((cmd)->common.opcode & 1)
+
+#define SSSRAID_IO_IOSQES 7
+#define SSSRAID_IO_IOCQES 4
+#define PRP_ENTRY_SIZE 8
+
+#define SMALL_POOL_SIZE 256
+#define MAX_SMALL_POOL_NUM 16
+#define MAX_CMD_PER_DEV 64
+#define MAX_CDB_LEN 16
+
+#define SSSRAID_UP_TO_MULTY4(x) (((x) + 4) & (~0x03))
+
+#define CQE_STATUS_SUCCESS (0x0)
+
+#define IO_6_DEFAULT_TX_LEN 256
+
+#define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct sssraid_sgl_desc))
+
+#define SSSRAID_CAP_TIMEOUT_UNIT_MS (HZ / 2)
+
+extern u32 admin_tmout;
+#define ADMIN_TIMEOUT (admin_tmout * HZ)
+
+#define SSSRAID_WAIT_ABNL_CMD_TIMEOUT 6
+
+#define SSSRAID_DMA_MSK_BIT_MAX 64
+
+enum {
+ SSSRAID_SGL_FMT_DATA_DESC = 0x00,
+ SSSRAID_SGL_FMT_SEG_DESC = 0x02,
+ SSSRAID_SGL_FMT_LAST_SEG_DESC = 0x03,
+ SSSRAID_KEY_SGL_FMT_DATA_DESC = 0x04,
+ SSSRAID_TRANSPORT_SGL_DATA_DESC = 0x05
+};
+
+
+enum {
+ SSSRAID_REQ_CANCELLED = (1 << 0),
+ SSSRAID_REQ_USERCMD = (1 << 1),
+};
+
+enum {
+ SSSRAID_SC_SUCCESS = 0x0,
+ SSSRAID_SC_INVALID_OPCODE = 0x1,
+ SSSRAID_SC_INVALID_FIELD = 0x2,
+
+ SSSRAID_SC_ABORT_LIMIT = 0x103,
+ SSSRAID_SC_ABORT_MISSING = 0x104,
+ SSSRAID_SC_ASYNC_LIMIT = 0x105,
+
+ SSSRAID_SC_DNR = 0x4000,
+};
+
+enum {
+ SSSRAID_REG_CAP = 0x0000,
+ SSSRAID_REG_CC = 0x0014,
+ SSSRAID_REG_CSTS = 0x001c,
+ SSSRAID_REG_AQA = 0x0024,
+ SSSRAID_REG_ASQ = 0x0028,
+ SSSRAID_REG_ACQ = 0x0030,
+ SSSRAID_REG_DBS = 0x1000,
+};
+
+enum {
+ SSSRAID_CC_ENABLE = 1 << 0,
+ SSSRAID_CC_CSS_NVM = 0 << 4,
+ SSSRAID_CC_MPS_SHIFT = 7,
+ SSSRAID_CC_AMS_SHIFT = 11,
+ SSSRAID_CC_SHN_SHIFT = 14,
+ SSSRAID_CC_IOSQES_SHIFT = 16,
+ SSSRAID_CC_IOCQES_SHIFT = 20,
+ SSSRAID_CC_AMS_RR = 0 << SSSRAID_CC_AMS_SHIFT,
+ SSSRAID_CC_SHN_NONE = 0 << SSSRAID_CC_SHN_SHIFT,
+ SSSRAID_CC_IOSQES = SSSRAID_IO_IOSQES << SSSRAID_CC_IOSQES_SHIFT,
+ SSSRAID_CC_IOCQES = SSSRAID_IO_IOCQES << SSSRAID_CC_IOCQES_SHIFT,
+ SSSRAID_CC_SHN_NORMAL = 1 << SSSRAID_CC_SHN_SHIFT,
+ SSSRAID_CC_SHN_MASK = 3 << SSSRAID_CC_SHN_SHIFT,
+ SSSRAID_CSTS_CFS_SHIFT = 1,
+ SSSRAID_CSTS_SHST_SHIFT = 2,
+ SSSRAID_CSTS_PP_SHIFT = 5,
+ SSSRAID_CSTS_RDY = 1 << 0,
+ SSSRAID_CSTS_SHST_CMPLT = 2 << 2,
+ SSSRAID_CSTS_SHST_MASK = 3 << 2,
+ SSSRAID_CSTS_CFS_MASK = 1 << SSSRAID_CSTS_CFS_SHIFT,
+ SSSRAID_CSTS_PP_MASK = 1 << SSSRAID_CSTS_PP_SHIFT,
+};
+
+enum {
+ SSSRAID_ADMIN_DELETE_SQ = 0x00,
+ SSSRAID_ADMIN_CREATE_SQ = 0x01,
+ SSSRAID_ADMIN_DELETE_CQ = 0x04,
+ SSSRAID_ADMIN_CREATE_CQ = 0x05,
+ SSSRAID_ADMIN_ABORT_CMD = 0x08,
+ SSSRAID_ADMIN_SET_FEATURES = 0x09,
+ SSSRAID_ADMIN_ASYNC_EVENT = 0x0c,
+ SSSRAID_ADMIN_GET_INFO = 0xc6,
+ SSSRAID_ADMIN_RESET = 0xc8,
+};
+
+enum {
+ SSSRAID_GET_INFO_CTRL = 0,
+ SSSRAID_GET_INFO_DEV_LIST = 1,
+};
+
+enum sssraid_scsi_rst_type {
+ SSSRAID_RESET_TARGET = 0,
+ SSSRAID_RESET_BUS = 1,
+};
+
+enum {
+ SSSRAID_AEN_ERROR = 0,
+ SSSRAID_AEN_NOTICE = 2,
+ SSSRAID_AEN_VS = 7,
+};
+
+enum {
+ SSSRAID_AEN_DEV_CHANGED = 0x00,
+ SSSRAID_AEN_FW_ACT_START = 0x01,
+ SSSRAID_AEN_HOST_PROBING = 0x10,
+};
+
+enum {
+ SSSRAID_AEN_TIMESYN = 0x00,
+ SSSRAID_AEN_FW_ACT_FINISH = 0x02,
+ SSSRAID_AEN_EVENT_MIN = 0x80,
+ SSSRAID_AEN_EVENT_MAX = 0xff,
+};
+
+enum {
+ SSSRAID_CMD_WRITE = 0x01,
+ SSSRAID_CMD_READ = 0x02,
+
+ SSSRAID_CMD_NONIO_NONE = 0x80,
+ SSSRAID_CMD_NONIO_TODEV = 0x81,
+ SSSRAID_CMD_NONIO_FROMDEV = 0x82,
+};
+
+enum {
+ SSSRAID_QUEUE_PHYS_CONTIG = (1 << 0),
+ SSSRAID_CQ_IRQ_ENABLED = (1 << 1),
+
+ SSSRAID_FEAT_NUM_QUEUES = 0x07,
+ SSSRAID_FEAT_ASYNC_EVENT = 0x0b,
+ SSSRAID_FEAT_TIMESTAMP = 0x0e,
+};
+
+enum sssraid_state {
+ SSSRAID_NEW,
+ SSSRAID_LIVE,
+ SSSRAID_RESETTING,
+ SSSRAID_DELETING,
+ SSSRAID_DEAD,
+};
+
+enum {
+ SSSRAID_CARD_HBA,
+ SSSRAID_CARD_RAID,
+};
+
+enum sssraid_cmd_type {
+ SSSRAID_CMD_ADM,
+ SSSRAID_CMD_IOPT,
+};
+
+/*
+ * SSSRAID completion queue entry struct
+ */
+struct sssraid_completion {
+ __le32 result;
+ union {
+ struct {
+ __u8 sense_len;
+ __u8 resv[3];
+ };
+ __le32 result1;
+ };
+ __le16 sq_head;
+ __le16 sq_id;
+ __le16 cmd_id;
+ __le16 status;
+};
+
+/*
+ * SSSRAID firmware controller properties
+ */
+struct sssraid_ctrl_info {
+ __le32 nd;
+ __le16 max_cmds;
+ __le16 max_channel;
+ __le32 max_tgt_id;
+ __le16 max_lun;
+ __le16 max_num_sge;
+ __le16 lun_num_in_boot;
+ __u8 mdts;
+ __u8 acl;
+ __u8 aerl;
+ __u8 card_type;
+ __u16 rsvd;
+ __le32 rtd3e;
+ __u8 sn[32];
+ __u8 fr[16];
+ __u8 rsvd1[4020];
+};
+
+struct sssraid_intr_info {
+ struct sssraid_dev *hdev;
+ u16 msix_index;
+ struct sssraid_cqueue *cqinfo;
+ char name[SSSRAID_NAME_LENGTH];
+};
+
+struct sssraid_fwevt {
+ struct list_head list;
+ struct work_struct work;
+ struct sssraid_dev *hdev;
+ u16 event_id;
+ bool send_ack;
+ bool process_evt;
+ u32 evt_ctx;
+ struct kref ref_count;
+ char event_data[0] __aligned(4);
+};
+
+/*
+ * SSSRAID private device struct definition
+ */
+struct sssraid_dev {
+ struct pci_dev *pdev;
+ struct Scsi_Host *shost;
+ struct sssraid_squeue *sqinfo;
+ struct sssraid_cqueue *cqinfo;
+ struct dma_pool *prp_page_pool;
+ struct dma_pool *prp_small_pool[MAX_SMALL_POOL_NUM];
+ void __iomem *bar;
+
+ u32 init_done_queue_cnt;
+ u32 ioq_depth;
+ u32 db_stride;
+ u32 __iomem *dbs;
+ struct rw_semaphore devices_rwsem;
+ int numa_node;
+ u32 page_size;
+ u32 ctrl_config;
+ u64 cap;
+ u32 instance;
+ u32 scsi_qd;
+ struct sssraid_ctrl_info *ctrl_info;
+ struct sssraid_dev_info *devices;
+
+ int logging_level;
+
+ char name[SSSRAID_NAME_LENGTH];
+ int cpu_count;
+ /*
+ * before_affinity_msix_cnt is
+ * min("FW support IO Queue count", num_online_cpus)+1
+ */
+ u16 before_affinity_msix_cnt;
+
+ struct sssraid_cmd *adm_cmds;
+ struct list_head adm_cmd_list;
+ spinlock_t adm_cmd_lock;
+
+ struct sssraid_cmd *ioq_ptcmds;
+ struct list_head ioq_pt_list;
+ spinlock_t ioq_pt_lock;
+
+ int reset_flag;
+
+ enum sssraid_state state;
+ spinlock_t state_lock;
+
+ struct request_queue *bsg_queue;
+
+ u8 intr_enabled;
+
+ struct sssraid_intr_info *intr_info;
+ u32 intr_info_count;
+
+ char watchdog_work_q_name[20];
+ struct workqueue_struct *watchdog_work_q;
+ struct delayed_work watchdog_work;
+ spinlock_t watchdog_lock;
+
+ char fwevt_worker_name[SSSRAID_NAME_LENGTH];
+ struct workqueue_struct *fwevt_worker_thread;
+ spinlock_t fwevt_lock;
+ struct list_head fwevt_list;
+
+ struct sssraid_fwevt *current_event;
+};
+
+/*
+ * SSSRAID scatter list descriptor
+ */
+struct sssraid_sgl_desc {
+ __le64 addr;
+ __le32 length;
+ __u8 rsvd[3];
+ __u8 type;
+};
+
+union sssraid_data_ptr {
+ struct {
+ __le64 prp1;
+ __le64 prp2;
+ };
+ struct sssraid_sgl_desc sgl;
+};
+
+/*
+ * SSSRAID general admin class command format struct
+ */
+struct sssraid_admin_common_command {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __le32 cdw2[4];
+ union sssraid_data_ptr dptr;
+ __le32 cdw10;
+ __le32 cdw11;
+ __le32 cdw12;
+ __le32 cdw13;
+ __le32 cdw14;
+ __le32 cdw15;
+};
+
+struct sssraid_features {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __u64 rsvd2[2];
+ union sssraid_data_ptr dptr;
+ __le32 fid;
+ __le32 dword11;
+ __le32 dword12;
+ __le32 dword13;
+ __le32 dword14;
+ __le32 dword15;
+};
+
+/*
+ * SSSRAID create completion queue command struct
+ */
+struct sssraid_create_cq {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __u32 rsvd1[5];
+ __le64 prp1;
+ __u64 rsvd8;
+ __le16 cqid;
+ __le16 qsize;
+ __le16 cq_flags;
+ __le16 irq_vector;
+ __u32 rsvd12[4];
+};
+
+/*
+ * SSSRAID create submission queue command struct
+ */
+struct sssraid_create_sq {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __u32 rsvd1[5];
+ __le64 prp1;
+ __u64 rsvd8;
+ __le16 sqid;
+ __le16 qsize;
+ __le16 sq_flags;
+ __le16 cqid;
+ __u32 rsvd12[4];
+};
+
+/*
+ * SSSRAID delete submission queue command struct
+ */
+struct sssraid_delete_queue {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __u32 rsvd1[9];
+ __le16 qid;
+ __u16 rsvd10;
+ __u32 rsvd11[5];
+};
+
+/*
+ * SSSRAID access to information command struct
+ */
+struct sssraid_get_info {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __u32 rsvd2[4];
+ union sssraid_data_ptr dptr;
+ __u8 type;
+ __u8 rsvd10[3];
+ __le32 cdw11;
+ __u32 rsvd12[4];
+};
+
+/*
+ * User command struct
+ */
+struct sssraid_usr_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ union {
+ struct {
+ __le16 subopcode;
+ __le16 rsvd1;
+ } info_0;
+ __le32 cdw2;
+ };
+ union {
+ struct {
+ __le16 data_len;
+ __le16 param_len;
+ } info_1;
+ __le32 cdw3;
+ };
+ __u64 metadata;
+ union sssraid_data_ptr dptr;
+ __le32 cdw10;
+ __le32 cdw11;
+ __le32 cdw12;
+ __le32 cdw13;
+ __le32 cdw14;
+ __le32 cdw15;
+};
+
+enum {
+ SSSRAID_CMD_FLAG_SGL_METABUF = (1 << 6),
+ SSSRAID_CMD_FLAG_SGL_METASEG = (1 << 7),
+ SSSRAID_CMD_FLAG_SGL_ALL = SSSRAID_CMD_FLAG_SGL_METABUF | SSSRAID_CMD_FLAG_SGL_METASEG,
+};
+
+enum sssraid_cmd_state {
+ SSSRAID_CMD_IDLE = 0,
+ SSSRAID_CMD_IN_FLIGHT = 1,
+ SSSRAID_CMD_COMPLETE = 2,
+ SSSRAID_CMD_TIMEOUT = 3,
+ SSSRAID_CMD_TMO_COMPLETE = 4,
+};
+
+/*
+ * SSSRAID abort command struct
+ */
+struct sssraid_abort_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __u64 rsvd2[4];
+ __le16 sqid;
+ __le16 cid;
+ __u32 rsvd11[5];
+};
+
+/*
+ * SSSRAID reset command struct
+ */
+struct sssraid_reset_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __u64 rsvd2[4];
+ __u8 type;
+ __u8 rsvd10[3];
+ __u32 rsvd11[5];
+};
+
+/*
+ * SSSRAID admin class command set struct
+ */
+struct sssraid_admin_command {
+ union {
+ struct sssraid_admin_common_command common;
+ struct sssraid_features features;
+ struct sssraid_create_cq create_cq;
+ struct sssraid_create_sq create_sq;
+ struct sssraid_delete_queue delete_queue;
+ struct sssraid_get_info get_info;
+ struct sssraid_abort_cmd abort;
+ struct sssraid_reset_cmd reset;
+ struct sssraid_usr_cmd usr_cmd;
+ };
+};
+
+/*
+ * SSSRAID general IO class command format struct
+ */
+struct sssraid_ioq_common_command {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __le16 sense_len;
+ __u8 cdb_len;
+ __u8 rsvd2;
+ __le32 cdw3[3];
+ union sssraid_data_ptr dptr;
+ __le32 cdw10[6];
+ __u8 cdb[32];
+ __le64 sense_addr;
+ __le32 cdw26[6];
+};
+
+/*
+ * SSSRAID read or write command struct
+ */
+struct sssraid_rw_command {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __le16 sense_len;
+ __u8 cdb_len;
+ __u8 rsvd2;
+ __u32 rsvd3[3];
+ union sssraid_data_ptr dptr;
+ __le64 slba;
+ __le16 nlb;
+ __le16 control;
+ __u32 rsvd13[3];
+ __u8 cdb[32];
+ __le64 sense_addr;
+ __u32 rsvd26[6];
+};
+
+struct sssraid_scsi_nonio {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 hdid;
+ __le16 sense_len;
+ __u8 cdb_length;
+ __u8 rsvd2;
+ __u32 rsvd3[3];
+ union sssraid_data_ptr dptr;
+ __u32 rsvd10[5];
+ __le32 buffer_len;
+ __u8 cdb[32];
+ __le64 sense_addr;
+ __u32 rsvd26[6];
+};
+
+/*
+ * SSSRAID IO class command struct
+ */
+struct sssraid_ioq_command {
+ union {
+ struct sssraid_ioq_common_command common;
+ struct sssraid_rw_command rw;
+ struct sssraid_scsi_nonio scsi_nonio;
+ };
+};
+
+/*
+ * SSSRAID passthru command struct
+ */
+struct sssraid_passthru_common_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 rsvd0;
+ __u32 nsid;
+ union {
+ struct {
+ __u16 subopcode;
+ __u16 rsvd1;
+ } info_0;
+ __u32 cdw2;
+ };
+ union {
+ struct {
+ __u16 data_len;
+ __u16 param_len;
+ } info_1;
+ __u32 cdw3;
+ };
+ __u64 metadata;
+
+ __u64 addr;
+ __u64 prp2;
+
+ __u32 cdw10;
+ __u32 cdw11;
+ __u32 cdw12;
+ __u32 cdw13;
+ __u32 cdw14;
+ __u32 cdw15;
+ __u32 timeout_ms;
+ __u32 result0;
+ __u32 result1;
+};
+
+struct sssraid_ioq_passthru_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 rsvd0;
+ __u32 nsid;
+ union {
+ struct {
+ __u16 res_sense_len;
+ __u8 cdb_len;
+ __u8 rsvd0;
+ } info_0;
+ __u32 cdw2;
+ };
+ union {
+ struct {
+ __u16 subopcode;
+ __u16 rsvd1;
+ } info_1;
+ __u32 cdw3;
+ };
+ union {
+ struct {
+ __u16 rsvd;
+ __u16 param_len;
+ } info_2;
+ __u32 cdw4;
+ };
+ __u32 cdw5;
+ __u64 addr;
+ __u64 prp2;
+ union {
+ struct {
+ __u16 eid;
+ __u16 sid;
+ } info_3;
+ __u32 cdw10;
+ };
+ union {
+ struct {
+ __u16 did;
+ __u8 did_flag;
+ __u8 rsvd2;
+ } info_4;
+ __u32 cdw11;
+ };
+ __u32 cdw12;
+ __u32 cdw13;
+ __u32 cdw14;
+ __u32 data_len;
+ __u32 cdw16;
+ __u32 cdw17;
+ __u32 cdw18;
+ __u32 cdw19;
+ __u32 cdw20;
+ __u32 cdw21;
+ __u32 cdw22;
+ __u32 cdw23;
+ __u64 sense_addr;
+ __u32 cdw26[4];
+ __u32 timeout_ms;
+ __u32 result0;
+ __u32 result1;
+};
+
+struct sssraid_bsg_request {
+ u32 msgcode;
+ u32 control;
+ union {
+ struct sssraid_passthru_common_cmd admcmd;
+ struct sssraid_ioq_passthru_cmd ioqcmd;
+ };
+};
+
+enum {
+ SSSRAID_BSG_ADM,
+ SSSRAID_BSG_IOQ,
+};
+
+/*
+ * define the transfer command struct
+ */
+struct sssraid_cmd {
+ u16 qid;
+ u16 cid;
+ u32 result0;
+ u32 result1;
+ u16 status;
+ void *priv;
+ enum sssraid_cmd_state state;
+ struct completion cmd_done;
+ struct list_head list;
+};
+
+/*
+ * define the SSSRAID physical queue struct
+ */
+struct sssraid_squeue {
+ struct sssraid_dev *hdev;
+ spinlock_t sq_lock; /* spinlock for lock handling */
+
+ void *sq_cmds;
+
+ dma_addr_t sq_dma_addr;
+ u32 __iomem *q_db;
+ u8 cq_phase;
+ u8 sqes;
+ u16 qidx;
+ u16 sq_tail;
+ u16 last_cq_head;
+ u16 q_depth;
+ void *sense;
+ dma_addr_t sense_dma_addr;
+ struct dma_pool *prp_small_pool;
+};
+
+struct sssraid_cqueue {
+ struct sssraid_dev *hdev;
+
+ spinlock_t cq_lock ____cacheline_aligned_in_smp; /* spinlock for lock handling */
+
+ struct sssraid_completion *cqes;
+
+ dma_addr_t cq_dma_addr;
+ u8 cq_phase;
+ u16 cq_head;
+ u16 last_cq_head;
+};
+
+/*
+ * define the SSSRAID IO queue descriptor struct
+ */
+struct sssraid_iod {
+ struct sssraid_squeue *sqinfo;
+ enum sssraid_cmd_state state;
+ int npages;
+ u32 nsge;
+ u32 length;
+ bool use_sgl;
+ dma_addr_t first_dma;
+ void *sense;
+ dma_addr_t sense_dma;
+ struct scatterlist *sg;
+ void *list[0];
+};
+
+/*
+ * define the SSSRAID scsi device attribution and information
+ */
+#define SSSRAID_DEV_INFO_ATTR_BOOT(attr) ((attr) & 0x01)
+#define SSSRAID_DEV_INFO_ATTR_VD(attr) (((attr) & 0x02) == 0x0)
+#define SSSRAID_DEV_INFO_ATTR_PT(attr) (((attr) & 0x22) == 0x02)
+#define SSSRAID_DEV_INFO_ATTR_RAWDISK(attr) ((attr) & 0x20)
+#define SSSRAID_DEV_DISK_TYPE(attr) ((attr) & 0x1e)
+
+#define SSSRAID_DEV_INFO_FLAG_VALID(flag) ((flag) & 0x01)
+#define SSSRAID_DEV_INFO_FLAG_CHANGE(flag) ((flag) & 0x02)
+
+/*
+ * define the SSSRAID scsi device identifier
+ */
+enum {
+ SSSRAID_SAS_HDD_VD = 0x04,
+ SSSRAID_SATA_HDD_VD = 0x08,
+ SSSRAID_SAS_SSD_VD = 0x0c,
+ SSSRAID_SATA_SSD_VD = 0x10,
+ SSSRAID_NVME_SSD_VD = 0x14,
+ SSSRAID_SAS_HDD_PD = 0x06,
+ SSSRAID_SATA_HDD_PD = 0x0a,
+ SSSRAID_SAS_SSD_PD = 0x0e,
+ SSSRAID_SATA_SSD_PD = 0x12,
+ SSSRAID_NVME_SSD_PD = 0x16,
+};
+
+/*
+ * define the SSSRAID scsi device queue depth
+ */
+#define SSSRAID_HDD_PD_QD 64
+#define SSSRAID_HDD_VD_QD 256
+#define SSSRAID_SSD_PD_QD 64
+#define SSSRAID_SSD_VD_QD 256
+
+#define BGTASK_TYPE_REBUILD 4
+#define USR_CMD_READ 0xc2
+#define USR_CMD_RDLEN 0x1000
+#define USR_CMD_VDINFO 0x704
+#define USR_CMD_BGTASK 0x504
+#define VDINFO_PARAM_LEN 0x04
+
+/*
+ * SSSRAID virtual device information struct
+ */
+struct sssraid_vd_info {
+ __u8 name[32];
+ __le16 id;
+ __u8 rg_id;
+ __u8 rg_level;
+ __u8 sg_num;
+ __u8 sg_disk_num;
+ __u8 vd_status;
+ __u8 vd_type;
+ __u8 rsvd1[4056];
+};
+
+#define MAX_REALTIME_BGTASK_NUM 32
+
+struct bgtask_info {
+ __u8 type;
+ __u8 progress;
+ __u8 rate;
+ __u8 rsvd0;
+ __le16 vd_id;
+ __le16 time_left;
+ __u8 rsvd1[4];
+};
+
+struct sssraid_bgtask {
+ __u8 sw;
+ __u8 task_num;
+ __u8 rsvd[6];
+ struct bgtask_info bgtask[MAX_REALTIME_BGTASK_NUM];
+};
+
+/*
+ * SSSRAID scsi device information struct
+ */
+struct sssraid_dev_info {
+ __le32 hdid;
+ __le16 target;
+ __u8 channel;
+ __u8 lun;
+ __u8 attr;
+ __u8 flag;
+ __le16 max_io_kb;
+};
+
+#define IOQ_PT_DATA_LEN 4096
+#define MAX_DEV_ENTRY_PER_PAGE_4K 340
+struct sssraid_dev_list {
+ __le32 dev_num;
+ __u32 rsvd0[3];
+ struct sssraid_dev_info devices[MAX_DEV_ENTRY_PER_PAGE_4K];
+};
+
+/*
+ * SSSRAID scsi device host data struct
+ */
+struct sssraid_sdev_hostdata {
+ u32 hdid;
+ u16 max_io_kb;
+ u8 attr;
+ u8 flag;
+ u8 rg_id;
+ u8 rsvd[3];
+};
+
+extern unsigned char small_pool_num;
+extern u32 io_queue_depth;
+irqreturn_t sssraid_isr_poll(int irq, void *privdata);
+bool sssraid_poll_cq(struct sssraid_dev *hdev, u16 qidx, int cid);
+void sssraid_submit_cmd(struct sssraid_squeue *sqinfo, const void *cmd);
+int sssraid_get_dev_list(struct sssraid_dev *hdev, struct sssraid_dev_info *devices);
+int sssraid_submit_admin_sync_cmd(struct sssraid_dev *hdev, struct sssraid_admin_command *cmd,
+ u32 *result0, u32 *result1, u32 timeout);
+int sssraid_send_abort_cmd(struct sssraid_dev *hdev, u32 hdid, u16 qidx, u16 cid);
+int sssraid_send_reset_cmd(struct sssraid_dev *hdev, u8 type, u32 hdid);
+void sssraid_adm_timeout(struct sssraid_dev *hdev, struct sssraid_cmd *cmd);
+int sssraid_init_ioc(struct sssraid_dev *hdev, u8 re_init);
+void sssraid_cleanup_ioc(struct sssraid_dev *hdev, u8 re_init);
+int sssraid_soft_reset_handler(struct sssraid_dev *hdev);
+void sssraid_free_iod_res(struct sssraid_dev *hdev, struct sssraid_iod *iod);
+bool sssraid_change_host_state(struct sssraid_dev *hdev, enum sssraid_state newstate);
+int sssraid_configure_timestamp(struct sssraid_dev *hdev);
+int sssraid_init_ctrl_info(struct sssraid_dev *hdev);
+struct sssraid_cmd *sssraid_get_cmd(struct sssraid_dev *hdev, enum sssraid_cmd_type type);
+void sssraid_put_cmd(struct sssraid_dev *hdev, struct sssraid_cmd *cmd,
+ enum sssraid_cmd_type type);
+int sssraid_send_event_ack(struct sssraid_dev *hdev, u8 event,
+ u32 event_ctx, u16 cid);
+struct sssraid_fwevt *sssraid_alloc_fwevt(int len);
+void sssraid_fwevt_add_to_list(struct sssraid_dev *hdev,
+ struct sssraid_fwevt *fwevt);
+void sssraid_cleanup_fwevt_list(struct sssraid_dev *hdev);
+void sssraid_ioc_enable_intr(struct sssraid_dev *hdev);
+void sssraid_ioc_disable_intr(struct sssraid_dev *hdev);
+void sssraid_cleanup_resources(struct sssraid_dev *hdev);
+void sssraid_complete_cqes(struct sssraid_dev *hdev, u16 qidx, u16 start, u16 end);
+int sssraid_io_map_data(struct sssraid_dev *hdev, struct sssraid_iod *iod,
+ struct scsi_cmnd *scmd, struct sssraid_ioq_command *ioq_cmd);
+void sssraid_map_status(struct sssraid_iod *iod, struct scsi_cmnd *scmd,
+ struct sssraid_completion *cqe);
+void sssraid_scan_disk(struct sssraid_dev *hdev);
+void sssraid_complete_aen(struct sssraid_dev *hdev, struct sssraid_completion *cqe);
+void sssraid_back_all_io(struct sssraid_dev *hdev);
+
+static inline void **sssraid_iod_list(struct sssraid_iod *iod)
+{
+ return iod->list;
+}
+
+#end
diff --git a/drivers/scsi/sssraid/sssraid_debug.h b/drivers/scsi/sssraid/sssraid_debug.h
new file mode 100644
index 000000000000..d48c57e275f7
--- /dev/null
+++ b/drivers/scsi/sssraid/sssraid_debug.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2022 3SNIC Information Technology, Ltd */
+
+/* 3SNIC RAID SSSXXX Series Linux Driver */
+
+#ifndef SSSRAID_DEBUG_H_INCLUDED
+#define SSSRAID_DEBUG_H_INCLUDED
+
+/*
+ * debug levels
+ */
+#define SSSRAID_DEBUG 0x00000001
+
+/*
+ * debug macros
+ */
+
+#define ioc_err(ioc, fmt, ...) \
+ pr_err("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
+#define ioc_notice(ioc, fmt, ...) \
+ pr_notice("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
+#define ioc_warn(ioc, fmt, ...) \
+ pr_warn("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
+#define ioc_info(ioc, fmt, ...) \
+ pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__)
+
+
+#define dbgprint(IOC, FMT, ...) \
+ do { \
+ if (unlikely(IOC->logging_level & SSSRAID_DEBUG)) \
+ pr_info("%s: " FMT, (IOC)->name, ##__VA_ARGS__); \
+ } while (0)
+
+#endif /* SSSRAID_DEBUG_H_INCLUDED */
diff --git a/drivers/scsi/sssraid/sssraid_fw.c b/drivers/scsi/sssraid/sssraid_fw.c
new file mode 100644
index 000000000000..54287cf70558
--- /dev/null
+++ b/drivers/scsi/sssraid/sssraid_fw.c
@@ -0,0 +1,1724 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2022 3SNIC Information Technology, Ltd */
+
+/* 3SNIC RAID SSSXXX Series Linux Driver */
+
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/sysfs.h>
+#include <linux/gfp.h>
+#include <linux/types.h>
+#include <linux/ratelimit.h>
+#include <linux/debugfs.h>
+#include <linux/blkdev.h>
+#include <linux/bsg-lib.h>
+#include <linux/sort.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_dbg.h>
+
+#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/once.h>
+#include <linux/sched/signal.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
+
+#include "sssraid.h"
+#include "sssraid_debug.h"
+
+static int sssraid_wait_ready(struct sssraid_dev *hdev, u64 cap, bool enabled)
+{
+ unsigned long timeout =
+ ((SSSRAID_CAP_TIMEOUT(cap) + 1) * SSSRAID_CAP_TIMEOUT_UNIT_MS) + jiffies;
+ u32 bit = enabled ? SSSRAID_CSTS_RDY : 0;
+
+ while ((readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_RDY) != bit) {
+ usleep_range(1000, 2000);
+ if (fatal_signal_pending(current))
+ return -EINTR;
+
+ if (time_after(jiffies, timeout)) {
+ ioc_err(hdev, "Device not ready; aborting %s\n",
+ enabled ? "initialisation" : "reset");
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+static int sssraid_enable_ctrl(struct sssraid_dev *hdev)
+{
+ u64 cap = hdev->cap;
+ u32 dev_page_min = SSSRAID_CAP_MPSMIN(cap) + 12;
+ u32 page_shift = PAGE_SHIFT;
+
+ if (page_shift < dev_page_min) {
+ ioc_err(hdev, "Minimum device page size[%u], too large for host[%u]\n",
+ 1U << dev_page_min, 1U << page_shift);
+ return -ENODEV;
+ }
+
+ page_shift = min_t(unsigned int, SSSRAID_CAP_MPSMAX(cap) + 12, PAGE_SHIFT);
+ hdev->page_size = 1U << page_shift;
+
+ hdev->ctrl_config = SSSRAID_CC_CSS_NVM;
+ hdev->ctrl_config |= (page_shift - 12) << SSSRAID_CC_MPS_SHIFT;
+ hdev->ctrl_config |= SSSRAID_CC_AMS_RR | SSSRAID_CC_SHN_NONE;
+ hdev->ctrl_config |= SSSRAID_CC_IOSQES | SSSRAID_CC_IOCQES;
+ hdev->ctrl_config |= SSSRAID_CC_ENABLE;
+ writel(hdev->ctrl_config, hdev->bar + SSSRAID_REG_CC);
+
+ return sssraid_wait_ready(hdev, cap, true);
+}
+
+static int sssraid_disable_ctrl(struct sssraid_dev *hdev)
+{
+ hdev->ctrl_config &= ~SSSRAID_CC_SHN_MASK;
+ hdev->ctrl_config &= ~SSSRAID_CC_ENABLE;
+ writel(hdev->ctrl_config, hdev->bar + SSSRAID_REG_CC);
+
+ return sssraid_wait_ready(hdev, hdev->cap, false);
+}
+
+static int sssraid_shutdown_ctrl(struct sssraid_dev *hdev)
+{
+ unsigned long timeout = le32_to_cpu(hdev->ctrl_info->rtd3e) / 1000000 * HZ + jiffies;
+
+ hdev->ctrl_config &= ~SSSRAID_CC_SHN_MASK;
+ hdev->ctrl_config |= SSSRAID_CC_SHN_NORMAL;
+ writel(hdev->ctrl_config, hdev->bar + SSSRAID_REG_CC);
+
+ while ((readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_SHST_MASK) !=
+ SSSRAID_CSTS_SHST_CMPLT) {
+ msleep(100);
+ if (fatal_signal_pending(current))
+ return -EINTR;
+ if (time_after(jiffies, timeout)) {
+ ioc_err(hdev, "Device shutdown incomplete; abort shutdown\n");
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+static int sssraid_remap_bar(struct sssraid_dev *hdev, u32 size)
+{
+ struct pci_dev *pdev = hdev->pdev;
+
+ if (size > pci_resource_len(pdev, 0)) {
+ ioc_err(hdev, "Input size[%u] exceed bar0 length[%llu]\n",
+ size, pci_resource_len(pdev, 0));
+ return -ENODEV;
+ }
+
+ if (hdev->bar)
+ iounmap(hdev->bar);
+
+ hdev->bar = ioremap(pci_resource_start(pdev, 0), size);
+ if (!hdev->bar) {
+ ioc_err(hdev, "ioremap for bar0 failed\n");
+ return -ENODEV;
+ }
+ hdev->dbs = hdev->bar + SSSRAID_REG_DBS;
+
+ return 0;
+}
+
+static int sssraid_create_dma_pools(struct sssraid_dev *hdev)
+{
+ int i;
+ char poolname[20] = { 0 };
+
+ hdev->prp_page_pool = dma_pool_create("prp list page", &hdev->pdev->dev,
+ PAGE_SIZE, PAGE_SIZE, 0);
+
+ if (!hdev->prp_page_pool) {
+ ioc_err(hdev, "create prp_page_pool failed\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < small_pool_num; i++) {
+ sprintf(poolname, "prp_list_256_%d", i);
+ hdev->prp_small_pool[i] = dma_pool_create(poolname, &hdev->pdev->dev,
+ SMALL_POOL_SIZE,
+ SMALL_POOL_SIZE, 0);
+
+ if (!hdev->prp_small_pool[i]) {
+ ioc_err(hdev, "create prp_small_pool %d failed\n", i);
+ goto destroy_prp_small_pool;
+ }
+ }
+
+ return 0;
+
+destroy_prp_small_pool:
+ while (i > 0)
+ dma_pool_destroy(hdev->prp_small_pool[--i]);
+ dma_pool_destroy(hdev->prp_page_pool);
+
+ return -ENOMEM;
+}
+
+static void sssraid_destroy_dma_pools(struct sssraid_dev *hdev)
+{
+ int i;
+
+ for (i = 0; i < small_pool_num; i++)
+ dma_pool_destroy(hdev->prp_small_pool[i]);
+ dma_pool_destroy(hdev->prp_page_pool);
+}
+
+static int sssraid_alloc_resources(struct sssraid_dev *hdev)
+{
+ int retval, nqueue;
+
+ hdev->ctrl_info = kzalloc_node(sizeof(*hdev->ctrl_info), GFP_KERNEL, hdev->numa_node);
+ if (!hdev->ctrl_info)
+ return -ENOMEM;
+
+ retval = sssraid_create_dma_pools(hdev);
+ if (retval)
+ goto free_ctrl_info;
+ /* not num_online_cpus */
+ nqueue = num_possible_cpus() + 1;
+ hdev->cqinfo = kcalloc_node(nqueue, sizeof(struct sssraid_cqueue),
+ GFP_KERNEL, hdev->numa_node);
+ if (!hdev->cqinfo) {
+ retval = -ENOMEM;
+ goto destroy_dma_pools;
+ }
+
+ hdev->sqinfo = kcalloc_node(nqueue, sizeof(struct sssraid_squeue),
+ GFP_KERNEL, hdev->numa_node);
+ if (!hdev->sqinfo) {
+ retval = -ENOMEM;
+ goto free_cqueues;
+ }
+
+ /* sssraid_alloc_admin_cmds moved to sssraid_init_ioc */
+
+ ioc_info(hdev, "queues num: %d\n", nqueue);
+
+ return 0;
+
+free_cqueues:
+ kfree(hdev->cqinfo);
+destroy_dma_pools:
+ sssraid_destroy_dma_pools(hdev);
+free_ctrl_info:
+ kfree(hdev->ctrl_info);
+
+ return retval;
+}
+
+void sssraid_ioc_enable_intr(struct sssraid_dev *hdev)
+{
+ hdev->intr_enabled = 1;
+}
+
+void sssraid_ioc_disable_intr(struct sssraid_dev *hdev)
+{
+ u16 i, max_vectors;
+
+ hdev->intr_enabled = 0;
+ max_vectors = hdev->intr_info_count;
+
+ for (i = 0; i < max_vectors; i++)
+ synchronize_irq(pci_irq_vector(hdev->pdev, i));
+}
+
+static int sssraid_setup_resources(struct sssraid_dev *hdev)
+{
+ struct pci_dev *pdev = hdev->pdev;
+ int retval = 0;
+ u64 maskbit = SSSRAID_DMA_MSK_BIT_MAX;
+
+ if (pci_enable_device_mem(pdev)) {
+ ioc_err(hdev, "pci_enable_device_mem: failed\n");
+ retval = -ENODEV;
+ goto out_failed;
+ }
+
+ retval = pci_request_mem_regions(pdev, SSSRAID_DRIVER_NAME);
+ if (retval) {
+ ioc_err(hdev, "fail to request memory regions\n");
+ retval = -ENODEV;
+ goto out_failed;
+ }
+
+ /* get cap value at first, so keep
+ * sssraid_remap_bar(hdev, SSSRAID_REG_DBS + 4096)
+ * ioremap(pci_resource_start(..)) still in sssraid_remap_bar
+ */
+ retval = sssraid_remap_bar(hdev, SSSRAID_REG_DBS + 4096);
+ if (retval) {
+ retval = -ENODEV;
+ goto out_failed;
+ }
+
+ pci_set_master(pdev);
+
+ if (readl(hdev->bar + SSSRAID_REG_CSTS) == U32_MAX) {
+ retval = -ENODEV;
+ ioc_err(hdev, "Read csts register failed\n");
+ goto out_failed;
+ }
+
+ hdev->cap = lo_hi_readq(hdev->bar + SSSRAID_REG_CAP);
+ hdev->ioq_depth = min_t(u32, SSSRAID_CAP_MQES(hdev->cap) + 1, io_queue_depth);
+ hdev->scsi_qd = hdev->ioq_depth - SSSRAID_PTCMDS_PERQ;
+ hdev->db_stride = 1 << SSSRAID_CAP_STRIDE(hdev->cap);
+
+ maskbit = SSSRAID_CAP_DMAMASK(hdev->cap);
+ if (maskbit < 32 || maskbit > SSSRAID_DMA_MSK_BIT_MAX) {
+ ioc_err(hdev, "err, dma mask invalid[%llu], set to default\n", maskbit);
+ maskbit = SSSRAID_DMA_MSK_BIT_MAX;
+ }
+
+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(maskbit))) {
+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+ ioc_err(hdev, "set dma mask[32] and coherent failed\n");
+ retval = -ENODEV;
+ goto out_failed;
+ }
+ ioc_info(hdev, "set dma mask[32] success\n");
+ } else {
+ ioc_info(hdev, "set dma mask[%llu] success\n", maskbit);
+ }
+
+ /* pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES) moved to setup_isr */
+
+ pci_set_drvdata(pdev, hdev->shost);
+
+ pci_enable_pcie_error_reporting(pdev);
+ pci_save_state(pdev);
+
+ sssraid_ioc_disable_intr(hdev);
+
+ return retval;
+
+out_failed:
+ sssraid_cleanup_resources(hdev);
+ return retval;
+}
+
+static int sssraid_alloc_admin_cmds(struct sssraid_dev *hdev)
+{
+ u16 i;
+
+ INIT_LIST_HEAD(&hdev->adm_cmd_list);
+ spin_lock_init(&hdev->adm_cmd_lock);
+
+ hdev->adm_cmds = kcalloc_node(SSSRAID_AQ_BLK_MQ_DEPTH, sizeof(struct sssraid_cmd),
+ GFP_KERNEL, hdev->numa_node);
+
+ if (!hdev->adm_cmds) {
+ ioc_err(hdev, "Alloc admin cmds failed\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < SSSRAID_AQ_BLK_MQ_DEPTH; i++) {
+ hdev->adm_cmds[i].qid = 0;
+ hdev->adm_cmds[i].cid = i;
+ list_add_tail(&(hdev->adm_cmds[i].list), &hdev->adm_cmd_list);
+ }
+
+ ioc_info(hdev, "Alloc admin cmds success, num[%d]\n", SSSRAID_AQ_BLK_MQ_DEPTH);
+
+ return 0;
+}
+
+static int sssraid_alloc_qpair(struct sssraid_dev *hdev, u16 qidx, u16 depth)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+ int retval = 0;
+
+ if (hdev->init_done_queue_cnt > qidx) {
+ ioc_info(hdev, "warn: queue[%d] is exist\n", qidx);
+ return 0;
+ }
+
+ cqinfo->cqes = dma_alloc_coherent(&hdev->pdev->dev, CQ_SIZE(depth),
+ &cqinfo->cq_dma_addr, GFP_KERNEL | __GFP_ZERO);
+ if (!cqinfo->cqes)
+ return -ENOMEM;
+
+ sqinfo->sq_cmds = dma_alloc_coherent(&hdev->pdev->dev, SQ_SIZE(qidx, depth),
+ &sqinfo->sq_dma_addr, GFP_KERNEL);
+ if (!sqinfo->sq_cmds) {
+ retval = -ENOMEM;
+ goto free_cqes;
+ }
+
+ /* alloc sense buffer */
+ sqinfo->sense = dma_alloc_coherent(&hdev->pdev->dev, SENSE_SIZE(depth),
+ &sqinfo->sense_dma_addr, GFP_KERNEL | __GFP_ZERO);
+ if (!sqinfo->sense) {
+ retval = -ENOMEM;
+ goto free_sq_cmds;
+ }
+
+ spin_lock_init(&sqinfo->sq_lock);
+ spin_lock_init(&cqinfo->cq_lock);
+ cqinfo->hdev = hdev;
+ sqinfo->hdev = hdev;
+ sqinfo->q_depth = depth;
+ sqinfo->qidx = qidx;
+ /* cq_vector replaced by msix_index */
+
+ /*
+ * online_queues: completely initialized queue count: sssraid_init_queue
+ * queue_count: allocated but not completely initialized queue count: sssraid_alloc_queue
+ * online_queues/queue_count replaced by init_done_queue_cnt.
+ */
+ hdev->init_done_queue_cnt++;
+
+ return 0;
+
+free_sq_cmds:
+ dma_free_coherent(&hdev->pdev->dev, SQ_SIZE(qidx, depth), (void *)sqinfo->sq_cmds,
+ sqinfo->sq_dma_addr);
+free_cqes:
+ dma_free_coherent(&hdev->pdev->dev, CQ_SIZE(depth), (void *)cqinfo->cqes,
+ cqinfo->cq_dma_addr);
+ return retval;
+}
+
+static void sssraid_init_queue(struct sssraid_dev *hdev, u16 qidx)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ memset((void *)cqinfo->cqes, 0, CQ_SIZE(sqinfo->q_depth));
+
+ sqinfo->sq_tail = 0;
+ cqinfo->cq_head = 0;
+ cqinfo->cq_phase = 1;
+ sqinfo->q_db = &hdev->dbs[qidx * 2 * hdev->db_stride];
+ sqinfo->prp_small_pool = hdev->prp_small_pool[qidx % small_pool_num];
+}
+
+static int sssraid_setup_admin_qpair(struct sssraid_dev *hdev)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[0];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[0];
+ u32 aqa;
+ int retval;
+
+ ioc_info(hdev, "start disable ctrl\n");
+
+ retval = sssraid_disable_ctrl(hdev);
+ if (retval)
+ return retval;
+
+ /* this func don't alloc admin queue */
+
+ aqa = sqinfo->q_depth - 1;
+ aqa |= aqa << 16;
+ writel(aqa, hdev->bar + SSSRAID_REG_AQA);
+ lo_hi_writeq(sqinfo->sq_dma_addr, hdev->bar + SSSRAID_REG_ASQ);
+ lo_hi_writeq(cqinfo->cq_dma_addr, hdev->bar + SSSRAID_REG_ACQ);
+
+ ioc_info(hdev, "start enable ctrl\n");
+
+ retval = sssraid_enable_ctrl(hdev);
+ if (retval) {
+ retval = -ENODEV;
+ return retval;
+ }
+
+ /* interrupt registry not here */
+ /* cq_vector replaced by msix_index */
+
+ sssraid_init_queue(hdev, 0);
+
+ ioc_info(hdev, "success, queuecount:[%d], pagesize[%d]\n",
+ hdev->init_done_queue_cnt, hdev->page_size);
+
+ return 0;
+}
+
+static void sssraid_cleanup_isr(struct sssraid_dev *hdev)
+{
+ u16 i;
+
+ sssraid_ioc_disable_intr(hdev);
+
+ if (!hdev->intr_info)
+ return;
+
+ for (i = 0; i < hdev->intr_info_count; i++)
+ free_irq(pci_irq_vector(hdev->pdev, i),
+ (hdev->intr_info + i));
+
+ kfree(hdev->intr_info);
+ hdev->intr_info = NULL;
+ hdev->intr_info_count = 0;
+ pci_free_irq_vectors(hdev->pdev);
+}
+
+static void sssraid_complete_adminq_cmnd(struct sssraid_dev *hdev, u16 qidx,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_cmd *adm_cmd;
+
+ adm_cmd = hdev->adm_cmds + le16_to_cpu(cqe->cmd_id);
+ if (unlikely(adm_cmd->state == SSSRAID_CMD_IDLE)) {
+ ioc_warn(hdev, "Invalid id %d completed on queue %d\n",
+ le16_to_cpu(cqe->cmd_id), le16_to_cpu(cqe->sq_id));
+ return;
+ }
+
+ adm_cmd->status = le16_to_cpu(cqe->status) >> 1;
+ adm_cmd->result0 = le32_to_cpu(cqe->result);
+ adm_cmd->result1 = le32_to_cpu(cqe->result1);
+
+ complete(&adm_cmd->cmd_done);
+}
+
+static inline bool sssraid_cqe_pending(struct sssraid_cqueue *cqinfo)
+{
+ return (le16_to_cpu(cqinfo->cqes[cqinfo->cq_head].status) & 1) ==
+ cqinfo->cq_phase;
+}
+
+static inline void sssraid_update_cq_head(struct sssraid_dev *hdev, u16 qidx)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ if (++cqinfo->cq_head == sqinfo->q_depth) {
+ cqinfo->cq_head = 0;
+ cqinfo->cq_phase = !cqinfo->cq_phase;
+ }
+}
+
+static inline bool sssraid_process_cq(struct sssraid_dev *hdev, u16 qidx, u16 *start,
+ u16 *end, int tag)
+{
+ bool found = false;
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ *start = cqinfo->cq_head;
+ while (!found && sssraid_cqe_pending(cqinfo)) {
+ if (le16_to_cpu(cqinfo->cqes[cqinfo->cq_head].cmd_id) == tag)
+ found = true;
+ sssraid_update_cq_head(hdev, qidx);
+ }
+ *end = cqinfo->cq_head;
+
+ if (*start != *end)
+ writel(cqinfo->cq_head, sqinfo->q_db + sqinfo->hdev->db_stride);
+
+ return found;
+}
+
+static irqreturn_t sssraid_isr(int irq, void *privdata)
+{
+ struct sssraid_intr_info *intr_info = privdata;
+ struct sssraid_dev *hdev = intr_info->hdev;
+ irqreturn_t ret = IRQ_NONE;
+ struct sssraid_cqueue *cqinfo;
+ u16 midx, start, end;
+
+ if (!intr_info)
+ return IRQ_NONE;
+
+ if (!hdev->intr_enabled)
+ return IRQ_NONE;
+
+ midx = intr_info->msix_index;
+ cqinfo = &hdev->cqinfo[midx];
+
+ spin_lock(&cqinfo->cq_lock);
+ if (cqinfo->cq_head != cqinfo->last_cq_head)
+ ret = IRQ_HANDLED;
+
+ sssraid_process_cq(hdev, midx, &start, &end, -1);
+ cqinfo->last_cq_head = cqinfo->cq_head;
+ spin_unlock(&cqinfo->cq_lock);
+
+ if (start != end) {
+ sssraid_complete_cqes(hdev, midx, start, end);
+ ret = IRQ_HANDLED;
+ }
+ return ret;
+}
+
+irqreturn_t sssraid_isr_poll(int irq, void *privdata)
+{
+ return IRQ_NONE;
+}
+
+bool sssraid_poll_cq(struct sssraid_dev *hdev, u16 qidx, int cid)
+{
+ u16 start, end;
+ bool found;
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+
+ if (!sssraid_cqe_pending(cqinfo))
+ return 0;
+
+ spin_lock_irq(&cqinfo->cq_lock);
+ found = sssraid_process_cq(hdev, qidx, &start, &end, cid);
+ spin_unlock_irq(&cqinfo->cq_lock);
+
+ sssraid_complete_cqes(hdev, qidx, start, end);
+ return found;
+}
+
+static inline int sssraid_request_irq(struct sssraid_dev *hdev, u16 index)
+{
+ struct pci_dev *pdev = hdev->pdev;
+ struct sssraid_intr_info *intr_info = hdev->intr_info + index;
+ int retval = 0;
+
+ intr_info->hdev = hdev;
+ intr_info->msix_index = index;
+ intr_info->cqinfo = NULL;
+
+ snprintf(intr_info->name, SSSRAID_NAME_LENGTH, "%s%d-msix%d",
+ SSSRAID_DRIVER_NAME, hdev->instance, index);
+
+ retval = request_threaded_irq(pci_irq_vector(pdev, index), sssraid_isr,
+ sssraid_isr_poll, IRQF_SHARED, intr_info->name, intr_info);
+
+ if (retval) {
+ ioc_err(hdev, "%s: Unable to allocate interrupt %d!\n",
+ intr_info->name, pci_irq_vector(pdev, index));
+ return retval;
+ }
+
+ return retval;
+}
+
+static int sssraid_setup_isr(struct sssraid_dev *hdev, u8 setup_one)
+{
+ unsigned int irq_flags = PCI_IRQ_MSIX;
+ u16 max_vectors = 0, i;
+ int retval = 0;
+
+ struct irq_affinity desc = { .pre_vectors = 1};
+
+ sssraid_cleanup_isr(hdev);
+
+ if (setup_one)
+ max_vectors = 1;
+ else {
+ max_vectors = hdev->before_affinity_msix_cnt;
+
+ ioc_info(hdev, "MSI-x vectors requested: %d\n", max_vectors);
+ }
+
+ irq_flags |= PCI_IRQ_AFFINITY | PCI_IRQ_ALL_TYPES;
+
+ i = pci_alloc_irq_vectors_affinity(hdev->pdev,
+ 1, max_vectors, irq_flags, &desc);
+
+ if (i <= 0) {
+ ioc_err(hdev, "Cannot alloc irq vectors\n");
+ goto out_failed;
+ }
+ if (i != max_vectors) {
+ ioc_info(hdev,
+ "allocated vectors (%d) are less than configured (%d)\n",
+ i, max_vectors);
+
+ max_vectors = i;
+ }
+
+ hdev->intr_info = kzalloc(sizeof(struct sssraid_intr_info) * max_vectors,
+ GFP_KERNEL);
+ if (!hdev->intr_info) {
+ retval = -1;
+ pci_free_irq_vectors(hdev->pdev);
+ goto out_failed;
+ }
+
+ for (i = 0; i < max_vectors; i++) {
+ retval = sssraid_request_irq(hdev, i);
+ if (retval) {
+ hdev->intr_info_count = i; /* =i is for offload interrupt loop counter */
+ goto out_failed;
+ }
+ }
+
+ /* intr_info_count replace max_qid */
+ hdev->intr_info_count = max_vectors;
+ sssraid_ioc_enable_intr(hdev);
+ return retval;
+out_failed:
+ sssraid_cleanup_isr(hdev);
+
+ return retval;
+}
+
+static bool sssraid_adm_need_reset(struct sssraid_admin_command *cmd)
+{
+ switch (cmd->common.opcode) {
+ case SSSRAID_ADMIN_DELETE_SQ:
+ case SSSRAID_ADMIN_CREATE_SQ:
+ case SSSRAID_ADMIN_DELETE_CQ:
+ case SSSRAID_ADMIN_CREATE_CQ:
+ case SSSRAID_ADMIN_SET_FEATURES:
+ return false;
+ default:
+ return true;
+ }
+}
+
+void sssraid_submit_cmd(struct sssraid_squeue *sqinfo, const void *cmd)
+{
+ u32 sqes = SQE_SIZE(sqinfo->qidx);
+ unsigned long flags;
+ struct sssraid_admin_common_command *acd = (struct sssraid_admin_common_command *)cmd;
+
+ spin_lock_irqsave(&sqinfo->sq_lock, flags);
+ memcpy((sqinfo->sq_cmds + sqes * sqinfo->sq_tail), cmd, sqes);
+ if (++sqinfo->sq_tail == sqinfo->q_depth)
+ sqinfo->sq_tail = 0;
+
+ writel(sqinfo->sq_tail, sqinfo->q_db);
+ spin_unlock_irqrestore(&sqinfo->sq_lock, flags);
+
+ dbgprint(sqinfo->hdev, "cid[%d] qidx[%d], opcode[0x%x], flags[0x%x], hdid[%u]\n",
+ le16_to_cpu(acd->command_id), sqinfo->qidx, acd->opcode, acd->flags,
+ le32_to_cpu(acd->hdid));
+}
+
+int sssraid_submit_admin_sync_cmd(struct sssraid_dev *hdev, struct sssraid_admin_command *cmd,
+ u32 *result0, u32 *result1, u32 timeout)
+{
+ struct sssraid_cmd *adm_cmd = sssraid_get_cmd(hdev, SSSRAID_CMD_ADM);
+
+ if (!adm_cmd) {
+ ioc_err(hdev, "err, get admin cmd failed\n");
+ return -EFAULT;
+ }
+
+ timeout = timeout ? timeout : ADMIN_TIMEOUT;
+
+ /*
+ * watch dog not as optimized as
+ * init_completion/complete
+ */
+ init_completion(&adm_cmd->cmd_done);
+
+ cmd->common.command_id = cpu_to_le16(adm_cmd->cid);
+ sssraid_submit_cmd(&hdev->sqinfo[0], cmd);
+
+ if (!wait_for_completion_timeout(&adm_cmd->cmd_done, timeout)) {
+ ioc_err(hdev, "cid[%d] qidx[%d] timeout, opcode[0x%x] subopcode[0x%x]\n",
+ adm_cmd->cid, adm_cmd->qid, cmd->usr_cmd.opcode,
+ cmd->usr_cmd.info_0.subopcode);
+
+ /* reset controller if admin timeout */
+ if (sssraid_adm_need_reset(cmd))
+ sssraid_adm_timeout(hdev, adm_cmd);
+
+ sssraid_put_cmd(hdev, adm_cmd, SSSRAID_CMD_ADM);
+ return -ETIME;
+ }
+
+ if (result0)
+ *result0 = adm_cmd->result0;
+ if (result1)
+ *result1 = adm_cmd->result1;
+
+ sssraid_put_cmd(hdev, adm_cmd, SSSRAID_CMD_ADM);
+
+ return adm_cmd->status;
+}
+
+static int sssraid_get_ctrl_info(struct sssraid_dev *hdev, struct sssraid_ctrl_info *ctrl_info)
+{
+ struct sssraid_admin_command admin_cmd;
+ u8 *data_ptr = NULL;
+ dma_addr_t data_dma = 0;
+ int retval;
+
+ data_ptr = dma_alloc_coherent(&hdev->pdev->dev, PAGE_SIZE, &data_dma, GFP_KERNEL);
+ if (!data_ptr)
+ return -ENOMEM;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.get_info.opcode = SSSRAID_ADMIN_GET_INFO;
+ admin_cmd.get_info.type = SSSRAID_GET_INFO_CTRL;
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ retval = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+ if (!retval)
+ memcpy(ctrl_info, data_ptr, sizeof(struct sssraid_ctrl_info));
+
+ dma_free_coherent(&hdev->pdev->dev, PAGE_SIZE, data_ptr, data_dma);
+
+ return retval;
+}
+
+int sssraid_init_ctrl_info(struct sssraid_dev *hdev)
+{
+ int retval;
+
+ hdev->ctrl_info->nd = cpu_to_le32(240);
+ hdev->ctrl_info->mdts = 8;
+ hdev->ctrl_info->max_cmds = cpu_to_le16(4096);
+ hdev->ctrl_info->max_num_sge = cpu_to_le16(128);
+ hdev->ctrl_info->max_channel = cpu_to_le16(4);
+ hdev->ctrl_info->max_tgt_id = cpu_to_le32(3239);
+ hdev->ctrl_info->max_lun = cpu_to_le16(2);
+
+ retval = sssraid_get_ctrl_info(hdev, hdev->ctrl_info);
+ if (retval)
+ ioc_err(hdev, "init controller info failed: %d\n", retval);
+
+ ioc_info(hdev, "nd = %d\n", le32_to_cpu(hdev->ctrl_info->nd));
+ ioc_info(hdev, "max_cmd = %d\n", le16_to_cpu(hdev->ctrl_info->max_cmds));
+ ioc_info(hdev, "max_channel = %d\n", le16_to_cpu(hdev->ctrl_info->max_channel));
+ ioc_info(hdev, "max_tgt_id = %d\n", le32_to_cpu(hdev->ctrl_info->max_tgt_id));
+ ioc_info(hdev, "max_lun = %d\n", le16_to_cpu(hdev->ctrl_info->max_lun));
+ ioc_info(hdev, "max_num_sge = %d\n", le16_to_cpu(hdev->ctrl_info->max_num_sge));
+ ioc_info(hdev, "lun_num_boot = %d\n", le16_to_cpu(hdev->ctrl_info->lun_num_in_boot));
+ ioc_info(hdev, "mdts = %d\n", hdev->ctrl_info->mdts);
+ ioc_info(hdev, "acl = %d\n", hdev->ctrl_info->acl);
+ ioc_info(hdev, "aer1 = %d\n", hdev->ctrl_info->aerl);
+ ioc_info(hdev, "card_type = %d\n", hdev->ctrl_info->card_type);
+ ioc_info(hdev, "rtd3e = %d\n", le32_to_cpu(hdev->ctrl_info->rtd3e));
+ ioc_info(hdev, "sn = %s\n", hdev->ctrl_info->sn);
+ ioc_info(hdev, "fr = %s\n", hdev->ctrl_info->fr);
+
+ if (!hdev->ctrl_info->aerl)
+ hdev->ctrl_info->aerl = 1;
+ if (hdev->ctrl_info->aerl > SSSRAID_NR_AEN_COMMANDS)
+ hdev->ctrl_info->aerl = SSSRAID_NR_AEN_COMMANDS;
+
+ return 0;
+}
+
+static int sssraid_set_features(struct sssraid_dev *hdev, u32 fid, u32 dword11, void *buffer,
+ size_t buflen, u32 *result)
+{
+ struct sssraid_admin_command admin_cmd;
+ int ret;
+ u8 *data_ptr = NULL;
+ dma_addr_t data_dma = 0;
+
+ if (buffer && buflen) {
+ data_ptr = dma_alloc_coherent(&hdev->pdev->dev, buflen, &data_dma, GFP_KERNEL);
+ if (!data_ptr)
+ return -ENOMEM;
+
+ memcpy(data_ptr, buffer, buflen);
+ }
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.features.opcode = SSSRAID_ADMIN_SET_FEATURES;
+ admin_cmd.features.fid = cpu_to_le32(fid);
+ admin_cmd.features.dword11 = cpu_to_le32(dword11);
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ ret = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, result, NULL, 0);
+
+ if (data_ptr)
+ dma_free_coherent(&hdev->pdev->dev, buflen, data_ptr, data_dma);
+
+ return ret;
+}
+
+static int sssraid_set_queue_cnt(struct sssraid_dev *hdev, u32 *cnt)
+{
+ u32 q_cnt = (*cnt - 1) | ((*cnt - 1) << 16);
+ u32 nr_ioqs, result;
+ int status;
+
+ status = sssraid_set_features(hdev, SSSRAID_FEAT_NUM_QUEUES, q_cnt, NULL, 0, &result);
+ if (status) {
+ ioc_err(hdev, "Set queue count failed, status: %d\n",
+ status);
+ return -EIO;
+ }
+
+ nr_ioqs = min(result & 0xffff, result >> 16) + 1;
+ *cnt = min(*cnt, nr_ioqs);
+ if (*cnt == 0) {
+ ioc_err(hdev, "Illegal queue count: zero\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int sssraid_create_cq(struct sssraid_dev *hdev, u16 qidx)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[qidx];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+ struct sssraid_admin_command admin_cmd;
+ int flags = SSSRAID_QUEUE_PHYS_CONTIG | SSSRAID_CQ_IRQ_ENABLED;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.create_cq.opcode = SSSRAID_ADMIN_CREATE_CQ;
+ admin_cmd.create_cq.prp1 = cpu_to_le64(cqinfo->cq_dma_addr);
+ admin_cmd.create_cq.cqid = cpu_to_le16(qidx);
+ admin_cmd.create_cq.qsize = cpu_to_le16(sqinfo->q_depth - 1);
+ admin_cmd.create_cq.cq_flags = cpu_to_le16(flags);
+ admin_cmd.create_cq.irq_vector = cpu_to_le16(qidx);
+
+ return sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+}
+
+static int sssraid_create_io_cq(struct sssraid_dev *hdev, u16 qidx)
+{
+ int retval;
+ struct sssraid_cqueue *cqinfo = hdev->cqinfo + qidx;
+ u16 midx = qidx;
+
+ retval = sssraid_create_cq(hdev, qidx);
+ if (retval)
+ return retval;
+
+ /*
+ * cqinfo initialization at sssraid_init_queue
+ */
+ hdev->intr_info[midx].cqinfo = cqinfo;
+
+ return retval;
+}
+
+static int sssraid_create_sq(struct sssraid_dev *hdev, u16 qidx)
+{
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+ struct sssraid_admin_command admin_cmd;
+ int flags = SSSRAID_QUEUE_PHYS_CONTIG;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.create_sq.opcode = SSSRAID_ADMIN_CREATE_SQ;
+ admin_cmd.create_sq.prp1 = cpu_to_le64(sqinfo->sq_dma_addr);
+ admin_cmd.create_sq.sqid = cpu_to_le16(qidx);
+ admin_cmd.create_sq.qsize = cpu_to_le16(sqinfo->q_depth - 1);
+ admin_cmd.create_sq.sq_flags = cpu_to_le16(flags);
+ admin_cmd.create_sq.cqid = cpu_to_le16(qidx);
+
+ return sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+}
+
+static int sssraid_create_io_sq(struct sssraid_dev *hdev, u16 qidx)
+{
+ return sssraid_create_sq(hdev, qidx);
+}
+
+int sssraid_get_dev_list(struct sssraid_dev *hdev, struct sssraid_dev_info *devices)
+{
+ u32 nd = le32_to_cpu(hdev->ctrl_info->nd);
+ struct sssraid_admin_command admin_cmd;
+ struct sssraid_dev_list *list_buf;
+ dma_addr_t data_dma = 0;
+ u32 i, idx, hdid, ndev;
+ int ret = 0;
+
+ list_buf = dma_alloc_coherent(&hdev->pdev->dev, PAGE_SIZE, &data_dma, GFP_KERNEL);
+ if (!list_buf)
+ return -ENOMEM;
+
+ for (idx = 0; idx < nd;) {
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.get_info.opcode = SSSRAID_ADMIN_GET_INFO;
+ admin_cmd.get_info.type = SSSRAID_GET_INFO_DEV_LIST;
+ admin_cmd.get_info.cdw11 = cpu_to_le32(idx);
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ ret = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+
+ if (ret) {
+ ioc_err(hdev, "Get device list failed, nd: %u, idx: %u, ret: %d\n",
+ nd, idx, ret);
+ goto out;
+ }
+ ndev = le32_to_cpu(list_buf->dev_num);
+
+ ioc_info(hdev, "ndev numbers: %u\n", ndev);
+
+ for (i = 0; i < ndev; i++) {
+ hdid = le32_to_cpu(list_buf->devices[i].hdid);
+ ioc_info(hdev, "list_buf->devices[%d], hdid: %u target: %d, channel: %d, lun: %d, attr[0x%x]\n",
+ i, hdid, le16_to_cpu(list_buf->devices[i].target),
+ list_buf->devices[i].channel,
+ list_buf->devices[i].lun,
+ list_buf->devices[i].attr);
+ if (hdid > nd || hdid == 0) {
+ ioc_err(hdev, "err, hdid[%d] invalid\n", hdid);
+ continue;
+ }
+ memcpy(&devices[hdid - 1], &list_buf->devices[i],
+ sizeof(struct sssraid_dev_info));
+ }
+ idx += ndev;
+
+ if (ndev < MAX_DEV_ENTRY_PER_PAGE_4K)
+ break;
+ }
+
+out:
+ dma_free_coherent(&hdev->pdev->dev, PAGE_SIZE, list_buf, data_dma);
+ return ret;
+}
+
+/* send abort command by admin queue temporary */
+int sssraid_send_abort_cmd(struct sssraid_dev *hdev, u32 hdid, u16 qidx, u16 cid)
+{
+ struct sssraid_admin_command admin_cmd;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.abort.opcode = SSSRAID_ADMIN_ABORT_CMD;
+ admin_cmd.abort.hdid = cpu_to_le32(hdid);
+ admin_cmd.abort.sqid = cpu_to_le16(qidx);
+ admin_cmd.abort.cid = cpu_to_le16(cid);
+
+ return sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+}
+
+/* send reset command by admin quueue temporary */
+int sssraid_send_reset_cmd(struct sssraid_dev *hdev, u8 type, u32 hdid)
+{
+ struct sssraid_admin_command admin_cmd;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.reset.opcode = SSSRAID_ADMIN_RESET;
+ admin_cmd.reset.hdid = cpu_to_le32(hdid);
+ admin_cmd.reset.type = type;
+
+ return sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+}
+
+static int sssraid_delete_queue(struct sssraid_dev *hdev, u8 op, u16 qidx)
+{
+ struct sssraid_admin_command admin_cmd;
+ int retval;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.delete_queue.opcode = op;
+ admin_cmd.delete_queue.qid = cpu_to_le16(qidx);
+
+ retval = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+
+ if (retval)
+ ioc_err(hdev, "Delete %s:[%d] failed\n",
+ (op == SSSRAID_ADMIN_DELETE_CQ) ? "cq" : "sq", qidx);
+
+ return retval;
+}
+
+static int sssraid_delete_cq(struct sssraid_dev *hdev, u16 qidx)
+{
+ return sssraid_delete_queue(hdev, SSSRAID_ADMIN_DELETE_CQ, qidx);
+}
+
+void sssraid_adm_timeout(struct sssraid_dev *hdev, struct sssraid_cmd *cmd)
+{
+ /* command may be returned because controller reset */
+ if (READ_ONCE(cmd->state) == SSSRAID_CMD_COMPLETE)
+ return;
+
+ if (!sssraid_change_host_state(hdev, SSSRAID_RESETTING)) {
+ ioc_info(hdev, "can't change to reset state\n");
+ return;
+ }
+ sssraid_soft_reset_handler(hdev);
+}
+
+static int sssraid_create_io_qpair(struct sssraid_dev *hdev, u16 qidx)
+{
+ int retval;
+
+ retval = sssraid_create_io_cq(hdev, qidx);
+ if (retval)
+ return retval;
+
+ retval = sssraid_create_io_sq(hdev, qidx);
+ if (retval)
+ goto delete_cq;
+
+ /* intr_info.msix_index substitute cq_vector */
+
+ /* io interrupt registry:
+ * not here, put above
+ */
+
+ sssraid_init_queue(hdev, qidx);
+
+ return 0;
+
+delete_cq:
+ sssraid_delete_cq(hdev, qidx);
+
+ return retval;
+}
+
+static int sssraid_setup_io_qpair(struct sssraid_dev *hdev)
+{
+ u32 i, num_queues;
+ int retval = 0;
+
+ num_queues = min(hdev->intr_info_count, hdev->init_done_queue_cnt - 1);
+ for (i = 1; i <= num_queues; i++) {
+ retval = sssraid_create_io_qpair(hdev, i);
+ if (retval) {
+ ioc_err(hdev, "Create queue[%d] failed\n", i);
+ break;
+ }
+ }
+
+ ioc_info(hdev, "init_done_queue_cnt[%d], intr_info_count[%d] num_queues[%d]",
+ hdev->init_done_queue_cnt, /*hdev->online_queues,*/
+ hdev->intr_info_count, num_queues);
+
+ return retval >= 0 ? 0 : retval;
+}
+
+static int sssraid_alloc_ioq_ptcmds(struct sssraid_dev *hdev)
+{
+ int i;
+ int ptnum = SSSRAID_NR_IOQ_PTCMDS;
+
+ INIT_LIST_HEAD(&hdev->ioq_pt_list);
+ spin_lock_init(&hdev->ioq_pt_lock);
+
+ hdev->ioq_ptcmds = kcalloc_node(ptnum, sizeof(struct sssraid_cmd),
+ GFP_KERNEL, hdev->numa_node);
+
+ if (!hdev->ioq_ptcmds) {
+ ioc_err(hdev, "Alloc ioq_ptcmds failed\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < ptnum; i++) {
+ hdev->ioq_ptcmds[i].qid = i / SSSRAID_PTCMDS_PERQ + 1;
+ hdev->ioq_ptcmds[i].cid = i % SSSRAID_PTCMDS_PERQ + SSSRAID_IO_BLK_MQ_DEPTH;
+ list_add_tail(&(hdev->ioq_ptcmds[i].list), &hdev->ioq_pt_list);
+ }
+
+ ioc_info(hdev, "Alloc ioq_ptcmds success, ptnum[%d]\n", ptnum);
+
+ return 0;
+}
+
+int sssraid_send_event_ack(struct sssraid_dev *hdev, u8 event,
+ u32 event_ctx, u16 cid)
+{
+ /* event,event_ctx no use at this time */
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[0];
+ struct sssraid_admin_command admin_cmd;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.common.opcode = SSSRAID_ADMIN_ASYNC_EVENT;
+ admin_cmd.common.command_id = cpu_to_le16(cid);
+
+ sssraid_submit_cmd(sqinfo, &admin_cmd);
+ ioc_info(hdev, "send aen, cid[%d]\n", cid);
+
+ return 0;
+}
+
+static void sssraid_handle_aen_notice(struct sssraid_dev *hdev, u32 result)
+{
+ switch ((result & 0xff00) >> 8) {
+ case SSSRAID_AEN_DEV_CHANGED:
+ sssraid_scan_disk(hdev);
+ break;
+ case SSSRAID_AEN_FW_ACT_START:
+ ioc_info(hdev, "fw activation starting\n");
+ break;
+ case SSSRAID_AEN_HOST_PROBING:
+ break;
+ default:
+ ioc_warn(hdev, "async event result %08x\n", result);
+ }
+}
+
+static void sssraid_handle_aen_vs(struct sssraid_dev *hdev, u32 result, u32 result1)
+{
+ switch ((result & 0xff00) >> 8) {
+ case SSSRAID_AEN_TIMESYN:
+ sssraid_configure_timestamp(hdev);
+ break;
+ case SSSRAID_AEN_FW_ACT_FINISH:
+ ioc_info(hdev, "fw activation finish\n");
+ if (sssraid_init_ctrl_info(hdev))
+ ioc_err(hdev, "get ctrl info failed after fw act\n");
+ break;
+ case SSSRAID_AEN_EVENT_MIN ... SSSRAID_AEN_EVENT_MAX:
+ ioc_info(hdev, "rcv card event[%d], param1[0x%x] param2[0x%x]\n",
+ (result & 0xff00) >> 8, result, result1);
+ break;
+ default:
+ ioc_warn(hdev, "async event result: 0x%x\n", result);
+ }
+}
+
+static inline void sssraid_send_all_aen(struct sssraid_dev *hdev)
+{
+ u16 i;
+
+ for (i = 0; i < hdev->ctrl_info->aerl; i++)
+ sssraid_send_event_ack(hdev, 0, 0, i + SSSRAID_AQ_BLK_MQ_DEPTH);
+}
+
+static int sssraid_dev_list_init(struct sssraid_dev *hdev)
+{
+ u32 nd = le32_to_cpu(hdev->ctrl_info->nd);
+
+ hdev->devices = kzalloc_node(nd * sizeof(struct sssraid_dev_info),
+ GFP_KERNEL, hdev->numa_node);
+ if (!hdev->devices)
+ return -ENOMEM;
+
+ return 0;
+}
+
+int sssraid_configure_timestamp(struct sssraid_dev *hdev)
+{
+ __le64 ts;
+ int retval;
+
+ ts = cpu_to_le64(ktime_to_ms(ktime_get_real()));
+ retval = sssraid_set_features(hdev, SSSRAID_FEAT_TIMESTAMP, 0, &ts, sizeof(ts), NULL);
+
+ if (retval)
+ ioc_err(hdev, "set timestamp failed: %d\n", retval);
+ return retval;
+}
+
+int sssraid_init_ioc(struct sssraid_dev *hdev, u8 re_init)
+{
+ int retval = 0;
+ int i;
+ u32 nr_ioqs, bar_size;
+
+ if (!re_init) {
+ hdev->cpu_count = num_online_cpus();
+
+ retval = sssraid_alloc_resources(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc resources:error %d\n",
+ retval);
+ goto out_nocleanup;
+ }
+ }
+
+ /* reset need re-setup */
+ retval = sssraid_setup_resources(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to setup resources:error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ if (!re_init) {
+ retval = sssraid_alloc_admin_cmds(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc admin cmds:error %d\n",
+ retval);
+ goto out_failed;
+ }
+ /* put here:
+ * alloc admin queue
+ */
+ retval = sssraid_alloc_qpair(hdev, 0, SSSRAID_AQ_DEPTH);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc admin queue:error %d\n",
+ retval);
+ goto out_failed;
+ }
+ }
+
+ retval = sssraid_setup_admin_qpair(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to setup admin queue:error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ /* 1. unregister all interrupt
+ * 2. admin interrupt registry
+ */
+ retval = sssraid_setup_isr(hdev, 1);
+ if (retval) {
+ ioc_err(hdev, "Failed to setup ISR error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ retval = sssraid_init_ctrl_info(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to get ctrl info error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ nr_ioqs = hdev->cpu_count;
+ retval = sssraid_set_queue_cnt(hdev, &nr_ioqs);
+ if (retval) {
+ ioc_err(hdev, "Failed to set queue cnt error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ hdev->before_affinity_msix_cnt = nr_ioqs + 1;
+
+ /* 1. unregister all interrupt
+ * 2. admin interrupt re-registry
+ * 3. io interrupt registry
+ */
+ retval = sssraid_setup_isr(hdev, 0);
+ if (retval) {
+ ioc_err(hdev, "Failed to re-setup ISR, error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ /* remap */
+ bar_size = SSSRAID_REG_DBS + ((nr_ioqs + 1) * 8 * hdev->db_stride);
+ retval = sssraid_remap_bar(hdev, bar_size);
+ if (retval) {
+ ioc_err(hdev, "Failed to re-map bar, error %d\n",
+ retval);
+ goto out_failed;
+ }
+ hdev->sqinfo[0].q_db = hdev->dbs;
+
+ /* num_vecs no sense, abandon */
+
+ if (!re_init) {
+ for (i = hdev->init_done_queue_cnt; i <= hdev->intr_info_count; i++) {
+ retval = sssraid_alloc_qpair(hdev, i, hdev->ioq_depth);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc io queue:error %d\n",
+ retval);
+ goto out_failed;
+ }
+ }
+ ioc_info(hdev, "intr_info_count: %d, init_done_queue_cnt: %d, ioq_depth: %d\n",
+ hdev->intr_info_count, hdev->init_done_queue_cnt, hdev->ioq_depth);
+ }
+
+ retval = sssraid_setup_io_qpair(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to setup io qpair, error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ if (!re_init) {
+ retval = sssraid_alloc_ioq_ptcmds(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to alloc ioq ptcmds, error %d\n",
+ retval);
+ goto out_failed;
+ }
+ }
+
+ sssraid_send_all_aen(hdev);
+
+ if (!re_init) {
+ retval = sssraid_dev_list_init(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to init device list, error %d\n",
+ retval);
+ goto out_failed;
+ }
+
+ retval = sssraid_configure_timestamp(hdev);
+ if (retval) {
+ ioc_err(hdev, "Failed to configure timestamp, error %d\n",
+ retval);
+ goto out_failed;
+ }
+ }
+
+ return retval;
+
+out_failed:
+ sssraid_cleanup_ioc(hdev, re_init);
+out_nocleanup:
+ return retval;
+}
+
+void sssraid_cleanup_resources(struct sssraid_dev *hdev)
+{
+ struct pci_dev *pdev = hdev->pdev;
+
+ sssraid_cleanup_isr(hdev);
+
+ if (hdev->bar) {
+ iounmap(hdev->bar);
+ hdev->bar = NULL;
+ }
+
+ if (pci_is_enabled(pdev)) {
+ pci_disable_pcie_error_reporting(pdev);
+ pci_release_mem_regions(pdev);
+ pci_disable_device(pdev);
+ }
+}
+
+static void sssraid_free_ioq_ptcmds(struct sssraid_dev *hdev)
+{
+ kfree(hdev->ioq_ptcmds);
+ hdev->ioq_ptcmds = NULL;
+
+ INIT_LIST_HEAD(&hdev->ioq_pt_list);
+}
+
+static void sssraid_delete_io_queues(struct sssraid_dev *hdev)
+{
+ u16 queues = hdev->init_done_queue_cnt - 1;
+ u8 opcode = SSSRAID_ADMIN_DELETE_SQ;
+ u16 i, pass;
+
+ if (!pci_device_is_present(hdev->pdev)) {
+ ioc_err(hdev, "pci_device is not present, skip disable io queues\n");
+ return;
+ }
+
+ if (hdev->init_done_queue_cnt < 2) {
+ ioc_err(hdev, "err, io queue has been delete\n");
+ return;
+ }
+
+ for (pass = 0; pass < 2; pass++) {
+ for (i = queues; i > 0; i--)
+ if (sssraid_delete_queue(hdev, opcode, i))
+ break;
+
+ opcode = SSSRAID_ADMIN_DELETE_CQ;
+ }
+}
+
+void sssraid_complete_aen(struct sssraid_dev *hdev, struct sssraid_completion *cqe)
+{
+ u32 result = le32_to_cpu(cqe->result);
+
+ ioc_info(hdev, "rcv aen, cid[%d], status[0x%x], result[0x%x]\n",
+ le16_to_cpu(cqe->cmd_id), le16_to_cpu(cqe->status) >> 1, result);
+
+ /*
+ * The response to event moved from this func.
+ * sssraid_send_aen changed to name sssraid_send_event_ack
+ */
+
+ if ((le16_to_cpu(cqe->status) >> 1) != SSSRAID_SC_SUCCESS)
+ return;
+ switch (result & 0x7) {
+ case SSSRAID_AEN_NOTICE:
+ sssraid_handle_aen_notice(hdev, result);
+ break;
+ case SSSRAID_AEN_VS:
+ sssraid_handle_aen_vs(hdev, result, le32_to_cpu(cqe->result1));
+ break;
+ default:
+ ioc_warn(hdev, "Unsupported async event type: %u\n",
+ result & 0x7);
+ break;
+ }
+}
+
+void sssraid_free_iod_res(struct sssraid_dev *hdev, struct sssraid_iod *iod)
+{
+ const int last_prp = hdev->page_size / sizeof(__le64) - 1;
+ dma_addr_t dma_addr, next_dma_addr;
+ struct sssraid_sgl_desc *sg_list;
+ __le64 *prp_list;
+ void *addr;
+ int i;
+
+ dma_addr = iod->first_dma;
+ if (iod->npages == 0)
+ dma_pool_free(iod->sqinfo->prp_small_pool, sssraid_iod_list(iod)[0], dma_addr);
+
+ for (i = 0; i < iod->npages; i++) {
+ addr = sssraid_iod_list(iod)[i];
+
+ if (iod->use_sgl) {
+ sg_list = addr;
+ next_dma_addr =
+ le64_to_cpu((sg_list[SGES_PER_PAGE - 1]).addr);
+ } else {
+ prp_list = addr;
+ next_dma_addr = le64_to_cpu(prp_list[last_prp]);
+ }
+
+ dma_pool_free(hdev->prp_page_pool, addr, dma_addr);
+ dma_addr = next_dma_addr;
+ }
+
+ iod->sense = NULL;
+ iod->npages = -1;
+}
+
+static void sssraid_complete_ioq_sync_cmnd(struct sssraid_dev *hdev, u16 qidx,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_cmd *ptcmd;
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ ptcmd = hdev->ioq_ptcmds + (sqinfo->qidx - 1) * SSSRAID_PTCMDS_PERQ +
+ le16_to_cpu(cqe->cmd_id) - SSSRAID_IO_BLK_MQ_DEPTH;
+
+ ptcmd->status = le16_to_cpu(cqe->status) >> 1;
+ ptcmd->result0 = le32_to_cpu(cqe->result);
+ ptcmd->result1 = le32_to_cpu(cqe->result1);
+
+ complete(&ptcmd->cmd_done);
+}
+
+static void sssraid_complete_ioq_cmnd(struct sssraid_dev *hdev, u16 qidx,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[qidx];
+
+ struct blk_mq_tags *tags;
+ struct scsi_cmnd *scmd;
+ struct sssraid_iod *iod;
+ struct request *req;
+ unsigned long elapsed;
+
+ tags = hdev->shost->tag_set.tags[sqinfo->qidx - 1];
+
+ req = blk_mq_tag_to_rq(tags, le16_to_cpu(cqe->cmd_id));
+ if (unlikely(!req || !blk_mq_request_started(req))) {
+ ioc_warn(hdev, "Invalid id %d completed on queue %d\n",
+ le16_to_cpu(cqe->cmd_id), sqinfo->qidx);
+ return;
+ }
+
+ scmd = blk_mq_rq_to_pdu(req);
+ iod = scsi_cmd_priv(scmd);
+
+ elapsed = jiffies - scmd->jiffies_at_alloc;
+ dbgprint(hdev, "cid[%d] qidx[%d] finish IO cost %3ld.%3ld seconds\n",
+ le16_to_cpu(cqe->cmd_id), sqinfo->qidx, elapsed / HZ, elapsed % HZ);
+
+ if (cmpxchg(&iod->state, SSSRAID_CMD_IN_FLIGHT, SSSRAID_CMD_COMPLETE) !=
+ SSSRAID_CMD_IN_FLIGHT) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] enters abnormal handler, cost %3ld.%3ld seconds\n",
+ le16_to_cpu(cqe->cmd_id), sqinfo->qidx, elapsed / HZ, elapsed % HZ);
+ WRITE_ONCE(iod->state, SSSRAID_CMD_TMO_COMPLETE);
+
+ if (iod->nsge) {
+ iod->nsge = 0;
+ scsi_dma_unmap(scmd);
+ }
+ sssraid_free_iod_res(hdev, iod);
+
+ return;
+ }
+
+ sssraid_map_status(iod, scmd, cqe);
+ if (iod->nsge) {
+ iod->nsge = 0;
+ scsi_dma_unmap(scmd);
+ }
+ sssraid_free_iod_res(hdev, iod);
+ scmd->scsi_done(scmd);
+}
+
+static void sssraid_process_admin_cq(struct sssraid_dev *hdev,
+ struct sssraid_squeue *sqinfo,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_fwevt *fwevt = NULL;
+ u16 cid = le16_to_cpu(cqe->cmd_id), sz;
+
+ if (likely(cid < SSSRAID_AQ_BLK_MQ_DEPTH))
+ sssraid_complete_adminq_cmnd(hdev, sqinfo->qidx, cqe);
+ else {
+ sz = sizeof(*cqe);
+ fwevt = sssraid_alloc_fwevt(sz);
+ if (!fwevt) {
+ ioc_info(hdev, "%s :failure at %s:%d/%s()!\n",
+ __func__, __FILE__, __LINE__, __func__);
+ return;
+ }
+
+ memcpy(fwevt->event_data, cqe, sz);
+ fwevt->hdev = hdev;
+ fwevt->event_id = 0; /* evt_type:0 */
+ fwevt->send_ack = 1; /* ack_req:1 */
+ fwevt->process_evt = 1; /* process_evt_bh:1 */
+ fwevt->evt_ctx = 0; /* 0 */
+ sssraid_fwevt_add_to_list(hdev, fwevt);
+ }
+}
+
+static void sssraid_process_io_cq(struct sssraid_dev *hdev,
+ struct sssraid_squeue *sqinfo,
+ struct sssraid_completion *cqe)
+{
+ u16 cid = le16_to_cpu(cqe->cmd_id);
+
+ if (likely(cid < SSSRAID_IO_BLK_MQ_DEPTH))
+ sssraid_complete_ioq_cmnd(hdev, sqinfo->qidx, cqe);
+ else /* io sync handle */
+ sssraid_complete_ioq_sync_cmnd(hdev, sqinfo->qidx, cqe);
+}
+
+static inline void sssraid_handle_cqe(struct sssraid_dev *hdev, u16 mdix, u16 didx)
+{
+ struct sssraid_cqueue *cqinfo = &hdev->cqinfo[mdix];
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[mdix];
+
+ struct sssraid_completion *cqe = &cqinfo->cqes[didx];
+ u16 cid = le16_to_cpu(cqe->cmd_id);
+
+ if (unlikely(cid >= sqinfo->q_depth)) {
+ ioc_err(hdev, "Invalid command id[%d] completed on queue %d\n",
+ cid, cqe->sq_id);
+ return;
+ }
+
+ dbgprint(hdev, "cid[%d] mdix[%d], result[0x%x], sq_id[%d], status[0x%x]\n",
+ cid, sqinfo->qidx, le32_to_cpu(cqe->result),
+ le16_to_cpu(cqe->sq_id), le16_to_cpu(cqe->status));
+
+ if (!mdix) /* admin */
+ sssraid_process_admin_cq(hdev, sqinfo, cqe);
+ else /* io */
+ sssraid_process_io_cq(hdev, sqinfo, cqe);
+}
+
+void sssraid_complete_cqes(struct sssraid_dev *hdev, u16 midx, u16 start, u16 end)
+{
+ struct sssraid_squeue *sqinfo = &hdev->sqinfo[midx];
+
+ while (start != end) {
+ sssraid_handle_cqe(hdev, midx, start);
+ if (++start == sqinfo->q_depth)
+ start = 0;
+ }
+}
+
+static void sssraid_disable_admin_queue(struct sssraid_dev *hdev, bool shutdown)
+{
+ struct sssraid_cqueue *adm_cqinfo = &hdev->cqinfo[0];
+ u16 start, end;
+
+ if (pci_device_is_present(hdev->pdev)) {
+ if (shutdown)
+ sssraid_shutdown_ctrl(hdev);
+ else
+ sssraid_disable_ctrl(hdev);
+ }
+
+ if (hdev->init_done_queue_cnt == 0) {
+ ioc_err(hdev, "err, admin queue has been delete\n");
+ return;
+ }
+
+ spin_lock_irq(&adm_cqinfo->cq_lock);
+ sssraid_process_cq(hdev, 0, &start, &end, -1);
+ spin_unlock_irq(&adm_cqinfo->cq_lock);
+ sssraid_complete_cqes(hdev, 0, start, end);
+}
+
+static void sssraid_free_all_queues(struct sssraid_dev *hdev)
+{
+ int i;
+ struct sssraid_cqueue *cqinfo;
+ struct sssraid_squeue *sqinfo;
+
+ for (i = 0; i < hdev->init_done_queue_cnt; i++) {
+ cqinfo = &hdev->cqinfo[i];
+ sqinfo = &hdev->sqinfo[i];
+ dma_free_coherent(&hdev->pdev->dev, CQ_SIZE(sqinfo->q_depth),
+ (void *)cqinfo->cqes, cqinfo->cq_dma_addr);
+ dma_free_coherent(&hdev->pdev->dev, SQ_SIZE(sqinfo->qidx, sqinfo->q_depth),
+ sqinfo->sq_cmds, sqinfo->sq_dma_addr);
+ dma_free_coherent(&hdev->pdev->dev, SENSE_SIZE(sqinfo->q_depth),
+ sqinfo->sense, sqinfo->sense_dma_addr);
+ }
+
+ hdev->init_done_queue_cnt = 0;
+}
+
+static void sssraid_free_admin_cmds(struct sssraid_dev *hdev)
+{
+ kfree(hdev->adm_cmds);
+ hdev->adm_cmds = NULL;
+ INIT_LIST_HEAD(&hdev->adm_cmd_list);
+}
+
+static void sssraid_free_resources(struct sssraid_dev *hdev)
+{
+ sssraid_free_admin_cmds(hdev);
+ kfree(hdev->sqinfo);
+ kfree(hdev->cqinfo);
+ sssraid_destroy_dma_pools(hdev);
+ kfree(hdev->ctrl_info);
+}
+
+void sssraid_cleanup_ioc(struct sssraid_dev *hdev, u8 re_init)
+{
+ if (!re_init)
+ sssraid_free_ioq_ptcmds(hdev);
+
+ sssraid_delete_io_queues(hdev);
+ sssraid_disable_admin_queue(hdev, !re_init);
+
+ if (!re_init)
+ sssraid_free_all_queues(hdev);
+
+ sssraid_ioc_disable_intr(hdev);
+ sssraid_cleanup_resources(hdev);
+
+ if (!re_init)
+ sssraid_free_resources(hdev);
+
+}
+
+int sssraid_soft_reset_handler(struct sssraid_dev *hdev)
+{
+ int retval = 0;
+
+ if (hdev->state != SSSRAID_RESETTING) {
+ ioc_err(hdev, "err, host is not reset state\n");
+ return retval;
+ }
+
+ ioc_info(hdev, "enter host reset\n");
+
+ sssraid_ioc_disable_intr(hdev);
+ sssraid_cleanup_fwevt_list(hdev);
+
+ /* realize above here:
+ * sssraid_dev_disable -> sssraid_back_all_io
+ */
+ sssraid_back_all_io(hdev);
+ /*
+ * realize sssraid_dev_disable,
+ * i.e. sssraid_cleanup_ioc(1)
+ */
+ if (hdev->ctrl_config & SSSRAID_CC_ENABLE) {
+ ioc_info(hdev, "start dev_disable\n");
+ sssraid_cleanup_ioc(hdev, 1);
+ }
+
+ retval = sssraid_init_ioc(hdev, 1);
+ if (retval) {
+ ioc_err(hdev, "init ioc fail.\n");
+ return retval;
+ }
+
+ sssraid_change_host_state(hdev, SSSRAID_LIVE);
+
+ return retval;
+}
diff --git a/drivers/scsi/sssraid/sssraid_os.c b/drivers/scsi/sssraid/sssraid_os.c
new file mode 100644
index 000000000000..16d2b94d78f3
--- /dev/null
+++ b/drivers/scsi/sssraid/sssraid_os.c
@@ -0,0 +1,2337 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2022 3SNIC Information Technology, Ltd */
+
+/* 3SNIC RAID SSSXXX Series Linux Driver */
+
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/sysfs.h>
+#include <linux/gfp.h>
+#include <linux/types.h>
+#include <linux/ratelimit.h>
+#include <linux/debugfs.h>
+#include <linux/blkdev.h>
+#include <linux/bsg-lib.h>
+#include <linux/sort.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_dbg.h>
+
+#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/once.h>
+#include <linux/sched/signal.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
+
+#include "sssraid.h"
+#include "sssraid_debug.h"
+
+u32 admin_tmout = 60;
+module_param(admin_tmout, uint, 0644);
+MODULE_PARM_DESC(admin_tmout, "admin commands timeout (seconds)");
+
+static u32 scmd_tmout_rawdisk = 180;
+module_param(scmd_tmout_rawdisk, uint, 0644);
+MODULE_PARM_DESC(scmd_tmout_rawdisk, "scsi commands timeout for rawdisk(seconds)");
+
+static u32 scmd_tmout_vd = 180;
+module_param(scmd_tmout_vd, uint, 0644);
+MODULE_PARM_DESC(scmd_tmout_vd, "scsi commands timeout for vd(seconds)");
+
+static int ioq_depth_set(const char *val, const struct kernel_param *kp);
+static const struct kernel_param_ops ioq_depth_ops = {
+ .set = ioq_depth_set,
+ .get = param_get_uint,
+};
+
+u32 io_queue_depth = 1024;
+module_param_cb(io_queue_depth, &ioq_depth_ops, &io_queue_depth, 0644);
+MODULE_PARM_DESC(io_queue_depth, "set io queue depth, should >= 2");
+
+static int logging_level_set(const char *val, const struct kernel_param *kp)
+{
+ u8 n = 0;
+ int ret;
+
+ ret = kstrtou8(val, 10, &n);
+ if (ret != 0)
+ return -EINVAL;
+
+ return param_set_byte(val, kp);
+}
+
+static const struct kernel_param_ops logging_level_ops = {
+ .set = logging_level_set,
+ .get = param_get_byte,
+};
+
+static unsigned char logging_level;
+module_param_cb(logging_level, &logging_level_ops, &logging_level, 0644);
+MODULE_PARM_DESC(logging_level, "set log level, default zero for switch off");
+
+static int small_pool_num_set(const char *val, const struct kernel_param *kp)
+{
+ u8 n = 0;
+ int ret;
+
+ ret = kstrtou8(val, 10, &n);
+ if (ret != 0)
+ return -EINVAL;
+ if (n > MAX_SMALL_POOL_NUM)
+ n = MAX_SMALL_POOL_NUM;
+ if (n < 1)
+ n = 1;
+ *((u8 *)kp->arg) = n;
+
+ return 0;
+}
+
+static const struct kernel_param_ops small_pool_num_ops = {
+ .set = small_pool_num_set,
+ .get = param_get_byte,
+};
+
+/* Small pools are used to save PRP for small IOs.It was
+ * found that the spinlock of a single pool conflicts a
+ * lot with multiple CPUs.So multiple pools are introduced
+ * to reduce the conflictions.
+ */
+unsigned char small_pool_num = 4;
+module_param_cb(small_pool_num, &small_pool_num_ops, &small_pool_num, 0644);
+MODULE_PARM_DESC(small_pool_num, "set prp small pool num, default 4, MAX 16");
+
+//static struct class *sssraid_class;
+
+enum FW_STAT_CODE {
+ FW_STAT_OK = 0,
+ FW_STAT_NEED_CHECK,
+ FW_STAT_ERROR,
+ FW_STAT_EP_PCIE_ERROR,
+ FW_STAT_NAC_DMA_ERROR,
+ FW_STAT_ABORTED,
+ FW_STAT_NEED_RETRY
+};
+
+static const char * const raid_levels[] = {"0", "1", "5", "6", "10", "50", "60", "NA"};
+
+static const char * const raid_states[] = {
+ "NA", "NORMAL", "FAULT", "DEGRADE", "NOT_FORMATTED", "FORMATTING", "SANITIZING",
+ "INITIALIZING", "INITIALIZE_FAIL", "DELETING", "DELETE_FAIL", "WRITE_PROTECT"
+};
+
+static int ioq_depth_set(const char *val, const struct kernel_param *kp)
+{
+ int n = 0;
+ int ret;
+
+ ret = kstrtoint(val, 10, &n);
+ if (ret != 0 || n < 2)
+ return -EINVAL;
+
+ return param_set_int(val, kp);
+}
+
+/*
+ * common
+ */
+static struct class *sssraid_class;
+
+struct sssraid_fwevt *sssraid_alloc_fwevt(int len)
+{
+ struct sssraid_fwevt *fwevt;
+
+ fwevt = kzalloc(sizeof(*fwevt) + len, GFP_ATOMIC);
+ if (!fwevt)
+ return NULL;
+
+ kref_init(&fwevt->ref_count);
+ return fwevt;
+
+}
+
+static void sssraid_fwevt_free(struct kref *r)
+{
+ kfree(container_of(r, struct sssraid_fwevt, ref_count));
+}
+
+static void sssraid_fwevt_get(struct sssraid_fwevt *fwevt)
+{
+ kref_get(&fwevt->ref_count);
+}
+
+static void sssraid_fwevt_put(struct sssraid_fwevt *fwevt)
+{
+ kref_put(&fwevt->ref_count, sssraid_fwevt_free);
+}
+
+static void sssraid_fwevt_del_from_list(struct sssraid_dev *hdev,
+ struct sssraid_fwevt *fwevt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdev->fwevt_lock, flags);
+ if (!list_empty(&fwevt->list)) {
+ list_del_init(&fwevt->list);
+ /*
+ * Put fwevt reference count after
+ * removing it from fwevt_list
+ */
+ sssraid_fwevt_put(fwevt);
+ }
+ spin_unlock_irqrestore(&hdev->fwevt_lock, flags);
+}
+
+static void sssraid_fwevt_bh(struct sssraid_dev *hdev,
+ struct sssraid_fwevt *fwevt)
+{
+ struct sssraid_completion *cqe;
+
+ hdev->current_event = fwevt;
+ sssraid_fwevt_del_from_list(hdev, fwevt);
+
+ cqe = (struct sssraid_completion *)fwevt->event_data;
+
+ if (!fwevt->process_evt)
+ goto evt_ack;
+
+ sssraid_complete_aen(hdev, cqe);
+
+evt_ack:
+ /* event response put here: event has been handled. */
+ sssraid_send_event_ack(hdev, fwevt->event_id,
+ fwevt->evt_ctx, le16_to_cpu(cqe->cmd_id));
+ sssraid_fwevt_put(fwevt);
+ hdev->current_event = NULL;
+}
+
+static void sssraid_fwevt_worker(struct work_struct *work)
+{
+ struct sssraid_fwevt *fwevt = container_of(work, struct sssraid_fwevt,
+ work);
+ sssraid_fwevt_bh(fwevt->hdev, fwevt);
+ /*
+ * Put fwevt reference count after
+ * dequeuing it from worker queue
+ */
+ sssraid_fwevt_put(fwevt);
+}
+
+void sssraid_fwevt_add_to_list(struct sssraid_dev *hdev,
+ struct sssraid_fwevt *fwevt)
+{
+ unsigned long flags;
+
+ if (!hdev->fwevt_worker_thread)
+ return;
+
+ spin_lock_irqsave(&hdev->fwevt_lock, flags);
+ /* get fwevt reference count while adding it to fwevt_list */
+ sssraid_fwevt_get(fwevt);
+ INIT_LIST_HEAD(&fwevt->list);
+ list_add_tail(&fwevt->list, &hdev->fwevt_list);
+ INIT_WORK(&fwevt->work, sssraid_fwevt_worker);
+ /* get fwevt reference count while enqueueing it to worker queue */
+ sssraid_fwevt_get(fwevt);
+ queue_work(hdev->fwevt_worker_thread, &fwevt->work);
+ spin_unlock_irqrestore(&hdev->fwevt_lock, flags);
+}
+
+static struct sssraid_fwevt *sssraid_dequeue_fwevt(
+ struct sssraid_dev *hdev)
+{
+ unsigned long flags;
+ struct sssraid_fwevt *fwevt = NULL;
+
+ spin_lock_irqsave(&hdev->fwevt_lock, flags);
+ if (!list_empty(&hdev->fwevt_list)) {
+ fwevt = list_first_entry(&hdev->fwevt_list,
+ struct sssraid_fwevt, list);
+ list_del_init(&fwevt->list);
+ /*
+ * Put fwevt reference count after
+ * removing it from fwevt_list
+ */
+ sssraid_fwevt_put(fwevt);
+ }
+ spin_unlock_irqrestore(&hdev->fwevt_lock, flags);
+
+ return fwevt;
+}
+
+void sssraid_cleanup_fwevt_list(struct sssraid_dev *hdev)
+{
+ struct sssraid_fwevt *fwevt = NULL;
+
+ if ((list_empty(&hdev->fwevt_list) && !hdev->current_event) ||
+ !hdev->fwevt_worker_thread)
+ return;
+
+ while ((fwevt = sssraid_dequeue_fwevt(hdev)) ||
+ (fwevt = hdev->current_event)) {
+ /*
+ * Wait on the fwevt to complete. If this returns 1, then
+ * the event was never executed, and we need a put for the
+ * reference the work had on the fwevt.
+ *
+ * If it did execute, we wait for it to finish, and the put will
+ * happen from sssraid_process_fwevt()
+ */
+ if (cancel_work_sync(&fwevt->work)) {
+ /*
+ * Put fwevt reference count after
+ * dequeuing it from worker queue
+ */
+ sssraid_fwevt_put(fwevt);
+ /*
+ * Put fwevt reference count to neutralize
+ * kref_init increment
+ */
+ sssraid_fwevt_put(fwevt);
+ }
+ }
+}
+
+/*
+ * common 1
+ */
+static int sssraid_npages_prp(struct sssraid_dev *hdev)
+{
+ u32 size = 1U << ((hdev->ctrl_info->mdts) * 1U) << 12;
+ u32 nprps = DIV_ROUND_UP(size + hdev->page_size, hdev->page_size);
+
+ return DIV_ROUND_UP(PRP_ENTRY_SIZE * nprps, hdev->page_size - PRP_ENTRY_SIZE);
+}
+
+static int sssraid_npages_sgl(struct sssraid_dev *hdev)
+{
+ u32 nsge = le16_to_cpu(hdev->ctrl_info->max_num_sge);
+
+ return DIV_ROUND_UP(nsge * sizeof(struct sssraid_sgl_desc), hdev->page_size);
+}
+
+static u32 sssraid_cmd_size(struct sssraid_dev *hdev)
+{
+ u32 alloc_size = sizeof(__le64 *) * max(sssraid_npages_prp(hdev), sssraid_npages_sgl(hdev));
+
+ ioc_info(hdev, "iod size: %lu, alloc_size: %u\n",
+ sizeof(struct sssraid_iod), alloc_size);
+
+ return sizeof(struct sssraid_iod) + alloc_size;
+}
+
+static int sssraid_setup_prps(struct sssraid_dev *hdev, struct sssraid_iod *iod)
+{
+ struct scatterlist *sg = iod->sg;
+ u64 dma_addr = sg_dma_address(sg);
+ int dma_len = sg_dma_len(sg);
+ __le64 *prp_list, *old_prp_list;
+ int page_size = hdev->page_size;
+ int offset = dma_addr & (page_size - 1);
+ void **list = sssraid_iod_list(iod);
+ int length = iod->length;
+ struct dma_pool *pool;
+ dma_addr_t prp_dma;
+ int nprps, i;
+
+ length -= (page_size - offset);
+ if (length <= 0) {
+ iod->first_dma = 0;
+ return 0;
+ }
+
+ dma_len -= (page_size - offset);
+ if (dma_len) {
+ dma_addr += (page_size - offset);
+ } else {
+ sg = sg_next(sg);
+ dma_addr = sg_dma_address(sg);
+ dma_len = sg_dma_len(sg);
+ }
+
+ if (length <= page_size) {
+ iod->first_dma = dma_addr;
+ return 0;
+ }
+
+ nprps = DIV_ROUND_UP(length, page_size);
+ if (nprps <= (SMALL_POOL_SIZE / PRP_ENTRY_SIZE)) {
+ pool = iod->sqinfo->prp_small_pool;
+ iod->npages = 0;
+ } else {
+ pool = hdev->prp_page_pool;
+ iod->npages = 1;
+ }
+
+ prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
+ if (!prp_list) {
+ dev_err_ratelimited(&hdev->pdev->dev, "Allocate first prp_list memory failed\n");
+ iod->first_dma = dma_addr;
+ iod->npages = -1;
+ return -ENOMEM;
+ }
+ list[0] = prp_list;
+ iod->first_dma = prp_dma;
+ i = 0;
+ for (;;) {
+ if (i == page_size / PRP_ENTRY_SIZE) {
+ old_prp_list = prp_list;
+
+ prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
+ if (!prp_list) {
+ dev_err_ratelimited(&hdev->pdev->dev, "Allocate %dth prp_list memory failed\n",
+ iod->npages + 1);
+ return -ENOMEM;
+ }
+ list[iod->npages++] = prp_list;
+ prp_list[0] = old_prp_list[i - 1];
+ old_prp_list[i - 1] = cpu_to_le64(prp_dma);
+ i = 1;
+ }
+ prp_list[i++] = cpu_to_le64(dma_addr);
+ dma_len -= page_size;
+ dma_addr += page_size;
+ length -= page_size;
+ if (length <= 0)
+ break;
+ if (dma_len > 0)
+ continue;
+ if (unlikely(dma_len < 0))
+ goto bad_sgl;
+ sg = sg_next(sg);
+ dma_addr = sg_dma_address(sg);
+ dma_len = sg_dma_len(sg);
+ }
+
+ return 0;
+
+bad_sgl:
+ ioc_err(hdev, "Setup prps, invalid SGL for payload: %d nents: %d\n",
+ iod->length, iod->nsge);
+ return -EIO;
+}
+
+static inline bool sssraid_is_rw_scmd(struct scsi_cmnd *scmd)
+{
+ switch (scmd->cmnd[0]) {
+ case READ_6:
+ case READ_10:
+ case READ_12:
+ case READ_16:
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_12:
+ case WRITE_16:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool sssraid_is_prp(struct sssraid_dev *hdev, struct scsi_cmnd *scmd, u32 nsge)
+{
+ struct scatterlist *sg = scsi_sglist(scmd);
+ u32 page_mask = hdev->page_size - 1;
+ bool is_prp = true;
+ int i = 0;
+
+ scsi_for_each_sg(scmd, sg, nsge, i) {
+ if (i != 0 && i != nsge - 1) {
+ if ((sg_dma_len(sg) & page_mask) ||
+ (sg_dma_address(sg) & page_mask)) {
+ is_prp = false;
+ break;
+ }
+ }
+
+ if (nsge > 1 && i == 0) {
+ if ((sg_dma_address(sg) + sg_dma_len(sg)) & page_mask) {
+ is_prp = false;
+ break;
+ }
+ }
+
+ if (nsge > 1 && i == (nsge - 1)) {
+ if (sg_dma_address(sg) & page_mask) {
+ is_prp = false;
+ break;
+ }
+ }
+ }
+
+ return is_prp;
+}
+
+static void sssraid_sgl_set_data(struct sssraid_sgl_desc *sge, struct scatterlist *sg)
+{
+ sge->addr = cpu_to_le64(sg_dma_address(sg));
+ sge->length = cpu_to_le32(sg_dma_len(sg));
+ sge->type = SSSRAID_SGL_FMT_DATA_DESC << 4;
+}
+
+static void sssraid_sgl_set_seg(struct sssraid_sgl_desc *sge, dma_addr_t dma_addr, int entries)
+{
+ sge->addr = cpu_to_le64(dma_addr);
+ if (entries <= SGES_PER_PAGE) {
+ sge->length = cpu_to_le32(entries * sizeof(*sge));
+ sge->type = SSSRAID_SGL_FMT_LAST_SEG_DESC << 4;
+ } else {
+ sge->length = cpu_to_le32(PAGE_SIZE);
+ sge->type = SSSRAID_SGL_FMT_SEG_DESC << 4;
+ }
+}
+
+
+static int sssraid_setup_ioq_cmd_sgl(struct sssraid_dev *hdev,
+ struct scsi_cmnd *scmd, struct sssraid_ioq_command *ioq_cmd,
+ struct sssraid_iod *iod)
+{
+ struct sssraid_sgl_desc *sg_list, *link, *old_sg_list;
+ struct scatterlist *sg = scsi_sglist(scmd);
+ void **list = sssraid_iod_list(iod);
+ struct dma_pool *pool;
+ int nsge = iod->nsge;
+ dma_addr_t sgl_dma;
+ int i = 0;
+
+ ioq_cmd->common.flags |= SSSRAID_CMD_FLAG_SGL_METABUF;
+
+ if (nsge == 1) {
+ sssraid_sgl_set_data(&ioq_cmd->common.dptr.sgl, sg);
+ return 0;
+ }
+
+ if (nsge <= (SMALL_POOL_SIZE / sizeof(struct sssraid_sgl_desc))) {
+ pool = iod->sqinfo->prp_small_pool;
+ iod->npages = 0;
+ } else {
+ pool = hdev->prp_page_pool;
+ iod->npages = 1;
+ }
+
+ sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma);
+ if (!sg_list) {
+ dev_err_ratelimited(&hdev->pdev->dev, "Allocate first sgl_list failed\n");
+ iod->npages = -1;
+ return -ENOMEM;
+ }
+
+ list[0] = sg_list;
+ iod->first_dma = sgl_dma;
+ sssraid_sgl_set_seg(&ioq_cmd->common.dptr.sgl, sgl_dma, nsge);
+ do {
+ if (i == SGES_PER_PAGE) {
+ old_sg_list = sg_list;
+ link = &old_sg_list[SGES_PER_PAGE - 1];
+
+ sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma);
+ if (!sg_list) {
+ dev_err_ratelimited(&hdev->pdev->dev, "Allocate %dth sgl_list failed\n",
+ iod->npages + 1);
+ return -ENOMEM;
+ }
+ list[iod->npages++] = sg_list;
+
+ i = 0;
+ memcpy(&sg_list[i++], link, sizeof(*link));
+ sssraid_sgl_set_seg(link, sgl_dma, nsge);
+ }
+
+ sssraid_sgl_set_data(&sg_list[i++], sg);
+ sg = sg_next(sg);
+ } while (--nsge > 0);
+
+ return 0;
+}
+
+static void sssraid_shost_init(struct sssraid_dev *hdev)
+{
+ struct pci_dev *pdev = hdev->pdev;
+ u8 domain, bus;
+ u32 dev_func;
+
+ domain = pci_domain_nr(pdev->bus);
+ bus = pdev->bus->number;
+ dev_func = pdev->devfn;
+
+ hdev->shost->nr_hw_queues = hdev->init_done_queue_cnt - 1;
+ hdev->shost->can_queue = (hdev->ioq_depth - SSSRAID_PTCMDS_PERQ);
+
+ hdev->shost->sg_tablesize = le16_to_cpu(hdev->ctrl_info->max_num_sge);
+ /* 512B per sector */
+ hdev->shost->max_sectors = (1U << ((hdev->ctrl_info->mdts) * 1U) << 12) / 512;
+ hdev->shost->cmd_per_lun = MAX_CMD_PER_DEV;
+ hdev->shost->max_channel = le16_to_cpu(hdev->ctrl_info->max_channel) - 1;
+ hdev->shost->max_id = le32_to_cpu(hdev->ctrl_info->max_tgt_id);
+ hdev->shost->max_lun = le16_to_cpu(hdev->ctrl_info->max_lun);
+
+ hdev->shost->this_id = -1;
+ hdev->shost->unique_id = (domain << 16) | (bus << 8) | dev_func;
+ hdev->shost->max_cmd_len = MAX_CDB_LEN;
+ hdev->shost->hostt->cmd_size = sssraid_cmd_size(hdev);
+}
+
+static inline void sssraid_get_tag_from_scmd(struct scsi_cmnd *scmd, u16 *qidx, u16 *cid)
+{
+ u32 tag = blk_mq_unique_tag(scmd->request);
+
+ *qidx = blk_mq_unique_tag_to_hwq(tag) + 1;
+ *cid = blk_mq_unique_tag_to_tag(tag);
+}
+
+static inline uint32_t get_unaligned_be24(const uint8_t *const p)
+{
+ return get_unaligned_be32(p - 1) & 0xffffffU;
+}
+
+static int sssraid_setup_rw_cmd(struct sssraid_dev *hdev,
+ struct sssraid_rw_command *rw,
+ struct scsi_cmnd *scmd)
+{
+ u32 start_lba_lo, start_lba_hi;
+ u32 datalength = 0;
+ u16 control = 0;
+
+ start_lba_lo = 0;
+ start_lba_hi = 0;
+
+ if (scmd->sc_data_direction == DMA_TO_DEVICE) {
+ rw->opcode = SSSRAID_CMD_WRITE;
+ } else if (scmd->sc_data_direction == DMA_FROM_DEVICE) {
+ rw->opcode = SSSRAID_CMD_READ;
+ } else {
+ ioc_err(hdev, "Invalid RW_IO for unsupported data direction: %d\n",
+ scmd->sc_data_direction);
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ /* 6-byte READ(0x08) or WRITE(0x0A) cdb */
+ if (scmd->cmd_len == 6) {
+ datalength = (u32)(scmd->cmnd[4] == 0 ?
+ IO_6_DEFAULT_TX_LEN : scmd->cmnd[4]);
+ start_lba_lo = (u32)get_unaligned_be24(&scmd->cmnd[1]);
+
+ start_lba_lo &= 0x1FFFFF;
+ }
+
+ /* 10-byte READ(0x28) or WRITE(0x2A) cdb */
+ else if (scmd->cmd_len == 10) {
+ datalength = (u32)get_unaligned_be16(&scmd->cmnd[7]);
+ start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]);
+
+ if (scmd->cmnd[1] & FUA_MASK)
+ control |= SSSRAID_RW_FUA;
+ }
+
+ /* 12-byte READ(0xA8) or WRITE(0xAA) cdb */
+ else if (scmd->cmd_len == 12) {
+ datalength = get_unaligned_be32(&scmd->cmnd[6]);
+ start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]);
+
+ if (scmd->cmnd[1] & FUA_MASK)
+ control |= SSSRAID_RW_FUA;
+ }
+ /* 16-byte READ(0x88) or WRITE(0x8A) cdb */
+ else if (scmd->cmd_len == 16) {
+ datalength = get_unaligned_be32(&scmd->cmnd[10]);
+ start_lba_lo = get_unaligned_be32(&scmd->cmnd[6]);
+ start_lba_hi = get_unaligned_be32(&scmd->cmnd[2]);
+
+ if (scmd->cmnd[1] & FUA_MASK)
+ control |= SSSRAID_RW_FUA;
+ }
+
+ if (unlikely(datalength > U16_MAX || datalength == 0)) {
+ ioc_err(hdev, "Invalid IO for illegal transfer data length: %u\n", datalength);
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ rw->slba = cpu_to_le64(((u64)start_lba_hi << 32) | start_lba_lo);
+ /* 0base for nlb */
+ rw->nlb = cpu_to_le16((u16)(datalength - 1));
+ rw->control = cpu_to_le16(control);
+
+ return 0;
+}
+
+static int sssraid_setup_nonio_cmd(struct sssraid_dev *hdev,
+ struct sssraid_scsi_nonio *scsi_nonio, struct scsi_cmnd *scmd)
+{
+ scsi_nonio->buffer_len = cpu_to_le32(scsi_bufflen(scmd));
+
+ switch (scmd->sc_data_direction) {
+ case DMA_NONE:
+ scsi_nonio->opcode = SSSRAID_CMD_NONIO_NONE;
+ break;
+ case DMA_TO_DEVICE:
+ scsi_nonio->opcode = SSSRAID_CMD_NONIO_TODEV;
+ break;
+ case DMA_FROM_DEVICE:
+ scsi_nonio->opcode = SSSRAID_CMD_NONIO_FROMDEV;
+ break;
+ default:
+ ioc_err(hdev, "Invalid NON_IO for unsupported data direction: %d\n",
+ scmd->sc_data_direction);
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int sssraid_setup_ioq_cmd(struct sssraid_dev *hdev,
+ struct sssraid_ioq_command *ioq_cmd, struct scsi_cmnd *scmd)
+{
+ memcpy(ioq_cmd->common.cdb, scmd->cmnd, scmd->cmd_len);
+ ioq_cmd->common.cdb_len = scmd->cmd_len;
+
+ if (sssraid_is_rw_scmd(scmd))
+ return sssraid_setup_rw_cmd(hdev, &ioq_cmd->rw, scmd);
+ else
+ return sssraid_setup_nonio_cmd(hdev, &ioq_cmd->scsi_nonio, scmd);
+}
+
+static inline void sssraid_init_iod(struct sssraid_iod *iod)
+{
+ iod->nsge = 0;
+ iod->npages = -1;
+ iod->use_sgl = false;
+ WRITE_ONCE(iod->state, SSSRAID_CMD_IDLE);
+}
+
+int sssraid_io_map_data(struct sssraid_dev *hdev, struct sssraid_iod *iod,
+ struct scsi_cmnd *scmd, struct sssraid_ioq_command *ioq_cmd)
+{
+ int retval;
+
+ retval = scsi_dma_map(scmd);
+ if (unlikely(retval < 0))
+ return retval;
+ iod->nsge = retval;
+ /* No data to DMA, it may be scsi no-rw command */
+ if (unlikely(iod->nsge == 0))
+ return 0;
+
+ iod->length = scsi_bufflen(scmd);
+ iod->sg = scsi_sglist(scmd);
+ iod->use_sgl = !sssraid_is_prp(hdev, scmd, iod->nsge);
+
+ if (iod->use_sgl) {
+ retval = sssraid_setup_ioq_cmd_sgl(hdev, scmd, ioq_cmd, iod);
+ } else {
+ retval = sssraid_setup_prps(hdev, iod);
+ ioq_cmd->common.dptr.prp1 =
+ cpu_to_le64(sg_dma_address(iod->sg));
+ ioq_cmd->common.dptr.prp2 = cpu_to_le64(iod->first_dma);
+ }
+
+ if (retval)
+ scsi_dma_unmap(scmd);
+
+ return retval;
+}
+
+void sssraid_map_status(struct sssraid_iod *iod, struct scsi_cmnd *scmd,
+ struct sssraid_completion *cqe)
+{
+ struct sssraid_dev *hdev = iod->sqinfo->hdev;
+
+ scsi_set_resid(scmd, 0);
+
+ switch ((le16_to_cpu(cqe->status) >> 1) & 0x7f) {
+ case FW_STAT_OK:
+ set_host_byte(scmd, DID_OK);
+ break;
+ case FW_STAT_NEED_CHECK:
+ set_host_byte(scmd, DID_OK);
+ scmd->result |= le16_to_cpu(cqe->status) >> 8;
+ if (scmd->result & SAM_STAT_CHECK_CONDITION) {
+ memset(scmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ memcpy(scmd->sense_buffer, iod->sense, SCSI_SENSE_BUFFERSIZE);
+ scmd->result = (scmd->result & 0x00ffffff) | (DRIVER_SENSE << 24);
+ }
+ break;
+ case FW_STAT_ABORTED:
+ set_host_byte(scmd, DID_ABORT);
+ break;
+ case FW_STAT_NEED_RETRY:
+ set_host_byte(scmd, DID_REQUEUE);
+ break;
+ default:
+ set_host_byte(scmd, DID_BAD_TARGET);
+ ioc_warn(hdev, "cid[%d] qid[%d] bad status[0x%x]\n",
+ le16_to_cpu(cqe->cmd_id), le16_to_cpu(cqe->sq_id),
+ le16_to_cpu(cqe->status));
+ break;
+ }
+}
+
+
+struct sssraid_cmd *sssraid_get_cmd(struct sssraid_dev *hdev, enum sssraid_cmd_type type)
+{
+ struct sssraid_cmd *cmd = NULL;
+ unsigned long flags;
+ struct list_head *head = &hdev->adm_cmd_list;
+ spinlock_t *slock = &hdev->adm_cmd_lock;
+
+ if (type == SSSRAID_CMD_IOPT) {
+ head = &hdev->ioq_pt_list;
+ slock = &hdev->ioq_pt_lock;
+ }
+
+ spin_lock_irqsave(slock, flags);
+ if (list_empty(head)) {
+ spin_unlock_irqrestore(slock, flags);
+ ioc_err(hdev, "err, cmd[%d] list empty\n", type);
+ return NULL;
+ }
+ cmd = list_entry(head->next, struct sssraid_cmd, list);
+ list_del_init(&cmd->list);
+ spin_unlock_irqrestore(slock, flags);
+
+ WRITE_ONCE(cmd->state, SSSRAID_CMD_IN_FLIGHT);
+
+ return cmd;
+}
+
+static int sssraid_add_device(struct sssraid_dev *hdev, struct sssraid_dev_info *device)
+{
+ struct Scsi_Host *shost = hdev->shost;
+ struct scsi_device *sdev;
+
+ ioc_info(hdev, "add device, hdid: %u target: %d, channel: %d, lun: %d, attr[0x%x]\n",
+ le32_to_cpu(device->hdid), le16_to_cpu(device->target),
+ device->channel, device->lun, device->attr);
+
+ sdev = scsi_device_lookup(shost, device->channel, le16_to_cpu(device->target), 0);
+ if (sdev) {
+ ioc_warn(hdev, "Device is already exist, channel: %d, target_id: %d, lun: %d\n",
+ device->channel, le16_to_cpu(device->target), 0);
+ scsi_device_put(sdev);
+ return -EEXIST;
+ }
+ scsi_add_device(shost, device->channel, le16_to_cpu(device->target), 0);
+ return 0;
+}
+
+static int sssraid_rescan_device(struct sssraid_dev *hdev, struct sssraid_dev_info *device)
+{
+ struct Scsi_Host *shost = hdev->shost;
+ struct scsi_device *sdev;
+
+ ioc_info(hdev, "rescan device, hdid: %u target: %d, channel: %d, lun: %d, attr[0x%x]\n",
+ le32_to_cpu(device->hdid), le16_to_cpu(device->target),
+ device->channel, device->lun, device->attr);
+
+ sdev = scsi_device_lookup(shost, device->channel, le16_to_cpu(device->target), 0);
+ if (!sdev) {
+ ioc_warn(hdev, "device is not exit rescan it, channel: %d, target_id: %d, lun: %d\n",
+ device->channel, le16_to_cpu(device->target), 0);
+ return -ENODEV;
+ }
+
+ scsi_rescan_device(&sdev->sdev_gendev);
+ scsi_device_put(sdev);
+ return 0;
+}
+
+static int sssraid_remove_device(struct sssraid_dev *hdev, struct sssraid_dev_info *org_device)
+{
+ struct Scsi_Host *shost = hdev->shost;
+ struct scsi_device *sdev;
+
+ ioc_info(hdev, "remove device, hdid: %u target: %d, channel: %d, lun: %d, attr[0x%x]\n",
+ le32_to_cpu(org_device->hdid), le16_to_cpu(org_device->target),
+ org_device->channel, org_device->lun, org_device->attr);
+
+ sdev = scsi_device_lookup(shost, org_device->channel, le16_to_cpu(org_device->target), 0);
+ if (!sdev) {
+ ioc_warn(hdev, "device is not exit remove it, channel: %d, target_id: %d, lun: %d\n",
+ org_device->channel, le16_to_cpu(org_device->target), 0);
+ return -ENODEV;
+ }
+
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ return 0;
+}
+
+static int luntarget_cmp_func(const void *l, const void *r)
+{
+ const struct sssraid_dev_info *ln = l;
+ const struct sssraid_dev_info *rn = r;
+ int l_attr = SSSRAID_DEV_INFO_ATTR_BOOT(ln->attr);
+ int r_attr = SSSRAID_DEV_INFO_ATTR_BOOT(rn->attr);
+
+ /* boot first */
+ if (l_attr != r_attr)
+ return (r_attr - l_attr);
+
+ if (ln->channel == rn->channel)
+ return le16_to_cpu(ln->target) - le16_to_cpu(rn->target);
+
+ return ln->channel - rn->channel;
+}
+
+void sssraid_scan_disk(struct sssraid_dev *hdev)
+{
+ struct sssraid_dev_info *devices, *org_devices;
+ struct sssraid_dev_info *sortdevice;
+ u32 nd = le32_to_cpu(hdev->ctrl_info->nd);
+ u8 flag, org_flag;
+ int i, ret;
+ int count = 0;
+
+ devices = kcalloc(nd, sizeof(struct sssraid_dev_info), GFP_KERNEL);
+ if (!devices)
+ return;
+
+ sortdevice = kcalloc(nd, sizeof(struct sssraid_dev_info), GFP_KERNEL);
+ if (!sortdevice)
+ goto free_list;
+
+ ret = sssraid_get_dev_list(hdev, devices);
+ if (ret)
+ goto free_all;
+ org_devices = hdev->devices;
+ for (i = 0; i < nd; i++) {
+ org_flag = org_devices[i].flag;
+ flag = devices[i].flag;
+
+ dbgprint(hdev, "i: %d, org_flag: 0x%x, flag: 0x%x\n", i, org_flag, flag);
+
+ if (SSSRAID_DEV_INFO_FLAG_VALID(flag)) {
+ if (!SSSRAID_DEV_INFO_FLAG_VALID(org_flag)) {
+ down_write(&hdev->devices_rwsem);
+ memcpy(&org_devices[i], &devices[i],
+ sizeof(struct sssraid_dev_info));
+ memcpy(&sortdevice[count++], &devices[i],
+ sizeof(struct sssraid_dev_info));
+ up_write(&hdev->devices_rwsem);
+ } else if (SSSRAID_DEV_INFO_FLAG_CHANGE(flag)) {
+ sssraid_rescan_device(hdev, &devices[i]);
+ }
+ } else {
+ if (SSSRAID_DEV_INFO_FLAG_VALID(org_flag)) {
+ down_write(&hdev->devices_rwsem);
+ org_devices[i].flag &= 0xfe;
+ up_write(&hdev->devices_rwsem);
+ sssraid_remove_device(hdev, &org_devices[i]);
+ }
+ }
+ }
+
+ ioc_info(hdev, "scan work add device count = %d\n", count);
+
+ sort(sortdevice, count, sizeof(sortdevice[0]), luntarget_cmp_func, NULL);
+
+ for (i = 0; i < count; i++)
+ sssraid_add_device(hdev, &sortdevice[i]);
+
+free_all:
+ kfree(sortdevice);
+free_list:
+ kfree(devices);
+}
+
+static int sssraid_wait_abnl_cmd_done(struct sssraid_iod *iod)
+{
+ u16 times = 0;
+
+ do {
+ if (READ_ONCE(iod->state) == SSSRAID_CMD_TMO_COMPLETE)
+ break;
+ msleep(500);
+ times++;
+ } while (times <= SSSRAID_WAIT_ABNL_CMD_TIMEOUT);
+
+ /* wait command completion timeout after abort/reset success */
+ if (times >= SSSRAID_WAIT_ABNL_CMD_TIMEOUT)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static bool sssraid_check_scmd_completed(struct scsi_cmnd *scmd)
+{
+ struct sssraid_dev *hdev = shost_priv(scmd->device->host);
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ struct sssraid_squeue *sqinfo;
+ u16 hwq, cid;
+
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+ sqinfo = &hdev->sqinfo[hwq];
+ if (READ_ONCE(iod->state) == SSSRAID_CMD_COMPLETE || sssraid_poll_cq(hdev, hwq, cid)) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] has been completed\n",
+ cid, sqinfo->qidx);
+ return true;
+ }
+ return false;
+}
+
+static int sssraid_scsi_reset(struct scsi_cmnd *scmd, enum sssraid_scsi_rst_type rst)
+{
+ struct sssraid_dev *hdev = shost_priv(scmd->device->host);
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ struct sssraid_sdev_hostdata *hostdata;
+ u16 hwq, cid;
+ int ret;
+
+ scsi_print_command(scmd);
+
+ if (hdev->state != SSSRAID_LIVE || !sssraid_wait_abnl_cmd_done(iod) ||
+ sssraid_check_scmd_completed(scmd))
+ return SUCCESS;
+
+ hostdata = scmd->device->hostdata;
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] timeout, %s reset\n", cid, hwq,
+ rst ? "bus" : "target");
+ ret = sssraid_send_reset_cmd(hdev, rst, hostdata->hdid);
+ if (ret == 0) {
+ ret = sssraid_wait_abnl_cmd_done(iod);
+ if (ret) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] %s reset failed, not found\n",
+ cid, hwq, rst ? "bus" : "target");
+ return FAILED;
+ }
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] %s reset success\n", cid, hwq,
+ rst ? "bus" : "target");
+ return SUCCESS;
+ }
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] ret[%d] %s reset failed\n", cid, hwq, ret,
+ rst ? "bus" : "target");
+ return FAILED;
+}
+
+bool sssraid_change_host_state(struct sssraid_dev *hdev, enum sssraid_state newstate)
+{
+ unsigned long flags;
+ enum sssraid_state oldstate;
+ bool change = false;
+
+ spin_lock_irqsave(&hdev->state_lock, flags);
+
+ oldstate = hdev->state;
+ switch (newstate) {
+ case SSSRAID_LIVE:
+ switch (oldstate) {
+ case SSSRAID_NEW:
+ case SSSRAID_RESETTING:
+ change = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SSSRAID_RESETTING:
+ switch (oldstate) {
+ case SSSRAID_LIVE:
+ change = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SSSRAID_DELETING:
+ if (oldstate != SSSRAID_DELETING)
+ change = true;
+ break;
+ case SSSRAID_DEAD:
+ switch (oldstate) {
+ case SSSRAID_NEW:
+ case SSSRAID_LIVE:
+ case SSSRAID_RESETTING:
+ change = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ if (change)
+ hdev->state = newstate;
+ spin_unlock_irqrestore(&hdev->state_lock, flags);
+
+ ioc_info(hdev, "[%d]->[%d], change[%d]\n", oldstate, newstate, change);
+
+ return change;
+}
+
+static int sssraid_get_qd_by_disk(u8 attr)
+{
+ switch (SSSRAID_DEV_DISK_TYPE(attr)) {
+ case SSSRAID_SAS_HDD_VD:
+ case SSSRAID_SATA_HDD_VD:
+ return SSSRAID_HDD_VD_QD;
+ case SSSRAID_SAS_SSD_VD:
+ case SSSRAID_SATA_SSD_VD:
+ case SSSRAID_NVME_SSD_VD:
+ return SSSRAID_SSD_VD_QD;
+ case SSSRAID_SAS_HDD_PD:
+ case SSSRAID_SATA_HDD_PD:
+ return SSSRAID_HDD_PD_QD;
+ case SSSRAID_SAS_SSD_PD:
+ case SSSRAID_SATA_SSD_PD:
+ case SSSRAID_NVME_SSD_PD:
+ return SSSRAID_SSD_PD_QD;
+ default:
+ return MAX_CMD_PER_DEV;
+ }
+}
+
+static int sssraid_match_dev(struct sssraid_dev *hdev, u16 idx, struct scsi_device *sdev)
+{
+ if (SSSRAID_DEV_INFO_FLAG_VALID(hdev->devices[idx].flag)) {
+ if (sdev->channel == hdev->devices[idx].channel &&
+ sdev->id == le16_to_cpu(hdev->devices[idx].target) &&
+ sdev->lun < hdev->devices[idx].lun) {
+ ioc_info(hdev, "Match device success, channel:target:lun[%d:%d:%d]\n",
+ hdev->devices[idx].channel,
+ hdev->devices[idx].target,
+ hdev->devices[idx].lun);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int sssraid_bsg_map_data(struct sssraid_dev *hdev, struct bsg_job *job,
+ struct sssraid_admin_command *cmd)
+{
+ struct request *rq = blk_mq_rq_from_pdu(job);
+ struct sssraid_iod *iod = job->dd_data;
+ enum dma_data_direction dma_dir = rq_data_dir(rq) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ int ret = 0;
+
+ iod->sg = job->request_payload.sg_list;
+ iod->nsge = job->request_payload.sg_cnt;
+ iod->length = job->request_payload.payload_len;
+ iod->use_sgl = false;
+ iod->npages = -1;
+
+ if (!iod->nsge)
+ goto out;
+
+ ret = dma_map_sg_attrs(&hdev->pdev->dev, iod->sg, iod->nsge, dma_dir, DMA_ATTR_NO_WARN);
+ if (!ret)
+ goto out;
+
+ ret = sssraid_setup_prps(hdev, iod);
+ if (ret)
+ goto unmap;
+
+ cmd->common.dptr.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
+ cmd->common.dptr.prp2 = cpu_to_le64(iod->first_dma);
+
+ return 0;
+
+unmap:
+ dma_unmap_sg(&hdev->pdev->dev, iod->sg, iod->nsge, dma_dir);
+out:
+ return ret;
+}
+
+static void sssraid_bsg_unmap_data(struct sssraid_dev *hdev, struct bsg_job *job)
+{
+ struct request *rq = blk_mq_rq_from_pdu(job);
+ struct sssraid_iod *iod = job->dd_data;
+ enum dma_data_direction dma_dir = rq_data_dir(rq) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+ if (iod->nsge)
+ dma_unmap_sg(&hdev->pdev->dev, iod->sg, iod->nsge, dma_dir);
+
+ sssraid_free_iod_res(hdev, iod);
+}
+
+void sssraid_put_cmd(struct sssraid_dev *hdev, struct sssraid_cmd *cmd,
+ enum sssraid_cmd_type type)
+{
+ unsigned long flags;
+ struct list_head *head = &hdev->adm_cmd_list;
+ spinlock_t *slock = &hdev->adm_cmd_lock;
+
+ if (type == SSSRAID_CMD_IOPT) {
+ head = &hdev->ioq_pt_list;
+ slock = &hdev->ioq_pt_lock;
+ }
+
+ spin_lock_irqsave(slock, flags);
+ WRITE_ONCE(cmd->state, SSSRAID_CMD_IDLE);
+ list_add_tail(&cmd->list, head);
+ spin_unlock_irqrestore(slock, flags);
+}
+
+static int sssraid_user_admin_cmd(struct sssraid_dev *hdev, struct bsg_job *job)
+{
+ struct sssraid_bsg_request *bsg_req = job->request;
+ struct sssraid_passthru_common_cmd *cmd = &(bsg_req->admcmd);
+ struct sssraid_admin_command admin_cmd;
+ u32 timeout = msecs_to_jiffies(cmd->timeout_ms);
+ u32 result[2] = {0};
+ int status;
+
+ if (hdev->state >= SSSRAID_RESETTING) {
+ ioc_err(hdev, "err, host state:[%d] is not right\n",
+ hdev->state);
+ return -EBUSY;
+ }
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.common.opcode = cmd->opcode;
+ admin_cmd.common.flags = cmd->flags;
+ admin_cmd.common.hdid = cpu_to_le32(cmd->nsid);
+ admin_cmd.common.cdw2[0] = cpu_to_le32(cmd->cdw2);
+ admin_cmd.common.cdw2[1] = cpu_to_le32(cmd->cdw3);
+ admin_cmd.common.cdw10 = cpu_to_le32(cmd->cdw10);
+ admin_cmd.common.cdw11 = cpu_to_le32(cmd->cdw11);
+ admin_cmd.common.cdw12 = cpu_to_le32(cmd->cdw12);
+ admin_cmd.common.cdw13 = cpu_to_le32(cmd->cdw13);
+ admin_cmd.common.cdw14 = cpu_to_le32(cmd->cdw14);
+ admin_cmd.common.cdw15 = cpu_to_le32(cmd->cdw15);
+
+ status = sssraid_bsg_map_data(hdev, job, &admin_cmd);
+ if (status) {
+ ioc_err(hdev, "err, map data failed\n");
+ return status;
+ }
+
+ status = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, &result[0], &result[1], timeout);
+ if (status >= 0) {
+ job->reply_len = sizeof(result);
+ memcpy(job->reply, result, sizeof(result));
+ }
+
+ if (status)
+ ioc_info(hdev, "opcode[0x%x] subopcode[0x%x], status[0x%x] result0[0x%x] result1[0x%x]\n",
+ cmd->opcode, cmd->info_0.subopcode, status, result[0], result[1]);
+
+ sssraid_bsg_unmap_data(hdev, job);
+
+ return status;
+}
+
+static int sssraid_submit_ioq_sync_cmd(struct sssraid_dev *hdev, struct sssraid_ioq_command *cmd,
+ u32 *result, u32 *reslen, u32 timeout)
+{
+ int ret;
+ dma_addr_t sense_dma;
+ struct sssraid_squeue *sqinfo;
+ void *sense_addr = NULL;
+ struct sssraid_cmd *pt_cmd = sssraid_get_cmd(hdev, SSSRAID_CMD_IOPT);
+
+ if (!pt_cmd) {
+ ioc_err(hdev, "err, get sqinfo cmd failed\n");
+ return -EFAULT;
+ }
+
+ timeout = timeout ? timeout : ADMIN_TIMEOUT;
+
+ init_completion(&pt_cmd->cmd_done);
+
+ sqinfo = &hdev->sqinfo[pt_cmd->qid];
+ ret = pt_cmd->cid * SCSI_SENSE_BUFFERSIZE;
+ sense_addr = sqinfo->sense + ret;
+ sense_dma = sqinfo->sense_dma_addr + ret;
+
+ cmd->common.sense_addr = cpu_to_le64(sense_dma);
+ cmd->common.sense_len = cpu_to_le16(SCSI_SENSE_BUFFERSIZE);
+ cmd->common.command_id = cpu_to_le16(pt_cmd->cid);
+
+ sssraid_submit_cmd(sqinfo, cmd);
+
+ if (!wait_for_completion_timeout(&pt_cmd->cmd_done, timeout)) {
+ ioc_err(hdev, "cid[%d] qid[%d] timeout, opcode[0x%x] subopcode[0x%x]\n",
+ pt_cmd->cid, pt_cmd->qid, cmd->common.opcode,
+ (le32_to_cpu(cmd->common.cdw3[0]) & 0xffff));
+
+ /* reset controller if admin timeout */
+ sssraid_adm_timeout(hdev, pt_cmd);
+
+ sssraid_put_cmd(hdev, pt_cmd, SSSRAID_CMD_IOPT);
+ return -ETIME;
+ }
+
+ if (result && reslen) {
+ if ((pt_cmd->status & 0x17f) == 0x101) {
+ memcpy(result, sense_addr, SCSI_SENSE_BUFFERSIZE);
+ *reslen = SCSI_SENSE_BUFFERSIZE;
+ }
+ }
+
+ sssraid_put_cmd(hdev, pt_cmd, SSSRAID_CMD_IOPT);
+
+ return pt_cmd->status;
+}
+
+static int sssraid_user_ioq_cmd(struct sssraid_dev *hdev, struct bsg_job *job)
+{
+ struct sssraid_bsg_request *bsg_req = (struct sssraid_bsg_request *)(job->request);
+ struct sssraid_ioq_passthru_cmd *cmd = &(bsg_req->ioqcmd);
+ struct sssraid_ioq_command ioq_cmd;
+ int status = 0;
+ u32 timeout = msecs_to_jiffies(cmd->timeout_ms);
+
+ if (cmd->data_len > IOQ_PT_DATA_LEN) {
+ ioc_err(hdev, "data len bigger than 4k\n");
+ return -EFAULT;
+ }
+
+ if (hdev->state != SSSRAID_LIVE) {
+ ioc_err(hdev, "err, host state:[%d] is not live\n",
+ hdev->state);
+ return -EBUSY;
+ }
+
+ ioc_info(hdev, "opcode[0x%x] subopcode[0x%x] init, datalen[%d]\n",
+ cmd->opcode, cmd->info_1.subopcode, cmd->data_len);
+
+ memset(&ioq_cmd, 0, sizeof(ioq_cmd));
+ ioq_cmd.common.opcode = cmd->opcode;
+ ioq_cmd.common.flags = cmd->flags;
+ ioq_cmd.common.hdid = cpu_to_le32(cmd->nsid);
+ ioq_cmd.common.sense_len = cpu_to_le16(cmd->info_0.res_sense_len);
+ ioq_cmd.common.cdb_len = cmd->info_0.cdb_len;
+ ioq_cmd.common.rsvd2 = cmd->info_0.rsvd0;
+ ioq_cmd.common.cdw3[0] = cpu_to_le32(cmd->cdw3);
+ ioq_cmd.common.cdw3[1] = cpu_to_le32(cmd->cdw4);
+ ioq_cmd.common.cdw3[2] = cpu_to_le32(cmd->cdw5);
+
+ ioq_cmd.common.cdw10[0] = cpu_to_le32(cmd->cdw10);
+ ioq_cmd.common.cdw10[1] = cpu_to_le32(cmd->cdw11);
+ ioq_cmd.common.cdw10[2] = cpu_to_le32(cmd->cdw12);
+ ioq_cmd.common.cdw10[3] = cpu_to_le32(cmd->cdw13);
+ ioq_cmd.common.cdw10[4] = cpu_to_le32(cmd->cdw14);
+ ioq_cmd.common.cdw10[5] = cpu_to_le32(cmd->data_len);
+
+ memcpy(ioq_cmd.common.cdb, &cmd->cdw16, cmd->info_0.cdb_len);
+
+ ioq_cmd.common.cdw26[0] = cpu_to_le32(cmd->cdw26[0]);
+ ioq_cmd.common.cdw26[1] = cpu_to_le32(cmd->cdw26[1]);
+ ioq_cmd.common.cdw26[2] = cpu_to_le32(cmd->cdw26[2]);
+ ioq_cmd.common.cdw26[3] = cpu_to_le32(cmd->cdw26[3]);
+
+ status = sssraid_bsg_map_data(hdev, job, (struct sssraid_admin_command *)&ioq_cmd);
+ if (status) {
+ ioc_err(hdev, "err, map data failed\n");
+ return status;
+ }
+
+ status = sssraid_submit_ioq_sync_cmd(hdev, &ioq_cmd, job->reply, &job->reply_len, timeout);
+ if (status)
+ ioc_info(hdev, "opcode[0x%x] subopcode[0x%x], status[0x%x], reply_len[%d]\n",
+ cmd->opcode, cmd->info_1.subopcode, status, job->reply_len);
+
+ sssraid_bsg_unmap_data(hdev, job);
+
+ return status;
+}
+
+
+/* bsg dispatch user command */
+static int sssraid_bsg_host_dispatch(struct bsg_job *job)
+{
+ struct Scsi_Host *shost = dev_to_shost(job->dev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ struct request *rq = blk_mq_rq_from_pdu(job);
+ struct sssraid_bsg_request *bsg_req = job->request;
+ int ret = -ENOMSG;
+
+ job->reply_len = 0;
+
+ if (bsg_req == NULL || job->request_len != sizeof(struct sssraid_bsg_request)) {
+ bsg_job_done(job, ret, 0);
+ return 0;
+ }
+ dbgprint(hdev, "bsg msgcode[%d] msglen[%d] timeout[%d];"
+ "reqnsge[%d], reqlen[%d]\n",
+ bsg_req->msgcode, job->request_len, rq->timeout,
+ job->request_payload.sg_cnt, job->request_payload.payload_len);
+
+ switch (bsg_req->msgcode) {
+ case SSSRAID_BSG_ADM:
+ ret = sssraid_user_admin_cmd(hdev, job);
+ break;
+ case SSSRAID_BSG_IOQ:
+ ret = sssraid_user_ioq_cmd(hdev, job);
+ break;
+ default:
+ ioc_info(hdev, "unsupport msgcode[%d]\n", bsg_req->msgcode);
+ break;
+ }
+
+ if (ret > 0)
+ ret = ret | (ret << 8);
+
+ bsg_job_done(job, ret, 0);
+ return 0;
+}
+
+static inline void sssraid_remove_bsg(struct sssraid_dev *hdev)
+{
+ if (hdev->bsg_queue) {
+ bsg_unregister_queue(hdev->bsg_queue);
+ blk_cleanup_queue(hdev->bsg_queue);
+ }
+}
+
+static void sssraid_back_fault_cqe(struct sssraid_squeue *sqinfo, struct sssraid_completion *cqe)
+{
+ struct sssraid_dev *hdev = sqinfo->hdev;
+ struct blk_mq_tags *tags;
+ struct scsi_cmnd *scmd;
+ struct sssraid_iod *iod;
+ struct request *req;
+
+ tags = hdev->shost->tag_set.tags[sqinfo->qidx - 1];
+ req = blk_mq_tag_to_rq(tags, le16_to_cpu(cqe->cmd_id));
+ if (unlikely(!req || !blk_mq_request_started(req)))
+ return;
+
+ scmd = blk_mq_rq_to_pdu(req);
+ iod = scsi_cmd_priv(scmd);
+
+ if (READ_ONCE(iod->state) != SSSRAID_CMD_IN_FLIGHT &&
+ READ_ONCE(iod->state) != SSSRAID_CMD_TIMEOUT)
+ return;
+
+ WRITE_ONCE(iod->state, SSSRAID_CMD_TMO_COMPLETE);
+ set_host_byte(scmd, DID_NO_CONNECT);
+ if (iod->nsge)
+ scsi_dma_unmap(scmd);
+ sssraid_free_iod_res(hdev, iod);
+ scmd->scsi_done(scmd);
+ ioc_warn(hdev, "Back fault CQE, cid[%d] qidx[%d]\n",
+ le16_to_cpu(cqe->cmd_id), sqinfo->qidx);
+}
+
+void sssraid_back_all_io(struct sssraid_dev *hdev)
+{
+ int i, j;
+ struct sssraid_squeue *sqinfo;
+ struct sssraid_completion cqe = { 0 };
+
+ scsi_block_requests(hdev->shost);
+
+ for (i = 1; i <= hdev->shost->nr_hw_queues; i++) {
+ sqinfo = &hdev->sqinfo[i];
+ for (j = 0; j < hdev->scsi_qd; j++) {
+ cqe.cmd_id = cpu_to_le16(j);
+ sssraid_back_fault_cqe(sqinfo, &cqe);
+ }
+ }
+
+ scsi_unblock_requests(hdev->shost);
+
+ j = SSSRAID_AQ_BLK_MQ_DEPTH;
+ for (i = 0; i < j; i++) {
+ if (READ_ONCE(hdev->adm_cmds[i].state) == SSSRAID_CMD_IN_FLIGHT) {
+ ioc_info(hdev, "Back adm, cid[%d]\n", i);
+ hdev->adm_cmds[i].status = 0xFFFF;
+ WRITE_ONCE(hdev->adm_cmds[i].state, SSSRAID_CMD_COMPLETE);
+ complete(&(hdev->adm_cmds[i].cmd_done));
+ }
+ }
+
+ j = SSSRAID_NR_IOQ_PTCMDS;
+ for (i = 0; i < j; i++) {
+ if (READ_ONCE(hdev->ioq_ptcmds[i].state) == SSSRAID_CMD_IN_FLIGHT) {
+ hdev->ioq_ptcmds[i].status = 0xFFFF;
+ WRITE_ONCE(hdev->ioq_ptcmds[i].state, SSSRAID_CMD_COMPLETE);
+ complete(&(hdev->ioq_ptcmds[i].cmd_done));
+ }
+ }
+}
+
+/**
+ * static struct scsi_host_template sssraid_driver_template
+ */
+static int sssraid_scan_finished(struct Scsi_Host *shost,
+ unsigned long time)
+{
+ struct sssraid_dev *hdev = shost_priv(shost);
+
+ sssraid_scan_disk(hdev);
+
+ return 1;
+}
+
+/* eh_target_reset_handler call back */
+static int sssraid_eh_target_reset(struct scsi_cmnd *scmd)
+{
+ return sssraid_scsi_reset(scmd, SSSRAID_RESET_TARGET);
+}
+
+/* eh_bus_reset_handler call back */
+static int sssraid_bus_reset_handler(struct scsi_cmnd *scmd)
+{
+ return sssraid_scsi_reset(scmd, SSSRAID_RESET_BUS);
+}
+
+/* eh_host_reset_handler call back */
+static int sssraid_eh_host_reset(struct scsi_cmnd *scmd)
+{
+ u16 hwq, cid;
+ struct sssraid_dev *hdev = shost_priv(scmd->device->host);
+
+ scsi_print_command(scmd);
+ if (hdev->state != SSSRAID_LIVE || sssraid_check_scmd_completed(scmd))
+ return SUCCESS;
+
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+ ioc_warn(hdev, "cid[%d] qidx[%d] host reset\n", cid, hwq);
+
+ /* It's useless:
+ * old code sssraid_reset_work_sync
+ * queue_work(reset_work) at first,
+ * then flush_work to synchronize.
+ */
+ if (!sssraid_change_host_state(hdev, SSSRAID_RESETTING)) {
+ ioc_info(hdev, "can't change to reset state\n");
+ return FAILED;
+ }
+ if (sssraid_soft_reset_handler(hdev)) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] host reset failed\n", cid, hwq);
+ return FAILED;
+ }
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] host reset success\n", cid, hwq);
+
+ return SUCCESS;
+}
+
+/* host_reset call back */
+static int sssraid_sysfs_host_reset(struct Scsi_Host *shost, int reset_type)
+{
+ int ret;
+ struct sssraid_dev *hdev = shost_priv(shost);
+
+ ioc_info(hdev, "start sysfs host reset cmd\n");
+ if (!sssraid_change_host_state(hdev, SSSRAID_RESETTING)) {
+ ioc_info(hdev, "can't change to reset state\n");
+ return -EBUSY;
+ }
+ ret = sssraid_soft_reset_handler(hdev);
+ ioc_info(hdev, "stop sysfs host reset cmd[%d]\n", ret);
+
+ return ret;
+}
+
+/* queuecommand call back */
+static int sssraid_qcmd(struct Scsi_Host *shost,
+ struct scsi_cmnd *scmd)
+{
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ struct scsi_device *sdev = scmd->device;
+ struct sssraid_sdev_hostdata *hostdata = sdev->hostdata;
+ u16 hwq, cid;
+ struct sssraid_squeue *sq;
+ struct sssraid_ioq_command ioq_cmd;
+ int retval;
+
+ if (unlikely(hdev->state == SSSRAID_RESETTING))
+ return SCSI_MLQUEUE_HOST_BUSY;
+
+ if (unlikely(hdev->state != SSSRAID_LIVE)) {
+ set_host_byte(scmd, DID_NO_CONNECT);
+ scmd->scsi_done(scmd);
+ return 0;
+ }
+
+ if (unlikely(hdev->logging_level & SSSRAID_DEBUG))
+ scsi_print_command(scmd);
+
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+ hostdata = sdev->hostdata;
+ sq = &hdev->sqinfo[hwq];
+
+ memset(&ioq_cmd, 0, sizeof(ioq_cmd));
+ ioq_cmd.rw.hdid = cpu_to_le32(hostdata->hdid);
+ ioq_cmd.rw.command_id = cpu_to_le16(cid);
+
+ retval = sssraid_setup_ioq_cmd(hdev, &ioq_cmd, scmd);
+ if (unlikely(retval)) {
+ set_host_byte(scmd, DID_ERROR);
+ scmd->scsi_done(scmd);
+ return 0;
+ }
+
+ iod->sense = sq->sense + retval;
+ iod->sense_dma = sq->sense_dma_addr + retval;
+ ioq_cmd.common.sense_addr = cpu_to_le64(iod->sense_dma);
+ ioq_cmd.common.sense_len = cpu_to_le16(SCSI_SENSE_BUFFERSIZE);
+
+ sssraid_init_iod(iod);
+
+ iod->sqinfo = sq;
+ sssraid_io_map_data(hdev, iod, scmd, &ioq_cmd);
+ if (unlikely(retval)) {
+ ioc_err(hdev, "sssraid_io_map_data Err.\n");
+ set_host_byte(scmd, DID_ERROR);
+ scmd->scsi_done(scmd);
+ retval = 0;
+ goto deinit_iod;
+ }
+
+ WRITE_ONCE(iod->state, SSSRAID_CMD_IN_FLIGHT);
+ sssraid_submit_cmd(sq, &ioq_cmd);
+
+ return 0;
+
+deinit_iod:
+ sssraid_free_iod_res(hdev, iod);
+ return retval;
+}
+
+/* change_queue_depth call back:
+ * keep as old
+ */
+
+/* slave_configure call back */
+static int sssraid_slave_configure(struct scsi_device *sdev)
+{
+ int qd = MAX_CMD_PER_DEV;
+ unsigned int timeout = scmd_tmout_rawdisk * HZ;
+ struct sssraid_dev *hdev = shost_priv(sdev->host);
+ struct sssraid_sdev_hostdata *hostdata = sdev->hostdata;
+ u32 max_sec = sdev->host->max_sectors;
+
+ if (hostdata) {
+ if (SSSRAID_DEV_INFO_ATTR_VD(hostdata->attr))
+ timeout = scmd_tmout_vd * HZ;
+ else if (SSSRAID_DEV_INFO_ATTR_RAWDISK(hostdata->attr))
+ timeout = scmd_tmout_rawdisk * HZ;
+ max_sec = hostdata->max_io_kb << 1;
+ qd = sssraid_get_qd_by_disk(hostdata->attr);
+ } else {
+ ioc_err(hdev, "err, sdev->hostdata is null\n");
+ }
+
+ blk_queue_rq_timeout(sdev->request_queue, timeout);
+ sdev->eh_timeout = timeout;
+ scsi_change_queue_depth(sdev, qd);
+
+ if ((max_sec == 0) || (max_sec > sdev->host->max_sectors))
+ max_sec = sdev->host->max_sectors;
+
+ blk_queue_max_hw_sectors(sdev->request_queue, max_sec);
+
+ ioc_info(hdev, "sdev->channel:id:lun[%d:%d:%lld], scmd_timeout[%d]s, maxsec[%d]\n",
+ sdev->channel, sdev->id, sdev->lun, timeout / HZ, max_sec);
+
+ return 0;
+}
+
+/* slave_alloc call back */
+static int sssraid_slave_alloc(struct scsi_device *sdev)
+{
+ struct sssraid_sdev_hostdata *hostdata;
+ struct sssraid_dev *hdev;
+ u16 idx;
+
+ hdev = shost_priv(sdev->host);
+ hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL);
+ if (!hostdata) {
+ ioc_err(hdev, "Alloc scsi host data memory failed\n");
+ return -ENOMEM;
+ }
+
+ down_read(&hdev->devices_rwsem);
+ for (idx = 0; idx < le32_to_cpu(hdev->ctrl_info->nd); idx++) {
+ if (sssraid_match_dev(hdev, idx, sdev))
+ goto scan_host;
+ }
+ up_read(&hdev->devices_rwsem);
+
+ kfree(hostdata);
+ return -ENXIO;
+
+scan_host:
+ hostdata->hdid = le32_to_cpu(hdev->devices[idx].hdid);
+ hostdata->max_io_kb = le16_to_cpu(hdev->devices[idx].max_io_kb);
+ hostdata->attr = hdev->devices[idx].attr;
+ hostdata->flag = hdev->devices[idx].flag;
+ hostdata->rg_id = 0xff;
+ sdev->hostdata = hostdata;
+ up_read(&hdev->devices_rwsem);
+ return 0;
+}
+
+/* slave_destroy call back */
+static void sssraid_slave_destroy(struct scsi_device *sdev)
+{
+ kfree(sdev->hostdata);
+ sdev->hostdata = NULL;
+}
+
+/* eh_timed_out call back */
+static enum blk_eh_timer_return sssraid_scmd_timeout(struct scsi_cmnd *scmd)
+{
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ unsigned int timeout = scmd->device->request_queue->rq_timeout;
+
+ if (sssraid_check_scmd_completed(scmd))
+ goto out;
+
+ if (time_after(jiffies, scmd->jiffies_at_alloc + timeout)) {
+ if (cmpxchg(&iod->state, SSSRAID_CMD_IN_FLIGHT, SSSRAID_CMD_TIMEOUT) ==
+ SSSRAID_CMD_IN_FLIGHT) {
+ return BLK_EH_DONE;
+ }
+ }
+out:
+ return BLK_EH_RESET_TIMER;
+}
+
+/* eh_abort_handler call back */
+static int sssraid_abort_handler(struct scsi_cmnd *scmd)
+{
+ struct sssraid_dev *hdev = shost_priv(scmd->device->host);
+ struct sssraid_iod *iod = scsi_cmd_priv(scmd);
+ struct sssraid_sdev_hostdata *hostdata;
+ u16 hwq, cid;
+ int ret;
+
+ scsi_print_command(scmd);
+
+ if (hdev->state != SSSRAID_LIVE || !sssraid_wait_abnl_cmd_done(iod) ||
+ sssraid_check_scmd_completed(scmd))
+ return SUCCESS;
+
+ hostdata = scmd->device->hostdata;
+ sssraid_get_tag_from_scmd(scmd, &hwq, &cid);
+
+ ioc_warn(hdev, "cid[%d] qidx[%d] timeout, aborting\n", cid, hwq);
+ ret = sssraid_send_abort_cmd(hdev, hostdata->hdid, hwq, cid);
+ if (ret != -ETIME) {
+ ret = sssraid_wait_abnl_cmd_done(iod);
+ if (ret) {
+ ioc_warn(hdev, "cid[%d] qidx[%d] abort failed, not found\n", cid, hwq);
+ return FAILED;
+ }
+ ioc_warn(hdev, "cid[%d] qidx[%d] abort succ\n", cid, hwq);
+ return SUCCESS;
+ }
+ ioc_warn(hdev, "cid[%d] qidx[%d] abort failed, timeout\n", cid, hwq);
+ return FAILED;
+}
+
+static ssize_t csts_pp_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ int ret = -1;
+
+ if (pci_device_is_present(hdev->pdev)) {
+ ret = (readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_PP_MASK);
+ ret >>= SSSRAID_CSTS_PP_SHIFT;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t csts_shst_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ int ret = -1;
+
+ if (pci_device_is_present(hdev->pdev)) {
+ ret = (readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_SHST_MASK);
+ ret >>= SSSRAID_CSTS_SHST_SHIFT;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t csts_cfs_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ int ret = -1;
+
+ if (pci_device_is_present(hdev->pdev)) {
+ ret = (readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_CFS_MASK);
+ ret >>= SSSRAID_CSTS_CFS_SHIFT;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t csts_rdy_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+ int ret = -1;
+
+ if (pci_device_is_present(hdev->pdev))
+ ret = (readl(hdev->bar + SSSRAID_REG_CSTS) & SSSRAID_CSTS_RDY);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+static ssize_t fw_version_show(struct device *cdev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sssraid_dev *hdev = shost_priv(shost);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", hdev->ctrl_info->fr);
+}
+
+static DEVICE_ATTR_RO(csts_pp);
+static DEVICE_ATTR_RO(csts_shst);
+static DEVICE_ATTR_RO(csts_cfs);
+static DEVICE_ATTR_RO(csts_rdy);
+static DEVICE_ATTR_RO(fw_version);
+
+static struct device_attribute *sssraid_host_attrs[] = {
+ &dev_attr_csts_pp,
+ &dev_attr_csts_shst,
+ &dev_attr_csts_cfs,
+ &dev_attr_csts_rdy,
+ &dev_attr_fw_version,
+ NULL,
+};
+
+static int sssraid_get_vd_info(struct sssraid_dev *hdev, struct sssraid_vd_info *vd_info, u16 vid)
+{
+ struct sssraid_admin_command admin_cmd;
+ u8 *data_ptr = NULL;
+ dma_addr_t data_dma = 0;
+ int ret;
+
+ if (hdev->state >= SSSRAID_RESETTING) {
+ ioc_err(hdev, "err, host state[%d] is not right\n", hdev->state);
+ return -EBUSY;
+ }
+
+ data_ptr = dma_alloc_coherent(&hdev->pdev->dev, PAGE_SIZE, &data_dma, GFP_KERNEL);
+ if (!data_ptr)
+ return -ENOMEM;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.usr_cmd.opcode = USR_CMD_READ;
+ admin_cmd.usr_cmd.info_0.subopcode = cpu_to_le16(USR_CMD_VDINFO);
+ admin_cmd.usr_cmd.info_1.data_len = cpu_to_le16(USR_CMD_RDLEN);
+ admin_cmd.usr_cmd.info_1.param_len = cpu_to_le16(VDINFO_PARAM_LEN);
+ admin_cmd.usr_cmd.cdw10 = cpu_to_le32(vid);
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ ret = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+ if (!ret)
+ memcpy(vd_info, data_ptr, sizeof(struct sssraid_vd_info));
+
+ dma_free_coherent(&hdev->pdev->dev, PAGE_SIZE, data_ptr, data_dma);
+
+ return ret;
+}
+
+static int sssraid_get_bgtask(struct sssraid_dev *hdev, struct sssraid_bgtask *bgtask)
+{
+ struct sssraid_admin_command admin_cmd;
+ u8 *data_ptr = NULL;
+ dma_addr_t data_dma = 0;
+ int ret;
+
+ if (hdev->state >= SSSRAID_RESETTING) {
+ ioc_err(hdev, "err, host state[%d] is not right\n", hdev->state);
+ return -EBUSY;
+ }
+
+ data_ptr = dma_alloc_coherent(&hdev->pdev->dev, PAGE_SIZE, &data_dma, GFP_KERNEL);
+ if (!data_ptr)
+ return -ENOMEM;
+
+ memset(&admin_cmd, 0, sizeof(admin_cmd));
+ admin_cmd.usr_cmd.opcode = USR_CMD_READ;
+ admin_cmd.usr_cmd.info_0.subopcode = cpu_to_le16(USR_CMD_BGTASK);
+ admin_cmd.usr_cmd.info_1.data_len = cpu_to_le16(USR_CMD_RDLEN);
+ admin_cmd.common.dptr.prp1 = cpu_to_le64(data_dma);
+
+ ret = sssraid_submit_admin_sync_cmd(hdev, &admin_cmd, NULL, NULL, 0);
+ if (!ret)
+ memcpy(bgtask, data_ptr, sizeof(struct sssraid_bgtask));
+
+ dma_free_coherent(&hdev->pdev->dev, PAGE_SIZE, data_ptr, data_dma);
+
+ return ret;
+}
+
+static ssize_t raid_level_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev;
+ struct sssraid_dev *hdev;
+ struct sssraid_vd_info *vd_info;
+ struct sssraid_sdev_hostdata *hostdata;
+ int ret;
+
+ sdev = to_scsi_device(dev);
+ hdev = shost_priv(sdev->host);
+ hostdata = sdev->hostdata;
+
+ vd_info = kmalloc(sizeof(*vd_info), GFP_KERNEL);
+ if (!vd_info || !SSSRAID_DEV_INFO_ATTR_VD(hostdata->attr))
+ return snprintf(buf, PAGE_SIZE, "NA\n");
+
+ ret = sssraid_get_vd_info(hdev, vd_info, sdev->id);
+ if (ret)
+ vd_info->rg_level = ARRAY_SIZE(raid_levels) - 1;
+
+ ret = (vd_info->rg_level < ARRAY_SIZE(raid_levels)) ?
+ vd_info->rg_level : (ARRAY_SIZE(raid_levels) - 1);
+
+ kfree(vd_info);
+
+ return snprintf(buf, PAGE_SIZE, "RAID-%s\n", raid_levels[ret]);
+}
+
+static ssize_t raid_state_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev;
+ struct sssraid_dev *hdev;
+ struct sssraid_vd_info *vd_info;
+ struct sssraid_sdev_hostdata *hostdata;
+ int ret;
+
+ sdev = to_scsi_device(dev);
+ hdev = shost_priv(sdev->host);
+ hostdata = sdev->hostdata;
+
+ vd_info = kmalloc(sizeof(*vd_info), GFP_KERNEL);
+ if (!vd_info || !SSSRAID_DEV_INFO_ATTR_VD(hostdata->attr))
+ return snprintf(buf, PAGE_SIZE, "NA\n");
+
+ ret = sssraid_get_vd_info(hdev, vd_info, sdev->id);
+ if (ret) {
+ vd_info->vd_status = 0;
+ vd_info->rg_id = 0xff;
+ }
+
+ ret = (vd_info->vd_status < ARRAY_SIZE(raid_states)) ? vd_info->vd_status : 0;
+
+ kfree(vd_info);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", raid_states[ret]);
+}
+
+static ssize_t raid_resync_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev;
+ struct sssraid_dev *hdev;
+ struct sssraid_vd_info *vd_info;
+ struct sssraid_bgtask *bgtask;
+ struct sssraid_sdev_hostdata *hostdata;
+ u8 rg_id, i, progress = 0;
+ int ret;
+
+ sdev = to_scsi_device(dev);
+ hdev = shost_priv(sdev->host);
+ hostdata = sdev->hostdata;
+
+ vd_info = kmalloc(sizeof(*vd_info), GFP_KERNEL);
+ if (!vd_info || !SSSRAID_DEV_INFO_ATTR_VD(hostdata->attr))
+ return snprintf(buf, PAGE_SIZE, "NA\n");
+
+ ret = sssraid_get_vd_info(hdev, vd_info, sdev->id);
+ if (ret)
+ goto out;
+
+ rg_id = vd_info->rg_id;
+
+ bgtask = (struct sssraid_bgtask *)vd_info;
+ ret = sssraid_get_bgtask(hdev, bgtask);
+ if (ret)
+ goto out;
+ for (i = 0; i < bgtask->task_num; i++) {
+ if ((bgtask->bgtask[i].type == BGTASK_TYPE_REBUILD) &&
+ (le16_to_cpu(bgtask->bgtask[i].vd_id) == rg_id))
+ progress = bgtask->bgtask[i].progress;
+ }
+
+out:
+ kfree(vd_info);
+ return snprintf(buf, PAGE_SIZE, "%d\n", progress);
+}
+
+static DEVICE_ATTR_RO(raid_level);
+static DEVICE_ATTR_RO(raid_state);
+static DEVICE_ATTR_RO(raid_resync);
+
+static struct device_attribute *sssraid_dev_attrs[] = {
+ &dev_attr_raid_level,
+ &dev_attr_raid_state,
+ &dev_attr_raid_resync,
+ NULL,
+};
+
+static struct scsi_host_template sssraid_driver_template = {
+ .module = THIS_MODULE,
+ .name = "3SNIC Logic sssraid driver",
+ .proc_name = "sssraid",
+ .queuecommand = sssraid_qcmd,
+ .slave_alloc = sssraid_slave_alloc,
+ .slave_destroy = sssraid_slave_destroy,
+ .slave_configure = sssraid_slave_configure,
+ .scan_finished = sssraid_scan_finished,
+ .eh_timed_out = sssraid_scmd_timeout,
+ .eh_abort_handler = sssraid_abort_handler,
+ .eh_target_reset_handler = sssraid_eh_target_reset,
+ .eh_bus_reset_handler = sssraid_bus_reset_handler,
+ .eh_host_reset_handler = sssraid_eh_host_reset,
+ .change_queue_depth = scsi_change_queue_depth,
+ .host_tagset = 0,
+ .this_id = -1,
+ .unchecked_isa_dma = 0,
+ .shost_attrs = sssraid_host_attrs,
+ .sdev_attrs = sssraid_dev_attrs,
+ .host_reset = sssraid_sysfs_host_reset,
+};
+
+/**
+ * sssraid_probe - PCI probe callback
+ * @pdev: PCI device instance
+ * @id: PCI device ID details
+ *
+ * controller initialization routine.
+ * Allocate per adapter instance through shost_priv and
+ * initialize controller specific data structures, initializae
+ * the controller hardware, add shost to the SCSI subsystem.
+ *
+ * Return: 0 on success, non-zero on failure.
+ */
+
+static int
+sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct sssraid_dev *hdev;
+ struct Scsi_Host *shost;
+ int node;
+ char bsg_name[15];
+ int retval = 0;
+
+ node = dev_to_node(&pdev->dev);
+ if (node == NUMA_NO_NODE) {
+ node = first_memory_node;
+ set_dev_node(&pdev->dev, node);
+ }
+
+ shost = scsi_host_alloc(&sssraid_driver_template, sizeof(*hdev));
+ if (!shost) {
+ retval = -ENODEV;
+ ioc_err(hdev, "Failed to allocate scsi host\n");
+ goto shost_failed;
+ }
+
+ hdev = shost_priv(shost);
+ hdev->numa_node = node;
+ hdev->instance = shost->host_no; /* for device instance */
+ sprintf(hdev->name, "%s%d", SSSRAID_DRIVER_NAME, hdev->instance);
+
+ init_rwsem(&hdev->devices_rwsem);
+ spin_lock_init(&hdev->state_lock);
+
+ spin_lock_init(&hdev->fwevt_lock);
+ spin_lock_init(&hdev->watchdog_lock);
+
+ INIT_LIST_HEAD(&hdev->fwevt_list);
+
+// logging_level = 1; //garden test
+ hdev->logging_level = logging_level; /* according to log_debug_switch*/
+
+ snprintf(hdev->fwevt_worker_name, sizeof(hdev->fwevt_worker_name),
+ "%s%d_fwevt_wrkr", SSSRAID_DRIVER_NAME, hdev->instance);
+ hdev->fwevt_worker_thread = alloc_ordered_workqueue(
+ hdev->fwevt_worker_name, WQ_MEM_RECLAIM);
+ if (!hdev->fwevt_worker_thread) {
+ ioc_err(hdev, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
+ retval = -ENODEV;
+ goto out_fwevtthread_failed;
+ }
+
+ hdev->shost = shost;
+ hdev->pdev = pdev;
+
+ if (sssraid_init_ioc(hdev, 0)) {
+ ioc_err(hdev, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
+ retval = -ENODEV;
+ goto out_iocinit_failed;
+ }
+
+ sssraid_shost_init(hdev);
+
+ retval = scsi_add_host(shost, &pdev->dev);
+ if (retval) {
+ ioc_err(hdev, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
+ goto addhost_failed;
+ }
+
+ snprintf(bsg_name, sizeof(bsg_name), "%s%d", SSSRAID_DRIVER_NAME, shost->host_no);
+ hdev->bsg_queue = bsg_setup_queue(&shost->shost_gendev, bsg_name,
+ sssraid_bsg_host_dispatch, NULL, sssraid_cmd_size(hdev));
+ if (IS_ERR(hdev->bsg_queue)) {
+ ioc_err(hdev, "err, setup bsg failed\n");
+ hdev->bsg_queue = NULL;
+ goto bsg_setup_failed;
+ }
+
+ sssraid_change_host_state(hdev, SSSRAID_LIVE);
+
+ scsi_scan_host(shost);
+ return retval;
+
+bsg_setup_failed:
+ scsi_remove_host(shost);
+addhost_failed:
+ sssraid_cleanup_ioc(hdev, 0);
+out_iocinit_failed:
+ destroy_workqueue(hdev->fwevt_worker_thread);
+out_fwevtthread_failed:
+ scsi_host_put(shost);
+shost_failed:
+ return retval;
+}
+
+static void sssraid_remove(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return;
+
+ ioc_info(hdev, "enter sssraid remove\n");
+
+ hdev = shost_priv(shost);
+
+ sssraid_change_host_state(hdev, SSSRAID_DELETING);
+
+ if (!pci_device_is_present(pdev))
+ sssraid_back_all_io(hdev);
+
+ sssraid_cleanup_fwevt_list(hdev);
+ destroy_workqueue(hdev->fwevt_worker_thread);
+
+ sssraid_remove_bsg(hdev);
+ scsi_remove_host(shost);
+ sssraid_cleanup_ioc(hdev, 0);
+
+ scsi_host_put(shost);
+}
+
+static void sssraid_shutdown(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return;
+
+ hdev = shost_priv(shost);
+
+ sssraid_cleanup_fwevt_list(hdev);
+ destroy_workqueue(hdev->fwevt_worker_thread);
+ sssraid_cleanup_ioc(hdev, 0);
+}
+
+#ifdef CONFIG_PM
+static int sssraid_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+ pci_power_t device_state;
+
+ if (!shost)
+ return 0;
+
+ hdev = shost_priv(shost);
+
+ while (hdev->state == SSSRAID_RESETTING)
+ ssleep(1);
+ sssraid_cleanup_fwevt_list(hdev);
+ scsi_block_requests(shost);
+ sssraid_cleanup_ioc(hdev, 1);
+
+ device_state = pci_choose_state(pdev, state);
+ pci_save_state(pdev);
+ pci_set_power_state(pdev, device_state);
+
+ return 0;
+}
+
+static int sssraid_resume(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+ pci_power_t device_state = pdev->current_state;
+
+ if (!shost)
+ return 0;
+
+ hdev = shost_priv(shost);
+
+ ioc_info(hdev, "pdev=0x%p, slot=%s, previous operating state [D%d]\n",
+ pdev, pci_name(pdev), device_state);
+ pci_set_power_state(pdev, PCI_D0);
+ pci_enable_wake(pdev, PCI_D0, 0);
+ pci_restore_state(pdev);
+ hdev->pdev = pdev;
+ hdev->cpu_count = num_online_cpus();
+
+ /* sssraid_setup_resources in sssraid_init_ioc */
+ sssraid_init_ioc(hdev, 1);
+ scsi_unblock_requests(shost);
+
+ return 0;
+}
+#endif
+
+static pci_ers_result_t sssraid_pci_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return PCI_ERS_RESULT_NONE;
+
+ hdev = shost_priv(shost);
+
+ ioc_info(hdev, "enter pci error detect, state:%d\n", state);
+
+ switch (state) {
+ case pci_channel_io_normal:
+ ioc_warn(hdev, "channel is normal, do nothing\n");
+
+ return PCI_ERS_RESULT_CAN_RECOVER;
+ case pci_channel_io_frozen:
+ ioc_warn(hdev, "channel io frozen, need reset controller\n");
+
+ scsi_block_requests(hdev->shost);
+
+ sssraid_change_host_state(hdev, SSSRAID_RESETTING);
+
+ return PCI_ERS_RESULT_NEED_RESET;
+ case pci_channel_io_perm_failure:
+ ioc_warn(hdev, "channel io failure, request disconnect\n");
+
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t sssraid_pci_slot_reset(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return PCI_ERS_RESULT_NONE;
+
+ hdev = shost_priv(shost);
+
+ ioc_info(hdev, "restart after slot reset\n");
+
+ pci_restore_state(pdev);
+
+ sssraid_soft_reset_handler(hdev);
+
+ scsi_unblock_requests(hdev->shost);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void sssraid_reset_done(struct pci_dev *pdev)
+{
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct sssraid_dev *hdev;
+
+ if (!shost)
+ return;
+
+ hdev = shost_priv(shost);
+
+ ioc_info(hdev, "enter sssraid reset done\n");
+}
+
+static struct pci_error_handlers sssraid_err_handler = {
+ .error_detected = sssraid_pci_error_detected,
+ .slot_reset = sssraid_pci_slot_reset,
+ .reset_done = sssraid_reset_done,
+};
+
+static const struct pci_device_id sssraid_pci_id_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_3SNIC_LOGIC, SSSRAID_SERVER_DEVICE_HBA_DID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_3SNIC_LOGIC, SSSRAID_SERVER_DEVICE_RAID_DID) },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, sssraid_pci_id_table);
+
+static struct pci_driver sssraid_pci_driver = {
+ .name = SSSRAID_DRIVER_NAME,
+ .id_table = sssraid_pci_id_table,
+ .probe = sssraid_probe,
+ .remove = sssraid_remove,
+ .shutdown = sssraid_shutdown,
+#ifdef CONFIG_PM
+ .suspend = sssraid_suspend,
+ .resume = sssraid_resume,
+#endif
+ .err_handler = &sssraid_err_handler,
+};
+
+static int __init sssraid_init(void)
+{
+ int ret_val;
+
+ pr_info("Loading %s version %s\n", SSSRAID_DRIVER_NAME,
+ SSSRAID_DRIVER_VERSION);
+
+ sssraid_class = class_create(THIS_MODULE, "sssraid");
+ if (IS_ERR(sssraid_class)) {
+ ret_val = PTR_ERR(sssraid_class);
+ return ret_val;
+ }
+
+ ret_val = pci_register_driver(&sssraid_pci_driver);
+
+ return ret_val;
+}
+
+static void __exit sssraid_exit(void)
+{
+ pr_info("Unloading %s version %s\n", SSSRAID_DRIVER_NAME,
+ SSSRAID_DRIVER_VERSION);
+
+ class_destroy(sssraid_class);
+ pci_unregister_driver(&sssraid_pci_driver);
+}
+
+MODULE_AUTHOR("liangry1(a)3snic.com");
+MODULE_DESCRIPTION("3SNIC Information Technology SSSRAID Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(SSSRAID_DRIVER_VERSION);
+module_init(sssraid_init);
+module_exit(sssraid_exit);
--
2.25.1
2
1

[PATCH openEuler-5.10-LTS] wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_CHANNEL_LIST attribute
by Zheng Zengkai 28 Dec '22
by Zheng Zengkai 28 Dec '22
28 Dec '22
From: Phil Turnbull <philipturnbull(a)github.com>
stable inclusion
from stable-v5.10.157
commit 5a068535c0073c8402aa0755e8ef259fb98a33c5
category: bugfix
bugzilla: 188173 https://gitee.com/src-openeuler/kernel/issues/I66M3J
CVE: CVE-2022-47521
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit f9b62f9843c7b0afdaecabbcebf1dbba18599408 upstream.
Validate that the IEEE80211_P2P_ATTR_CHANNEL_LIST attribute contains
enough space for a 'struct wilc_attr_oper_ch'. If the attribute is too
small then it can trigger an out-of-bounds write later in the function.
'struct wilc_attr_oper_ch' is variable sized so also check 'attr_len'
does not extend beyond the end of 'buf'.
Signed-off-by: Phil Turnbull <philipturnbull(a)github.com>
Tested-by: Ajay Kathat <ajay.kathat(a)microchip.com>
Acked-by: Ajay Kathat <ajay.kathat(a)microchip.com>
Signed-off-by: Kalle Valo <kvalo(a)kernel.org>
Link: https://lore.kernel.org/r/20221123153543.8568-4-philipturnbull@github.com
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Liu Jian <liujian56(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com>
---
drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
index 64e01b84d98d..dd26f2086180 100644
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -947,7 +947,8 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
if (index + sizeof(*e) + attr_size > len)
return;
- if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
+ if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST &&
+ attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e)))
ch_list_idx = index;
else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
--
2.20.1
1
0

[PATCH openEuler-5.10-LTS 1/6] drm/amdkfd: Check for null pointer after calling kmemdup
by Zheng Zengkai 28 Dec '22
by Zheng Zengkai 28 Dec '22
28 Dec '22
From: Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
stable inclusion
from stable-v6.0.14
commit abfaf0eee97925905e742aa3b0b72e04a918fa9e
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6694U
CVE: CVE-2022-3108
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
As the possible failure of the allocation, kmemdup() may return NULL
pointer.
Therefore, it should be better to check the 'props2' in order to prevent
the dereference of NULL pointer.
Fixes: 3a87177eb141 ("drm/amdkfd: Add topology support for dGPUs")
Signed-off-by: Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
Reviewed-by: Felix Kuehling <Felix.Kuehling(a)amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling(a)amd.com>
Signed-off-by: Alex Deucher <alexander.deucher(a)amd.com>
Signed-off-by: Ren Zhijie <renzhijie2(a)huawei.com>
Reviewed-by: songping yu <yusongping(a)huawei.com>
Reviewed-by: Chen Hui <judy.chenhui(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
index 86b4dadf772e..02e3c650ed1c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
@@ -408,6 +408,9 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink,
return -ENODEV;
/* same everything but the other direction */
props2 = kmemdup(props, sizeof(*props2), GFP_KERNEL);
+ if (!props2)
+ return -ENOMEM;
+
props2->node_from = id_to;
props2->node_to = id_from;
props2->kobj = NULL;
--
2.20.1
1
5

[PATCH openEuler-1.0-LTS] dm thin: Use last transaction's pmd->root when commit failed
by Yongqiang Liu 27 Dec '22
by Yongqiang Liu 27 Dec '22
27 Dec '22
From: Zhihao Cheng <chengzhihao1(a)huawei.com>
mainline inclusion
from mainline-v6.2-rc1
commit 7991dbff6849f67e823b7cc0c15e5a90b0549b9f
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I65M32
CVE: NA
--------------------------------
Recently we found a softlock up problem in dm thin pool btree lookup
code due to corrupted metadata:
Kernel panic - not syncing: softlockup: hung tasks
CPU: 7 PID: 2669225 Comm: kworker/u16:3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
Workqueue: dm-thin do_worker [dm_thin_pool]
Call Trace:
<IRQ>
dump_stack+0x9c/0xd3
panic+0x35d/0x6b9
watchdog_timer_fn.cold+0x16/0x25
__run_hrtimer+0xa2/0x2d0
</IRQ>
RIP: 0010:__relink_lru+0x102/0x220 [dm_bufio]
__bufio_new+0x11f/0x4f0 [dm_bufio]
new_read+0xa3/0x1e0 [dm_bufio]
dm_bm_read_lock+0x33/0xd0 [dm_persistent_data]
ro_step+0x63/0x100 [dm_persistent_data]
btree_lookup_raw.constprop.0+0x44/0x220 [dm_persistent_data]
dm_btree_lookup+0x16f/0x210 [dm_persistent_data]
dm_thin_find_block+0x12c/0x210 [dm_thin_pool]
__process_bio_read_only+0xc5/0x400 [dm_thin_pool]
process_thin_deferred_bios+0x1a4/0x4a0 [dm_thin_pool]
process_one_work+0x3c5/0x730
Following process may generate a broken btree mixed with fresh and
stale btree nodes, which could get dm thin trapped in an infinite loop
while looking up data block:
Transaction 1: pmd->root = A, A->B->C // One path in btree
pmd->root = X, X->Y->Z // Copy-up
Transaction 2: X,Z is updated on disk, Y write failed.
// Commit failed, dm thin becomes read-only.
process_bio_read_only
dm_thin_find_block
__find_block
dm_btree_lookup(pmd->root)
The pmd->root points to a broken btree, Y may contain stale node
pointing to any block, for example X, which gets dm thin trapped into
a dead loop while looking up Z.
Fix this by setting pmd->root in __open_metadata(), so that dm thin
will use the last transaction's pmd->root if commit failed.
Fetch a reproducer in [Link].
Linke: https://bugzilla.kernel.org/show_bug.cgi?id=216790
Cc: stable(a)vger.kernel.org
Fixes: 991d9fa02da0 ("dm: add thin provisioning target")
Signed-off-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Acked-by: Joe Thornber <ejt(a)redhat.com>
Signed-off-by: Mike Snitzer <snitzer(a)kernel.org>
Signed-off-by: Zhihao Cheng <chengzhihao1(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/md/dm-thin-metadata.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
index 80c4f27e99f9..26f04b84e8a2 100644
--- a/drivers/md/dm-thin-metadata.c
+++ b/drivers/md/dm-thin-metadata.c
@@ -660,6 +660,15 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
goto bad_cleanup_data_sm;
}
+ /*
+ * For pool metadata opening process, root setting is redundant
+ * because it will be set again in __begin_transaction(). But dm
+ * pool aborting process really needs to get last transaction's
+ * root to avoid accessing broken btree.
+ */
+ pmd->root = le64_to_cpu(disk_super->data_mapping_root);
+ pmd->details_root = le64_to_cpu(disk_super->device_details_root);
+
__setup_btree_details(pmd);
dm_bm_unlock(sblock);
--
2.25.1
1
0

[PATCH openEuler-5.10] timekeeping: Adding a padding before timekeeper in tk_core
by Zheng Zengkai 26 Dec '22
by Zheng Zengkai 26 Dec '22
26 Dec '22
From: Jialin Zhang <zhangjialin11(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I47W8L
CVE: NA
---------------------------
Adding a padding before timekeeper in tk_core can futhor fix
the false sharing problem discovered by commit 605276666775
("timekeeping: Avoiding false sharing in field access of tk_core")
context1 of unixbench is tested on Huawei Kunpeng920.
before this patch
0 CPUs in system; running 96 parallel copies of tests
Pipe-based Context Switching 17213571.7 lps (10.0 s, 1 samples)
System Benchmarks Partial Index BASELINE RESULT INDEX
Pipe-based Context Switching 4000.0 17213571.7 43033.9
========
System Benchmarks Index Score (Partial Only) 43033.9
after this patch
0 CPUs in system; running 96 parallel copies of tests
Pipe-based Context Switching 20321268.3 lps (10.0 s, 1 samples)
System Benchmarks Partial Index BASELINE RESULT INDEX
Pipe-based Context Switching 4000.0 20321268.3 50803.2
========
System Benchmarks Index Score (Partial Only) 50803.2
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
Reviewed-by: Xie XiuQi <xiexiuqi(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
kernel/time/timekeeping.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index e3142bf7648e..c8d9b89a7571 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -52,6 +52,9 @@ static struct {
u64 padding[8];
#endif
seqcount_raw_spinlock_t seq;
+#ifdef CONFIG_ARCH_LLC_128_LINE_SIZE
+ u64 padding2[2];
+#endif
struct timekeeper timekeeper;
#ifdef CONFIG_ARCH_LLC_128_LINE_SIZE
} tk_core ____cacheline_aligned_128 = {
--
2.20.1
1
0

[PATCH openEuler-5.10] timekeeping: Adding a padding before timekeeper in tk_core
by Zheng Zengkai 26 Dec '22
by Zheng Zengkai 26 Dec '22
26 Dec '22
From: Jialin Zhang <zhangjialin11(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I47W8L
CVE: NA
---------------------------
Adding a padding before timekeeper in tk_core can futhor fix
the false sharing problem discovered by commit 605276666775
("timekeeping: Avoiding false sharing in field access of tk_core")
context1 of unixbench is tested on Huawei Kunpeng920.
before this patch
0 CPUs in system; running 96 parallel copies of tests
Pipe-based Context Switching 17213571.7 lps (10.0 s, 1 samples)
System Benchmarks Partial Index BASELINE RESULT INDEX
Pipe-based Context Switching 4000.0 17213571.7 43033.9
========
System Benchmarks Index Score (Partial Only) 43033.9
after this patch
0 CPUs in system; running 96 parallel copies of tests
Pipe-based Context Switching 20321268.3 lps (10.0 s, 1 samples)
System Benchmarks Partial Index BASELINE RESULT INDEX
Pipe-based Context Switching 4000.0 20321268.3 50803.2
========
System Benchmarks Index Score (Partial Only) 50803.2
Signed-off-by: Jialin Zhang <zhangjialin11(a)huawei.com>
Reviewed-by: Xie XiuQi <xiexiuqi(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
kernel/time/timekeeping.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index e3142bf7648e..c8d9b89a7571 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -52,6 +52,9 @@ static struct {
u64 padding[8];
#endif
seqcount_raw_spinlock_t seq;
+#ifdef CONFIG_ARCH_LLC_128_LINE_SIZE
+ u64 padding2[2];
+#endif
struct timekeeper timekeeper;
#ifdef CONFIG_ARCH_LLC_128_LINE_SIZE
} tk_core ____cacheline_aligned_128 = {
--
2.20.1
1
0

[PATCH openEuler-1.0-LTS 1/2] power: supply: wm8350-power: Add missing free in free_charger_irq
by Yongqiang Liu 24 Dec '22
by Yongqiang Liu 24 Dec '22
24 Dec '22
From: Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
stable inclusion
from stable-v4.19.269
commit 60dd1082322966f192f42fe2a6605dfa08eef41f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6694F
CVE: CVE-2022-3111
--------------------------------
[ Upstream commit 6dee930f6f6776d1e5a7edf542c6863b47d9f078 ]
In free_charger_irq(), there is no free for 'WM8350_IRQ_CHG_FAST_RDY'.
Therefore, it should be better to add it in order to avoid the memory leak.
Fixes: 14431aa0c5a4 ("power_supply: Add support for WM8350 PMU")
Signed-off-by: Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
Acked-by: Charles Keepax <ckeepax(a)opensource.cirrus.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel(a)collabora.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Chen jun <chenjun102(a)huawei.com>
Reviewed-by: chenweilong <chenweilong(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/power/supply/wm8350_power.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/power/supply/wm8350_power.c b/drivers/power/supply/wm8350_power.c
index 15c0ca15e2aa..034ddfe3b62c 100644
--- a/drivers/power/supply/wm8350_power.c
+++ b/drivers/power/supply/wm8350_power.c
@@ -459,6 +459,7 @@ static void free_charger_irq(struct wm8350 *wm8350)
wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350);
wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350);
wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350);
+ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, wm8350);
wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350);
wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350);
wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350);
--
2.25.1
1
1

[PATCH openEuler-1.0-LTS] media: dvb-core: Fix UAF due to refcount races at releasing
by Yongqiang Liu 24 Dec '22
by Yongqiang Liu 24 Dec '22
24 Dec '22
From: Takashi Iwai <tiwai(a)suse.de>
stable inclusion
from stable-v6.1.1
commit fd3d91ab1c6ab0628fe642dd570b56302c30a792
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5SDE4
CVE: CVE-2022-41218
--------------------------------
The dvb-core tries to sync the releases of opened files at
dvb_dmxdev_release() with two refcounts: dvbdev->users and
dvr_dvbdev->users. A problem is present in those two syncs: when yet
another dvb_demux_open() is called during those sync waits,
dvb_demux_open() continues to process even if the device is being
closed. This includes the increment of the former refcount, resulting
in the leftover refcount after the sync of the latter refcount at
dvb_dmxdev_release(). It ends up with use-after-free, since the
function believes that all usages were gone and releases the
resources.
This patch addresses the problem by adding the check of dmxdev->exit
flag at dvb_demux_open(), just like dvb_dvr_open() already does. With
the exit flag check, the second call of dvb_demux_open() fails, hence
the further corruption can be avoided.
Also for avoiding the races of the dmxdev->exit flag reference, this
patch serializes the dmxdev->exit set up and the sync waits with the
dmxdev->mutex lock at dvb_dmxdev_release(). Without the mutex lock,
dvb_demux_open() (or dvb_dvr_open()) may run concurrently with
dvb_dmxdev_release(), which allows to skip the exit flag check and
continue the open process that is being closed.
CVE-2022-41218 is assigned to those bugs above.
Reported-by: Hyunwoo Kim <imv4bel(a)gmail.com>
Cc: <stable(a)vger.kernel.org>
Link: https://lore.kernel.org/20220908132754.30532-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco(a)xs4all.nl>
Signed-off-by: Ren Zhijie <renzhijie2(a)huawei.com>
Reviewed-by: songping yu <yusongping(a)huawei.com>
Reviewed-by: Zhang Qiao <zhangqiao22(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/media/dvb-core/dmxdev.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index d548f98c7a67..6f0121aa546e 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -800,6 +800,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
+ if (dmxdev->exit) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ENODEV;
+ }
+
for (i = 0; i < dmxdev->filternum; i++)
if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
break;
@@ -1445,7 +1450,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
+ mutex_lock(&dmxdev->mutex);
dmxdev->exit = 1;
+ mutex_unlock(&dmxdev->mutex);
+
if (dmxdev->dvbdev->users > 1) {
wait_event(dmxdev->dvbdev->wait_queue,
dmxdev->dvbdev->users == 1);
--
2.25.1
1
0

[PATCH openEuler-1.0-LTS] sched: Reinit task's vruntime if a task sleep over 200 days
by Yongqiang Liu 24 Dec '22
by Yongqiang Liu 24 Dec '22
24 Dec '22
From: Zhang Qiao <zhangqiao22(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I67BL1
CVE: NA
-------------------------------
If a task sleep for long time, it maybe cause a s64 overflow
issue at max_vruntime() and the task will be set an incorrect
vruntime, lead to the task be starve.
For fix it, we set the task's vruntime as cfs_rq->min_vruntime
when wakeup.
Signed-off-by: Zhang Qiao <zhangqiao22(a)huawei.com>
Reviewed-by: Chen Hui <judy.chenhui(a)huawei.com>
Reviewed-by: songping yu <yusongping(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
kernel/sched/fair.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 0dba06ce0677..ad6a7923c9ed 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3949,10 +3949,14 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se)
#endif
}
+/* The threshold when the wakee's vruntime should be set cfs_rq->min_vruntime, default: 200 days */
+#define WAKEUP_REINIT_THRESHOLD_NS (200 * 24 * 3600 * NSEC_PER_SEC)
+
static void
place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
{
u64 vruntime = cfs_rq->min_vruntime;
+ struct rq *rq = rq_of(cfs_rq);
/*
* The 'current' period is already promised to the current tasks,
@@ -3977,8 +3981,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
vruntime -= thresh;
}
+ if (unlikely(!initial && (s64)(rq_clock_task(rq) - se->exec_start) > WAKEUP_REINIT_THRESHOLD_NS))
+ se->vruntime = vruntime;
+ else
/* ensure we never gain time by being placed backwards. */
- se->vruntime = max_vruntime(se->vruntime, vruntime);
+ se->vruntime = max_vruntime(se->vruntime, vruntime);
}
static void check_enqueue_throttle(struct cfs_rq *cfs_rq);
--
2.25.1
1
0

[PATCH OLK-5.10 1/2] Revert "scsi: iscsi: fix kabi broken in struct iscsi_transport"
by Yongqiang Liu 23 Dec '22
by Yongqiang Liu 23 Dec '22
23 Dec '22
From: Li Nan <linan122(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 188176, https://gitee.com/openeuler/kernel/issues/I67294
CVE: NA
--------------------------------
This reverts commit 230035efb98b6edc066f3671e092a25013a131a2.
Drivers use tgt_dscvr will compile failed because API has changed.
Signed-off-by: Li Nan <linan122(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 9 ++-----
drivers/scsi/be2iscsi/be_main.c | 9 ++-----
drivers/scsi/bnx2i/bnx2i_iscsi.c | 9 ++-----
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 9 ++-----
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 9 ++-----
drivers/scsi/qedi/qedi_iscsi.c | 8 ++----
drivers/scsi/qla4xxx/ql4_os.c | 8 ++----
drivers/scsi/scsi_transport_iscsi.c | 31 ++++++------------------
include/scsi/iscsi_if.h | 1 -
include/scsi/scsi_transport_iscsi.h | 17 +------------
10 files changed, 23 insertions(+), 87 deletions(-)
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 4884b122e413..a16e066989fa 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -979,22 +979,17 @@ static struct scsi_host_template iscsi_iser_sht = {
.track_queue_depth = 1,
};
-static struct iscsi_transport_expand iscsi_iser_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
static struct iscsi_transport iscsi_iser_transport = {
.owner = THIS_MODULE,
.name = "iser",
- .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_TEXT_NEGO
- | CAP_OPS_EXPAND,
+ .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_TEXT_NEGO,
/* session management */
.create_session = iscsi_iser_session_create,
.destroy_session = iscsi_iser_session_destroy,
/* connection management */
.create_conn = iscsi_iser_conn_create,
.bind_conn = iscsi_iser_conn_bind,
- .ops_expand = &iscsi_iser_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_conn_teardown,
.attr_is_visible = iser_attr_is_visible,
.set_param = iscsi_iser_set_param,
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 06f697bfc49f..b977e039bb78 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5801,21 +5801,16 @@ static struct pci_error_handlers beiscsi_eeh_handlers = {
.resume = beiscsi_eeh_resume,
};
-struct iscsi_transport_expand beiscsi_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
struct iscsi_transport beiscsi_iscsi_transport = {
.owner = THIS_MODULE,
.name = DRV_NAME,
.caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_TEXT_NEGO |
- CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD |
- CAP_OPS_EXPAND,
+ CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD,
.create_session = beiscsi_session_create,
.destroy_session = beiscsi_session_destroy,
.create_conn = beiscsi_conn_create,
.bind_conn = beiscsi_conn_bind,
- .ops_expand = &beiscsi_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_conn_teardown,
.attr_is_visible = beiscsi_attr_is_visible,
.set_iface_param = beiscsi_iface_set_param,
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index e13c77a76150..8cf2f9a7cfdc 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -2274,23 +2274,18 @@ static struct scsi_host_template bnx2i_host_template = {
.track_queue_depth = 1,
};
-
-static struct iscsi_transport_expand bnx2i_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
struct iscsi_transport bnx2i_iscsi_transport = {
.owner = THIS_MODULE,
.name = "bnx2i",
.caps = CAP_RECOVERY_L0 | CAP_HDRDGST |
CAP_MULTI_R2T | CAP_DATADGST |
CAP_DATA_PATH_OFFLOAD |
- CAP_TEXT_NEGO | CAP_OPS_EXPAND,
+ CAP_TEXT_NEGO,
.create_session = bnx2i_session_create,
.destroy_session = bnx2i_session_destroy,
.create_conn = bnx2i_conn_create,
.bind_conn = bnx2i_conn_bind,
- .ops_expand = &bnx2i_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = bnx2i_conn_destroy,
.attr_is_visible = bnx2i_attr_is_visible,
.set_param = iscsi_set_param,
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index 65eb6230d390..edcd3fab6973 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -100,18 +100,13 @@ static struct scsi_host_template cxgb3i_host_template = {
.track_queue_depth = 1,
};
-static struct iscsi_transport_expand cxgb3i_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
static struct iscsi_transport cxgb3i_iscsi_transport = {
.owner = THIS_MODULE,
.name = DRV_MODULE_NAME,
/* owner and name should be set already */
.caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
| CAP_DATADGST | CAP_DIGEST_OFFLOAD |
- CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO |
- CAP_OPS_EXPAND,
+ CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO,
.attr_is_visible = cxgbi_attr_is_visible,
.get_host_param = cxgbi_get_host_param,
.set_host_param = cxgbi_set_host_param,
@@ -122,7 +117,7 @@ static struct iscsi_transport cxgb3i_iscsi_transport = {
/* connection management */
.create_conn = cxgbi_create_conn,
.bind_conn = cxgbi_bind_conn,
- .ops_expand = &cxgb3i_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_tcp_conn_teardown,
.start_conn = iscsi_conn_start,
.stop_conn = iscsi_conn_stop,
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index 88f96964c356..efb3e2b3398e 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -118,17 +118,12 @@ static struct scsi_host_template cxgb4i_host_template = {
.track_queue_depth = 1,
};
-static struct iscsi_transport_expand cxgb4i_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
static struct iscsi_transport cxgb4i_iscsi_transport = {
.owner = THIS_MODULE,
.name = DRV_MODULE_NAME,
.caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST |
CAP_DATADGST | CAP_DIGEST_OFFLOAD |
- CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO |
- CAP_OPS_EXPAND,
+ CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO,
.attr_is_visible = cxgbi_attr_is_visible,
.get_host_param = cxgbi_get_host_param,
.set_host_param = cxgbi_set_host_param,
@@ -139,7 +134,7 @@ static struct iscsi_transport cxgb4i_iscsi_transport = {
/* connection management */
.create_conn = cxgbi_create_conn,
.bind_conn = cxgbi_bind_conn,
- .ops_expand = &cxgb4i_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_tcp_conn_teardown,
.start_conn = iscsi_conn_start,
.stop_conn = iscsi_conn_stop,
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 8003b3519b95..3bcadb3dd40d 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -1429,20 +1429,16 @@ static void qedi_cleanup_task(struct iscsi_task *task)
cmd->scsi_cmd = NULL;
}
-static struct iscsi_transport_expand qedi_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
struct iscsi_transport qedi_iscsi_transport = {
.owner = THIS_MODULE,
.name = QEDI_MODULE_NAME,
.caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_MULTI_R2T | CAP_DATADGST |
- CAP_DATA_PATH_OFFLOAD | CAP_TEXT_NEGO | CAP_OPS_EXPAND,
+ CAP_DATA_PATH_OFFLOAD | CAP_TEXT_NEGO,
.create_session = qedi_session_create,
.destroy_session = qedi_session_destroy,
.create_conn = qedi_conn_create,
.bind_conn = qedi_conn_bind,
- .ops_expand = &qedi_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.start_conn = qedi_conn_start,
.stop_conn = iscsi_conn_stop,
.destroy_conn = qedi_conn_destroy,
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 377d83762099..8d82d2a83059 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -246,24 +246,20 @@ static struct scsi_host_template qla4xxx_driver_template = {
.vendor_id = SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC,
};
-static struct iscsi_transport_expand qla4xxx_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
static struct iscsi_transport qla4xxx_iscsi_transport = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
.caps = CAP_TEXT_NEGO |
CAP_DATA_PATH_OFFLOAD | CAP_HDRDGST |
CAP_DATADGST | CAP_LOGIN_OFFLOAD |
- CAP_MULTI_R2T | CAP_OPS_EXPAND,
+ CAP_MULTI_R2T,
.attr_is_visible = qla4_attr_is_visible,
.create_session = qla4xxx_session_create,
.destroy_session = qla4xxx_session_destroy,
.start_conn = qla4xxx_conn_start,
.create_conn = qla4xxx_conn_create,
.bind_conn = qla4xxx_conn_bind,
- .ops_expand = &qla4xxx_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.stop_conn = iscsi_conn_stop,
.destroy_conn = qla4xxx_conn_destroy,
.set_param = iscsi_set_param,
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index a213362524c9..517a3c4d879b 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2257,11 +2257,7 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
ep = conn->ep;
conn->ep = NULL;
- if (session->transport->caps & CAP_OPS_EXPAND &&
- session->transport->ops_expand &&
- session->transport->ops_expand->unbind_conn)
- session->transport->ops_expand->unbind_conn(conn, is_active);
-
+ session->transport->unbind_conn(conn, is_active);
session->transport->ep_disconnect(ep);
ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
}
@@ -3228,19 +3224,10 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport,
struct Scsi_Host *shost;
struct sockaddr *dst_addr;
int err;
- int (*tgt_dscvr)(struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
- uint32_t enable, struct sockaddr *dst_addr);
- if (transport->caps & CAP_OPS_EXPAND) {
- if (!transport->ops_expand || !transport->ops_expand->tgt_dscvr)
- return -EINVAL;
- tgt_dscvr = transport->ops_expand->tgt_dscvr;
- } else {
- if (!transport->ops_expand)
- return -EINVAL;
- tgt_dscvr = (int (*)(struct Scsi_Host *, enum iscsi_tgt_dscvr, uint32_t,
- struct sockaddr *))(transport->ops_expand);
- }
+ if (!transport->tgt_dscvr)
+ return -EINVAL;
+
shost = scsi_host_lookup(ev->u.tgt_dscvr.host_no);
if (!shost) {
printk(KERN_ERR "target discovery could not find host no %u\n",
@@ -3250,8 +3237,8 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport,
dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
- err = tgt_dscvr(shost, ev->u.tgt_dscvr.type,
- ev->u.tgt_dscvr.enable, dst_addr);
+ err = transport->tgt_dscvr(shost, ev->u.tgt_dscvr.type,
+ ev->u.tgt_dscvr.enable, dst_addr);
scsi_host_put(shost);
return err;
}
@@ -4904,10 +4891,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
int err;
BUG_ON(!tt);
- if (tt->caps & CAP_OPS_EXPAND) {
- BUG_ON(!tt->ops_expand);
- WARN_ON(tt->ep_disconnect && !tt->ops_expand->unbind_conn);
- }
+ WARN_ON(tt->ep_disconnect && !tt->unbind_conn);
+
priv = iscsi_if_transport_lookup(tt);
if (priv)
return NULL;
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 5679b9fb2b1e..5225a23f2d0e 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -761,7 +761,6 @@ enum iscsi_ping_status_code {
and verification */
#define CAP_LOGIN_OFFLOAD 0x4000 /* offload session login */
-#define CAP_OPS_EXPAND 0x8000 /* oiscsi_transport->ops_expand flag */
/*
* These flags describes reason of stop_conn() call
*/
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 1f7574d89822..b7fd8b738aa8 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -29,15 +29,6 @@ struct bsg_job;
struct iscsi_bus_flash_session;
struct iscsi_bus_flash_conn;
-/*
- * The expansion of iscsi_transport to fix kabi while adding members.
- */
-struct iscsi_transport_expand {
- int (*tgt_dscvr)(struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
- uint32_t enable, struct sockaddr *dst_addr);
- void (*unbind_conn)(struct iscsi_cls_conn *conn, bool is_active);
-};
-
/**
* struct iscsi_transport - iSCSI Transport template
*
@@ -91,6 +82,7 @@ struct iscsi_transport {
void (*destroy_session) (struct iscsi_cls_session *session);
struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
uint32_t cid);
+ void (*unbind_conn) (struct iscsi_cls_conn *conn, bool is_active);
int (*bind_conn) (struct iscsi_cls_session *session,
struct iscsi_cls_conn *cls_conn,
uint64_t transport_eph, int is_leading);
@@ -132,15 +124,8 @@ struct iscsi_transport {
int non_blocking);
int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms);
void (*ep_disconnect) (struct iscsi_endpoint *ep);
-#ifdef __GENKSYMS__
int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
uint32_t enable, struct sockaddr *dst_addr);
-#else
- /*
- * onece ops_expand is used, caps must be set to CAP_OPS_EXPAND
- */
- struct iscsi_transport_expand *ops_expand;
-#endif
int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params);
int (*set_iface_param) (struct Scsi_Host *shost, void *data,
uint32_t len);
--
2.27.0
1
1

[PATCH openEuler-5.10 1/2] Revert "scsi: iscsi: fix kabi broken in struct iscsi_transport"
by Zheng Zengkai 22 Dec '22
by Zheng Zengkai 22 Dec '22
22 Dec '22
From: Li Nan <linan122(a)huawei.com>
hulk inclusion
category: bugfix
bugzilla: 188176, https://gitee.com/openeuler/kernel/issues/I67294
CVE: NA
--------------------------------
This reverts commit 230035efb98b6edc066f3671e092a25013a131a2.
Drivers use tgt_dscvr will compile failed because API has changed.
Signed-off-by: Li Nan <linan122(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai(a)huawei.com>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 9 ++-----
drivers/scsi/be2iscsi/be_main.c | 9 ++-----
drivers/scsi/bnx2i/bnx2i_iscsi.c | 9 ++-----
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 9 ++-----
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 9 ++-----
drivers/scsi/qedi/qedi_iscsi.c | 8 ++----
drivers/scsi/qla4xxx/ql4_os.c | 8 ++----
drivers/scsi/scsi_transport_iscsi.c | 31 ++++++------------------
include/scsi/iscsi_if.h | 1 -
include/scsi/scsi_transport_iscsi.h | 17 +------------
10 files changed, 23 insertions(+), 87 deletions(-)
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 4884b122e413..a16e066989fa 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -979,22 +979,17 @@ static struct scsi_host_template iscsi_iser_sht = {
.track_queue_depth = 1,
};
-static struct iscsi_transport_expand iscsi_iser_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
static struct iscsi_transport iscsi_iser_transport = {
.owner = THIS_MODULE,
.name = "iser",
- .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_TEXT_NEGO
- | CAP_OPS_EXPAND,
+ .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_TEXT_NEGO,
/* session management */
.create_session = iscsi_iser_session_create,
.destroy_session = iscsi_iser_session_destroy,
/* connection management */
.create_conn = iscsi_iser_conn_create,
.bind_conn = iscsi_iser_conn_bind,
- .ops_expand = &iscsi_iser_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_conn_teardown,
.attr_is_visible = iser_attr_is_visible,
.set_param = iscsi_iser_set_param,
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 06f697bfc49f..b977e039bb78 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5801,21 +5801,16 @@ static struct pci_error_handlers beiscsi_eeh_handlers = {
.resume = beiscsi_eeh_resume,
};
-struct iscsi_transport_expand beiscsi_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
struct iscsi_transport beiscsi_iscsi_transport = {
.owner = THIS_MODULE,
.name = DRV_NAME,
.caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_TEXT_NEGO |
- CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD |
- CAP_OPS_EXPAND,
+ CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD,
.create_session = beiscsi_session_create,
.destroy_session = beiscsi_session_destroy,
.create_conn = beiscsi_conn_create,
.bind_conn = beiscsi_conn_bind,
- .ops_expand = &beiscsi_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_conn_teardown,
.attr_is_visible = beiscsi_attr_is_visible,
.set_iface_param = beiscsi_iface_set_param,
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index e13c77a76150..8cf2f9a7cfdc 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -2274,23 +2274,18 @@ static struct scsi_host_template bnx2i_host_template = {
.track_queue_depth = 1,
};
-
-static struct iscsi_transport_expand bnx2i_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
struct iscsi_transport bnx2i_iscsi_transport = {
.owner = THIS_MODULE,
.name = "bnx2i",
.caps = CAP_RECOVERY_L0 | CAP_HDRDGST |
CAP_MULTI_R2T | CAP_DATADGST |
CAP_DATA_PATH_OFFLOAD |
- CAP_TEXT_NEGO | CAP_OPS_EXPAND,
+ CAP_TEXT_NEGO,
.create_session = bnx2i_session_create,
.destroy_session = bnx2i_session_destroy,
.create_conn = bnx2i_conn_create,
.bind_conn = bnx2i_conn_bind,
- .ops_expand = &bnx2i_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = bnx2i_conn_destroy,
.attr_is_visible = bnx2i_attr_is_visible,
.set_param = iscsi_set_param,
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index 65eb6230d390..edcd3fab6973 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -100,18 +100,13 @@ static struct scsi_host_template cxgb3i_host_template = {
.track_queue_depth = 1,
};
-static struct iscsi_transport_expand cxgb3i_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
static struct iscsi_transport cxgb3i_iscsi_transport = {
.owner = THIS_MODULE,
.name = DRV_MODULE_NAME,
/* owner and name should be set already */
.caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
| CAP_DATADGST | CAP_DIGEST_OFFLOAD |
- CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO |
- CAP_OPS_EXPAND,
+ CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO,
.attr_is_visible = cxgbi_attr_is_visible,
.get_host_param = cxgbi_get_host_param,
.set_host_param = cxgbi_set_host_param,
@@ -122,7 +117,7 @@ static struct iscsi_transport cxgb3i_iscsi_transport = {
/* connection management */
.create_conn = cxgbi_create_conn,
.bind_conn = cxgbi_bind_conn,
- .ops_expand = &cxgb3i_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_tcp_conn_teardown,
.start_conn = iscsi_conn_start,
.stop_conn = iscsi_conn_stop,
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index 88f96964c356..efb3e2b3398e 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -118,17 +118,12 @@ static struct scsi_host_template cxgb4i_host_template = {
.track_queue_depth = 1,
};
-static struct iscsi_transport_expand cxgb4i_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
static struct iscsi_transport cxgb4i_iscsi_transport = {
.owner = THIS_MODULE,
.name = DRV_MODULE_NAME,
.caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST |
CAP_DATADGST | CAP_DIGEST_OFFLOAD |
- CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO |
- CAP_OPS_EXPAND,
+ CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO,
.attr_is_visible = cxgbi_attr_is_visible,
.get_host_param = cxgbi_get_host_param,
.set_host_param = cxgbi_set_host_param,
@@ -139,7 +134,7 @@ static struct iscsi_transport cxgb4i_iscsi_transport = {
/* connection management */
.create_conn = cxgbi_create_conn,
.bind_conn = cxgbi_bind_conn,
- .ops_expand = &cxgb4i_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_tcp_conn_teardown,
.start_conn = iscsi_conn_start,
.stop_conn = iscsi_conn_stop,
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 8003b3519b95..3bcadb3dd40d 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -1429,20 +1429,16 @@ static void qedi_cleanup_task(struct iscsi_task *task)
cmd->scsi_cmd = NULL;
}
-static struct iscsi_transport_expand qedi_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
struct iscsi_transport qedi_iscsi_transport = {
.owner = THIS_MODULE,
.name = QEDI_MODULE_NAME,
.caps = CAP_RECOVERY_L0 | CAP_HDRDGST | CAP_MULTI_R2T | CAP_DATADGST |
- CAP_DATA_PATH_OFFLOAD | CAP_TEXT_NEGO | CAP_OPS_EXPAND,
+ CAP_DATA_PATH_OFFLOAD | CAP_TEXT_NEGO,
.create_session = qedi_session_create,
.destroy_session = qedi_session_destroy,
.create_conn = qedi_conn_create,
.bind_conn = qedi_conn_bind,
- .ops_expand = &qedi_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.start_conn = qedi_conn_start,
.stop_conn = iscsi_conn_stop,
.destroy_conn = qedi_conn_destroy,
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 377d83762099..8d82d2a83059 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -246,24 +246,20 @@ static struct scsi_host_template qla4xxx_driver_template = {
.vendor_id = SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC,
};
-static struct iscsi_transport_expand qla4xxx_iscsi_expand = {
- .unbind_conn = iscsi_conn_unbind,
-};
-
static struct iscsi_transport qla4xxx_iscsi_transport = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
.caps = CAP_TEXT_NEGO |
CAP_DATA_PATH_OFFLOAD | CAP_HDRDGST |
CAP_DATADGST | CAP_LOGIN_OFFLOAD |
- CAP_MULTI_R2T | CAP_OPS_EXPAND,
+ CAP_MULTI_R2T,
.attr_is_visible = qla4_attr_is_visible,
.create_session = qla4xxx_session_create,
.destroy_session = qla4xxx_session_destroy,
.start_conn = qla4xxx_conn_start,
.create_conn = qla4xxx_conn_create,
.bind_conn = qla4xxx_conn_bind,
- .ops_expand = &qla4xxx_iscsi_expand,
+ .unbind_conn = iscsi_conn_unbind,
.stop_conn = iscsi_conn_stop,
.destroy_conn = qla4xxx_conn_destroy,
.set_param = iscsi_set_param,
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index a213362524c9..517a3c4d879b 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2257,11 +2257,7 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
ep = conn->ep;
conn->ep = NULL;
- if (session->transport->caps & CAP_OPS_EXPAND &&
- session->transport->ops_expand &&
- session->transport->ops_expand->unbind_conn)
- session->transport->ops_expand->unbind_conn(conn, is_active);
-
+ session->transport->unbind_conn(conn, is_active);
session->transport->ep_disconnect(ep);
ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
}
@@ -3228,19 +3224,10 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport,
struct Scsi_Host *shost;
struct sockaddr *dst_addr;
int err;
- int (*tgt_dscvr)(struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
- uint32_t enable, struct sockaddr *dst_addr);
- if (transport->caps & CAP_OPS_EXPAND) {
- if (!transport->ops_expand || !transport->ops_expand->tgt_dscvr)
- return -EINVAL;
- tgt_dscvr = transport->ops_expand->tgt_dscvr;
- } else {
- if (!transport->ops_expand)
- return -EINVAL;
- tgt_dscvr = (int (*)(struct Scsi_Host *, enum iscsi_tgt_dscvr, uint32_t,
- struct sockaddr *))(transport->ops_expand);
- }
+ if (!transport->tgt_dscvr)
+ return -EINVAL;
+
shost = scsi_host_lookup(ev->u.tgt_dscvr.host_no);
if (!shost) {
printk(KERN_ERR "target discovery could not find host no %u\n",
@@ -3250,8 +3237,8 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport,
dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
- err = tgt_dscvr(shost, ev->u.tgt_dscvr.type,
- ev->u.tgt_dscvr.enable, dst_addr);
+ err = transport->tgt_dscvr(shost, ev->u.tgt_dscvr.type,
+ ev->u.tgt_dscvr.enable, dst_addr);
scsi_host_put(shost);
return err;
}
@@ -4904,10 +4891,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
int err;
BUG_ON(!tt);
- if (tt->caps & CAP_OPS_EXPAND) {
- BUG_ON(!tt->ops_expand);
- WARN_ON(tt->ep_disconnect && !tt->ops_expand->unbind_conn);
- }
+ WARN_ON(tt->ep_disconnect && !tt->unbind_conn);
+
priv = iscsi_if_transport_lookup(tt);
if (priv)
return NULL;
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 5679b9fb2b1e..5225a23f2d0e 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -761,7 +761,6 @@ enum iscsi_ping_status_code {
and verification */
#define CAP_LOGIN_OFFLOAD 0x4000 /* offload session login */
-#define CAP_OPS_EXPAND 0x8000 /* oiscsi_transport->ops_expand flag */
/*
* These flags describes reason of stop_conn() call
*/
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 1f7574d89822..b7fd8b738aa8 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -29,15 +29,6 @@ struct bsg_job;
struct iscsi_bus_flash_session;
struct iscsi_bus_flash_conn;
-/*
- * The expansion of iscsi_transport to fix kabi while adding members.
- */
-struct iscsi_transport_expand {
- int (*tgt_dscvr)(struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
- uint32_t enable, struct sockaddr *dst_addr);
- void (*unbind_conn)(struct iscsi_cls_conn *conn, bool is_active);
-};
-
/**
* struct iscsi_transport - iSCSI Transport template
*
@@ -91,6 +82,7 @@ struct iscsi_transport {
void (*destroy_session) (struct iscsi_cls_session *session);
struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
uint32_t cid);
+ void (*unbind_conn) (struct iscsi_cls_conn *conn, bool is_active);
int (*bind_conn) (struct iscsi_cls_session *session,
struct iscsi_cls_conn *cls_conn,
uint64_t transport_eph, int is_leading);
@@ -132,15 +124,8 @@ struct iscsi_transport {
int non_blocking);
int (*ep_poll) (struct iscsi_endpoint *ep, int timeout_ms);
void (*ep_disconnect) (struct iscsi_endpoint *ep);
-#ifdef __GENKSYMS__
int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
uint32_t enable, struct sockaddr *dst_addr);
-#else
- /*
- * onece ops_expand is used, caps must be set to CAP_OPS_EXPAND
- */
- struct iscsi_transport_expand *ops_expand;
-#endif
int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params);
int (*set_iface_param) (struct Scsi_Host *shost, void *data,
uint32_t len);
--
2.20.1
1
1

[PATCH openEuler-1.0-LTS] drm/amdkfd: Check for null pointer after calling kmemdup
by Yongqiang Liu 22 Dec '22
by Yongqiang Liu 22 Dec '22
22 Dec '22
From: Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
stable inclusion
from stable-v6.0.14
commit abfaf0eee97925905e742aa3b0b72e04a918fa9e
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6694U
CVE: CVE-2022-3108
--------------------------------
As the possible failure of the allocation, kmemdup() may return NULL
pointer.
Therefore, it should be better to check the 'props2' in order to prevent
the dereference of NULL pointer.
Fixes: 3a87177eb141 ("drm/amdkfd: Add topology support for dGPUs")
Signed-off-by: Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
Reviewed-by: Felix Kuehling <Felix.Kuehling(a)amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling(a)amd.com>
Signed-off-by: Alex Deucher <alexander.deucher(a)amd.com>
Signed-off-by: Ren Zhijie <renzhijie2(a)huawei.com>
Reviewed-by: songping yu <yusongping(a)huawei.com>
Reviewed-by: Chen Hui <judy.chenhui(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
index ee4996029a86..e84285130bde 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
@@ -397,6 +397,9 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink,
return -ENODEV;
/* same everything but the other direction */
props2 = kmemdup(props, sizeof(*props2), GFP_KERNEL);
+ if (!props2)
+ return -ENOMEM;
+
props2->node_from = id_to;
props2->node_to = id_from;
props2->kobj = NULL;
--
2.25.1
1
0

[PATCH openEuler-1.0-LTS 1/4] Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put
by Yongqiang Liu 19 Dec '22
by Yongqiang Liu 19 Dec '22
19 Dec '22
From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
stable inclusion
from stable-v4.19.255
commit d0be8347c623e0ac4202a1d4e0373882821f56b0
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I64WCC
CVE: CVE-2022-20566
--------------------------------
commit d0be8347c623e0ac4202a1d4e0373882821f56b0 upstream.
This fixes the following trace which is caused by hci_rx_work starting up
*after* the final channel reference has been put() during sock_close() but
*before* the references to the channel have been destroyed, so instead
the code now rely on kref_get_unless_zero/l2cap_chan_hold_unless_zero to
prevent referencing a channel that is about to be destroyed.
refcount_t: increment on 0; use-after-free.
BUG: KASAN: use-after-free in refcount_dec_and_test+0x20/0xd0
Read of size 4 at addr ffffffc114f5bf18 by task kworker/u17:14/705
CPU: 4 PID: 705 Comm: kworker/u17:14 Tainted: G S W
4.14.234-00003-g1fb6d0bd49a4-dirty #28
Hardware name: Qualcomm Technologies, Inc. SM8150 V2 PM8150
Google Inc. MSM sm8150 Flame DVT (DT)
Workqueue: hci0 hci_rx_work
Call trace:
dump_backtrace+0x0/0x378
show_stack+0x20/0x2c
dump_stack+0x124/0x148
print_address_description+0x80/0x2e8
__kasan_report+0x168/0x188
kasan_report+0x10/0x18
__asan_load4+0x84/0x8c
refcount_dec_and_test+0x20/0xd0
l2cap_chan_put+0x48/0x12c
l2cap_recv_frame+0x4770/0x6550
l2cap_recv_acldata+0x44c/0x7a4
hci_acldata_packet+0x100/0x188
hci_rx_work+0x178/0x23c
process_one_work+0x35c/0x95c
worker_thread+0x4cc/0x960
kthread+0x1a8/0x1c4
ret_from_fork+0x10/0x18
Cc: stable(a)kernel.org
Reported-by: Lee Jones <lee.jones(a)linaro.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
Tested-by: Lee Jones <lee.jones(a)linaro.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Lu Jialin <lujialin4(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
include/net/bluetooth/l2cap.h | 1 +
net/bluetooth/l2cap_core.c | 61 +++++++++++++++++++++++++++--------
2 files changed, 49 insertions(+), 13 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 21dbd38f724d..da0ef935c5a9 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -798,6 +798,7 @@ enum {
};
void l2cap_chan_hold(struct l2cap_chan *c);
+struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c);
void l2cap_chan_put(struct l2cap_chan *c);
static inline void l2cap_chan_lock(struct l2cap_chan *chan)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3b02e881cec1..7c2bb0571573 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -113,7 +113,8 @@ static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
}
/* Find channel with given SCID.
- * Returns locked channel. */
+ * Returns a reference locked channel.
+ */
static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
u16 cid)
{
@@ -121,15 +122,19 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
mutex_lock(&conn->chan_lock);
c = __l2cap_get_chan_by_scid(conn, cid);
- if (c)
- l2cap_chan_lock(c);
+ if (c) {
+ /* Only lock if chan reference is not 0 */
+ c = l2cap_chan_hold_unless_zero(c);
+ if (c)
+ l2cap_chan_lock(c);
+ }
mutex_unlock(&conn->chan_lock);
return c;
}
/* Find channel with given DCID.
- * Returns locked channel.
+ * Returns a reference locked channel.
*/
static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
u16 cid)
@@ -138,8 +143,12 @@ static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
mutex_lock(&conn->chan_lock);
c = __l2cap_get_chan_by_dcid(conn, cid);
- if (c)
- l2cap_chan_lock(c);
+ if (c) {
+ /* Only lock if chan reference is not 0 */
+ c = l2cap_chan_hold_unless_zero(c);
+ if (c)
+ l2cap_chan_lock(c);
+ }
mutex_unlock(&conn->chan_lock);
return c;
@@ -164,8 +173,12 @@ static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
mutex_lock(&conn->chan_lock);
c = __l2cap_get_chan_by_ident(conn, ident);
- if (c)
- l2cap_chan_lock(c);
+ if (c) {
+ /* Only lock if chan reference is not 0 */
+ c = l2cap_chan_hold_unless_zero(c);
+ if (c)
+ l2cap_chan_lock(c);
+ }
mutex_unlock(&conn->chan_lock);
return c;
@@ -486,6 +499,16 @@ void l2cap_chan_hold(struct l2cap_chan *c)
kref_get(&c->kref);
}
+struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
+{
+ BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref));
+
+ if (!kref_get_unless_zero(&c->kref))
+ return NULL;
+
+ return c;
+}
+
void l2cap_chan_put(struct l2cap_chan *c)
{
BT_DBG("chan %p orig refcnt %d", c, kref_read(&c->kref));
@@ -1796,7 +1819,10 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
src_match = !bacmp(&c->src, src);
dst_match = !bacmp(&c->dst, dst);
if (src_match && dst_match) {
- l2cap_chan_hold(c);
+ c = l2cap_chan_hold_unless_zero(c);
+ if (!c)
+ continue;
+
read_unlock(&chan_list_lock);
return c;
}
@@ -1811,7 +1837,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
}
if (c1)
- l2cap_chan_hold(c1);
+ c1 = l2cap_chan_hold_unless_zero(c1);
read_unlock(&chan_list_lock);
@@ -4198,6 +4224,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
unlock:
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
return err;
}
@@ -4310,6 +4337,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
done:
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
return err;
}
@@ -5037,6 +5065,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
l2cap_send_move_chan_rsp(chan, result);
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
return 0;
}
@@ -5129,6 +5158,7 @@ static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
}
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
}
static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
@@ -5158,6 +5188,7 @@ static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
}
static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
@@ -5221,6 +5252,7 @@ static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
return 0;
}
@@ -5256,6 +5288,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
}
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
return 0;
}
@@ -5641,12 +5674,11 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
if (credits > max_credits) {
BT_ERR("LE credits overflow");
l2cap_send_disconn_req(chan, ECONNRESET);
- l2cap_chan_unlock(chan);
/* Return 0 so that we don't trigger an unnecessary
* command reject packet.
*/
- return 0;
+ goto unlock;
}
chan->tx_credits += credits;
@@ -5657,7 +5689,9 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
if (chan->tx_credits)
chan->ops->resume(chan);
+unlock:
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
return 0;
}
@@ -6989,6 +7023,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
done:
l2cap_chan_unlock(chan);
+ l2cap_chan_put(chan);
}
static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
@@ -7393,7 +7428,7 @@ static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c,
if (src_type != c->src_type)
continue;
- l2cap_chan_hold(c);
+ c = l2cap_chan_hold_unless_zero(c);
read_unlock(&chan_list_lock);
return c;
}
--
2.25.1
1
3