Skip to content

LoongArch: non-root zone cannot boot normally after shutdown and restart #369

Description

@li041

Summary

On LoongArch ls3a6000, a non-root Linux zone (linux1, CPUs 2-3) can boot the first time, but after hvisor zone shutdown -id 1 and then ./start.sh 1, it no longer boots normally. The hypercall path reports the zone as running, but the non-root console does not reach login and screen /dev/pts/0 times out.

Environment

  • Board: Loongson 3A6000 / ls3a6000
  • Branch under test: fix-interrupt-la
  • Root Linux: 6.11.6
  • Non-root linux1: 6.13.7
  • Non-root zone config: linux1, CPU mask 0xc (pCPU 2 and 3)

Reproduction

  1. Boot hvisor on ls3a6000.
  2. In root Linux, start daemon and then start linux1:
    ./daemon.sh
    ./start.sh 1
  3. Confirm linux1 boots and can reach its console.
  4. Shut down linux1:
    hvisor zone shutdown -id 1
  5. Start linux1 again:
    ./start.sh 1
  6. Check zone list and console:
    hvisor zone list
    timeout -k 2s 12s screen /dev/pts/0

Observed behavior

During shutdown, both shutdown events are enqueued, but CPU3 may not enter Stopped before MAX_WAIT_TIMES expires:

hvisor zone shutdown -id 1;
[INFO  0] (hvisor::hypercall:269) handle hvc zone shutdown, id=1
[INFO  0] (hvisor::event:87) [HVDBG:event-enqueue] seq=8884 src_cpu=0 dst_cpu=2 event=1 armed=true queue_len=1 kick=true
[INFO  0] (hvisor::event:87) [HVDBG:event-enqueue] seq=8885 src_cpu=0 dst_cpu=3 event=1 armed=true queue_len=1 kick=true
[INFO  2] (hvisor::event:240) [HVDBG:event-drain] seq=8886 cpu=2 event=1 more_pending=false
[INFO  2] (hvisor::arch::loongarch64::cpu:144) loongarch64: ArchCpu::idle: cpuid=2
[ERROR 0] (hvisor::hypercall:316) cpu 3 cannot be shut down
[INFO  3] (hvisor::event:240) [HVDBG:event-drain] seq=8887 cpu=3 event=1 more_pending=false
[INFO  3] (hvisor::arch::loongarch64::cpu:144) loongarch64: ArchCpu::idle: cpuid=3
[INFO  0] (hvisor::hypercall:346) zone 1 has been shutdown

The shutdown ioctl still returns success and the zone is removed. The following restart returns success and reports the zone as running, but only CPU2 is observed to run; the log does not show the expected CPU3 wakeup/drain sequence before the console test:

./start.sh 1;
booting zone linux1 with configuration: /tool/linux1.json
[INFO  0] (hvisor::zone:914) zone cpu_set: 0b1100
[INFO  0] (hvisor::hypercall:255) boot_cpu: 2
[INFO  0] (hvisor::event:87) [HVDBG:event-enqueue] seq=8922 src_cpu=0 dst_cpu=2 event=0 armed=true queue_len=1 kick=true

hvisor zone list
|     zone_id     |       cpus        |      name       |     status |
|               0 |              0, 1 | root-linux-la64 |    running |
|               1 |              2, 3 |          linux1 |    running |

timeout -k 2s 12s screen /dev/pts/0

A later iteration with additional idle IRQ logging shows the boot CPU does drain the wakeup event and enters guest at the kernel entry, but the console still times out:

[INFO  1] (hvisor::hypercall:255) boot_cpu: 2
[INFO  1] (hvisor::event:87) [HVDBG:event-enqueue] seq=9077 src_cpu=1 dst_cpu=2 event=0 armed=true queue_len=1 kick=true
[INFO  2] (hvisor::event:240) [HVDBG:event-drain] seq=9078 cpu=2 event=0 more_pending=false
[INFO  2] (hvisor::arch::loongarch64::cpu:90) [[CPU virtualization]] CPU2 run@0x900000021da22000

hvisor zone list
|     zone_id     |       cpus        |      name       |     status |
|               0 |              0, 1 | root-linux-la64 |    running |
|               1 |              2, 3 |          linux1 |    running |

timeout -k 2s 12s screen /dev/pts/0

Expected behavior

After a successful hvisor zone shutdown -id 1, starting the same non-root zone again should reproduce the first boot behavior: linux1 should boot, bring up its secondary CPU if configured, and the non-root console should reach login.

Initial investigation

The failure appears related to LoongArch zone lifecycle cleanup/reinitialization rather than the userspace CLI path:

  • HVISOR_ZONE_SHUTDOWN maps directly to hvisor_call(HVISOR_HC_SHUTDOWN_ZONE, arg, 0) in hvisor-tool/driver/hvisor_main.c.
  • hv_zone_shutdown() enqueues IPI_EVENT_SHUTDOWN to each zone CPU, then busy-waits for all CPUs to become Stopped. The log shows CPU3 can process shutdown after the wait path has already emitted cpu 3 cannot be shut down.
  • The shutdown function still proceeds to clear zone, reset irqchip state, remove the zone, and return success.
  • On restart, hv_zone_start() only sends IPI_EVENT_WAKEUP to the boot CPU. The non-root kernel is then expected to bring up CPU3 through virtual IPI/SMP. In the failing run, linux1 does not reach a usable console.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions