Preserve Linx block state across Linux context switches and early boot - #23

Draft
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530
Draft

Preserve Linx block state across Linux context switches and early boot#23
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530

Conversation

@zhoubot

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx Linux work from the existing checkout
  • save and restore the full ACR1 EBSTATE window across __switch_to
  • tighten exception/return control flow and early MMU/initramfs bring-up for the firmwareless lane

Testing

  • git diff --check

Not tested

  • kernel build
  • initramfs smoke
  • BusyBox full-OS regression lane

The current work renames the EBSTATE window to spec-shaped SSR aliases, saves and restores the full ACR1 block-state window in __switch_to, tightens exception and return control flow, and adjusts early MMU and initramfs bring-up around the firmwareless runtime lane.
Constraint: The active PR lane still depends on full ACR1 EBSTATE save and restore across task switches
Rejected: Save only named EBARG fields | current bring-up still needs the full 0x1f40..0x1f5f window preserved per task
Confidence: medium
Scope-risk: broad
Directive: Do not shrink the saved ACR1 window without re-proving task-switch, FRET.STK, and full runtime lanes
Tested: git diff --check
Not-tested: kernel build, initramfs smoke, BusyBox full-OS regression
Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces numerous early bring-up workarounds, fixes, and boot-time bypasses for the Linx architecture, covering memory management, scheduling, locking, and CPU hotplug subsystems. The code review identified several critical issues that must be addressed: a severe security vulnerability in __get_kernel_nofault and __put_kernel_nofault due to global virtual-to-physical address conversion; a potential post-boot crash caused by marking the persistent linx_root_task_group_boot_buf with __initdata; missing parentheses in the LINX_BOOT_PT_LOW_ALIAS_LIMIT macro definition; broken cacheinfo initialization on SMP systems due to boot-CPU-only hotplug callbacks; a severe memory leak in finish_task_switch caused by an unreachable cleanup path; and a resource leak of MSI domains on initialization failure in the interrupt controller driver.

Comment on lines +347 to +349
if (is_kernel_mapping((unsigned long)__kr_src) || \
is_linear_mapping((unsigned long)__kr_src)) \
__kr_src = (const void *)(uintptr_t)__pa(__kr_src); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-criticalcritical

Converting kernel virtual addresses to physical addresses globally in __get_kernel_nofault and __put_kernel_nofault is highly dangerous. While this might work during early boot when identity mappings are active, at runtime (when user space processes are running), the active page table (current->mm->pgd) maps low virtual addresses to user space memory. Consequently, any attempt to use these nofault helpers at runtime while a user process is active will access the user's virtual memory instead of the kernel's physical memory. This is a critical security vulnerability and correctness bug. Please restrict this physical address conversion workaround to early boot (e.g., by checking system_state == SYSTEM_BOOTING) or avoid doing it globally.

Comment threadkernel/sched/core.c
Comment on lines +8845 to +8846
static unsigned long linx_root_task_group_boot_buf[512] __initdata
__aligned(SMP_CACHE_BYTES);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The static buffer linx_root_task_group_boot_buf is marked with __initdata. However, it is used as a persistent fallback backing store for root_task_group.se and root_task_group.cfs_rq, which must remain valid for the entire lifetime of the system. Since __initdata memory is freed and reclaimed after early boot completes, any scheduling activity after boot will access freed/reclaimed memory, leading to undefined behavior, silent data corruption, or a catastrophic kernel panic. Please remove the __initdata attribute from this buffer.

staticunsigned longlinx_root_task_group_boot_buf[512] __aligned(SMP_CACHE_BYTES);

#define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))

#if defined(__LINX__)
#define LINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The macro LINX_BOOT_PT_LOW_ALIAS_LIMIT is defined using a shift operator (<<) without surrounding parentheses. In C, shift operators have lower precedence than additive operators (+, -). If this macro is ever used in an additive expression (e.g., LINX_BOOT_PT_LOW_ALIAS_LIMIT + offset), it will be evaluated incorrectly as 64UL << (20 + offset). Please wrap the macro definition in parentheses to ensure safe evaluation.

Suggested change
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT(_AC(64, UL) << 20)

Comment on lines +1045 to +1056
ret = cpuhp_setup_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE,
"base/cacheinfo:online",
cacheinfo_cpu_online,
cacheinfo_cpu_pre_down);
if (ret)
return ret;

ret = cacheinfo_cpu_online(smp_processor_id());
if (ret) {
cpuhp_remove_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE);
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cpuhp_setup_state_nocalls and manually invoking the callback only on the boot CPU (smp_processor_id()) will break cacheinfo initialization on multi-core (SMP) systems. Since cacheinfo_sysfs_init is a device_initcall, it runs after secondary CPUs have already been brought online. By using nocalls and only manually invoking it on the boot CPU, all secondary CPUs will miss the cacheinfo_cpu_online callback, resulting in missing or uninitialized cacheinfo sysfs attributes for those CPUs. Please ensure that the callback is executed for all online CPUs, or restrict this workaround specifically to non-SMP/UP configurations.

Comment threadkernel/sched/core.c
Comment on lines +5348 to +5350
#if defined(CONFIG_LINX) || defined(__LINX__)
return rq;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The early return rq; added at line 5349 under defined(CONFIG_LINX) || defined(__LINX__) makes the entire rest of the finish_task_switch function unreachable. This completely bypasses critical cleanup steps, most notably mmdrop_lazy_tlb_sched(mm). As a result, mm_struct reference counts will leak on every task switch from a user process, leading to a severe memory leak. Please restructure the conditional compilation so that necessary cleanup steps are still executed.

Comment on lines +858 to +862
ret = setup_lxic(node, &nvec, &ndev, priv);
if (ret) {
error = ret;
goto out_iounmap;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If setup_lxic fails in lxic_init, the function jumps to out_iounmap but does not clean up the allocated MSI domains. This results in a resource leak of the PCI domain, base domain, and irqdomain created earlier in lxic_allocate_msi_domains. Please call irq_domain_cleanup(priv) in the error path before returning.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@zhoubot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Preserve Linx block state across Linux context switches and early boot - #23

Draft
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530
Draft

Preserve Linx block state across Linux context switches and early boot#23
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530

Conversation

@zhoubot

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx Linux work from the existing checkout
  • save and restore the full ACR1 EBSTATE window across __switch_to
  • tighten exception/return control flow and early MMU/initramfs bring-up for the firmwareless lane

Testing

  • git diff --check

Not tested

  • kernel build
  • initramfs smoke
  • BusyBox full-OS regression lane

The current work renames the EBSTATE window to spec-shaped SSR aliases, saves and restores the full ACR1 block-state window in __switch_to, tightens exception and return control flow, and adjusts early MMU and initramfs bring-up around the firmwareless runtime lane.
Constraint: The active PR lane still depends on full ACR1 EBSTATE save and restore across task switches
Rejected: Save only named EBARG fields | current bring-up still needs the full 0x1f40..0x1f5f window preserved per task
Confidence: medium
Scope-risk: broad
Directive: Do not shrink the saved ACR1 window without re-proving task-switch, FRET.STK, and full runtime lanes
Tested: git diff --check
Not-tested: kernel build, initramfs smoke, BusyBox full-OS regression
Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces numerous early bring-up workarounds, fixes, and boot-time bypasses for the Linx architecture, covering memory management, scheduling, locking, and CPU hotplug subsystems. The code review identified several critical issues that must be addressed: a severe security vulnerability in __get_kernel_nofault and __put_kernel_nofault due to global virtual-to-physical address conversion; a potential post-boot crash caused by marking the persistent linx_root_task_group_boot_buf with __initdata; missing parentheses in the LINX_BOOT_PT_LOW_ALIAS_LIMIT macro definition; broken cacheinfo initialization on SMP systems due to boot-CPU-only hotplug callbacks; a severe memory leak in finish_task_switch caused by an unreachable cleanup path; and a resource leak of MSI domains on initialization failure in the interrupt controller driver.

Comment on lines +347 to +349
if (is_kernel_mapping((unsigned long)__kr_src) || \
is_linear_mapping((unsigned long)__kr_src)) \
__kr_src = (const void *)(uintptr_t)__pa(__kr_src); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-criticalcritical

Converting kernel virtual addresses to physical addresses globally in __get_kernel_nofault and __put_kernel_nofault is highly dangerous. While this might work during early boot when identity mappings are active, at runtime (when user space processes are running), the active page table (current->mm->pgd) maps low virtual addresses to user space memory. Consequently, any attempt to use these nofault helpers at runtime while a user process is active will access the user's virtual memory instead of the kernel's physical memory. This is a critical security vulnerability and correctness bug. Please restrict this physical address conversion workaround to early boot (e.g., by checking system_state == SYSTEM_BOOTING) or avoid doing it globally.

Comment threadkernel/sched/core.c
Comment on lines +8845 to +8846
static unsigned long linx_root_task_group_boot_buf[512] __initdata
__aligned(SMP_CACHE_BYTES);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The static buffer linx_root_task_group_boot_buf is marked with __initdata. However, it is used as a persistent fallback backing store for root_task_group.se and root_task_group.cfs_rq, which must remain valid for the entire lifetime of the system. Since __initdata memory is freed and reclaimed after early boot completes, any scheduling activity after boot will access freed/reclaimed memory, leading to undefined behavior, silent data corruption, or a catastrophic kernel panic. Please remove the __initdata attribute from this buffer.

staticunsigned longlinx_root_task_group_boot_buf[512] __aligned(SMP_CACHE_BYTES);

#define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))

#if defined(__LINX__)
#define LINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The macro LINX_BOOT_PT_LOW_ALIAS_LIMIT is defined using a shift operator (<<) without surrounding parentheses. In C, shift operators have lower precedence than additive operators (+, -). If this macro is ever used in an additive expression (e.g., LINX_BOOT_PT_LOW_ALIAS_LIMIT + offset), it will be evaluated incorrectly as 64UL << (20 + offset). Please wrap the macro definition in parentheses to ensure safe evaluation.

Suggested change
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT(_AC(64, UL) << 20)

Comment on lines +1045 to +1056
ret = cpuhp_setup_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE,
"base/cacheinfo:online",
cacheinfo_cpu_online,
cacheinfo_cpu_pre_down);
if (ret)
return ret;

ret = cacheinfo_cpu_online(smp_processor_id());
if (ret) {
cpuhp_remove_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE);
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cpuhp_setup_state_nocalls and manually invoking the callback only on the boot CPU (smp_processor_id()) will break cacheinfo initialization on multi-core (SMP) systems. Since cacheinfo_sysfs_init is a device_initcall, it runs after secondary CPUs have already been brought online. By using nocalls and only manually invoking it on the boot CPU, all secondary CPUs will miss the cacheinfo_cpu_online callback, resulting in missing or uninitialized cacheinfo sysfs attributes for those CPUs. Please ensure that the callback is executed for all online CPUs, or restrict this workaround specifically to non-SMP/UP configurations.

Comment threadkernel/sched/core.c
Comment on lines +5348 to +5350
#if defined(CONFIG_LINX) || defined(__LINX__)
return rq;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The early return rq; added at line 5349 under defined(CONFIG_LINX) || defined(__LINX__) makes the entire rest of the finish_task_switch function unreachable. This completely bypasses critical cleanup steps, most notably mmdrop_lazy_tlb_sched(mm). As a result, mm_struct reference counts will leak on every task switch from a user process, leading to a severe memory leak. Please restructure the conditional compilation so that necessary cleanup steps are still executed.

Comment on lines +858 to +862
ret = setup_lxic(node, &nvec, &ndev, priv);
if (ret) {
error = ret;
goto out_iounmap;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If setup_lxic fails in lxic_init, the function jumps to out_iounmap but does not clean up the allocated MSI domains. This results in a resource leak of the PCI domain, base domain, and irqdomain created earlier in lxic_allocate_msi_domains. Please call irq_domain_cleanup(priv) in the error path before returning.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@zhoubot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Preserve Linx block state across Linux context switches and early boot - #23

Draft
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530
Draft

Preserve Linx block state across Linux context switches and early boot#23
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530

Conversation

@zhoubot

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx Linux work from the existing checkout
  • save and restore the full ACR1 EBSTATE window across __switch_to
  • tighten exception/return control flow and early MMU/initramfs bring-up for the firmwareless lane

Testing

  • git diff --check

Not tested

  • kernel build
  • initramfs smoke
  • BusyBox full-OS regression lane

The current work renames the EBSTATE window to spec-shaped SSR aliases, saves and restores the full ACR1 block-state window in __switch_to, tightens exception and return control flow, and adjusts early MMU and initramfs bring-up around the firmwareless runtime lane.
Constraint: The active PR lane still depends on full ACR1 EBSTATE save and restore across task switches
Rejected: Save only named EBARG fields | current bring-up still needs the full 0x1f40..0x1f5f window preserved per task
Confidence: medium
Scope-risk: broad
Directive: Do not shrink the saved ACR1 window without re-proving task-switch, FRET.STK, and full runtime lanes
Tested: git diff --check
Not-tested: kernel build, initramfs smoke, BusyBox full-OS regression
Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces numerous early bring-up workarounds, fixes, and boot-time bypasses for the Linx architecture, covering memory management, scheduling, locking, and CPU hotplug subsystems. The code review identified several critical issues that must be addressed: a severe security vulnerability in __get_kernel_nofault and __put_kernel_nofault due to global virtual-to-physical address conversion; a potential post-boot crash caused by marking the persistent linx_root_task_group_boot_buf with __initdata; missing parentheses in the LINX_BOOT_PT_LOW_ALIAS_LIMIT macro definition; broken cacheinfo initialization on SMP systems due to boot-CPU-only hotplug callbacks; a severe memory leak in finish_task_switch caused by an unreachable cleanup path; and a resource leak of MSI domains on initialization failure in the interrupt controller driver.

Comment on lines +347 to +349
if (is_kernel_mapping((unsigned long)__kr_src) || \
is_linear_mapping((unsigned long)__kr_src)) \
__kr_src = (const void *)(uintptr_t)__pa(__kr_src); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-criticalcritical

Converting kernel virtual addresses to physical addresses globally in __get_kernel_nofault and __put_kernel_nofault is highly dangerous. While this might work during early boot when identity mappings are active, at runtime (when user space processes are running), the active page table (current->mm->pgd) maps low virtual addresses to user space memory. Consequently, any attempt to use these nofault helpers at runtime while a user process is active will access the user's virtual memory instead of the kernel's physical memory. This is a critical security vulnerability and correctness bug. Please restrict this physical address conversion workaround to early boot (e.g., by checking system_state == SYSTEM_BOOTING) or avoid doing it globally.

Comment threadkernel/sched/core.c
Comment on lines +8845 to +8846
static unsigned long linx_root_task_group_boot_buf[512] __initdata
__aligned(SMP_CACHE_BYTES);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The static buffer linx_root_task_group_boot_buf is marked with __initdata. However, it is used as a persistent fallback backing store for root_task_group.se and root_task_group.cfs_rq, which must remain valid for the entire lifetime of the system. Since __initdata memory is freed and reclaimed after early boot completes, any scheduling activity after boot will access freed/reclaimed memory, leading to undefined behavior, silent data corruption, or a catastrophic kernel panic. Please remove the __initdata attribute from this buffer.

staticunsigned longlinx_root_task_group_boot_buf[512] __aligned(SMP_CACHE_BYTES);

#define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))

#if defined(__LINX__)
#define LINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The macro LINX_BOOT_PT_LOW_ALIAS_LIMIT is defined using a shift operator (<<) without surrounding parentheses. In C, shift operators have lower precedence than additive operators (+, -). If this macro is ever used in an additive expression (e.g., LINX_BOOT_PT_LOW_ALIAS_LIMIT + offset), it will be evaluated incorrectly as 64UL << (20 + offset). Please wrap the macro definition in parentheses to ensure safe evaluation.

Suggested change
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT(_AC(64, UL) << 20)

Comment on lines +1045 to +1056
ret = cpuhp_setup_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE,
"base/cacheinfo:online",
cacheinfo_cpu_online,
cacheinfo_cpu_pre_down);
if (ret)
return ret;

ret = cacheinfo_cpu_online(smp_processor_id());
if (ret) {
cpuhp_remove_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE);
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cpuhp_setup_state_nocalls and manually invoking the callback only on the boot CPU (smp_processor_id()) will break cacheinfo initialization on multi-core (SMP) systems. Since cacheinfo_sysfs_init is a device_initcall, it runs after secondary CPUs have already been brought online. By using nocalls and only manually invoking it on the boot CPU, all secondary CPUs will miss the cacheinfo_cpu_online callback, resulting in missing or uninitialized cacheinfo sysfs attributes for those CPUs. Please ensure that the callback is executed for all online CPUs, or restrict this workaround specifically to non-SMP/UP configurations.

Comment threadkernel/sched/core.c
Comment on lines +5348 to +5350
#if defined(CONFIG_LINX) || defined(__LINX__)
return rq;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The early return rq; added at line 5349 under defined(CONFIG_LINX) || defined(__LINX__) makes the entire rest of the finish_task_switch function unreachable. This completely bypasses critical cleanup steps, most notably mmdrop_lazy_tlb_sched(mm). As a result, mm_struct reference counts will leak on every task switch from a user process, leading to a severe memory leak. Please restructure the conditional compilation so that necessary cleanup steps are still executed.

Comment on lines +858 to +862
ret = setup_lxic(node, &nvec, &ndev, priv);
if (ret) {
error = ret;
goto out_iounmap;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If setup_lxic fails in lxic_init, the function jumps to out_iounmap but does not clean up the allocated MSI domains. This results in a resource leak of the PCI domain, base domain, and irqdomain created earlier in lxic_allocate_msi_domains. Please call irq_domain_cleanup(priv) in the error path before returning.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@zhoubot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Preserve Linx block state across Linux context switches and early boot - #23

Draft
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530
Draft

Preserve Linx block state across Linux context switches and early boot#23
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530

Conversation

@zhoubot

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx Linux work from the existing checkout
  • save and restore the full ACR1 EBSTATE window across __switch_to
  • tighten exception/return control flow and early MMU/initramfs bring-up for the firmwareless lane

Testing

  • git diff --check

Not tested

  • kernel build
  • initramfs smoke
  • BusyBox full-OS regression lane

The current work renames the EBSTATE window to spec-shaped SSR aliases, saves and restores the full ACR1 block-state window in __switch_to, tightens exception and return control flow, and adjusts early MMU and initramfs bring-up around the firmwareless runtime lane.
Constraint: The active PR lane still depends on full ACR1 EBSTATE save and restore across task switches
Rejected: Save only named EBARG fields | current bring-up still needs the full 0x1f40..0x1f5f window preserved per task
Confidence: medium
Scope-risk: broad
Directive: Do not shrink the saved ACR1 window without re-proving task-switch, FRET.STK, and full runtime lanes
Tested: git diff --check
Not-tested: kernel build, initramfs smoke, BusyBox full-OS regression
Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces numerous early bring-up workarounds, fixes, and boot-time bypasses for the Linx architecture, covering memory management, scheduling, locking, and CPU hotplug subsystems. The code review identified several critical issues that must be addressed: a severe security vulnerability in __get_kernel_nofault and __put_kernel_nofault due to global virtual-to-physical address conversion; a potential post-boot crash caused by marking the persistent linx_root_task_group_boot_buf with __initdata; missing parentheses in the LINX_BOOT_PT_LOW_ALIAS_LIMIT macro definition; broken cacheinfo initialization on SMP systems due to boot-CPU-only hotplug callbacks; a severe memory leak in finish_task_switch caused by an unreachable cleanup path; and a resource leak of MSI domains on initialization failure in the interrupt controller driver.

Comment on lines +347 to +349
if (is_kernel_mapping((unsigned long)__kr_src) || \
is_linear_mapping((unsigned long)__kr_src)) \
__kr_src = (const void *)(uintptr_t)__pa(__kr_src); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-criticalcritical

Converting kernel virtual addresses to physical addresses globally in __get_kernel_nofault and __put_kernel_nofault is highly dangerous. While this might work during early boot when identity mappings are active, at runtime (when user space processes are running), the active page table (current->mm->pgd) maps low virtual addresses to user space memory. Consequently, any attempt to use these nofault helpers at runtime while a user process is active will access the user's virtual memory instead of the kernel's physical memory. This is a critical security vulnerability and correctness bug. Please restrict this physical address conversion workaround to early boot (e.g., by checking system_state == SYSTEM_BOOTING) or avoid doing it globally.

Comment threadkernel/sched/core.c
Comment on lines +8845 to +8846
static unsigned long linx_root_task_group_boot_buf[512] __initdata
__aligned(SMP_CACHE_BYTES);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The static buffer linx_root_task_group_boot_buf is marked with __initdata. However, it is used as a persistent fallback backing store for root_task_group.se and root_task_group.cfs_rq, which must remain valid for the entire lifetime of the system. Since __initdata memory is freed and reclaimed after early boot completes, any scheduling activity after boot will access freed/reclaimed memory, leading to undefined behavior, silent data corruption, or a catastrophic kernel panic. Please remove the __initdata attribute from this buffer.

staticunsigned longlinx_root_task_group_boot_buf[512] __aligned(SMP_CACHE_BYTES);

#define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))

#if defined(__LINX__)
#define LINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The macro LINX_BOOT_PT_LOW_ALIAS_LIMIT is defined using a shift operator (<<) without surrounding parentheses. In C, shift operators have lower precedence than additive operators (+, -). If this macro is ever used in an additive expression (e.g., LINX_BOOT_PT_LOW_ALIAS_LIMIT + offset), it will be evaluated incorrectly as 64UL << (20 + offset). Please wrap the macro definition in parentheses to ensure safe evaluation.

Suggested change
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT(_AC(64, UL) << 20)

Comment on lines +1045 to +1056
ret = cpuhp_setup_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE,
"base/cacheinfo:online",
cacheinfo_cpu_online,
cacheinfo_cpu_pre_down);
if (ret)
return ret;

ret = cacheinfo_cpu_online(smp_processor_id());
if (ret) {
cpuhp_remove_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE);
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cpuhp_setup_state_nocalls and manually invoking the callback only on the boot CPU (smp_processor_id()) will break cacheinfo initialization on multi-core (SMP) systems. Since cacheinfo_sysfs_init is a device_initcall, it runs after secondary CPUs have already been brought online. By using nocalls and only manually invoking it on the boot CPU, all secondary CPUs will miss the cacheinfo_cpu_online callback, resulting in missing or uninitialized cacheinfo sysfs attributes for those CPUs. Please ensure that the callback is executed for all online CPUs, or restrict this workaround specifically to non-SMP/UP configurations.

Comment threadkernel/sched/core.c
Comment on lines +5348 to +5350
#if defined(CONFIG_LINX) || defined(__LINX__)
return rq;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The early return rq; added at line 5349 under defined(CONFIG_LINX) || defined(__LINX__) makes the entire rest of the finish_task_switch function unreachable. This completely bypasses critical cleanup steps, most notably mmdrop_lazy_tlb_sched(mm). As a result, mm_struct reference counts will leak on every task switch from a user process, leading to a severe memory leak. Please restructure the conditional compilation so that necessary cleanup steps are still executed.

Comment on lines +858 to +862
ret = setup_lxic(node, &nvec, &ndev, priv);
if (ret) {
error = ret;
goto out_iounmap;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If setup_lxic fails in lxic_init, the function jumps to out_iounmap but does not clean up the allocated MSI domains. This results in a resource leak of the PCI domain, base domain, and irqdomain created earlier in lxic_allocate_msi_domains. Please call irq_domain_cleanup(priv) in the error path before returning.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@zhoubot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Preserve Linx block state across Linux context switches and early boot - #23

Draft
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530
Draft

Preserve Linx block state across Linux context switches and early boot#23
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530

Conversation

@zhoubot

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx Linux work from the existing checkout
  • save and restore the full ACR1 EBSTATE window across __switch_to
  • tighten exception/return control flow and early MMU/initramfs bring-up for the firmwareless lane

Testing

  • git diff --check

Not tested

  • kernel build
  • initramfs smoke
  • BusyBox full-OS regression lane

The current work renames the EBSTATE window to spec-shaped SSR aliases, saves and restores the full ACR1 block-state window in __switch_to, tightens exception and return control flow, and adjusts early MMU and initramfs bring-up around the firmwareless runtime lane.
Constraint: The active PR lane still depends on full ACR1 EBSTATE save and restore across task switches
Rejected: Save only named EBARG fields | current bring-up still needs the full 0x1f40..0x1f5f window preserved per task
Confidence: medium
Scope-risk: broad
Directive: Do not shrink the saved ACR1 window without re-proving task-switch, FRET.STK, and full runtime lanes
Tested: git diff --check
Not-tested: kernel build, initramfs smoke, BusyBox full-OS regression
Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces numerous early bring-up workarounds, fixes, and boot-time bypasses for the Linx architecture, covering memory management, scheduling, locking, and CPU hotplug subsystems. The code review identified several critical issues that must be addressed: a severe security vulnerability in __get_kernel_nofault and __put_kernel_nofault due to global virtual-to-physical address conversion; a potential post-boot crash caused by marking the persistent linx_root_task_group_boot_buf with __initdata; missing parentheses in the LINX_BOOT_PT_LOW_ALIAS_LIMIT macro definition; broken cacheinfo initialization on SMP systems due to boot-CPU-only hotplug callbacks; a severe memory leak in finish_task_switch caused by an unreachable cleanup path; and a resource leak of MSI domains on initialization failure in the interrupt controller driver.

Comment on lines +347 to +349
if (is_kernel_mapping((unsigned long)__kr_src) || \
is_linear_mapping((unsigned long)__kr_src)) \
__kr_src = (const void *)(uintptr_t)__pa(__kr_src); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-criticalcritical

Converting kernel virtual addresses to physical addresses globally in __get_kernel_nofault and __put_kernel_nofault is highly dangerous. While this might work during early boot when identity mappings are active, at runtime (when user space processes are running), the active page table (current->mm->pgd) maps low virtual addresses to user space memory. Consequently, any attempt to use these nofault helpers at runtime while a user process is active will access the user's virtual memory instead of the kernel's physical memory. This is a critical security vulnerability and correctness bug. Please restrict this physical address conversion workaround to early boot (e.g., by checking system_state == SYSTEM_BOOTING) or avoid doing it globally.

Comment threadkernel/sched/core.c
Comment on lines +8845 to +8846
static unsigned long linx_root_task_group_boot_buf[512] __initdata
__aligned(SMP_CACHE_BYTES);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The static buffer linx_root_task_group_boot_buf is marked with __initdata. However, it is used as a persistent fallback backing store for root_task_group.se and root_task_group.cfs_rq, which must remain valid for the entire lifetime of the system. Since __initdata memory is freed and reclaimed after early boot completes, any scheduling activity after boot will access freed/reclaimed memory, leading to undefined behavior, silent data corruption, or a catastrophic kernel panic. Please remove the __initdata attribute from this buffer.

staticunsigned longlinx_root_task_group_boot_buf[512] __aligned(SMP_CACHE_BYTES);

#define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))

#if defined(__LINX__)
#define LINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The macro LINX_BOOT_PT_LOW_ALIAS_LIMIT is defined using a shift operator (<<) without surrounding parentheses. In C, shift operators have lower precedence than additive operators (+, -). If this macro is ever used in an additive expression (e.g., LINX_BOOT_PT_LOW_ALIAS_LIMIT + offset), it will be evaluated incorrectly as 64UL << (20 + offset). Please wrap the macro definition in parentheses to ensure safe evaluation.

Suggested change
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT(_AC(64, UL) << 20)

Comment on lines +1045 to +1056
ret = cpuhp_setup_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE,
"base/cacheinfo:online",
cacheinfo_cpu_online,
cacheinfo_cpu_pre_down);
if (ret)
return ret;

ret = cacheinfo_cpu_online(smp_processor_id());
if (ret) {
cpuhp_remove_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE);
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cpuhp_setup_state_nocalls and manually invoking the callback only on the boot CPU (smp_processor_id()) will break cacheinfo initialization on multi-core (SMP) systems. Since cacheinfo_sysfs_init is a device_initcall, it runs after secondary CPUs have already been brought online. By using nocalls and only manually invoking it on the boot CPU, all secondary CPUs will miss the cacheinfo_cpu_online callback, resulting in missing or uninitialized cacheinfo sysfs attributes for those CPUs. Please ensure that the callback is executed for all online CPUs, or restrict this workaround specifically to non-SMP/UP configurations.

Comment threadkernel/sched/core.c
Comment on lines +5348 to +5350
#if defined(CONFIG_LINX) || defined(__LINX__)
return rq;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The early return rq; added at line 5349 under defined(CONFIG_LINX) || defined(__LINX__) makes the entire rest of the finish_task_switch function unreachable. This completely bypasses critical cleanup steps, most notably mmdrop_lazy_tlb_sched(mm). As a result, mm_struct reference counts will leak on every task switch from a user process, leading to a severe memory leak. Please restructure the conditional compilation so that necessary cleanup steps are still executed.

Comment on lines +858 to +862
ret = setup_lxic(node, &nvec, &ndev, priv);
if (ret) {
error = ret;
goto out_iounmap;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If setup_lxic fails in lxic_init, the function jumps to out_iounmap but does not clean up the allocated MSI domains. This results in a resource leak of the PCI domain, base domain, and irqdomain created earlier in lxic_allocate_msi_domains. Please call irq_domain_cleanup(priv) in the error path before returning.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@zhoubot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Preserve Linx block state across Linux context switches and early boot - #23

Draft
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530
Draft

Preserve Linx block state across Linux context switches and early boot#23
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530

Conversation

@zhoubot

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx Linux work from the existing checkout
  • save and restore the full ACR1 EBSTATE window across __switch_to
  • tighten exception/return control flow and early MMU/initramfs bring-up for the firmwareless lane

Testing

  • git diff --check

Not tested

  • kernel build
  • initramfs smoke
  • BusyBox full-OS regression lane

The current work renames the EBSTATE window to spec-shaped SSR aliases, saves and restores the full ACR1 block-state window in __switch_to, tightens exception and return control flow, and adjusts early MMU and initramfs bring-up around the firmwareless runtime lane.
Constraint: The active PR lane still depends on full ACR1 EBSTATE save and restore across task switches
Rejected: Save only named EBARG fields | current bring-up still needs the full 0x1f40..0x1f5f window preserved per task
Confidence: medium
Scope-risk: broad
Directive: Do not shrink the saved ACR1 window without re-proving task-switch, FRET.STK, and full runtime lanes
Tested: git diff --check
Not-tested: kernel build, initramfs smoke, BusyBox full-OS regression
Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces numerous early bring-up workarounds, fixes, and boot-time bypasses for the Linx architecture, covering memory management, scheduling, locking, and CPU hotplug subsystems. The code review identified several critical issues that must be addressed: a severe security vulnerability in __get_kernel_nofault and __put_kernel_nofault due to global virtual-to-physical address conversion; a potential post-boot crash caused by marking the persistent linx_root_task_group_boot_buf with __initdata; missing parentheses in the LINX_BOOT_PT_LOW_ALIAS_LIMIT macro definition; broken cacheinfo initialization on SMP systems due to boot-CPU-only hotplug callbacks; a severe memory leak in finish_task_switch caused by an unreachable cleanup path; and a resource leak of MSI domains on initialization failure in the interrupt controller driver.

Comment on lines +347 to +349
if (is_kernel_mapping((unsigned long)__kr_src) || \
is_linear_mapping((unsigned long)__kr_src)) \
__kr_src = (const void *)(uintptr_t)__pa(__kr_src); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-criticalcritical

Converting kernel virtual addresses to physical addresses globally in __get_kernel_nofault and __put_kernel_nofault is highly dangerous. While this might work during early boot when identity mappings are active, at runtime (when user space processes are running), the active page table (current->mm->pgd) maps low virtual addresses to user space memory. Consequently, any attempt to use these nofault helpers at runtime while a user process is active will access the user's virtual memory instead of the kernel's physical memory. This is a critical security vulnerability and correctness bug. Please restrict this physical address conversion workaround to early boot (e.g., by checking system_state == SYSTEM_BOOTING) or avoid doing it globally.

Comment threadkernel/sched/core.c
Comment on lines +8845 to +8846
static unsigned long linx_root_task_group_boot_buf[512] __initdata
__aligned(SMP_CACHE_BYTES);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The static buffer linx_root_task_group_boot_buf is marked with __initdata. However, it is used as a persistent fallback backing store for root_task_group.se and root_task_group.cfs_rq, which must remain valid for the entire lifetime of the system. Since __initdata memory is freed and reclaimed after early boot completes, any scheduling activity after boot will access freed/reclaimed memory, leading to undefined behavior, silent data corruption, or a catastrophic kernel panic. Please remove the __initdata attribute from this buffer.

staticunsigned longlinx_root_task_group_boot_buf[512] __aligned(SMP_CACHE_BYTES);

#define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))

#if defined(__LINX__)
#define LINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The macro LINX_BOOT_PT_LOW_ALIAS_LIMIT is defined using a shift operator (<<) without surrounding parentheses. In C, shift operators have lower precedence than additive operators (+, -). If this macro is ever used in an additive expression (e.g., LINX_BOOT_PT_LOW_ALIAS_LIMIT + offset), it will be evaluated incorrectly as 64UL << (20 + offset). Please wrap the macro definition in parentheses to ensure safe evaluation.

Suggested change
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT(_AC(64, UL) << 20)

Comment on lines +1045 to +1056
ret = cpuhp_setup_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE,
"base/cacheinfo:online",
cacheinfo_cpu_online,
cacheinfo_cpu_pre_down);
if (ret)
return ret;

ret = cacheinfo_cpu_online(smp_processor_id());
if (ret) {
cpuhp_remove_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE);
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cpuhp_setup_state_nocalls and manually invoking the callback only on the boot CPU (smp_processor_id()) will break cacheinfo initialization on multi-core (SMP) systems. Since cacheinfo_sysfs_init is a device_initcall, it runs after secondary CPUs have already been brought online. By using nocalls and only manually invoking it on the boot CPU, all secondary CPUs will miss the cacheinfo_cpu_online callback, resulting in missing or uninitialized cacheinfo sysfs attributes for those CPUs. Please ensure that the callback is executed for all online CPUs, or restrict this workaround specifically to non-SMP/UP configurations.

Comment threadkernel/sched/core.c
Comment on lines +5348 to +5350
#if defined(CONFIG_LINX) || defined(__LINX__)
return rq;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The early return rq; added at line 5349 under defined(CONFIG_LINX) || defined(__LINX__) makes the entire rest of the finish_task_switch function unreachable. This completely bypasses critical cleanup steps, most notably mmdrop_lazy_tlb_sched(mm). As a result, mm_struct reference counts will leak on every task switch from a user process, leading to a severe memory leak. Please restructure the conditional compilation so that necessary cleanup steps are still executed.

Comment on lines +858 to +862
ret = setup_lxic(node, &nvec, &ndev, priv);
if (ret) {
error = ret;
goto out_iounmap;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If setup_lxic fails in lxic_init, the function jumps to out_iounmap but does not clean up the allocated MSI domains. This results in a resource leak of the PCI domain, base domain, and irqdomain created earlier in lxic_allocate_msi_domains. Please call irq_domain_cleanup(priv) in the error path before returning.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@zhoubot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Preserve Linx block state across Linux context switches and early boot - #23

Draft
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530
Draft

Preserve Linx block state across Linux context switches and early boot#23
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530

Conversation

@zhoubot

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx Linux work from the existing checkout
  • save and restore the full ACR1 EBSTATE window across __switch_to
  • tighten exception/return control flow and early MMU/initramfs bring-up for the firmwareless lane

Testing

  • git diff --check

Not tested

  • kernel build
  • initramfs smoke
  • BusyBox full-OS regression lane

The current work renames the EBSTATE window to spec-shaped SSR aliases, saves and restores the full ACR1 block-state window in __switch_to, tightens exception and return control flow, and adjusts early MMU and initramfs bring-up around the firmwareless runtime lane.
Constraint: The active PR lane still depends on full ACR1 EBSTATE save and restore across task switches
Rejected: Save only named EBARG fields | current bring-up still needs the full 0x1f40..0x1f5f window preserved per task
Confidence: medium
Scope-risk: broad
Directive: Do not shrink the saved ACR1 window without re-proving task-switch, FRET.STK, and full runtime lanes
Tested: git diff --check
Not-tested: kernel build, initramfs smoke, BusyBox full-OS regression
Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces numerous early bring-up workarounds, fixes, and boot-time bypasses for the Linx architecture, covering memory management, scheduling, locking, and CPU hotplug subsystems. The code review identified several critical issues that must be addressed: a severe security vulnerability in __get_kernel_nofault and __put_kernel_nofault due to global virtual-to-physical address conversion; a potential post-boot crash caused by marking the persistent linx_root_task_group_boot_buf with __initdata; missing parentheses in the LINX_BOOT_PT_LOW_ALIAS_LIMIT macro definition; broken cacheinfo initialization on SMP systems due to boot-CPU-only hotplug callbacks; a severe memory leak in finish_task_switch caused by an unreachable cleanup path; and a resource leak of MSI domains on initialization failure in the interrupt controller driver.

Comment on lines +347 to +349
if (is_kernel_mapping((unsigned long)__kr_src) || \
is_linear_mapping((unsigned long)__kr_src)) \
__kr_src = (const void *)(uintptr_t)__pa(__kr_src); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-criticalcritical

Converting kernel virtual addresses to physical addresses globally in __get_kernel_nofault and __put_kernel_nofault is highly dangerous. While this might work during early boot when identity mappings are active, at runtime (when user space processes are running), the active page table (current->mm->pgd) maps low virtual addresses to user space memory. Consequently, any attempt to use these nofault helpers at runtime while a user process is active will access the user's virtual memory instead of the kernel's physical memory. This is a critical security vulnerability and correctness bug. Please restrict this physical address conversion workaround to early boot (e.g., by checking system_state == SYSTEM_BOOTING) or avoid doing it globally.

Comment threadkernel/sched/core.c
Comment on lines +8845 to +8846
static unsigned long linx_root_task_group_boot_buf[512] __initdata
__aligned(SMP_CACHE_BYTES);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The static buffer linx_root_task_group_boot_buf is marked with __initdata. However, it is used as a persistent fallback backing store for root_task_group.se and root_task_group.cfs_rq, which must remain valid for the entire lifetime of the system. Since __initdata memory is freed and reclaimed after early boot completes, any scheduling activity after boot will access freed/reclaimed memory, leading to undefined behavior, silent data corruption, or a catastrophic kernel panic. Please remove the __initdata attribute from this buffer.

staticunsigned longlinx_root_task_group_boot_buf[512] __aligned(SMP_CACHE_BYTES);

#define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))

#if defined(__LINX__)
#define LINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The macro LINX_BOOT_PT_LOW_ALIAS_LIMIT is defined using a shift operator (<<) without surrounding parentheses. In C, shift operators have lower precedence than additive operators (+, -). If this macro is ever used in an additive expression (e.g., LINX_BOOT_PT_LOW_ALIAS_LIMIT + offset), it will be evaluated incorrectly as 64UL << (20 + offset). Please wrap the macro definition in parentheses to ensure safe evaluation.

Suggested change
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT(_AC(64, UL) << 20)

Comment on lines +1045 to +1056
ret = cpuhp_setup_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE,
"base/cacheinfo:online",
cacheinfo_cpu_online,
cacheinfo_cpu_pre_down);
if (ret)
return ret;

ret = cacheinfo_cpu_online(smp_processor_id());
if (ret) {
cpuhp_remove_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE);
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cpuhp_setup_state_nocalls and manually invoking the callback only on the boot CPU (smp_processor_id()) will break cacheinfo initialization on multi-core (SMP) systems. Since cacheinfo_sysfs_init is a device_initcall, it runs after secondary CPUs have already been brought online. By using nocalls and only manually invoking it on the boot CPU, all secondary CPUs will miss the cacheinfo_cpu_online callback, resulting in missing or uninitialized cacheinfo sysfs attributes for those CPUs. Please ensure that the callback is executed for all online CPUs, or restrict this workaround specifically to non-SMP/UP configurations.

Comment threadkernel/sched/core.c
Comment on lines +5348 to +5350
#if defined(CONFIG_LINX) || defined(__LINX__)
return rq;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The early return rq; added at line 5349 under defined(CONFIG_LINX) || defined(__LINX__) makes the entire rest of the finish_task_switch function unreachable. This completely bypasses critical cleanup steps, most notably mmdrop_lazy_tlb_sched(mm). As a result, mm_struct reference counts will leak on every task switch from a user process, leading to a severe memory leak. Please restructure the conditional compilation so that necessary cleanup steps are still executed.

Comment on lines +858 to +862
ret = setup_lxic(node, &nvec, &ndev, priv);
if (ret) {
error = ret;
goto out_iounmap;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If setup_lxic fails in lxic_init, the function jumps to out_iounmap but does not clean up the allocated MSI domains. This results in a resource leak of the PCI domain, base domain, and irqdomain created earlier in lxic_allocate_msi_domains. Please call irq_domain_cleanup(priv) in the error path before returning.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@zhoubot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Preserve Linx block state across Linux context switches and early boot - #23

Draft
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530
Draft

Preserve Linx block state across Linux context switches and early boot#23
zhoubot wants to merge 1 commit into
mainfrom
codex/model-polish-20260530

Conversation

@zhoubot

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx Linux work from the existing checkout
  • save and restore the full ACR1 EBSTATE window across __switch_to
  • tighten exception/return control flow and early MMU/initramfs bring-up for the firmwareless lane

Testing

  • git diff --check

Not tested

  • kernel build
  • initramfs smoke
  • BusyBox full-OS regression lane

The current work renames the EBSTATE window to spec-shaped SSR aliases, saves and restores the full ACR1 block-state window in __switch_to, tightens exception and return control flow, and adjusts early MMU and initramfs bring-up around the firmwareless runtime lane.
Constraint: The active PR lane still depends on full ACR1 EBSTATE save and restore across task switches
Rejected: Save only named EBARG fields | current bring-up still needs the full 0x1f40..0x1f5f window preserved per task
Confidence: medium
Scope-risk: broad
Directive: Do not shrink the saved ACR1 window without re-proving task-switch, FRET.STK, and full runtime lanes
Tested: git diff --check
Not-tested: kernel build, initramfs smoke, BusyBox full-OS regression
Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assistgemini-code-assistBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces numerous early bring-up workarounds, fixes, and boot-time bypasses for the Linx architecture, covering memory management, scheduling, locking, and CPU hotplug subsystems. The code review identified several critical issues that must be addressed: a severe security vulnerability in __get_kernel_nofault and __put_kernel_nofault due to global virtual-to-physical address conversion; a potential post-boot crash caused by marking the persistent linx_root_task_group_boot_buf with __initdata; missing parentheses in the LINX_BOOT_PT_LOW_ALIAS_LIMIT macro definition; broken cacheinfo initialization on SMP systems due to boot-CPU-only hotplug callbacks; a severe memory leak in finish_task_switch caused by an unreachable cleanup path; and a resource leak of MSI domains on initialization failure in the interrupt controller driver.

Comment on lines +347 to +349
if (is_kernel_mapping((unsigned long)__kr_src) || \
is_linear_mapping((unsigned long)__kr_src)) \
__kr_src = (const void *)(uintptr_t)__pa(__kr_src); \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-criticalcritical

Converting kernel virtual addresses to physical addresses globally in __get_kernel_nofault and __put_kernel_nofault is highly dangerous. While this might work during early boot when identity mappings are active, at runtime (when user space processes are running), the active page table (current->mm->pgd) maps low virtual addresses to user space memory. Consequently, any attempt to use these nofault helpers at runtime while a user process is active will access the user's virtual memory instead of the kernel's physical memory. This is a critical security vulnerability and correctness bug. Please restrict this physical address conversion workaround to early boot (e.g., by checking system_state == SYSTEM_BOOTING) or avoid doing it globally.

Comment threadkernel/sched/core.c
Comment on lines +8845 to +8846
static unsigned long linx_root_task_group_boot_buf[512] __initdata
__aligned(SMP_CACHE_BYTES);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The static buffer linx_root_task_group_boot_buf is marked with __initdata. However, it is used as a persistent fallback backing store for root_task_group.se and root_task_group.cfs_rq, which must remain valid for the entire lifetime of the system. Since __initdata memory is freed and reclaimed after early boot completes, any scheduling activity after boot will access freed/reclaimed memory, leading to undefined behavior, silent data corruption, or a catastrophic kernel panic. Please remove the __initdata attribute from this buffer.

staticunsigned longlinx_root_task_group_boot_buf[512] __aligned(SMP_CACHE_BYTES);

#define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))

#if defined(__LINX__)
#define LINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The macro LINX_BOOT_PT_LOW_ALIAS_LIMIT is defined using a shift operator (<<) without surrounding parentheses. In C, shift operators have lower precedence than additive operators (+, -). If this macro is ever used in an additive expression (e.g., LINX_BOOT_PT_LOW_ALIAS_LIMIT + offset), it will be evaluated incorrectly as 64UL << (20 + offset). Please wrap the macro definition in parentheses to ensure safe evaluation.

Suggested change
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT _AC(64, UL) << 20
#defineLINX_BOOT_PT_LOW_ALIAS_LIMIT(_AC(64, UL) << 20)

Comment on lines +1045 to +1056
ret = cpuhp_setup_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE,
"base/cacheinfo:online",
cacheinfo_cpu_online,
cacheinfo_cpu_pre_down);
if (ret)
return ret;

ret = cacheinfo_cpu_online(smp_processor_id());
if (ret) {
cpuhp_remove_state_nocalls(CPUHP_AP_BASE_CACHEINFO_ONLINE);
return ret;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using cpuhp_setup_state_nocalls and manually invoking the callback only on the boot CPU (smp_processor_id()) will break cacheinfo initialization on multi-core (SMP) systems. Since cacheinfo_sysfs_init is a device_initcall, it runs after secondary CPUs have already been brought online. By using nocalls and only manually invoking it on the boot CPU, all secondary CPUs will miss the cacheinfo_cpu_online callback, resulting in missing or uninitialized cacheinfo sysfs attributes for those CPUs. Please ensure that the callback is executed for all online CPUs, or restrict this workaround specifically to non-SMP/UP configurations.

Comment threadkernel/sched/core.c
Comment on lines +5348 to +5350
#if defined(CONFIG_LINX) || defined(__LINX__)
return rq;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The early return rq; added at line 5349 under defined(CONFIG_LINX) || defined(__LINX__) makes the entire rest of the finish_task_switch function unreachable. This completely bypasses critical cleanup steps, most notably mmdrop_lazy_tlb_sched(mm). As a result, mm_struct reference counts will leak on every task switch from a user process, leading to a severe memory leak. Please restructure the conditional compilation so that necessary cleanup steps are still executed.

Comment on lines +858 to +862
ret = setup_lxic(node, &nvec, &ndev, priv);
if (ret) {
error = ret;
goto out_iounmap;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If setup_lxic fails in lxic_init, the function jumps to out_iounmap but does not clean up the allocated MSI domains. This results in a resource leak of the PCI domain, base domain, and irqdomain created earlier in lxic_allocate_msi_domains. Please call irq_domain_cleanup(priv) in the error path before returning.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@zhoubot