Skip to content

Model Linx EBSTATE and firmwareless direct-kernel boot in QEMU#31

Draft
zhoubot wants to merge 4 commits into
masterfrom
codex/model-polish-20260530
Draft

Model Linx EBSTATE and firmwareless direct-kernel boot in QEMU#31
zhoubot wants to merge 4 commits into
masterfrom
codex/model-polish-20260530

Conversation

@zhoubot

@zhoubot zhoubot commented May 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • package the current model-generated Linx QEMU work from the existing checkout
  • make the ACR1 EBSTATE window explicit in CSR naming and state handling
  • add firmwareless direct-kernel boot seeding, low-page diagnostics, and related translate/execute bring-up changes

Testing

  • git diff --check

Not tested

  • QEMU build
  • runtime smoke
  • TSVC and full-OS gates

RuoyuZhou and others added 4 commits May 18, 2026 19:26
…base

The recovered my.patch is treated as the authoritative latest Linx QEMU line. This commit captures the full applied tree on the old upstream base that best matches the patch, including target/linx, linux-user/linx, the older linx-softmmu and linx-linux-user target surfaces, and the supporting core-file changes.

Constraint: The recovered patch references an unrecoverable LinxInit firmware blob and internal submodule URLs, so this commit keeps the source tree coherent while making minimal local build adaptations for missing firmware-at-configure and Darwin host gating

Rejected: Keep the newer partial forward-port as master | it does not represent the authoritative latest implementation from my.patch

Confidence: medium

Scope-risk: broad

Reversibility: clean

Directive: Treat this branch as the source of truth for the recovered latest Linx QEMU line; do not mix it with the newer partial linx64-softmmu line without an explicit port plan

Tested: linx-linux-user configure reaches target generation on Darwin after local host-policy relaxations

Not-tested: successful full build of qemu-linx or qemu-system-linx from this branch
The previous commit captured the applied latest tree from my.patch, but also included transient files from local configure probing under build-user. Remove those generated artifacts so the branch contains only intended source content.

Confidence: high

Scope-risk: narrow

Reversibility: clean

Tested: branch status clean aside from expected source changes before commit
* Sync QEMU firmware and CI submodule baselines

Advance the vendored ROM and libvirt-ci gitlinks together so the emulator tree points at one consistent set of external firmware and CI snapshots.

Constraint: This repository tracks ROM and CI dependencies as gitlink snapshots rather than in-tree copies
Rejected: Leave the existing mixed submodule revisions in place | makes emulator state harder to reproduce
Confidence: medium
Scope-risk: narrow
Directive: Treat these gitlink bumps as a coordinated baseline update and validate firmware-dependent flows before bisecting emulator regressions across them
Tested: git diff --check
Not-tested: QEMU build, firmware boot, or CI execution

* Stabilize the recovered Linx64 QEMU branch for clean rebuilds

Preserve the recovered v7.0.0-based Linx implementation while making the branch reproducible from a fresh configure/build and aligning boot/reset handling with the recovered firmwareless lane.

Constraint: Recovered patch line is authoritative and must stay on the v7.0.0 compatibility base
Rejected: Rebase the recovered implementation onto current upstream master | much larger integration surface with no validation benefit for this lane
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep linx64-softmmu single-target shims in sync with target/linx header expectations before changing Meson target wiring
Tested: Fresh ../configure --target-list=linx64-softmmu --disable-werror, full ninja build, qemu-system-linx64-unsigned --version
Not-tested: Guest boot/runtime smoke beyond binary startup

---------

Co-authored-by: RuoyuZhou <ruoyu.zhou@hisilicon.com>
The staged work extends CSR naming and live block-state handling, adds firmwareless direct-kernel boot seeding plus low-page debug hooks, and broadens decode, translate, execute, and bring-up device behavior around the current Linux runtime lane.

Constraint: The current runtime lane depends on ACR1 EBSTATE visibility and firmwareless boot instead of a Linx firmware blob

Rejected: Split direct-boot hooks from EBSTATE and translate/execute work | the user asked to package the current cohesive worktree state

Confidence: medium

Scope-risk: broad

Directive: Keep the ACR1 0x1f40..0x1f5f window as live architectural block state; emulator-only spill data belongs in hidden extension slots

Tested: git diff --check

Not-tested: qemu build, runtime smoke, TSVC and full-OS gates

Co-authored-by: OmX <omx@oh-my-codex.dev>

@gemini-code-assist gemini-code-assist Bot 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 the new 'linx' target architecture, including custom CPU, memory, and interrupt controller (LXIC) models, along with support for atomic block execution, custom debugging tools, and low-precision softfloat types. While the implementation is comprehensive, several critical issues must be addressed. These include a potential out-of-bounds memory read in loader.c due to integer underflow, a potential NULL pointer dereference in linx_hart.c, a missing break statement in tcg-accel-ops-mttcg.c, and a regression in configure that breaks non-Linux compilation. Additionally, several portability issues with format specifiers, GDB syntax errors, and code style violations should be resolved.

Comment thread hw/core/loader.c
Comment on lines +1176 to +1183
if (rom->data && rom->datasize > 0x5c - rom->addr + 7) {
size_t off = 0x5c - rom->addr;
uint8_t *p = rom->data + off;
error_report("LINX_ROM_LOW[%s] src_5c=%02x %02x %02x %02x %02x %02x %02x %02x",
rom->name,
p[0], p[1], p[2], p[3],
p[4], p[5], p[6], p[7]);
}

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

If rom->addr is greater than 0x5c (for example, 0x60), the expression 0x5c - rom->addr will underflow to a very large unsigned value. This causes rom->datasize > 0x5c - rom->addr + 7 to evaluate to true, and subsequently rom->data + off will point to an out-of-bounds memory location (before rom->data), leading to an out-of-bounds read and potential crash. Add a check to ensure rom->addr <= 0x5c before performing the subtraction.

                if (rom->data && rom->addr <= 0x5c && rom->datasize > 0x5c - rom->addr + 7) {
                    size_t off = 0x5c - rom->addr;
                    uint8_t *p = rom->data + off;
                    error_report("LINX_ROM_LOW[%s] src_5c=%02x %02x %02x %02x %02x %02x %02x %02x",
                                 rom->name,
                                 p[0], p[1], p[2], p[3],
                                 p[4], p[5], p[6], p[7]);
                }

Comment thread accel/tcg/cpu-exec.c
Comment on lines +1013 to +1014
printf("cpu %d: linx_debug max insn (%lu) reach on %lu\n",
cpu->cpu_index, cpu->max_insn_count, cpu->insn_count);

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 %lu to print uint64_t variables (cpu->max_insn_count and cpu->insn_count) is non-portable and will cause compilation warnings or errors on 32-bit platforms or 64-bit Windows where long is 32-bit. Use PRIu64 instead. Also, consider using qemu_log instead of printf to avoid polluting stdout.

            qemu_log("cpu %d: linx_debug max insn (%" PRIu64 ") reach on %" PRIu64 "\n",
                     cpu->cpu_index, cpu->max_insn_count, cpu->insn_count);

case EXCP_ATOMIC_BLK:
qemu_mutex_unlock_iothread();
cpu_exec_multi_steps_atomic(cpu);
qemu_mutex_lock_iothread();

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

There is a missing break statement at the end of case EXCP_ATOMIC_BLK:, which causes execution to fall through to default:. While default currently only contains a break, this is extremely fragile and violates coding standards.

Suggested change
qemu_mutex_lock_iothread();
qemu_mutex_lock_iothread();
break;

Comment thread configure

if [ "$linux_user" != no ]; then
if [ "$targetos" = linux ] && [ -d $source_path/linux-user/include/host/$cpu ]; then
if [ -d $source_path/linux-user/include/host/$cpu ]; then

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

Removing [ "$targetos" = linux ] allows linux-user to be enabled on non-Linux hosts (such as macOS or BSD) if the directory $source_path/linux-user/include/host/$cpu exists. Since linux-user relies on Linux-specific system calls and headers, this will cause compilation failures on non-Linux platforms.

Suggested change
if [ -d $source_path/linux-user/include/host/$cpu ]; then
if [ "$targetos" = linux ] && [ -d $source_path/linux-user/include/host/$cpu ]; then

Comment thread hw/intc/lxintc.c
offset = offset % VIRT_LXIC_DOMAIN_STRIDE;

if (dom < 0 || dom >= VIRT_LXIC_DOMAIN_NUM) {
qemu_log("Error offset: %lx, error domain: %x\n", offset, dom);

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 %lx to print hwaddr (which is uint64_t) is non-portable and will fail to compile on 32-bit hosts where hwaddr is unsigned long long. Use HWADDR_PRIx instead. Also, use qemu_log_mask(LOG_GUEST_ERROR, ...) instead of bare qemu_log for guest errors.

        qemu_log_mask(LOG_GUEST_ERROR, "Error offset: %" HWADDR_PRIx ", error domain: %x\n", offset, dom);

Comment thread .gdbinit

# Load QEMU-specific sub-commands and settings
source scripts/qemu-gdb.py
qemu.gdbinit No newline at end of file

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

Just writing qemu.gdbinit is not a valid GDB command and will result in a syntax error when GDB attempts to load this file. It should be prefixed with the source command.

source qemu.gdbinit

Comment thread .gitmodules
[submodule "dtc"]
path = dtc
url = https://gitlab.com/qemu-project/dtc.git
url = ssh://git@szv-y.codehub.huawei.com:2222/qemu/dtc.git

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

Hardcoding internal corporate URLs (such as szv-y.codehub.huawei.com) in .gitmodules prevents external contributors from cloning the submodules. Consider using public mirrors or relative paths if possible.

Comment thread hw/intc/lxintc.c
Comment on lines +444 to +449
ctl->page[i].threshold = 0;
for (j = 0; j < CTL_PENDING_WORD; j++)
ctl->page[i].pending[j] = 0;
for (j = 0; j < CTL_ENABLE_WORD; j++)
ctl->page[i].enable[j] = 0xFFFFFFFF;
for (j = 0; j < CTL_TYPE_WORD; j++)

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

QEMU coding style requires braces {} for all blocks, even single-line ones.

        for (j = 0; j < CTL_PENDING_WORD; j++) {
            ctl->page[i].pending[j] = 0;
        }
        for (j = 0; j < CTL_ENABLE_WORD; j++) {
            ctl->page[i].enable[j] = 0xFFFFFFFF;
        }
        for (j = 0; j < CTL_TYPE_WORD; j++) {
            ctl->page[i].type[j] = 0x11111111;
        }

Comment thread hw/linx/boot.c
Comment on lines +282 to +287
int i;
uint32_t start_addr_hi32 = start_addr >> 32;
uint32_t kernel_entry_hi32 = kernel_entry >> 32;

/* reset vector */
/* a0->lxlcid, a1->fdt_laddr, a2->kernel_entry */

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

Assigning start_addr and kernel_entry (which are 64-bit hwaddr/uint64_t values) directly to elements of the uint32_t array reset_vec will cause implicit truncation compiler warnings. Cast them to uint32_t explicitly.

        (uint32_t)start_addr,                  /* start: .dword                   */
        start_addr_hi32,
        fdt_load_addr,               /* fdt_laddr: .dword               */
        0x00000000,
        (uint32_t)kernel_entry,                /* kernel_entry: .dword            */
        kernel_entry_hi32,

Comment thread include/hw/core/cpu.h
#define QEMU_CPU_H

#include "hw/qdev-core.h"
#include "hw/core/cpu.h"

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

The header file include/hw/core/cpu.h is including itself, which is redundant and a code smell.

Sign up for free to 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