diff options
Diffstat (limited to 'pkg/sentry/platform/kvm/machine.go')
-rw-r--r-- | pkg/sentry/platform/kvm/machine.go | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index 68e099d1b..9f60b6b31 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -22,6 +22,7 @@ import ( "syscall" "gvisor.googlesource.com/gvisor/pkg/atomicbitops" + "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/sentry/platform/procid" "gvisor.googlesource.com/gvisor/pkg/sentry/platform/ring0" "gvisor.googlesource.com/gvisor/pkg/sentry/platform/ring0/pagetables" @@ -55,6 +56,12 @@ type machine struct { // // These are populated dynamically. vCPUs map[uint64]*vCPU + + // vCPUsByID are the machine vCPUs, can be indexed by the vCPU's ID. + vCPUsByID map[int]*vCPU + + // maxVCPUs is the maximum number of vCPUs supported by the machine. + maxVCPUs int } const ( @@ -135,6 +142,7 @@ func (m *machine) newVCPU() *vCPU { c.CPU.Init(&m.kernel) c.CPU.KernelSyscall = bluepillSyscall c.CPU.KernelException = bluepillException + m.vCPUsByID[c.id] = c // Ensure the signal mask is correct. if err := c.setSignalMask(); err != nil { @@ -160,14 +168,23 @@ func (m *machine) newVCPU() *vCPU { func newMachine(vm int) (*machine, error) { // Create the machine. m := &machine{ - fd: vm, - vCPUs: make(map[uint64]*vCPU), + fd: vm, + vCPUs: make(map[uint64]*vCPU), + vCPUsByID: make(map[int]*vCPU), } m.available.L = &m.mu m.kernel.Init(ring0.KernelOpts{ PageTables: pagetables.New(newAllocator()), }) + maxVCPUs, _, errno := syscall.RawSyscall(syscall.SYS_IOCTL, uintptr(m.fd), _KVM_CHECK_EXTENSION, _KVM_CAP_MAX_VCPUS) + if errno != 0 { + m.maxVCPUs = _KVM_NR_VCPUS + } else { + m.maxVCPUs = int(maxVCPUs) + } + log.Debugf("The maximum number of vCPUs is %d.", m.maxVCPUs) + // Apply the physical mappings. Note that these mappings may point to // guest physical addresses that are not actually available. These // physical pages are mapped on demand, see kernel_unsafe.go. @@ -315,7 +332,7 @@ func (m *machine) Get() *vCPU { } // Create a new vCPU (maybe). - if len(m.vCPUs) < _KVM_NR_VCPUS { + if len(m.vCPUs) < m.maxVCPUs { c := m.newVCPU() c.lock() m.vCPUs[tid] = c @@ -365,6 +382,13 @@ func (m *machine) Put(c *vCPU) { m.available.Signal() } +// newDirtySet returns a new dirty set. +func (m *machine) newDirtySet() *dirtySet { + return &dirtySet{ + vCPUs: make([]uint64, (m.maxVCPUs+63)/64, (m.maxVCPUs+63)/64), + } +} + // lock marks the vCPU as in user mode. // // This should only be called directly when known to be safe, i.e. when |