Skip to content

Commit

Permalink
Support context in VCPC thread.
Browse files Browse the repository at this point in the history
TODO: We need to more test cases.

Signed-off-by: Nobuhiro MIKI <[email protected]>
  • Loading branch information
bobuhiro11 committed Aug 20, 2024
1 parent 0d81149 commit d947c0e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 33 deletions.
69 changes: 40 additions & 29 deletions machine/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package machine

import (
"bytes"
"context"
"debug/elf"
"encoding/binary"
"encoding/hex"
Expand Down Expand Up @@ -803,7 +804,7 @@ func (m *Machine) SingleStep(onoff bool) error {

// RunInfiniteLoop runs the guest cpu until there is an error.
// If the error is ErrExitDebug, this function can be called again.
func (m *Machine) RunInfiniteLoop(cpu int) error {
func (m *Machine) RunInfiniteLoop(ctx context.Context, cpu int) error {
// https://www.kernel.org/doc/Documentation/virtual/kvm/api.txt
// - vcpu ioctls: These query and set attributes that control the operation
// of a single virtual cpu.
Expand All @@ -822,17 +823,22 @@ func (m *Machine) RunInfiniteLoop(cpu int) error {
defer runtime.UnlockOSThread()

for {
isContinue, err := m.RunOnce(cpu)
if isContinue {
if err != nil {
fmt.Printf("%v\r\n", err)
}
select {
case <-ctx.Done():
return nil
default:
isContinue, err := m.RunOnce(cpu)
if isContinue {
if err != nil {
fmt.Printf("%v\r\n", err)
}

continue
}
continue
}

if err != nil {
return err
if err != nil {
return err
}
}
}
}
Expand Down Expand Up @@ -1248,36 +1254,41 @@ func initVMandVCPU(
return kvmFd, vmFd, vcpuFds, runs, nil
}

func (m *Machine) VCPU(stdout io.Writer, cpu, traceCount int) error {
func (m *Machine) VCPU(ctx context.Context, stdout io.Writer, cpu, traceCount int) error {
trace := traceCount > 0

var err error
// Consider ANOTHER option, maxInsCount, which would
// exit this loop after a certain number of instructions
// were run.
for tc := 0; ; tc++ {
err = m.RunInfiniteLoop(cpu)
if err == nil {
continue
}
select {
case <-ctx.Done():
return nil
default:
err = m.RunInfiniteLoop(ctx, cpu)
if err == nil {
continue
}

if !errors.Is(err, kvm.ErrDebug) {
return fmt.Errorf("CPU %d: %w", cpu, err)
}
if !errors.Is(err, kvm.ErrDebug) {
return fmt.Errorf("CPU %d: %w", cpu, err)
}

if err := m.SingleStep(trace); err != nil {
fmt.Fprintf(stdout, "Setting trace to %v:%v", trace, err)
}
if err := m.SingleStep(trace); err != nil {
fmt.Fprintf(stdout, "Setting trace to %v:%v", trace, err)
}

if tc%traceCount != 0 {
continue
}
if tc%traceCount != 0 {
continue
}

_, r, s, err := m.Inst(cpu)
if err != nil {
fmt.Fprintf(stdout, "disassembling after debug exit:%v", err)
} else {
fmt.Fprintf(stdout, "%#x:%s\r\n", r.RIP, s)
_, r, s, err := m.Inst(cpu)
if err != nil {
fmt.Fprintf(stdout, "disassembling after debug exit:%v", err)
} else {
fmt.Fprintf(stdout, "%#x:%s\r\n", r.RIP, s)
}
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions machine/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package machine_test

import (
"bytes"
"context"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -71,8 +72,10 @@ func testNewAndLoadLinux(t *testing.T, kernel, tap, guestIPv4, hostIPv4, prefixL

m.RunData()

ctx := context.Background()

go func() {
if err = m.RunInfiniteLoop(0); err != nil {
if err = m.RunInfiniteLoop(ctx, 0); err != nil {
panic(err)
}
}()
Expand Down Expand Up @@ -146,8 +149,10 @@ func TestNewAndLoadEDK2PVH(t *testing.T) { // nolint:paralleltest

m.RunData()

ctx := context.Background()

go func() {
if err = m.RunInfiniteLoop(0); err != nil {
if err = m.RunInfiniteLoop(ctx, 0); err != nil {
panic(err)
}
}()
Expand Down
5 changes: 3 additions & 2 deletions vmm/vmm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package vmm

import (
"bufio"
"context"
"fmt"
"log"
"os"
Expand Down Expand Up @@ -104,15 +105,15 @@ func (v *VMM) Boot() error {
return fmt.Errorf("setting trace to %v:%w", trace, err)
}

g := new(errgroup.Group)
g, ctx := errgroup.WithContext(context.Background())

for cpu := 0; cpu < v.NCPUs; cpu++ {
fmt.Printf("Start CPU %d of %d\r\n", cpu, v.NCPUs)

i := cpu

f := func() error {
return v.VCPU(os.Stderr, i, v.TraceCount)
return v.VCPU(ctx, os.Stderr, i, v.TraceCount)
}

g.Go(f)
Expand Down

0 comments on commit d947c0e

Please sign in to comment.