mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 17:23:06 +00:00
ece86bd260
Closes #287, closes #288. Signed-off-by: Omar Sandoval <osandov@osandov.com>
405 lines
10 KiB
Python
405 lines
10 KiB
Python
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
|
|
from collections import OrderedDict
|
|
import inspect
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Dict, Mapping, NamedTuple, Sequence
|
|
|
|
from util import NORMALIZED_MACHINE_NAME
|
|
|
|
# Kernel versions that we run tests on and therefore support. Keep this in sync
|
|
# with docs/support_matrix.rst.
|
|
SUPPORTED_KERNEL_VERSIONS = (
|
|
"6.5",
|
|
"6.4",
|
|
"6.3",
|
|
"6.2",
|
|
"6.1",
|
|
"6.0",
|
|
"5.19",
|
|
"5.18",
|
|
"5.17",
|
|
"5.16",
|
|
"5.15",
|
|
"5.14",
|
|
"5.13",
|
|
"5.12",
|
|
"5.11",
|
|
"5.10",
|
|
"5.4",
|
|
"4.19",
|
|
"4.14",
|
|
"4.9",
|
|
)
|
|
|
|
KERNEL_ORG_COMPILER_VERSION = "12.2.0"
|
|
VMTEST_KERNEL_VERSION = 21
|
|
|
|
|
|
BASE_KCONFIG = """
|
|
CONFIG_EXPERT=y
|
|
CONFIG_MODULES=y
|
|
CONFIG_MODULE_UNLOAD=y
|
|
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
|
|
|
# We run the tests in KVM.
|
|
CONFIG_HYPERVISOR_GUEST=y
|
|
CONFIG_KVM_GUEST=y
|
|
CONFIG_PARAVIRT=y
|
|
CONFIG_PARAVIRT_SPINLOCKS=y
|
|
|
|
# Minimum requirements for vmtest.
|
|
CONFIG_9P_FS=y
|
|
CONFIG_DEVTMPFS=y
|
|
CONFIG_INET=y
|
|
CONFIG_NET=y
|
|
CONFIG_NETWORK_FILESYSTEMS=y
|
|
CONFIG_NET_9P=y
|
|
CONFIG_NET_9P_VIRTIO=y
|
|
CONFIG_OVERLAY_FS=y
|
|
CONFIG_PCI=y
|
|
CONFIG_PROC_FS=y
|
|
CONFIG_SYSFS=y
|
|
CONFIG_TMPFS=y
|
|
CONFIG_TMPFS_XATTR=y
|
|
CONFIG_VIRTIO_CONSOLE=y
|
|
CONFIG_VIRTIO_PCI=y
|
|
CONFIG_HW_RANDOM=m
|
|
CONFIG_HW_RANDOM_VIRTIO=m
|
|
|
|
# Lots of stuff expect Unix sockets.
|
|
CONFIG_UNIX=y
|
|
|
|
# drgn needs debug info.
|
|
CONFIG_DEBUG_KERNEL=y
|
|
CONFIG_DEBUG_INFO=y
|
|
CONFIG_DEBUG_INFO_DWARF4=y
|
|
|
|
# For testing live kernel debugging with /proc/kcore.
|
|
CONFIG_PROC_KCORE=y
|
|
# drgn needs /proc/kallsyms in some cases. Some test cases also need it.
|
|
CONFIG_KALLSYMS=y
|
|
CONFIG_KALLSYMS_ALL=y
|
|
|
|
# For testing kernel core dumps with /proc/vmcore.
|
|
CONFIG_CRASH_DUMP=y
|
|
CONFIG_PROC_VMCORE=y
|
|
CONFIG_KEXEC=y
|
|
CONFIG_KEXEC_FILE=y
|
|
# Needed for CONFIG_KEXEC_FILE.
|
|
CONFIG_CRYPTO=y
|
|
CONFIG_CRYPTO_SHA256=y
|
|
|
|
# So that we can trigger a crash with /proc/sysrq-trigger.
|
|
CONFIG_MAGIC_SYSRQ=y
|
|
|
|
# For block tests.
|
|
CONFIG_BLK_DEV_LOOP=m
|
|
|
|
# For BPF tests.
|
|
CONFIG_BPF_SYSCALL=y
|
|
CONFIG_BPF_JIT=y
|
|
CONFIG_BPF_JIT_ALWAYS_ON=y
|
|
CONFIG_CGROUP_BPF=y
|
|
CONFIG_DEBUG_INFO_BTF=y
|
|
CONFIG_DEBUG_INFO_BTF_MODULES=y
|
|
|
|
# For cgroup tests.
|
|
CONFIG_CGROUPS=y
|
|
# To select CONFIG_SOCK_CGROUP_DATA. (CONFIG_CGROUP_BPF also selects
|
|
# CONFIG_SOCK_CGROUP_DATA, but that's only present since Linux kernel commit
|
|
# 3007098494be ("cgroup: add support for eBPF programs") (in v4.10)).
|
|
CONFIG_CGROUP_NET_CLASSID=y
|
|
|
|
# For kconfig tests.
|
|
CONFIG_IKCONFIG=m
|
|
CONFIG_IKCONFIG_PROC=y
|
|
|
|
# For filesystem tests.
|
|
CONFIG_BTRFS_FS=m
|
|
CONFIG_EXT4_FS=m
|
|
CONFIG_XFS_FS=m
|
|
|
|
# For mm tests.
|
|
CONFIG_HUGETLBFS=y
|
|
|
|
# For net tests.
|
|
CONFIG_NAMESPACES=y
|
|
|
|
# For nodemask tests.
|
|
CONFIG_NUMA=y
|
|
|
|
# For slab allocator tests.
|
|
CONFIG_SLAB_FREELIST_HARDENED=y
|
|
|
|
# For Traffic Control tests.
|
|
CONFIG_NET_SCHED=y
|
|
CONFIG_NET_SCH_PRIO=m
|
|
CONFIG_NET_SCH_SFQ=m
|
|
CONFIG_NET_SCH_TBF=m
|
|
CONFIG_NET_SCH_INGRESS=m
|
|
CONFIG_NET_CLS_ACT=y
|
|
CONFIG_NETDEVICES=y
|
|
CONFIG_DUMMY=m
|
|
|
|
# To enable CONFIG_XARRAY_MULTI for xarray tests.
|
|
CONFIG_TRANSPARENT_HUGEPAGE=y
|
|
CONFIG_READ_ONLY_THP_FOR_FS=y
|
|
"""
|
|
|
|
|
|
class KernelFlavor(NamedTuple):
|
|
name: str
|
|
description: str
|
|
config: str
|
|
|
|
|
|
KERNEL_FLAVORS = OrderedDict(
|
|
(flavor.name, flavor)
|
|
for flavor in (
|
|
KernelFlavor(
|
|
name="default",
|
|
description="Default configuration",
|
|
config="""
|
|
CONFIG_SMP=y
|
|
CONFIG_SLUB=y
|
|
# For slab tests.
|
|
CONFIG_SLUB_DEBUG=y
|
|
""",
|
|
),
|
|
KernelFlavor(
|
|
name="alternative",
|
|
description="SLAB allocator",
|
|
config="""
|
|
CONFIG_SMP=y
|
|
CONFIG_SLAB=y
|
|
""",
|
|
),
|
|
KernelFlavor(
|
|
name="tiny",
|
|
description="!SMP, !PREEMPT, and SLOB allocator",
|
|
config="""
|
|
CONFIG_SMP=n
|
|
CONFIG_SLOB=y
|
|
# Linux kernel commit 149b6fa228ed ("mm, slob: rename CONFIG_SLOB to
|
|
# CONFIG_SLOB_DEPRECATED") (in v6.2) renamed the option for SLOB.
|
|
CONFIG_SLOB_DEPRECATED=y
|
|
# CONFIG_PREEMPT_DYNAMIC is not set
|
|
CONFIG_PREEMPT_NONE=y
|
|
# !PREEMPTION && !SMP will also select TINY_RCU.
|
|
""",
|
|
),
|
|
)
|
|
)
|
|
|
|
|
|
class Architecture(NamedTuple):
|
|
# Architecture name. This matches the names used by
|
|
# util.NORMALIZED_MACHINE_NAME and qemu-system-$arch_name.
|
|
name: str
|
|
# Value of ARCH variable to build the Linux kernel.
|
|
kernel_arch: str
|
|
# Directory under arch/ in the Linux kernel source tree.
|
|
kernel_srcarch: str
|
|
# Linux kernel configuration options.
|
|
kernel_config: str
|
|
# Flavor-specific Linux kernel configuration options.
|
|
kernel_flavor_configs: Mapping[str, str]
|
|
# Name of compiler target on
|
|
# https://mirrors.kernel.org/pub/tools/crosstool/.
|
|
kernel_org_compiler_name: str
|
|
# Options to pass to QEMU.
|
|
qemu_options: Sequence[str]
|
|
# Console device when using QEMU.
|
|
qemu_console: str
|
|
|
|
|
|
ARCHITECTURES = {
|
|
arch.name: arch
|
|
for arch in (
|
|
Architecture(
|
|
name="aarch64",
|
|
kernel_arch="arm64",
|
|
kernel_srcarch="arm64",
|
|
kernel_config="""
|
|
CONFIG_PCI_HOST_GENERIC=y
|
|
CONFIG_RTC_CLASS=y
|
|
CONFIG_RTC_DRV_PL031=y
|
|
CONFIG_SERIAL_AMBA_PL011=y
|
|
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
|
""",
|
|
kernel_flavor_configs={
|
|
"default": """
|
|
CONFIG_ARM64_4K_PAGES=y
|
|
CONFIG_ARM64_VA_BITS_48=y
|
|
""",
|
|
"alternative": """
|
|
CONFIG_ARM64_64K_PAGES=y
|
|
CONFIG_ARM64_VA_BITS_52=y
|
|
CONFIG_ARM64_PA_BITS_52=y
|
|
""",
|
|
"tiny": """
|
|
CONFIG_ARM64_16K_PAGES=y
|
|
""",
|
|
},
|
|
kernel_org_compiler_name="aarch64-linux",
|
|
qemu_options=("-M", "virt", "-cpu", "cortex-a57"),
|
|
qemu_console="ttyAMA0",
|
|
),
|
|
Architecture(
|
|
name="arm",
|
|
kernel_arch="arm",
|
|
kernel_srcarch="arm",
|
|
kernel_config="""
|
|
CONFIG_NR_CPUS=8
|
|
CONFIG_HIGHMEM=y
|
|
CONFIG_ARM_LPAE=n
|
|
# Debian armhf userspace assumes EABI and VFP.
|
|
CONFIG_AEABI=y
|
|
CONFIG_VFP=y
|
|
CONFIG_ARCH_VIRT=y
|
|
CONFIG_PCI_HOST_GENERIC=y
|
|
CONFIG_RTC_CLASS=y
|
|
CONFIG_RTC_DRV_PL031=y
|
|
CONFIG_SERIAL_AMBA_PL011=y
|
|
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
|
# Before Linux kernel commit f05eb1d24eb5 ("ARM:
|
|
# stackprotector: prefer compiler for TLS based per-task
|
|
# protector") (in v5.18), this enables the
|
|
# arm_ssp_per_task_plugin GCC plugin, which fails to build with
|
|
# the kernel.org cross compiler.
|
|
CONFIG_STACKPROTECTOR_PER_TASK=n
|
|
""",
|
|
kernel_flavor_configs={
|
|
"alternative": """
|
|
CONFIG_ARM_LPAE=y
|
|
""",
|
|
},
|
|
kernel_org_compiler_name="arm-linux-gnueabi",
|
|
qemu_options=("-M", "virt,highmem=off"),
|
|
qemu_console="ttyAMA0",
|
|
),
|
|
Architecture(
|
|
name="ppc64",
|
|
kernel_arch="powerpc",
|
|
kernel_srcarch="powerpc",
|
|
kernel_config="""
|
|
CONFIG_PPC64=y
|
|
CONFIG_CPU_LITTLE_ENDIAN=y
|
|
# Debian ppc64el userspace assumes AltiVec and VSX support.
|
|
CONFIG_ALTIVEC=y
|
|
CONFIG_VSX=y
|
|
CONFIG_RTC_CLASS=y
|
|
CONFIG_RTC_DRV_GENERIC=y
|
|
CONFIG_HVC_CONSOLE=y
|
|
# This has a missing dependency in v6.5-rc1 that causes a build
|
|
# failure, and we don't need it.
|
|
CONFIG_CRYPTO_AES_GCM_P10=n
|
|
""",
|
|
kernel_flavor_configs={},
|
|
kernel_org_compiler_name="powerpc64-linux",
|
|
qemu_options=(),
|
|
qemu_console="hvc0",
|
|
),
|
|
Architecture(
|
|
name="s390x",
|
|
kernel_arch="s390",
|
|
kernel_srcarch="s390",
|
|
kernel_config="""
|
|
# Needed for CONFIG_KEXEC_FILE.
|
|
CONFIG_CRYPTO_SHA256_S390=y
|
|
""",
|
|
kernel_flavor_configs={},
|
|
kernel_org_compiler_name="s390-linux",
|
|
qemu_options=(),
|
|
qemu_console="ttysclp0",
|
|
),
|
|
Architecture(
|
|
name="x86_64",
|
|
kernel_arch="x86_64",
|
|
kernel_srcarch="x86",
|
|
kernel_config="""
|
|
CONFIG_RTC_CLASS=y
|
|
CONFIG_RTC_DRV_CMOS=y
|
|
CONFIG_SERIAL_8250=y
|
|
CONFIG_SERIAL_8250_CONSOLE=y
|
|
""",
|
|
kernel_flavor_configs={},
|
|
kernel_org_compiler_name="x86_64-linux",
|
|
qemu_options=("-nodefaults",),
|
|
qemu_console="ttyS0",
|
|
),
|
|
)
|
|
}
|
|
|
|
|
|
HOST_ARCHITECTURE = ARCHITECTURES.get(NORMALIZED_MACHINE_NAME)
|
|
|
|
|
|
class Kernel(NamedTuple):
|
|
arch: Architecture
|
|
release: str
|
|
path: Path
|
|
|
|
|
|
def local_kernel(arch: Architecture, path: Path) -> Kernel:
|
|
return Kernel(
|
|
arch=arch,
|
|
release=(path / "build/include/config/kernel.release").read_text().strip(),
|
|
path=path,
|
|
)
|
|
|
|
|
|
class Compiler(NamedTuple):
|
|
target: Architecture
|
|
bin: Path
|
|
prefix: str
|
|
|
|
def env(self) -> Dict[str, str]:
|
|
path = str(self.bin.resolve())
|
|
try:
|
|
path += ":" + os.environ["PATH"]
|
|
except KeyError:
|
|
pass
|
|
return {
|
|
"PATH": path,
|
|
"CROSS_COMPILE": self.prefix,
|
|
}
|
|
|
|
|
|
def kconfig_localversion(flavor: KernelFlavor) -> str:
|
|
localversion = f"-vmtest{VMTEST_KERNEL_VERSION}"
|
|
# The default flavor should be the "latest" version.
|
|
localversion += ".1" if flavor.name == "default" else ".0"
|
|
localversion += flavor.name
|
|
return localversion
|
|
|
|
|
|
def kconfig(arch: Architecture, flavor: KernelFlavor) -> str:
|
|
return f"""\
|
|
# Minimal Linux kernel configuration for booting into vmtest and running drgn
|
|
# tests ({arch.name} {flavor.name} flavor).
|
|
|
|
CONFIG_LOCALVERSION=""
|
|
CONFIG_LOCALVERSION_AUTO=n
|
|
|
|
# base options
|
|
|
|
{inspect.cleandoc(BASE_KCONFIG)}
|
|
|
|
# {flavor.name} flavor options
|
|
|
|
{inspect.cleandoc(flavor.config)}
|
|
|
|
# {arch.name} options
|
|
|
|
{inspect.cleandoc(arch.kernel_config)}
|
|
|
|
# {arch.name} {flavor.name} flavor options
|
|
|
|
{inspect.cleandoc(arch.kernel_flavor_configs.get(flavor.name, ""))}
|
|
"""
|