blob: af740add65ae43b8782fb7135d285f0cbcfdcee4 [file] [log] [blame]
Tomasz Jeznach2ee9f222021-04-12 13:41:43 -07001#!/bin/busybox sh
2# Copyright 2021 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6# Bind PCI device to VFIO-PCI passthrough bus.
7vfio_pci() {
8 local sysfs=$1
9 local bdf=$(basename "${sysfs}")
10 local vendor_id=$(cat "${sysfs}/vendor")
11 local device_id=$(cat "${sysfs}/device")
12 local class=$(cat "${sysfs}/class")
13
14 # Filter by CLASS
15 case "${class}" in
16 0x060000)
17 return 1 # Ignore PCI Host Bridge.
18 ;;
19 0x060400)
20 return 1 # Ignore PCI-PCI Bridge.
21 ;;
22 esac
23
24 case "${bdf}" in
25 0000:00:1e.?)
26# Uncomment to keep hypervisor access to serial console.
27# return 1
28 ;;
29 esac
30
31 # Detach from current driver if any.
32 local driver="${sysfs}/driver"
33 if [[ -f "${driver}/unbind" ]]; then
34 echo "${bdf}" > "${driver}/unbind"
35 fi
36
37 # Attach pci device to VFIO-PCI bus driver.
38 echo "${vendor_id} ${device_id}" > /sys/bus/pci/drivers/vfio-pci/new_id
39}
40
41# Interrupt forwarding argument helper.
42get_irqs() {
43 local path
44 local args=""
45 local irqs="edge:1 level:14 edge:35 edge:51 level:59 level:100 level:116"
46 for irq in ${irqs}; do
47 args="${args} --direct-${irq%:*}-irq ${irq#*:}"
48 done
49 echo "${args}"
50}
51
52# Get guest kernel command line options.
53get_cmdline() {
54 local cmd="$(cat /proc/cmdline)"
55
56 # PCI workaround
57 cmd="pci=lastbus=255 pci=nocrs pci=realloc=off ${cmd}"
58
59 # Uncomment to disable standard boot flow.
60 # cmd="${cmd/init=*root=/root=} init=/bin/bash"
61
62 # Uncomment for incorrect rootfs UUID workaround
63 # cmd="${cmd/root=*\ rootwait/root=\/dev\/nvme0n1p3}"
64
65 echo "${cmd}"
66}
67
68# Start primary guest VM.
69run() {
70 # Crosvm-direct command line.
71 local args="-s /run/crosvm.sock --cid 3"
72
73 # TODO(b/184871003): Enable user space IOAPIC implementation.
74 # args="${args} --split-irqchip"
75
76 # TODO(b/185150434): enable minijail sandboxing.
77 args="${args} --disable-sandbox"
78
79 # Use all available CPUs for primary VM.
80 local nproc=$(nproc)
81 local affinity=$(for n in $(seq 0 $((nproc - 1))); do echo -n "$n=$n:"; done)
82 args="${args} --cpus ${nproc} --cpu-affinity ${affinity%?}"
83
84 # Reserve 512MB of total system memory for hypervisor.
85 local mem_total=$(grep MemTotal /proc/meminfo)
86 local mem_kb=${mem_total//[^0-9]/}
87 local mem_vm=$((mem_kb/1024 - 512))
88 args="${args} --mem ${mem_vm}"
89
90 # DMI: Use host SMBIOS info
91 if [[ -d "/sys/firmware/dmi/tables" ]]; then
92 args="${args} --dmi /sys/firmware/dmi/tables"
93 fi
94
95 # ACPI: Collect all valid host tables.
96 for acpi in `find /sys/firmware/acpi/tables/ -type f`; do
97 # Filter by name
98 case "${acpi##*/}" in
99 DMAR | FACS)
100 ;;
101 *)
102 args="${args} --acpi-table ${acpi}"
103 ;;
104 esac
105 done
106
107 # VFIO: Disable functional reset (b/173632817).
108 echo 1 > /sys/module/vfio_pci/parameters/disable_function_reset
109 # VFIO: Disable power management.
110 echo 1 > /sys/module/vfio_pci/parameters/disable_idle_d3
111
112 # VFIO: Direct attach all usable PCI devices.
113 for dev in `find /sys/bus/pci/devices -type l | sort`; do
114 vfio_pci "${dev}"
115 if [[ $? -eq 0 ]]; then
116 args="${args} --vfio ${dev}"
117 fi
118 done
119
120 # IOs
121 local pmio="128" # POST
122 pmio="${pmio},178" # SMI
123 pmio="${pmio},46-47,78-79" # Super I/O
124 pmio="${pmio},96,98,100,102" # KBD
125 pmio="${pmio},112-119" # EC
126 pmio="${pmio},512,516,2048-2559,6144-6399"
127 args="${args} --direct-pmio /dev/port@${pmio}"
128
129 # Platform IRQs
130 args="${args} $(get_irqs)"
131
132 exec /sbin/crosvm-direct run ${args} --params "$(get_cmdline)" /boot/vmlinuz
133}
134
135run
136