|
44 | 44 |
|
45 | 45 | CFG="scripts/config --file .config" |
46 | 46 |
|
| 47 | +# --- no loadable modules ----------------------------------------------------- |
| 48 | +# We ship a single vmlinuz and never run `make modules_install`, so a module is |
| 49 | +# unreachable by construction. Turning MODULES off makes that invariant |
| 50 | +# structural rather than a convention: nothing can sit at =m and silently |
| 51 | +# vanish from the shipped kernel, and the module loader stops being attack |
| 52 | +# surface in a guest that has no use for it. olddefconfig promotes the handful |
| 53 | +# of defconfig tristates that were =m up to =y. |
| 54 | +$CFG --disable MODULES |
| 55 | + |
| 56 | +# `scripts/config --enable FOO` is a silent no-op in two cases: FOO isn't a real |
| 57 | +# symbol (typo, or upstream renamed it), or FOO's dependencies aren't satisfied |
| 58 | +# — either way `make olddefconfig` drops the line without complaint. So route |
| 59 | +# the must-haves through want() and assert on the resulting .config below, |
| 60 | +# instead of finding the hole from inside a guest. |
| 61 | +REQUIRED=() |
| 62 | +want() { |
| 63 | + local sym |
| 64 | + for sym in "$@"; do |
| 65 | + $CFG --enable "$sym" |
| 66 | + REQUIRED+=("$sym") |
| 67 | + done |
| 68 | +} |
| 69 | + |
47 | 70 | # --- virtio guest drivers ---------------------------------------------------- |
48 | 71 | # Pin the core virtio transports and every guest-side device driver we'd |
49 | 72 | # plausibly want from a microVM hypervisor, plus the modern transports |
50 | 73 | # (MMIO for firecracker-style, PCI for cloud-hypervisor/qemu). |
51 | | -$CFG --enable VIRTIO |
52 | | -$CFG --enable VIRTIO_PCI |
| 74 | +want VIRTIO VIRTIO_PCI VIRTIO_MMIO VIRTIO_MMIO_CMDLINE_DEVICES |
| 75 | +want VIRTIO_BLK VIRTIO_NET VIRTIO_CONSOLE VIRTIO_BALLOON VIRTIO_INPUT |
| 76 | +want VIRTIO_IOMMU VIRTIO_DMA_SHARED_BUFFER |
| 77 | +want HW_RANDOM HW_RANDOM_VIRTIO |
53 | 78 | $CFG --enable VIRTIO_PCI_LEGACY |
54 | | -$CFG --enable VIRTIO_MMIO |
55 | | -$CFG --enable VIRTIO_MMIO_CMDLINE_DEVICES |
56 | | -$CFG --enable VIRTIO_BLK |
57 | | -$CFG --enable VIRTIO_NET |
58 | | -$CFG --enable VIRTIO_CONSOLE |
59 | | -$CFG --enable VIRTIO_BALLOON |
60 | | -$CFG --enable VIRTIO_INPUT |
61 | | -$CFG --enable VIRTIO_SCSI |
62 | | -$CFG --enable VIRTIO_GPU |
63 | | -$CFG --enable VIRTIO_PMEM |
64 | | -$CFG --enable VIRTIO_IOMMU |
65 | | -$CFG --enable VIRTIO_MEM |
66 | | -$CFG --enable VIRTIO_NET_FAILOVER |
67 | | -$CFG --enable VIRTIO_DMA_SHARED_BUFFER |
68 | | -$CFG --enable HW_RANDOM |
69 | | -$CFG --enable HW_RANDOM_VIRTIO |
70 | | -# vsock + virtio-vsock for host<->guest sockets |
71 | | -$CFG --enable VSOCKETS |
72 | | -$CFG --enable VIRTIO_VSOCKETS |
73 | | -# virtiofs (needs FUSE) |
74 | | -$CFG --enable FUSE_FS |
75 | | -$CFG --enable VIRTIO_FS |
| 79 | + |
| 80 | +# The SCSI and GPU guest drivers are not called VIRTIO_SCSI / VIRTIO_GPU (no |
| 81 | +# such symbols), and the failover netdev is NET_FAILOVER, which VIRTIO_NET |
| 82 | +# selects for us anyway. Asking by the wrong name was invisible on x86 — where |
| 83 | +# kvm_guest.config happens to set the real symbols — and a missing driver on |
| 84 | +# arm64, where we don't merge that fragment. |
| 85 | +want SCSI_VIRTIO DRM_VIRTIO_GPU NET_FAILOVER |
| 86 | + |
| 87 | +# virtio-mem is gated on the memory hotplug/hotremove machinery; without it the |
| 88 | +# driver silently drops out of the config. |
| 89 | +want MEMORY_HOTPLUG MEMORY_HOTREMOVE VIRTIO_MEM |
| 90 | + |
| 91 | +# virtio-pmem likewise needs libnvdimm, and DAX is what makes a pmem device (or |
| 92 | +# virtiofs, below) mappable without going through the guest page cache. |
| 93 | +want ZONE_DEVICE LIBNVDIMM VIRTIO_PMEM DAX FS_DAX |
| 94 | + |
| 95 | +# vsock + virtio-vsock for host<->guest sockets. The loopback transport lets |
| 96 | +# guest-local services speak vsock without a host peer, which is what most |
| 97 | +# vsock-based agents test against. |
| 98 | +want VSOCKETS VSOCKETS_LOOPBACK VIRTIO_VSOCKETS |
| 99 | + |
| 100 | +# virtiofs (needs FUSE). DAX mapping and passthrough are what make it fast |
| 101 | +# enough to use as a real rootfs/workspace share. |
| 102 | +want FUSE_FS VIRTIO_FS FUSE_DAX FUSE_PASSTHROUGH |
| 103 | + |
| 104 | +# 9p-over-virtio: the older host share, and something x86 gets for free from |
| 105 | +# kvm_guest.config — pin it so arm64 has it too. |
| 106 | +want NET_9P NET_9P_VIRTIO 9P_FS |
| 107 | + |
| 108 | +# ip=/DHCP autoconfiguration from the kernel cmdline (also x86-only via the |
| 109 | +# fragment otherwise). |
| 110 | +want IP_PNP IP_PNP_DHCP |
76 | 111 |
|
77 | 112 | # --- namespaces + cgroups (containers / sandboxing) -------------------------- |
78 | | -$CFG --enable NAMESPACES |
79 | | -$CFG --enable UTS_NS |
80 | | -$CFG --enable IPC_NS |
81 | | -$CFG --enable PID_NS |
82 | | -$CFG --enable NET_NS |
83 | | -$CFG --enable USER_NS |
84 | | -$CFG --enable TIME_NS |
85 | | -$CFG --enable CGROUPS |
86 | | -$CFG --enable MEMCG |
87 | | -$CFG --enable CPUSETS |
88 | | -$CFG --enable CGROUP_PIDS |
89 | | -$CFG --enable CGROUP_FREEZER |
90 | | -$CFG --enable CGROUP_DEVICE |
91 | | -$CFG --enable CGROUP_CPUACCT |
92 | | -$CFG --enable CGROUP_SCHED |
93 | | -$CFG --enable BLK_CGROUP |
| 113 | +want NAMESPACES UTS_NS IPC_NS PID_NS NET_NS USER_NS TIME_NS |
| 114 | +want CGROUPS MEMCG CPUSETS CGROUP_PIDS CGROUP_FREEZER CGROUP_DEVICE |
| 115 | +want CGROUP_CPUACCT CGROUP_SCHED BLK_CGROUP CGROUP_HUGETLB CGROUP_MISC |
| 116 | +want CGROUP_PERF CGROUP_BPF CGROUP_NET_PRIO CGROUP_NET_CLASSID NET_CLS_CGROUP |
| 117 | +# Pressure-stall + delay accounting: what memory/CPU-aware schedulers, |
| 118 | +# systemd-oomd and cgroup `*.pressure` readers need. |
| 119 | +want PSI TASKSTATS TASK_DELAY_ACCT TASK_IO_ACCOUNTING |
| 120 | +# Note: cgroup v1's memory and cpuset controllers (MEMCG_V1 / CPUSETS_V1) stay |
| 121 | +# off — v2-only, same as modern distros. |
| 122 | + |
| 123 | +# --- /proc + process introspection userspace expects ------------------------- |
| 124 | +# PROC_CHILDREN backs /proc/<pid>/task/<tid>/children, which process |
| 125 | +# supervisors use to walk a tree without scanning all of /proc. |
| 126 | +# CHECKPOINT_RESTORE brings /proc/<pid>/map_files plus the rest of the CRIU |
| 127 | +# surface, and USERFAULTFD is how CRIU (and lazy restore / live migration) |
| 128 | +# faults pages back in. PROC_PAGE_MONITOR is /proc/<pid>/pagemap + smaps, |
| 129 | +# which every memory profiler reads. |
| 130 | +want PROC_CHILDREN PROC_PAGE_MONITOR PROC_KCORE CHECKPOINT_RESTORE USERFAULTFD |
| 131 | + |
| 132 | +# --- core syscall surface container runtimes assume -------------------------- |
| 133 | +# seccomp is how every runtime filters syscalls; runc's default spec mounts |
| 134 | +# /dev/mqueue (POSIX_MQUEUE) and needs ptys for `exec -t`. |
| 135 | +want SECCOMP SECCOMP_FILTER |
| 136 | +want SYSVIPC SYSVIPC_SYSCTL POSIX_MQUEUE POSIX_MQUEUE_SYSCTL UNIX98_PTYS |
| 137 | +want EPOLL SIGNALFD TIMERFD EVENTFD AIO IO_URING FUTEX |
| 138 | +want BINFMT_ELF BINFMT_SCRIPT BINFMT_MISC |
| 139 | +want HUGETLBFS TRANSPARENT_HUGEPAGE |
| 140 | + |
| 141 | +# --- BPF --------------------------------------------------------------------- |
| 142 | +# systemd's device access control, container runtimes and the whole |
| 143 | +# observability stack are BPF-first now; CGROUP_BPF is the cgroup-v2 attach |
| 144 | +# point. KPROBES/PERF_EVENTS are what BPF_EVENTS — and therefore BPF_LSM — |
| 145 | +# are gated on. |
| 146 | +# Not enabled: DEBUG_INFO_BTF. CO-RE tooling (bpftrace, libbpf skeletons) |
| 147 | +# wants it, but it needs pahole (dwarves) as a build dep and a DWARF-enabled |
| 148 | +# build, so it's a deliberate follow-up rather than a free win. |
| 149 | +want BPF_SYSCALL BPF_JIT CGROUP_BPF PERF_EVENTS KPROBES |
| 150 | +# BPF_EVENTS is what gates BPF_LSM (and attaching BPF to kprobes/uprobes/ |
| 151 | +# tracepoints at all), and it needs KPROBE_EVENTS || UPROBE_EVENTS — both of |
| 152 | +# which live inside `if FTRACE` in kernel/trace/Kconfig. FTRACE is |
| 153 | +# `default y if DEBUG_KERNEL`, which x86_64_defconfig satisfies, but arm64's |
| 154 | +# defconfig explicitly carries `# CONFIG_FTRACE is not set` — so on arm64 the |
| 155 | +# probe-event symbols were unreachable and BPF_EVENTS silently fell to n, |
| 156 | +# taking BPF_LSM with it. Turn the menu on and pin both probe backends. |
| 157 | +want FTRACE KPROBE_EVENTS UPROBE_EVENTS BPF_EVENTS |
94 | 158 |
|
95 | 159 | # --- container networking ---------------------------------------------------- |
96 | | -$CFG --enable VETH |
97 | | -$CFG --enable TUN |
98 | | -$CFG --enable WIREGUARD |
| 160 | +want VETH TUN WIREGUARD MACVLAN IPVLAN DUMMY BRIDGE BRIDGE_NETFILTER |
| 161 | +want VLAN_8021Q IPV6 |
| 162 | +# Port publishing and egress NAT: docker, podman and CNI plugins program either |
| 163 | +# nftables or iptables, and their rules lean on the addrtype/conntrack/multiport |
| 164 | +# matches. defconfig sets NETFILTER_ADVANCED=n, which hides most of this and |
| 165 | +# defaults the rest to =m — invisible to us, since we ship no modules. |
| 166 | +want NETFILTER NETFILTER_ADVANCED NETFILTER_XTABLES |
| 167 | +want NF_CONNTRACK NF_NAT NF_NAT_MASQUERADE |
| 168 | +want NF_TABLES NF_TABLES_INET NF_TABLES_IPV4 NF_TABLES_IPV6 |
| 169 | +want NFT_CT NFT_NAT NFT_MASQ NFT_COMPAT NFT_LIMIT NFT_LOG |
| 170 | +want NFT_REJECT NFT_REJECT_IPV4 NFT_REJECT_IPV6 NFT_FIB_IPV4 NFT_FIB_IPV6 |
| 171 | +want IP_NF_IPTABLES IP_NF_IPTABLES_LEGACY IP_NF_FILTER IP_NF_NAT IP_NF_MANGLE |
| 172 | +want IP_NF_TARGET_MASQUERADE IP_NF_TARGET_REJECT IP_NF_TARGET_REDIRECT |
| 173 | +want IP6_NF_IPTABLES IP6_NF_IPTABLES_LEGACY IP6_NF_FILTER IP6_NF_NAT |
| 174 | +want IP6_NF_MANGLE IP6_NF_TARGET_MASQUERADE IP6_NF_TARGET_REJECT |
| 175 | +want NETFILTER_XT_NAT NETFILTER_XT_MARK NETFILTER_XT_MATCH_ADDRTYPE |
| 176 | +want NETFILTER_XT_MATCH_CONNTRACK NETFILTER_XT_MATCH_MULTIPORT |
| 177 | +want NETFILTER_XT_MATCH_COMMENT NETFILTER_XT_MATCH_STATE |
| 178 | +want NETFILTER_XT_TARGET_MASQUERADE NETFILTER_XT_TARGET_REDIRECT |
| 179 | +# The log backends default to =m, which for us means `nft ... log` and |
| 180 | +# `iptables -j LOG` rules would load but never emit anything. |
| 181 | +want NETFILTER_XT_TARGET_LOG NF_LOG_SYSLOG NF_LOG_IPV4 NF_LOG_IPV6 NF_LOG_ARP |
| 182 | +# `ss` and anything else that enumerates sockets goes through sock_diag. |
| 183 | +want INET_DIAG INET_TCP_DIAG INET_UDP_DIAG UNIX_DIAG NETLINK_DIAG PACKET_DIAG |
| 184 | +# tc classifiers/qdiscs, including the eBPF datapath hooks. NET_ACT_MIRRED is |
| 185 | +# both how `tc` redirects/mirrors traffic and IFB's hard dependency — without |
| 186 | +# it the ifb driver drops out of the config. |
| 187 | +want NET_SCH_INGRESS NET_SCH_FQ_CODEL NET_CLS_BPF NET_ACT_BPF |
| 188 | +want NET_ACT_MIRRED IFB |
| 189 | + |
| 190 | +# --- block devices + filesystems --------------------------------------------- |
| 191 | +# Loop devices and device-mapper are how disk images get mounted and how the |
| 192 | +# thin/crypt/verity storage stacks work; dm-verity is what a signed read-only |
| 193 | +# rootfs is built on. |
| 194 | +want BLK_DEV_LOOP BLK_DEV_DM DM_SNAPSHOT DM_THIN_PROVISIONING DM_CRYPT DM_VERITY |
| 195 | +# initramfs, and the decompressors a packed initrd might use. |
| 196 | +want BLK_DEV_INITRD RD_GZIP RD_XZ RD_ZSTD |
| 197 | +want EXT4_FS EXT4_FS_POSIX_ACL EXT4_FS_SECURITY |
| 198 | +# Read-only image formats: squashfs and erofs both show up as container/rootfs |
| 199 | +# images; ISO9660 + vfat are what cloud-init style config drives use. |
| 200 | +want SQUASHFS SQUASHFS_XZ SQUASHFS_ZSTD EROFS_FS EROFS_FS_ZIP |
| 201 | +want ISO9660_FS VFAT_FS NLS_CODEPAGE_437 NLS_ISO8859_1 NLS_UTF8 NLS_ASCII |
| 202 | +# systemd mounts /proc/sys/fs/binfmt_misc and friends through autofs. |
| 203 | +want AUTOFS_FS |
99 | 204 |
|
100 | 205 | # --- bind mounts / pivot_root substrate -------------------------------------- |
101 | 206 | # Bind mounts are part of core VFS, but pivot_root + the filesystems people |
102 | 207 | # commonly use to assemble container roots are configurable. Make sure the |
103 | | -# usual suspects are present. |
104 | | -$CFG --enable TMPFS |
105 | | -$CFG --enable TMPFS_POSIX_ACL |
106 | | -$CFG --enable TMPFS_XATTR |
107 | | -$CFG --enable PROC_FS |
108 | | -$CFG --enable SYSFS |
109 | | -$CFG --enable DEVTMPFS |
110 | | -$CFG --enable DEVTMPFS_MOUNT |
| 208 | +# usual suspects are present. TMPFS_INODE64 avoids inode-number reuse on |
| 209 | +# long-lived tmpfs trees. |
| 210 | +want TMPFS TMPFS_POSIX_ACL TMPFS_XATTR TMPFS_INODE64 |
| 211 | +want PROC_FS SYSFS DEVTMPFS DEVTMPFS_MOUNT |
111 | 212 |
|
112 | 213 | # --- overlayfs --------------------------------------------------------------- |
113 | | -$CFG --enable OVERLAY_FS |
114 | | -$CFG --enable OVERLAY_FS_REDIRECT_DIR |
115 | | -$CFG --enable OVERLAY_FS_INDEX |
116 | | -$CFG --enable OVERLAY_FS_XINO_AUTO |
117 | | -$CFG --enable OVERLAY_FS_METACOPY |
| 214 | +want OVERLAY_FS OVERLAY_FS_REDIRECT_DIR OVERLAY_FS_INDEX |
| 215 | +want OVERLAY_FS_XINO_AUTO OVERLAY_FS_METACOPY |
118 | 216 |
|
119 | 217 | # --- fanotify (privileged FS event monitoring + access control) ------------- |
120 | | -$CFG --enable FANOTIFY |
121 | | -$CFG --enable FANOTIFY_ACCESS_PERMISSIONS |
| 218 | +want FANOTIFY FANOTIFY_ACCESS_PERMISSIONS |
122 | 219 |
|
123 | | -# --- landlock (unprivileged sandboxing LSM) ---------------------------------- |
124 | | -$CFG --enable SECURITY |
125 | | -$CFG --enable SECURITY_LANDLOCK |
126 | | -# Landlock is a stackable LSM; make sure it's actually in the active list. |
127 | | -$CFG --set-str LSM "landlock,lockdown,yama,integrity,apparmor,bpf" |
| 220 | +# --- LSMs -------------------------------------------------------------------- |
| 221 | +# landlock for unprivileged sandboxing, yama for ptrace scoping, bpf-lsm for |
| 222 | +# programmable policy. |
| 223 | +want SECURITY SECURITY_NETWORK SECURITY_LANDLOCK SECURITY_YAMA BPF_LSM |
| 224 | +# Deliberately not enabling SECURITY_LOCKDOWN_LSM: it does |
| 225 | +# `select MODULE_SIG if MODULES`, and MODULE_SIG with the default |
| 226 | +# CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" makes the build generate a |
| 227 | +# fresh RSA keypair and embed the cert in the image — a different vmlinuz on |
| 228 | +# every build. Lockdown buys us nothing here anyway (we ship no modules and |
| 229 | +# there's no secure-boot chain in a microVM guest). |
| 230 | +# Stackable LSMs only run if they're in this list, and only names that are |
| 231 | +# actually compiled in mean anything — so keep the list and the config in sync. |
| 232 | +# (The list previously named lockdown, apparmor and integrity, none of which |
| 233 | +# was built.) |
| 234 | +$CFG --set-str LSM "landlock,yama,bpf" |
128 | 235 |
|
129 | 236 | # --- nested KVM (let this guest itself host VMs) ----------------------------- |
130 | 237 | # CONFIG_KVM is host-side virtualization; enabling it inside the guest is |
131 | 238 | # what makes nesting work from the guest's point of view. Whether nesting |
132 | 239 | # is *actually* available depends on the outer hypervisor exposing |
133 | 240 | # vmx/svm/EL2-virt to us, but the kernel side has to be built either way. |
134 | 241 | # KVM_INTEL/KVM_AMD only exist on x86; on arm64 the equivalent is folded |
135 | | -# into CONFIG_KVM. scripts/config silently no-ops on unknown symbols and |
136 | | -# olddefconfig drops them, so listing both arches' symbols here is safe. |
| 242 | +# into CONFIG_KVM. These stay outside want() precisely because they're |
| 243 | +# arch-conditional, so olddefconfig is free to drop the ones that don't apply. |
137 | 244 | $CFG --enable VIRTUALIZATION |
138 | 245 | $CFG --enable KVM |
139 | 246 | $CFG --enable KVM_INTEL |
140 | 247 | $CFG --enable KVM_AMD |
141 | | -$CFG --enable KVM_XFER_TO_GUEST_WORK |
142 | | -$CFG --enable KVM_GENERIC_DIRTYLOG_READ_PROTECT |
143 | 248 |
|
144 | 249 | # Resolve any new dependencies / silently drop options renamed upstream. |
145 | 250 | make olddefconfig |
146 | 251 |
|
| 252 | +# --- assert the config we asked for is the config we got --------------------- |
| 253 | +missing=() |
| 254 | +for sym in "${REQUIRED[@]}"; do |
| 255 | + grep -qx "CONFIG_${sym}=y" .config || missing+=("CONFIG_${sym}") |
| 256 | +done |
| 257 | +if [ "${#missing[@]}" -gt 0 ]; then |
| 258 | + echo "error: required kernel options absent from .config after olddefconfig:" >&2 |
| 259 | + printf ' %s\n' "${missing[@]}" >&2 |
| 260 | + echo "cause is one of: symbol renamed/removed upstream, unmet dependency," >&2 |
| 261 | + echo "or left as =m (no modules are shipped by this package)." >&2 |
| 262 | + exit 1 |
| 263 | +fi |
| 264 | + |
147 | 265 | make -j"$JOBS" "$KERNEL_TARGET" |
148 | 266 |
|
149 | 267 | OUT=$OUTPUT_DIR/usr/share/virtio-linux |
|
0 commit comments