[PATCH] build: support driver profiles

15 views
Skip to first unread message

Waldemar Kozaczuk

unread,
Feb 8, 2022, 9:19:12 PM2/8/22
to osv...@googlegroups.com, Waldemar Kozaczuk
This patch introduces new build mechanism that allows creating
custom kernel with specific list of device drivers intended to target
given hypervisor. Such kernel benefits from smaller size and better
security as all unneeded code is removed. This patch partially addresses
the modularization/librarization functionality as explained by the issue
#1110 and this part of the roadmap - https://github.com/cloudius-systems/osv/wiki/Roadmap#modularizationlibrarization.
This idea was also mentioned in the P99 OSv presentation - see slide 11.

In essence, we introduce new build script and makefile parameter:
`drivers_profile`. This new parameter is intended to specify a
drivers profile which is simply a list of device drivers to be linked
into kernel with some extra functionality like PCI or ACPI these drivers
depend on. Each profile is specified in a tiny make include file (*.mk)
under new conf/profiles/$(arch) directory and included by the main
makefile as requested by drivers_profile parameter. The main makefile
has number of new ifeq conditions that add given driver object file
to the linked objects list depending on the value (0 or 1) of given
conf_drivers_* variable specified in the relevant profile file.
Sometimes it is necessary to conditionally enable/disable given
code depending on the drivers selected. The good example of it is
arch-setup.cc which actually registers individual drivers and this
is where we need some kind of #if-way of registering given driver.
To that end, this patch adds new script gen-drivers-config-header and
new rule to the makefile, which automatically generates driver-config.h
header file under build/$(mode)/gen/include/osv. The driver-config.h
is comprised of the #define CONF_drivers_* macros that specify if given
driver is enabled or not (1, 0) and is included by relatively few source
file like arch-setup.cc. The extra benefit of this approach is that
every time we change value of drivers_profile, all relevant files are
recompiled and new kernel linked.

Most of the patch are changes to the relevant source file to include
new #if CONF_drivers_* conditional logic, changes to the main makefile
to conditionality link specific object files and new makefile include
file under conf/profiles/.

The benefits of using drivers are most profound when building kernel
with most symbols hidden. Below you can see examples of some build
commands along with the kernel size produced:

./scripts/build fs=rofs conf_hide_symbols=1 image=native-example #all
3632K build/release/kernel-stripped.elf

./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-pci
3380K build/release/kernel-stripped.elf

./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=vmware
3308K build/release/kernel-stripped.elf

./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-mmio
3120K build/release/kernel-stripped.elf

./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=base #most drivers out
3036K build/release/kernel-stripped.elf

Partially addresses #1110

Signed-off-by: Waldemar Kozaczuk <jwkoz...@gmail.com>
---
Makefile | 109 ++++++++++++++++++++++++--
arch/aarch64/arch-dtb.cc | 7 ++
arch/aarch64/arch-setup.cc | 41 +++++++++-
arch/aarch64/boot.S | 3 +
arch/aarch64/cpuid.cc | 5 ++
arch/aarch64/xen.cc | 1 +
arch/x64/apic.cc | 1 +
arch/x64/arch-setup.cc | 74 +++++++++++++++++
arch/x64/cpuid.cc | 15 ++++
arch/x64/entry-xen.S | 5 ++
arch/x64/power.cc | 9 +++
arch/x64/smp.cc | 9 +++
arch/x64/xen.cc | 1 +
conf/profiles/README.md | 71 +++++++++++++++++
conf/profiles/aarch64/all.mk | 5 ++
conf/profiles/aarch64/base.mk | 26 ++++++
conf/profiles/aarch64/microvm.mk | 1 +
conf/profiles/aarch64/virtio-mmio.mk | 4 +
conf/profiles/aarch64/virtio-pci.mk | 6 ++
conf/profiles/aarch64/xen.mk | 2 +
conf/profiles/x64/all.mk | 8 ++
conf/profiles/x64/base.mk | 74 +++++++++++++++++
conf/profiles/x64/cloud_hypervisor.mk | 2 +
conf/profiles/x64/hyperv.mk | 6 ++
conf/profiles/x64/microvm.mk | 1 +
conf/profiles/x64/vbox.mk | 8 ++
conf/profiles/x64/virtio-mmio.mk | 4 +
conf/profiles/x64/virtio-pci.mk | 10 +++
conf/profiles/x64/vmware.mk | 10 +++
conf/profiles/x64/xen.mk | 6 ++
core/xen_intr.cc | 1 +
drivers/acpi.cc | 9 ++-
drivers/hpet.cc | 9 +++
drivers/pci-generic.cc | 5 ++
drivers/virtio-blk.cc | 5 ++
drivers/virtio-fs.cc | 5 ++
drivers/virtio-net.cc | 5 ++
drivers/xenclock.cc | 1 +
drivers/xenfront-xenbus.cc | 1 +
drivers/xenplatform-pci.cc | 1 +
fs/vfs/vfs_conf.cc | 7 ++
include/osv/xen.hh | 4 +
loader.cc | 9 +++
runtime.cc | 5 ++
scripts/gen-drivers-config-header | 40 ++++++++++
45 files changed, 621 insertions(+), 10 deletions(-)
create mode 100644 conf/profiles/README.md
create mode 100644 conf/profiles/aarch64/all.mk
create mode 100644 conf/profiles/aarch64/base.mk
create mode 120000 conf/profiles/aarch64/microvm.mk
create mode 100644 conf/profiles/aarch64/virtio-mmio.mk
create mode 100644 conf/profiles/aarch64/virtio-pci.mk
create mode 100644 conf/profiles/aarch64/xen.mk
create mode 100644 conf/profiles/x64/all.mk
create mode 100644 conf/profiles/x64/base.mk
create mode 100644 conf/profiles/x64/cloud_hypervisor.mk
create mode 100644 conf/profiles/x64/hyperv.mk
create mode 120000 conf/profiles/x64/microvm.mk
create mode 100644 conf/profiles/x64/vbox.mk
create mode 100644 conf/profiles/x64/virtio-mmio.mk
create mode 100644 conf/profiles/x64/virtio-pci.mk
create mode 100644 conf/profiles/x64/vmware.mk
create mode 100644 conf/profiles/x64/xen.mk
create mode 100755 scripts/gen-drivers-config-header

diff --git a/Makefile b/Makefile
index 59cc6de4..c1c0eb84 100644
--- a/Makefile
+++ b/Makefile
@@ -82,6 +82,25 @@ ifeq (,$(wildcard conf/$(arch).mk))
endif
include conf/$(arch).mk

+# This parameter can be passed in to the build command to specify name of
+# a drivers profile. The drivers profile allows to build custom kernel with
+# a specific set of drivers enabled in the corresponding makefile include
+# file - conf/profiles/$(arch)/$(drivers_profile).mk). The default profile is
+# 'all' which incorporates all drivers into kernel.
+# In general the profiles set variables named conf_drivers_*, which then in turn
+# are used in the rules below to decide which object files are linked into
+# kernel.
+drivers_profile?=all
+ifeq (,$(wildcard conf/profiles/$(arch)/$(drivers_profile).mk))
+ $(error unsupported drivers profile $(drivers_profile))
+endif
+include conf/profiles/$(arch)/$(drivers_profile).mk
+# The base profile disables all drivers unless they are explicitly enabled
+# by the profile file included in the line above. The base profile also enforces
+# certain dependencies between drivers, for example the ide driver needs pci support, etc.
+# For more details please read comments in the profile file.
+include conf/profiles/$(arch)/base.mk
+
CROSS_PREFIX ?= $(if $(filter-out $(arch),$(host_arch)),$(arch)-linux-gnu-)
CXX=$(CROSS_PREFIX)g++
CC=$(CROSS_PREFIX)gcc
@@ -617,10 +636,13 @@ bsd += bsd/sys/netinet/cc/cc_cubic.o
bsd += bsd/sys/netinet/cc/cc_htcp.o
bsd += bsd/sys/netinet/cc/cc_newreno.o
bsd += bsd/sys/netinet/arpcache.o
+ifeq ($(conf_drivers_xen),1)
bsd += bsd/sys/xen/evtchn.o
+endif

ifeq ($(arch),x64)
$(out)/bsd/%.o: COMMON += -DXEN -DXENHVM
+ifeq ($(conf_drivers_xen),1)
bsd += bsd/sys/xen/gnttab.o
bsd += bsd/sys/xen/xenstore/xenstore.o
bsd += bsd/sys/xen/xenbus/xenbus.o
@@ -628,8 +650,11 @@ bsd += bsd/sys/xen/xenbus/xenbusb.o
bsd += bsd/sys/xen/xenbus/xenbusb_front.o
bsd += bsd/sys/dev/xen/netfront/netfront.o
bsd += bsd/sys/dev/xen/blkfront/blkfront.o
+endif
+ifeq ($(conf_drivers_hyperv),1)
bsd += bsd/sys/dev/hyperv/vmbus/hyperv.o
endif
+endif

bsd += bsd/sys/dev/random/hash.o
bsd += bsd/sys/dev/random/randomdev_soft.o
@@ -817,54 +842,101 @@ drivers += drivers/random.o
drivers += drivers/zfs.o
drivers += drivers/null.o
drivers += drivers/device.o
+ifeq ($(conf_drivers_pci),1)
drivers += drivers/pci-generic.o
drivers += drivers/pci-device.o
drivers += drivers/pci-function.o
drivers += drivers/pci-bridge.o
+endif
drivers += drivers/driver.o

ifeq ($(arch),x64)
+ifeq ($(conf_drivers_vga),1)
drivers += $(libtsm)
-drivers += drivers/vga.o drivers/kbd.o drivers/isa-serial.o
+drivers += drivers/vga.o
+endif
+drivers += drivers/kbd.o drivers/isa-serial.o
drivers += arch/$(arch)/pvclock-abi.o
+
+ifeq ($(conf_drivers_virtio),1)
drivers += drivers/virtio.o
+ifeq ($(conf_drivers_pci),1)
drivers += drivers/virtio-pci-device.o
+endif
drivers += drivers/virtio-vring.o
+ifeq ($(conf_drivers_mmio),1)
drivers += drivers/virtio-mmio.o
+endif
drivers += drivers/virtio-net.o
-drivers += drivers/vmxnet3.o
-drivers += drivers/vmxnet3-queues.o
drivers += drivers/virtio-blk.o
drivers += drivers/virtio-scsi.o
drivers += drivers/virtio-rng.o
drivers += drivers/virtio-fs.o
-drivers += drivers/kvmclock.o drivers/xenclock.o drivers/hypervclock.o
+endif
+
+ifeq ($(conf_drivers_vmxnet3),1)
+drivers += drivers/vmxnet3.o
+drivers += drivers/vmxnet3-queues.o
+endif
+drivers += drivers/kvmclock.o
+ifeq ($(conf_drivers_hyperv),1)
+drivers += drivers/hypervclock.o
+endif
+ifeq ($(conf_drivers_acpi),1)
drivers += drivers/acpi.o
+endif
+ifeq ($(conf_drivers_hpet),1)
drivers += drivers/hpet.o
-drivers += drivers/rtc.o
-drivers += drivers/xenfront.o drivers/xenfront-xenbus.o drivers/xenfront-blk.o
+endif
+ifeq ($(conf_drivers_pvpanic),1)
drivers += drivers/pvpanic.o
+endif
+drivers += drivers/rtc.o
+ifeq ($(conf_drivers_ahci),1)
drivers += drivers/ahci.o
-drivers += drivers/ide.o
+endif
+ifeq ($(conf_drivers_scsi),1)
drivers += drivers/scsi-common.o
+endif
+ifeq ($(conf_drivers_ide),1)
+drivers += drivers/ide.o
+endif
+ifeq ($(conf_drivers_pvscsi),1)
drivers += drivers/vmw-pvscsi.o
+endif
+
+ifeq ($(conf_drivers_xen),1)
+drivers += drivers/xenclock.o
+drivers += drivers/xenfront.o drivers/xenfront-xenbus.o drivers/xenfront-blk.o
drivers += drivers/xenplatform-pci.o
+endif
endif # x64

ifeq ($(arch),aarch64)
drivers += drivers/mmio-isa-serial.o
drivers += drivers/pl011.o
drivers += drivers/pl031.o
+ifeq ($(conf_drivers_cadence),1)
drivers += drivers/cadence-uart.o
+endif
+ifeq ($(conf_drivers_xen),1)
drivers += drivers/xenconsole.o
+endif
+
+ifeq ($(conf_drivers_virtio),1)
drivers += drivers/virtio.o
+ifeq ($(conf_drivers_pci),1)
drivers += drivers/virtio-pci-device.o
+endif
+ifeq ($(conf_drivers_mmio),1)
drivers += drivers/virtio-mmio.o
+endif
drivers += drivers/virtio-vring.o
drivers += drivers/virtio-rng.o
drivers += drivers/virtio-blk.o
drivers += drivers/virtio-net.o
drivers += drivers/virtio-fs.o
+endif
endif # aarch64

objects += arch/$(arch)/arch-trace.o
@@ -883,11 +955,15 @@ objects += arch/$(arch)/cpuid.o
objects += arch/$(arch)/firmware.o
objects += arch/$(arch)/hypervisor.o
objects += arch/$(arch)/interrupt.o
+ifeq ($(conf_drivers_pci),1)
objects += arch/$(arch)/pci.o
objects += arch/$(arch)/msi.o
+endif
objects += arch/$(arch)/power.o
objects += arch/$(arch)/feexcept.o
+ifeq ($(conf_drivers_xen),1)
objects += arch/$(arch)/xen.o
+endif

$(out)/arch/x64/string-ssse3.o: CXXFLAGS += -mssse3

@@ -917,10 +993,14 @@ objects += arch/x64/entry-xen.o
objects += arch/x64/vmlinux.o
objects += arch/x64/vmlinux-boot64.o
objects += arch/x64/pvh-boot.o
+ifeq ($(conf_drivers_acpi),1)
objects += $(acpi)
+endif
endif # x64

+ifeq ($(conf_drivers_xen),1)
objects += core/xen_intr.o
+endif
objects += core/math.o
objects += core/spinlock.o
objects += core/lfmutex.o
@@ -1847,9 +1927,11 @@ fs_objs += rofs/rofs_vfsops.o \
rofs/rofs_cache.o \
rofs/rofs_common.o

+ifeq ($(conf_drivers_virtio),1)
fs_objs += virtiofs/virtiofs_vfsops.o \
virtiofs/virtiofs_vnops.o \
virtiofs/virtiofs_dax.o
+endif

fs_objs += pseudofs/pseudofs.o
fs_objs += procfs/procfs_vnops.o
@@ -2055,7 +2137,7 @@ $(out)/tools/cpiod/cpiod.so: $(out)/tools/cpiod/cpiod.o $(out)/tools/cpiod/cpio.
# re-created on every compilation. "generated-headers" is used as an order-
# only dependency on C compilation rules above, so we don't try to compile
# C code before generating these headers.
-generated-headers: $(out)/gen/include/bits/alltypes.h perhaps-modify-version-h
+generated-headers: $(out)/gen/include/bits/alltypes.h perhaps-modify-version-h perhaps-modify-drivers-config-h
.PHONY: generated-headers

# While other generated headers only need to be generated once, version.h
@@ -2066,6 +2148,17 @@ perhaps-modify-version-h:
$(call quiet, sh scripts/gen-version-header $(out)/gen/include/osv/version.h, GEN gen/include/osv/version.h)
.PHONY: perhaps-modify-version-h

+# Using 'if ($(conf_drivers_*),1)' in the rules below is enough to include whole object
+# files. Sometimes though we need to enable or disable portions of the code specific
+# to given driver (the arch-setup.cc is best example). To that end the rule below
+# generates drivers_config.h header file with the macros CONF_drivers_* which is
+# then included by relevant source files.
+# This allows for fairly rapid rebuilding of the kernel for specified profiles
+# as only few files need to be re-compiled.
+perhaps-modify-drivers-config-h:
+ $(call quiet, sh scripts/gen-drivers-config-header $(arch) $(out)/gen/include/osv/drivers_config.h, GEN gen/include/osv/drivers_config.h)
+.PHONY: perhaps-modify-drivers-config-h
+
$(out)/gen/include/bits/alltypes.h: include/api/$(arch)/bits/alltypes.h.sh
$(makedir)
$(call quiet, sh $^ > $@, GEN $@)
diff --git a/arch/aarch64/arch-dtb.cc b/arch/aarch64/arch-dtb.cc
index 63db8b00..7a7ef51f 100644
--- a/arch/aarch64/arch-dtb.cc
+++ b/arch/aarch64/arch-dtb.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include <osv/types.h>
#include <osv/debug.h>
#include <stdlib.h>
@@ -16,7 +17,9 @@
#include <osv/mempool.hh>
#include <osv/commands.hh>
#include <osv/elf.hh>
+#if CONF_drivers_mmio
#include "drivers/virtio-mmio.hh"
+#endif

#define DTB_INTERRUPT_CELLS 3

@@ -279,6 +282,7 @@ u64 dtb_get_cadence_uart(int *irqid)
return addr;
}

+#if CONF_drivers_mmio
#define VIRTIO_MMIO_DEV_COMPAT "virtio,mmio"
#define DTB_MAX_VIRTIO_MMIO_DEV_COUNT 8
static virtio::mmio_device_info dtb_dtb_virtio_mmio_devices_infos[DTB_MAX_VIRTIO_MMIO_DEV_COUNT];
@@ -321,6 +325,7 @@ void dtb_collect_parsed_mmio_virtio_devices()
virtio::add_mmio_device_configuration(dtb_dtb_virtio_mmio_devices_infos[idx]);
}
}
+#endif

/* this gets the virtual timer irq, we are not interested
* about the other timers.
@@ -796,7 +801,9 @@ void __attribute__((constructor(init_prio::dtb))) dtb_setup()
abort("dtb_setup: failed to parse pci_irq_map.\n");
}

+#if CONF_drivers_mmio
dtb_parse_mmio_virtio_devices();
+#endif

register u64 edata;
asm volatile ("adrp %0, .edata" : "=r"(edata));
diff --git a/arch/aarch64/arch-setup.cc b/arch/aarch64/arch-setup.cc
index bfa47f9f..f9854b6a 100644
--- a/arch/aarch64/arch-setup.cc
+++ b/arch/aarch64/arch-setup.cc
@@ -7,6 +7,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "arch-setup.hh"
#include <osv/sched.hh>
#include <osv/mempool.hh>
@@ -16,7 +17,9 @@
#include <osv/boot.hh>
#include <osv/debug.hh>
#include <osv/commands.hh>
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif

#include "arch-mmu.hh"
#include "arch-dtb.hh"
@@ -24,7 +27,9 @@
#include "drivers/console.hh"
#include "drivers/pl011.hh"
#include "early-console.hh"
+#if CONF_drivers_pci
#include <osv/pci.hh>
+#endif
#include "drivers/mmio-isa-serial.hh"

#include <alloca.h>
@@ -41,6 +46,7 @@ void setup_temporary_phys_map()
mmu::flush_tlb_all();
}

+#if CONF_drivers_pci
void arch_setup_pci()
{
pci::set_pci_ecam(dtb_get_pci_is_ecam());
@@ -71,6 +77,7 @@ void arch_setup_pci()
mmu::linear_map((void *)ranges[1], (mmu::phys)ranges[1], ranges_len[1],
mmu::page_size, mmu::mattr::dev);
}
+#endif

extern bool opt_pci_disabled;
void arch_setup_free_memory()
@@ -101,12 +108,14 @@ void arch_setup_free_memory()
mmu::mattr::dev);
}

+#if CONF_drivers_cadence
if (console::Cadence_Console::active) {
// linear_map [TTBR0 - UART]
addr = (mmu::phys)console::aarch64_console.cadence.get_base_addr();
mmu::linear_map((void *)addr, addr, 0x1000, mmu::page_size,
mmu::mattr::dev);
}
+#endif

/* linear_map [TTBR0 - GIC DIST and GIC CPU] */
u64 dist, cpu;
@@ -120,15 +129,19 @@ void arch_setup_free_memory()
mmu::linear_map((void *)cpu, (mmu::phys)cpu, cpu_len, mmu::page_size,
mmu::mattr::dev);

+#if CONF_drivers_pci
if (!opt_pci_disabled) {
arch_setup_pci();
}
+#endif

// get rid of the command line, before memory is unmapped
console::mmio_isa_serial_console::clean_cmdline(cmdline);
osv::parse_cmdline(cmdline);

+#if CONF_drivers_mmio
dtb_collect_parsed_mmio_virtio_devices();
+#endif

mmu::switch_to_runtime_page_tables();

@@ -155,17 +168,28 @@ void arch_init_premain()
}

#include "drivers/driver.hh"
+#if CONF_drivers_virtio
#include "drivers/virtio.hh"
+#include "drivers/virtio-mmio.hh"
+#endif
+#if CONF_drivers_virtio_rng
#include "drivers/virtio-rng.hh"
+#endif
+#if CONF_drivers_virtio_blk
#include "drivers/virtio-blk.hh"
+#endif
+#if CONF_drivers_virtio_net
#include "drivers/virtio-net.hh"
-#include "drivers/virtio-mmio.hh"
+#endif
+#if CONF_drivers_virtio_fs
#include "drivers/virtio-fs.hh"
+#endif

void arch_init_drivers()
{
extern boot_time_chart boot_time;

+#if CONF_drivers_pci
if (!opt_pci_disabled) {
int irqmap_count = dtb_get_pci_irqmap_count();
if (irqmap_count > 0) {
@@ -189,16 +213,27 @@ void arch_init_drivers()
boot_time.event("pci enumerated");
}
}
+#endif

+#if CONF_drivers_mmio
// Register any parsed virtio-mmio devices
virtio::register_mmio_devices(device_manager::instance());
+#endif

// Initialize all drivers
hw::driver_manager* drvman = hw::driver_manager::instance();
+#if CONF_drivers_virtio_rng
drvman->register_driver(virtio::rng::probe);
+#endif
+#if CONF_drivers_virtio_blk
drvman->register_driver(virtio::blk::probe);
+#endif
+#if CONF_drivers_virtio_net
drvman->register_driver(virtio::net::probe);
+#endif
+#if CONF_drivers_virtio_fs
drvman->register_driver(virtio::fs::probe);
+#endif
boot_time.event("drivers probe");
drvman->load_all();
drvman->list_drivers();
@@ -208,11 +243,13 @@ void arch_init_early_console()
{
console::mmio_isa_serial_console::_phys_mmio_address = 0;

+#if CONF_drivers_xen
if (is_xen()) {
new (&console::aarch64_console.xen) console::XEN_Console();
console::arch_early_console = console::aarch64_console.xen;
return;
}
+#endif

int irqid;
u64 mmio_serial_address = dtb_get_mmio_serial_console(&irqid);
@@ -225,6 +262,7 @@ void arch_init_early_console()
return;
}

+#if CONF_drivers_cadence
mmio_serial_address = dtb_get_cadence_uart(&irqid);
if (mmio_serial_address) {
new (&console::aarch64_console.cadence) console::Cadence_Console();
@@ -234,6 +272,7 @@ void arch_init_early_console()
console::Cadence_Console::active = true;
return;
}
+#endif

new (&console::aarch64_console.pl011) console::PL011_Console();
console::arch_early_console = console::aarch64_console.pl011;
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index dc59197b..5fce7853 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
.text
.align 16
.globl start_elf
@@ -31,8 +32,10 @@ start_elf:
adrp x1, dtb // store dtb (arch-setup.cc)
str x5, [x1, #:lo12:dtb]

+#if CONF_drivers_xen
mov x29, xzr
bl init_xen
+#endif

mov x29, xzr
bl premain
diff --git a/arch/aarch64/cpuid.cc b/arch/aarch64/cpuid.cc
index d4da09d4..3b803afc 100644
--- a/arch/aarch64/cpuid.cc
+++ b/arch/aarch64/cpuid.cc
@@ -5,9 +5,12 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "cpuid.hh"
#include "processor.hh"
+#if CONF_drivers_xen
#include "xen.hh"
+#endif

namespace processor {

@@ -131,7 +134,9 @@ const unsigned long hwcap32()

void process_cpuid(features_type& features)
{
+#if CONF_drivers_xen
xen::get_features(features);
+#endif
}

const features_type& features()
diff --git a/arch/aarch64/xen.cc b/arch/aarch64/xen.cc
index 47994609..50f752c4 100644
--- a/arch/aarch64/xen.cc
+++ b/arch/aarch64/xen.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#define CONF_drivers_xen 1
#include <osv/types.h>
#include <osv/xen.hh>
#include <xen/interface/xen.h>
diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc
index d0ea6a7d..03518deb 100644
--- a/arch/x64/apic.cc
+++ b/arch/x64/apic.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "apic.hh"
#include "msr.hh"
#include <osv/xen.hh>
diff --git a/arch/x64/arch-setup.cc b/arch/x64/arch-setup.cc
index 439d0650..582cb1b5 100644
--- a/arch/x64/arch-setup.cc
+++ b/arch/x64/arch-setup.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "arch.hh"
#include "arch-cpu.hh"
#include "arch-setup.hh"
@@ -13,7 +14,9 @@
#include "processor.hh"
#include "processor-flags.h"
#include "msr.hh"
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/elf.hh>
#include <osv/types.h>
#include <alloca.h>
@@ -21,15 +24,21 @@
#include <osv/boot.hh>
#include <osv/commands.hh>
#include "dmi.hh"
+#if CONF_drivers_acpi
#include "drivers/acpi.hh"
+#endif

osv_multiboot_info_type* osv_multiboot_info;

+#if CONF_drivers_mmio
#include "drivers/virtio-mmio.hh"
+#endif
void parse_cmdline(multiboot_info_type& mb)
{
auto p = reinterpret_cast<char*>(mb.cmdline);
+#if CONF_drivers_mmio
virtio::parse_mmio_device_configuration(p);
+#endif
osv::parse_cmdline(p);
}

@@ -214,8 +223,13 @@ void arch_setup_tls(void *tls, const elf::tls_data& info)

static inline void disable_pic()
{
+#if CONF_drivers_xen
// PIC not present in Xen
XENPV_ALTERNATIVE({ processor::outb(0xff, 0x21); processor::outb(0xff, 0xa1); }, {});
+#else
+ processor::outb(0xff, 0x21);
+ processor::outb(0xff, 0xa1);
+#endif
}

extern "C" void syscall_entry(void);
@@ -247,53 +261,105 @@ void arch_init_premain()
if (omb.disk_err)
debug_early_u64("Error reading disk (real mode): ", static_cast<u64>(omb.disk_err));

+#if CONF_drivers_acpi
acpi::pvh_rsdp_paddr = omb.pvh_rsdp;
+#endif

disable_pic();
}

#include "drivers/driver.hh"
+#if CONF_drivers_acpi
#include "drivers/pvpanic.hh"
+#endif
+#if CONF_drivers_virtio
#include "drivers/virtio.hh"
+#endif
+#if CONF_drivers_virtio_blk
#include "drivers/virtio-blk.hh"
+#endif
+#if CONF_drivers_virtio_scsi
#include "drivers/virtio-scsi.hh"
+#endif
+#if CONF_drivers_virtio_net
#include "drivers/virtio-net.hh"
+#endif
+#if CONF_drivers_virtio_rng
#include "drivers/virtio-rng.hh"
+#endif
+#if CONF_drivers_virtio_fs
#include "drivers/virtio-fs.hh"
+#endif
+#if CONF_drivers_xen
#include "drivers/xenplatform-pci.hh"
+#endif
+#if CONF_drivers_ahci
#include "drivers/ahci.hh"
+#endif
+#if CONF_drivers_pvscsi
#include "drivers/vmw-pvscsi.hh"
+#endif
+#if CONF_drivers_vmxnet3
#include "drivers/vmxnet3.hh"
+#endif
+#if CONF_drivers_ide
#include "drivers/ide.hh"
+#endif

extern bool opt_pci_disabled;
void arch_init_drivers()
{
+#if CONF_drivers_acpi
// initialize panic drivers
panic::pvpanic::probe_and_setup();
boot_time.event("pvpanic done");
+#endif

+#if CONF_drivers_pci
if (!opt_pci_disabled) {
// Enumerate PCI devices
pci::pci_device_enumeration();
boot_time.event("pci enumerated");
}
+#endif

+#if CONF_drivers_mmio
// Register any parsed virtio-mmio devices
virtio::register_mmio_devices(device_manager::instance());
+#endif

// Initialize all drivers
hw::driver_manager* drvman = hw::driver_manager::instance();
+#if CONF_drivers_virtio_blk
drvman->register_driver(virtio::blk::probe);
+#endif
+#if CONF_drivers_virtio_scsi
drvman->register_driver(virtio::scsi::probe);
+#endif
+#if CONF_drivers_virtio_net
drvman->register_driver(virtio::net::probe);
+#endif
+#if CONF_drivers_virtio_rng
drvman->register_driver(virtio::rng::probe);
+#endif
+#if CONF_drivers_virtio_fs
drvman->register_driver(virtio::fs::probe);
+#endif
+#if CONF_drivers_xen
drvman->register_driver(xenfront::xenplatform_pci::probe);
+#endif
+#if CONF_drivers_ahci
drvman->register_driver(ahci::hba::probe);
+#endif
+#if CONF_drivers_pvscsi
drvman->register_driver(vmw::pvscsi::probe);
+#endif
+#if CONF_drivers_vmxnet3
drvman->register_driver(vmw::vmxnet3::probe);
+#endif
+#if CONF_drivers_ide
drvman->register_driver(ide::ide_drive::probe);
+#endif
boot_time.event("drivers probe");
drvman->load_all();
drvman->list_drivers();
@@ -301,7 +367,9 @@ void arch_init_drivers()

#include "drivers/console.hh"
#include "drivers/isa-serial.hh"
+#if CONF_drivers_vga
#include "drivers/vga.hh"
+#endif
#include "early-console.hh"

void arch_init_early_console()
@@ -311,15 +379,21 @@ void arch_init_early_console()

bool arch_setup_console(std::string opt_console)
{
+#if CONF_drivers_vga
hw::driver_manager* drvman = hw::driver_manager::instance();
+#endif

if (opt_console.compare("serial") == 0) {
console::console_driver_add(&console::arch_early_console);
+#if CONF_drivers_vga
} else if (opt_console.compare("vga") == 0) {
drvman->register_driver(console::VGAConsole::probe);
+#endif
} else if (opt_console.compare("all") == 0) {
console::console_driver_add(&console::arch_early_console);
+#if CONF_drivers_vga
drvman->register_driver(console::VGAConsole::probe);
+#endif
} else {
return false;
}
diff --git a/arch/x64/cpuid.cc b/arch/x64/cpuid.cc
index 29bc8d6e..73064158 100644
--- a/arch/x64/cpuid.cc
+++ b/arch/x64/cpuid.cc
@@ -5,10 +5,15 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "cpuid.hh"
#include "processor.hh"
+#if CONF_drivers_xen
#include "xen.hh"
+#endif
+#if CONF_drivers_hyperv
#include <dev/hyperv/include/hyperv.h>
+#endif

namespace processor {

@@ -96,6 +101,7 @@ static void process_cpuid_bit(features_type& features, const cpuid_bit& b)
features.*(b.flag) = (w >> b.bit) & 1;
}

+#if CONF_drivers_xen
static void process_xen_bits(features_type &features)
{
signature sig = { 0x566e6558, 0x65584d4d, 0x4d4d566e };
@@ -109,20 +115,27 @@ static void process_xen_bits(features_type &features)
break;
}
}
+#endif

+#if CONF_drivers_hyperv
static void process_hyperv_bits(features_type &features) {
if(hyperv_identify() && hyperv_is_timecount_available()) {
features.hyperv_clocksource = true;
}
}
+#endif

static void process_cpuid(features_type& features)
{
for (unsigned i = 0; i < nr_cpuid_bits; ++i) {
process_cpuid_bit(features, cpuid_bits[i]);
}
+#if CONF_drivers_xen
process_xen_bits(features);
+#endif
+#if CONF_drivers_hyperv
process_hyperv_bits(features);
+#endif
}

}
@@ -140,6 +153,7 @@ const std::string& features_str()
}
}

+#if CONF_drivers_xen
// FIXME: Even though Xen does not have its features in cpuid, there has to
// be a better way to do it, by creating a string map directly from the xen
// PV features. But since we add features here very rarely, leave it be for now.
@@ -152,6 +166,7 @@ const std::string& features_str()
if (features().xen_pci) {
cpuid_str += std::string("xen_pci ");
}
+#endif
cpuid_str.pop_back();

return cpuid_str;
diff --git a/arch/x64/entry-xen.S b/arch/x64/entry-xen.S
index be67b33d..451d35e4 100644
--- a/arch/x64/entry-xen.S
+++ b/arch/x64/entry-xen.S
@@ -3,6 +3,7 @@
# This work is open source software, licensed under the terms of the
# BSD license as described in the LICENSE file in the top-level directory.

+#include <osv/drivers_config.h>
#include <xen/interface/elfnote.h>

#define elfnote(type, valtype, value) \
@@ -21,6 +22,7 @@
#define elfnote_val(type, value) elfnote(type, .quad, value)
#define elfnote_str(type, value) elfnote(type, .asciz, value)

+#if CONF_drivers_xen
elfnote_val(XEN_ELFNOTE_ENTRY, xen_start)
elfnote_val(XEN_ELFNOTE_HYPERCALL_PAGE, hypercall_page)
elfnote_val(XEN_ELFNOTE_VIRT_BASE, OSV_KERNEL_VM_SHIFT)
@@ -30,6 +32,7 @@ elfnote_str(XEN_ELFNOTE_GUEST_VERSION, "?.?")
elfnote_str(XEN_ELFNOTE_LOADER, "generic")
elfnote_str(XEN_ELFNOTE_FEATURES, "!writable_page_tables")
elfnote_str(XEN_ELFNOTE_BSD_SYMTAB, "yes")
+#endif
elfnote_val(XEN_ELFNOTE_PHYS32_ENTRY, hvm_xen_start-OSV_KERNEL_VM_SHIFT)

.data
@@ -41,6 +44,7 @@ elfnote_val(XEN_ELFNOTE_PHYS32_ENTRY, hvm_xen_start-OSV_KERNEL_VM_SHIFT)
xen_bootstrap_end: .quad 0

.text
+#if CONF_drivers_xen
.align 4096
.globl hypercall_page
.hidden hypercall_page
@@ -54,6 +58,7 @@ xen_start:
call xen_init
mov $0x0, %rdi
jmp start64
+#endif

.code32
hvm_xen_start:
diff --git a/arch/x64/power.cc b/arch/x64/power.cc
index c9656fe0..71cba972 100644
--- a/arch/x64/power.cc
+++ b/arch/x64/power.cc
@@ -5,17 +5,20 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include <osv/power.hh>
#include <osv/debug.hh>
#include <smp.hh>
#include <processor.hh>
#include <arch.hh>

+#if CONF_drivers_acpi
extern "C" {
#include "acpi.h"
}

#include <drivers/acpi.hh>
+#endif

namespace osv {

@@ -29,6 +32,7 @@ void halt(void)

void poweroff(void)
{
+#if CONF_drivers_acpi
if (acpi::is_enabled()) {
ACPI_STATUS status = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
if (ACPI_FAILURE(status)) {
@@ -41,6 +45,7 @@ void poweroff(void)
halt();
}
} else {
+#endif
// On hypervisors that do not support ACPI like firecracker we
// resort to a reset using the 8042 PS/2 Controller ("keyboard controller")
// as a way to shutdown the VM
@@ -49,7 +54,9 @@ void poweroff(void)
// then cause triple fault by loading a broken IDT and triggering an interrupt.
processor::lidt(processor::desc_ptr(0, 0));
__asm__ __volatile__("int3");
+#if CONF_drivers_acpi
}
+#endif

// We shouldn't get here on x86.
halt();
@@ -71,9 +78,11 @@ static void kbd_reboot(void) {

void reboot(void)
{
+#if CONF_drivers_acpi
// Method 1: AcpiReset, does not work on qemu or kvm now because the reset
// register is not supported. Nevertheless, we should try it first
AcpiReset();
+#endif
// Method 2: "fast reset" via System Control Port A (port 0x92)
processor::outb(1, 0x92);
// Method 3: Reset using the 8042 PS/2 Controller ("keyboard controller")
diff --git a/arch/x64/smp.cc b/arch/x64/smp.cc
index be655881..7141c2a9 100644
--- a/arch/x64/smp.cc
+++ b/arch/x64/smp.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include <smp.hh>
#include "processor.hh"
#include "msr.hh"
@@ -12,10 +13,12 @@
#include "ioapic.hh"
#include <osv/mmu.hh>
#include <string.h>
+#if CONF_drivers_acpi
extern "C" {
#include "acpi.h"
}
#include <drivers/acpi.hh>
+#endif
#include <boost/intrusive/parent_from_member.hpp>
#include <osv/debug.hh>
#include <osv/sched.hh>
@@ -49,6 +52,7 @@ static void register_cpu(unsigned cpu_id, u32 apic_id, u32 acpi_id = 0)
sched::cpus.push_back(c);
}

+#if CONF_drivers_acpi
void parse_madt()
{
char madt_sig[] = ACPI_SIG_MADT;
@@ -88,6 +92,7 @@ void parse_madt()
}
debug(fmt("%d CPUs detected\n") % nr_cpus);
}
+#endif

#define MPF_IDENTIFIER (('_'<<24) | ('P'<<16) | ('M'<<8) | '_')
struct mpf_structure {
@@ -195,11 +200,15 @@ void parse_mp_table()

void smp_init()
{
+#if CONF_drivers_acpi
if (acpi::is_enabled()) {
parse_madt();
} else {
+#endif
parse_mp_table();
+#if CONF_drivers_acpi
}
+#endif

sched::current_cpu = sched::cpus[0];
for (auto c : sched::cpus) {
diff --git a/arch/x64/xen.cc b/arch/x64/xen.cc
index d642c4fa..2482c56a 100644
--- a/arch/x64/xen.cc
+++ b/arch/x64/xen.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#define CONF_drivers_xen 1
#include "xen.hh"
#include <osv/debug.hh>
#include <osv/mmu.hh>
diff --git a/conf/profiles/README.md b/conf/profiles/README.md
new file mode 100644
index 00000000..5350fe70
--- /dev/null
+++ b/conf/profiles/README.md
@@ -0,0 +1,71 @@
+The two subdirectories `aarch64` and `x64` contain tiny makefile
+include files (`*.mk`) which specify which drivers should be linked
+and enabled into kernel.
+
+The `base.mk` is the file included last by the main makefile and is
+intended to disable all drivers unless enabled specifically in a
+given profile file. For example, each driver configuration variable
+like `conf_drivers_virtio_fs` is disabled in a line in the `base.mk` like this:
+```make
+export conf_drivers_virtio_fs?=0
+```
+but would be enabled by this line in the `virtio-pci.mk`:
+```make
+conf_drivers_virtio_fs?=1
+```
+if the profile `virtio-pci` is selected when building the kernel like so:
+```bash
+./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-pci
+```
+The `base.mk` also enforces some dependencies between given driver and other kernel
+components. For example this line:
+```make
+ifeq ($(conf_drivers_hpet),1)
+export conf_drivers_acpi?=1
+endif
+```
+enables ACPI support if the hpet driver is selected. There is also another rule that
+enables PCI support if ACPI is selected. And so on.
+
+The individual files under given architecture directory other than `base.mk` enable
+list of drivers for each profile that typically corresponds to a hypervisor like `vbox.mk`
+for Virtual Box or a type of hypervisor like `microvm.mk`. One exception is the `all.mk`
+file which enables all drivers and is a default profile.
+
+Please note that one can build custom kernel with specific list of drivers by passing
+corresponding `conf_drivers_*` parameters to the build script like so:
+```bash
+./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=base \
+ conf_drivers_acpi=1 conf_drivers_virtio_fs=1 conf_drivers_virtio_net=1 conf_drivers_pvpanic=1
+```
+The kernel built using the command line above comes with enough drivers to mount virtio-FS filesystem and support networking over virtio-net device.
+
+Lastly if you want to verify which exact drivers were enabled, you can examine content of the generated `drivers-config.h` header:
+```c
+cat build/release/gen/include/osv/drivers_config.h
+/* This file is generated automatically. */
+#ifndef OSV_DRIVERS_CONFIG_H
+#define OSV_DRIVERS_CONFIG_H
+
+#define CONF_drivers_acpi 1
+#define CONF_drivers_ahci 0
+#define CONF_drivers_hpet 0
+#define CONF_drivers_hyperv 0
+#define CONF_drivers_ide 0
+#define CONF_drivers_mmio 0
+#define CONF_drivers_pci 1
+#define CONF_drivers_pvpanic 1
+#define CONF_drivers_pvscsi 0
+#define CONF_drivers_scsi 0
+#define CONF_drivers_vga 0
+#define CONF_drivers_virtio 1
+#define CONF_drivers_virtio_blk 0
+#define CONF_drivers_virtio_fs 1
+#define CONF_drivers_virtio_net 1
+#define CONF_drivers_virtio_rng 0
+#define CONF_drivers_virtio_scsi 0
+#define CONF_drivers_vmxnet3 0
+#define CONF_drivers_xen 0
+
+#endif
+```
diff --git a/conf/profiles/aarch64/all.mk b/conf/profiles/aarch64/all.mk
new file mode 100644
index 00000000..afc51954
--- /dev/null
+++ b/conf/profiles/aarch64/all.mk
@@ -0,0 +1,5 @@
+include conf/profiles/$(arch)/virtio-mmio.mk
+include conf/profiles/$(arch)/virtio-pci.mk
+include conf/profiles/$(arch)/xen.mk
+
+conf_drivers_cadence?=1
diff --git a/conf/profiles/aarch64/base.mk b/conf/profiles/aarch64/base.mk
new file mode 100644
index 00000000..a3894f54
--- /dev/null
+++ b/conf/profiles/aarch64/base.mk
@@ -0,0 +1,26 @@
+export conf_drivers_xen?=0
+
+export conf_drivers_virtio_blk?=0
+ifeq ($(conf_drivers_virtio_blk),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_fs?=0
+ifeq ($(conf_drivers_virtio_fs),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_net?=0
+ifeq ($(conf_drivers_virtio_net),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_rng?=0
+ifeq ($(conf_drivers_virtio_rng),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_cadence?=0
+export conf_drivers_virtio?=0
+export conf_drivers_pci?=0
+export conf_drivers_mmio?=0
diff --git a/conf/profiles/aarch64/microvm.mk b/conf/profiles/aarch64/microvm.mk
new file mode 120000
index 00000000..d85dd828
--- /dev/null
+++ b/conf/profiles/aarch64/microvm.mk
@@ -0,0 +1 @@
+virtio-mmio.mk
\ No newline at end of file
diff --git a/conf/profiles/aarch64/virtio-mmio.mk b/conf/profiles/aarch64/virtio-mmio.mk
new file mode 100644
index 00000000..d8d9669b
--- /dev/null
+++ b/conf/profiles/aarch64/virtio-mmio.mk
@@ -0,0 +1,4 @@
+conf_drivers_mmio?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_net?=1
diff --git a/conf/profiles/aarch64/virtio-pci.mk b/conf/profiles/aarch64/virtio-pci.mk
new file mode 100644
index 00000000..599a530c
--- /dev/null
+++ b/conf/profiles/aarch64/virtio-pci.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_fs?=1
+conf_drivers_virtio_net?=1
+conf_drivers_virtio_rng?=1
diff --git a/conf/profiles/aarch64/xen.mk b/conf/profiles/aarch64/xen.mk
new file mode 100644
index 00000000..2c5f0c87
--- /dev/null
+++ b/conf/profiles/aarch64/xen.mk
@@ -0,0 +1,2 @@
+conf_drivers_pci?=1
+conf_drivers_xen?=1
diff --git a/conf/profiles/x64/all.mk b/conf/profiles/x64/all.mk
new file mode 100644
index 00000000..c13790e2
--- /dev/null
+++ b/conf/profiles/x64/all.mk
@@ -0,0 +1,8 @@
+include conf/profiles/$(arch)/hyperv.mk
+include conf/profiles/$(arch)/vbox.mk
+include conf/profiles/$(arch)/virtio-mmio.mk
+include conf/profiles/$(arch)/virtio-pci.mk
+include conf/profiles/$(arch)/vmware.mk
+include conf/profiles/$(arch)/xen.mk
+
+conf_drivers_vga?=1
diff --git a/conf/profiles/x64/base.mk b/conf/profiles/x64/base.mk
new file mode 100644
index 00000000..26dd054e
--- /dev/null
+++ b/conf/profiles/x64/base.mk
@@ -0,0 +1,74 @@
+export conf_drivers_xen?=0
+export conf_drivers_hyperv?=0
+
+export conf_drivers_virtio_blk?=0
+ifeq ($(conf_drivers_virtio_blk),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_scsi?=0
+ifeq ($(conf_drivers_virtio_scsi),1)
+export conf_drivers_virtio?=1
+export conf_drivers_scsi?=1
+endif
+
+export conf_drivers_virtio_fs?=0
+ifeq ($(conf_drivers_virtio_fs),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_net?=0
+ifeq ($(conf_drivers_virtio_net),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_virtio_rng?=0
+ifeq ($(conf_drivers_virtio_rng),1)
+export conf_drivers_virtio?=1
+endif
+
+export conf_drivers_ahci?=0
+ifeq ($(conf_drivers_ahci),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_pvscsi?=0
+ifeq ($(conf_drivers_pvscsi),1)
+export conf_drivers_pci?=1
+export conf_drivers_scsi?=1
+endif
+
+export conf_drivers_vmxnet3?=0
+ifeq ($(conf_drivers_vmxnet3),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_ide?=0
+ifeq ($(conf_drivers_ide),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_vga?=0
+ifeq ($(conf_drivers_vga),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_pvpanic?=0
+ifeq ($(conf_drivers_pvpanic),1)
+export conf_drivers_acpi?=1
+endif
+
+export conf_drivers_hpet?=0
+ifeq ($(conf_drivers_hpet),1)
+export conf_drivers_acpi?=1
+endif
+
+export conf_drivers_acpi?=0
+ifeq ($(conf_drivers_acpi),1)
+export conf_drivers_pci?=1
+endif
+
+export conf_drivers_virtio?=0
+export conf_drivers_pci?=0
+export conf_drivers_mmio?=0
+export conf_drivers_scsi?=0
diff --git a/conf/profiles/x64/cloud_hypervisor.mk b/conf/profiles/x64/cloud_hypervisor.mk
new file mode 100644
index 00000000..aa8695dc
--- /dev/null
+++ b/conf/profiles/x64/cloud_hypervisor.mk
@@ -0,0 +1,2 @@
+include conf/profiles/$(arch)/virtio-pci.mk
+conf_drivers_pvpanic?=1
diff --git a/conf/profiles/x64/hyperv.mk b/conf/profiles/x64/hyperv.mk
new file mode 100644
index 00000000..69af65ca
--- /dev/null
+++ b/conf/profiles/x64/hyperv.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_hyperv?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/microvm.mk b/conf/profiles/x64/microvm.mk
new file mode 120000
index 00000000..d85dd828
--- /dev/null
+++ b/conf/profiles/x64/microvm.mk
@@ -0,0 +1 @@
+virtio-mmio.mk
\ No newline at end of file
diff --git a/conf/profiles/x64/vbox.mk b/conf/profiles/x64/vbox.mk
new file mode 100644
index 00000000..f0a26b2d
--- /dev/null
+++ b/conf/profiles/x64/vbox.mk
@@ -0,0 +1,8 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+
+conf_drivers_ahci?=1
+conf_drivers_virtio_net?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/virtio-mmio.mk b/conf/profiles/x64/virtio-mmio.mk
new file mode 100644
index 00000000..d8d9669b
--- /dev/null
+++ b/conf/profiles/x64/virtio-mmio.mk
@@ -0,0 +1,4 @@
+conf_drivers_mmio?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_net?=1
diff --git a/conf/profiles/x64/virtio-pci.mk b/conf/profiles/x64/virtio-pci.mk
new file mode 100644
index 00000000..a1d0a1ef
--- /dev/null
+++ b/conf/profiles/x64/virtio-pci.mk
@@ -0,0 +1,10 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_scsi?=1
+conf_drivers_virtio_fs?=1
+conf_drivers_virtio_net?=1
+conf_drivers_virtio_rng?=1
+
+conf_drivers_pvpanic?=1
diff --git a/conf/profiles/x64/vmware.mk b/conf/profiles/x64/vmware.mk
new file mode 100644
index 00000000..1a37e1d1
--- /dev/null
+++ b/conf/profiles/x64/vmware.mk
@@ -0,0 +1,10 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_scsi?=1
+
+conf_drivers_pvscsi?=1
+conf_drivers_vmxnet3?=1
+conf_drivers_ide?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/xen.mk b/conf/profiles/x64/xen.mk
new file mode 100644
index 00000000..8a0d49fa
--- /dev/null
+++ b/conf/profiles/x64/xen.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_xen?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/core/xen_intr.cc b/core/xen_intr.cc
index 16065a3d..adb4e3da 100644
--- a/core/xen_intr.cc
+++ b/core/xen_intr.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include <osv/xen_intr.hh>
#include <bsd/porting/bus.h>
diff --git a/drivers/acpi.cc b/drivers/acpi.cc
index 55ea126e..d1f5f422 100644
--- a/drivers/acpi.cc
+++ b/drivers/acpi.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include <map>
#include <memory>

@@ -19,7 +20,9 @@ extern "C" {
#include <osv/shutdown.hh>
#include "processor.hh"
#include <osv/align.hh>
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif

#include <osv/debug.h>
#include <osv/mutex.h>
@@ -635,5 +638,9 @@ void init()

void __attribute__((constructor(init_prio::acpi))) acpi_init_early()
{
- XENPV_ALTERNATIVE({ acpi::early_init(); }, {});
+#if CONF_drivers_xen
+ XENPV_ALTERNATIVE({ acpi::early_init(); }, {});
+#else
+ acpi::early_init();
+#endif
}
diff --git a/drivers/hpet.cc b/drivers/hpet.cc
index 6b67d8b7..8c582f80 100644
--- a/drivers/hpet.cc
+++ b/drivers/hpet.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
extern "C" {
#include "acpi.h"
}
@@ -15,7 +16,9 @@ extern "C" {
#include <osv/mmu.hh>
#include <osv/mmio.hh>
#include "arch.hh"
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/irqlock.hh>
#include "rtc.hh"
#include <osv/percpu.hh>
@@ -146,7 +149,9 @@ s64 hpetclock::boot_time()

void __attribute__((constructor(init_prio::hpet))) hpet_init()
{
+#if CONF_drivers_xen
XENPV_ALTERNATIVE(
+#endif
{
auto c = clock::get();

@@ -178,5 +183,9 @@ void __attribute__((constructor(init_prio::hpet))) hpet_init()
else {
clock::register_clock(new hpet_32bit_clock(hpet_mmio_address));
}
+#if CONF_drivers_xen
}, {});
+#else
+ }
+#endif
}
diff --git a/drivers/pci-generic.cc b/drivers/pci-generic.cc
index 6b0a9185..ff967715 100644
--- a/drivers/pci-generic.cc
+++ b/drivers/pci-generic.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include <sstream>
#include <iomanip>

@@ -16,8 +17,10 @@
#include "drivers/pci-function.hh"
#include "drivers/pci-bridge.hh"
#include "drivers/pci-device.hh"
+#if CONF_drivers_virtio
#include "drivers/virtio.hh"
#include "drivers/virtio-pci-device.hh"
+#endif

extern bool opt_pci_disabled;

@@ -102,6 +105,7 @@ bool check_bus(u16 bus)
}

hw_device *dev_to_register = dev;
+#if CONF_drivers_virtio
//
// Create virtio_device if vendor is VIRTIO_VENDOR_ID
if (dev->get_vendor_id() == virtio::VIRTIO_VENDOR_ID) {
@@ -117,6 +121,7 @@ bool check_bus(u16 bus)
pci_e("Error: expected regular pci device %02x:%02x.%x",
bus, slot, func);
}
+#endif

if (dev_to_register && !device_manager::instance()->register_device(dev_to_register)) {
pci_e("Error: couldn't register device %02x:%02x.%x",
diff --git a/drivers/virtio-blk.cc b/drivers/virtio-blk.cc
index 91ca492e..e03d41f7 100644
--- a/drivers/virtio-blk.cc
+++ b/drivers/virtio-blk.cc
@@ -6,6 +6,7 @@
*/


+#include <osv/drivers_config.h>
#include <sys/cdefs.h>

#include "drivers/virtio.hh"
@@ -133,6 +134,7 @@ blk::blk(virtio_device& virtio_dev)
auto queue = get_virt_queue(0);

interrupt_factory int_factory;
+#if CONF_drivers_pci
int_factory.register_msi_bindings = [queue, t](interrupt_manager &msi) {
msi.easy_register( {{ 0, [=] { queue->disable_interrupts(); }, t }});
};
@@ -143,6 +145,7 @@ blk::blk(virtio_device& virtio_dev)
[=] { return this->ack_irq(); },
[=] { t->wake(); });
};
+#endif

#ifdef __aarch64__
int_factory.create_spi_edge_interrupt = [this,t]() {
@@ -153,11 +156,13 @@ blk::blk(virtio_device& virtio_dev)
[=] { t->wake(); });
};
#else
+#if CONF_drivers_mmio
int_factory.create_gsi_edge_interrupt = [this,t]() {
return new gsi_edge_interrupt(
_dev.get_irq(),
[=] { if (this->ack_irq()) t->wake(); });
};
+#endif
#endif

_dev.register_interrupt(int_factory);
diff --git a/drivers/virtio-fs.cc b/drivers/virtio-fs.cc
index 0c5ffb4e..e87d0ce1 100644
--- a/drivers/virtio-fs.cc
+++ b/drivers/virtio-fs.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include <string>

#include <osv/debug.h>
@@ -101,6 +102,7 @@ fs::fs(virtio_device& virtio_dev)
auto* queue = get_virt_queue(VQ_REQUEST);

interrupt_factory int_factory;
+#if CONF_drivers_pci
int_factory.register_msi_bindings = [queue, t](interrupt_manager& msi) {
msi.easy_register({
{VQ_HIPRIO, nullptr, nullptr},
@@ -114,13 +116,16 @@ fs::fs(virtio_device& virtio_dev)
[=] { return this->ack_irq(); },
[=] { t->wake(); });
};
+#endif

#ifdef __x86_64__
+#if CONF_drivers_mmio
int_factory.create_gsi_edge_interrupt = [this, t]() {
return new gsi_edge_interrupt(
_dev.get_irq(),
[=] { if (this->ack_irq()) t->wake(); });
};
+#endif
#endif

_dev.register_interrupt(int_factory);
diff --git a/drivers/virtio-net.cc b/drivers/virtio-net.cc
index 4be60f10..d2ab7c76 100644
--- a/drivers/virtio-net.cc
+++ b/drivers/virtio-net.cc
@@ -6,6 +6,7 @@
*/


+#include <osv/drivers_config.h>
#include <sys/cdefs.h>

#include "drivers/virtio.hh"
@@ -303,6 +304,7 @@ net::net(virtio_device& dev)
ether_ifattach(_ifn, _config.mac);

interrupt_factory int_factory;
+#if CONF_drivers_pci
int_factory.register_msi_bindings = [this,poll_task](interrupt_manager &msi) {
msi.easy_register({
{ 0, [&] { this->_rxq.vqueue->disable_interrupts(); }, poll_task },
@@ -316,6 +318,7 @@ net::net(virtio_device& dev)
[=] { return this->ack_irq(); },
[=] { poll_task->wake(); });
};
+#endif

#ifdef __aarch64__
int_factory.create_spi_edge_interrupt = [this,poll_task]() {
@@ -326,11 +329,13 @@ net::net(virtio_device& dev)
[=] { poll_task->wake(); });
};
#else
+#if CONF_drivers_mmio
int_factory.create_gsi_edge_interrupt = [this,poll_task]() {
return new gsi_edge_interrupt(
_dev.get_irq(),
[=] { if (this->ack_irq()) poll_task->wake(); });
};
+#endif
#endif

_dev.register_interrupt(int_factory);
diff --git a/drivers/xenclock.cc b/drivers/xenclock.cc
index 6f5093cd..e9269d60 100644
--- a/drivers/xenclock.cc
+++ b/drivers/xenclock.cc
@@ -14,6 +14,7 @@
#include "string.h"
#include "cpuid.hh"
#include <osv/barrier.hh>
+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include <osv/debug.hh>
#include <osv/prio.hh>
diff --git a/drivers/xenfront-xenbus.cc b/drivers/xenfront-xenbus.cc
index ba143841..36e7f3dc 100644
--- a/drivers/xenfront-xenbus.cc
+++ b/drivers/xenfront-xenbus.cc
@@ -11,6 +11,7 @@
#include "cpuid.hh"
#include <osv/barrier.hh>
#include <osv/debug.hh>
+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include "processor.hh"
#include "xenfront.hh"
diff --git a/drivers/xenplatform-pci.cc b/drivers/xenplatform-pci.cc
index 16488cfa..15f1ea51 100644
--- a/drivers/xenplatform-pci.cc
+++ b/drivers/xenplatform-pci.cc
@@ -6,6 +6,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#define CONF_drivers_xen 1
#include "xen.hh"
#include "xenplatform-pci.hh"

diff --git a/fs/vfs/vfs_conf.cc b/fs/vfs/vfs_conf.cc
index 4a54cb97..48211e77 100644
--- a/fs/vfs/vfs_conf.cc
+++ b/fs/vfs/vfs_conf.cc
@@ -38,6 +38,7 @@
* vfs_conf.c - File system configuration.
*/

+#include <osv/drivers_config.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
@@ -52,11 +53,15 @@ extern struct vfsops nfs_vfsops;
extern struct vfsops procfs_vfsops;
extern struct vfsops sysfs_vfsops;
extern struct vfsops zfs_vfsops;
+#if CONF_drivers_virtio_fs
extern struct vfsops virtiofs_vfsops;
+#endif

extern int ramfs_init(void);
extern int rofs_init(void);
+#if CONF_drivers_virtio_fs
extern int virtiofs_init(void);
+#endif
extern int devfs_init(void);
extern int nfs_init(void);
extern int procfs_init(void);
@@ -74,6 +79,8 @@ const struct vfssw vfssw[] = {
{"sysfs", sysfs_init, &sysfs_vfsops},
{"zfs", zfs_init, &zfs_vfsops},
{"rofs", rofs_init, &rofs_vfsops},
+#if CONF_drivers_virtio_fs
{"virtiofs", virtiofs_init, &virtiofs_vfsops},
+#endif
{nullptr, fs_noop, nullptr},
};
diff --git a/include/osv/xen.hh b/include/osv/xen.hh
index 5b50c2b6..76ca3b49 100644
--- a/include/osv/xen.hh
+++ b/include/osv/xen.hh
@@ -24,7 +24,11 @@ extern struct start_info* xen_start_info;
extern "C" shared_info_t *HYPERVISOR_shared_info;

#define XENPV_ALTERNATIVE(x, y) ALTERNATIVE((xen_start_info != nullptr), x, y)
+#if CONF_drivers_xen
#define is_xen() (HYPERVISOR_shared_info != nullptr)
+#else
+#define is_xen() (0)
+#endif

// We don't support 32 bit
struct xen_vcpu_info {
diff --git a/loader.cc b/loader.cc
index da254492..48716587 100644
--- a/loader.cc
+++ b/loader.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "fs/fs.hh"
#include <bsd/init.hh>
#include <bsd/net.hh>
@@ -20,7 +21,9 @@
#include "smp.hh"

#ifdef __x86_64__
+#if CONF_drivers_acpi
#include "drivers/acpi.hh"
+#endif
#endif /* __x86_64__ */

#include <osv/sched.hh>
@@ -43,7 +46,9 @@
#include <osv/sampler.hh>
#include <osv/app.hh>
#include <osv/firmware.hh>
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/options.hh>
#include <dirent.h>
#include <iostream>
@@ -672,7 +677,9 @@ void main_cont(int loader_argc, char** loader_argv)

setenv("OSV_VERSION", osv::version().c_str(), 1);

+#if CONF_drivers_xen
xen::irq_init();
+#endif
smp_launch();
setenv("OSV_CPUS", std::to_string(sched::cpus.size()).c_str(), 1);
boot_time.event("SMP launched");
@@ -685,7 +692,9 @@ void main_cont(int loader_argc, char** loader_argv)
memory::enable_debug_allocator();

#ifdef __x86_64__
+#if CONF_drivers_acpi
acpi::init();
+#endif
#endif /* __x86_64__ */

if (sched::cpus.size() > sched::max_cpus) {
diff --git a/runtime.cc b/runtime.cc
index 10c72cca..3942982c 100644
--- a/runtime.cc
+++ b/runtime.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include <osv/sched.hh>
#include <osv/elf.hh>
#include <stdlib.h>
@@ -48,7 +49,9 @@
#include <boost/range/adaptor/reversed.hpp>
#include <osv/align.hh>
#include <osv/stubbing.hh>
+#if CONF_drivers_acpi
#include "drivers/pvpanic.hh"
+#endif
#include <api/sys/resource.h>
#include <api/math.h>
#include <osv/shutdown.hh>
@@ -128,7 +131,9 @@ void abort(const char *fmt, ...)
debug_early("Halting.\n");
}
#ifndef AARCH64_PORT_STUB
+#if CONF_drivers_acpi
panic::pvpanic::panicked();
+#endif
#endif /* !AARCH64_PORT_STUB */

if (opt_power_off_on_abort) {
diff --git a/scripts/gen-drivers-config-header b/scripts/gen-drivers-config-header
new file mode 100755
index 00000000..daa0f373
--- /dev/null
+++ b/scripts/gen-drivers-config-header
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+if [ "$#" -ne 2 ]; then
+ echo "usage: $(basename $0) ARCH OUTPUT" >&2
+ exit 1
+fi
+
+arch=$1
+
+output=$2
+
+drivers_config_base_file=`dirname $0`/../conf/profiles/$arch/base.mk
+
+tmp=$(mktemp)
+
+cat >$tmp <<EOL
+/* This file is generated automatically. */
+#ifndef OSV_DRIVERS_CONFIG_H
+#define OSV_DRIVERS_CONFIG_H
+
+EOL
+
+template_tmp=$(mktemp)
+cat $drivers_config_base_file | grep "export conf" | cut --delimiter=_ -f 2- | cut --delimiter=? -f 1 | \
+ sort | uniq | awk '{ printf("echo define CONF_%s $conf_%s\n", $0, $0) }' > $template_tmp
+. $template_tmp | awk '{printf("#%s\n",$0)}' >> $tmp
+rm $template_tmp
+
+cat >>$tmp <<EOL
+
+#endif
+EOL
+
+if cmp -s $tmp $output
+then
+ rm $tmp
+else
+ mkdir -p $(dirname $output)
+ mv $tmp $output
+fi
--
2.31.1

Nadav Har'El

unread,
Feb 10, 2022, 8:04:49 AM2/10/22
to Waldemar Kozaczuk, Osv Dev
On Wed, Feb 9, 2022 at 4:19 AM Waldemar Kozaczuk <jwkoz...@gmail.com> wrote:
This patch introduces new build mechanism that allows creating
custom kernel with specific list of device drivers intended to target
given hypervisor. Such kernel benefits from smaller size and better
security as all unneeded code is removed. This patch partially addresses
the modularization/librarization functionality as explained by the issue
#1110 and this part of the roadmap - https://github.com/cloudius-systems/osv/wiki/Roadmap#modularizationlibrarization.
This idea was also mentioned in the P99 OSv presentation - see slide 11.

Nice progress!


In essence, we introduce new build script and makefile parameter:
`drivers_profile`. This new parameter is intended to specify a
drivers profile which is simply a list of device drivers to be linked
into kernel with some extra functionality like PCI or ACPI these drivers
depend on.

I just want to make one comment on this approach of "profiles".

When we started OSv, we had the concept of "image" file (used by "make image=..."),
which would define which applications, libraries, and so on, an image should contain.
We soon discovered that having a full list was inconvenient - if we wanted sometimes
to have an image with Cassandra and Java 8 and another time to have an image with
Cassandra and Java 9 (just making up an example), we would need separate "image"
file for each of these combinations - and this became ugly and inconvenient.

The solution was to come up with the notion of "module" instead of image.
So someone can ask to build with "module=cassandra,java8" and get this combination
and someone else can request "module=cassandra,java9" and get the differet
combination - and we don't need to think of all the combinations up-front.

I think probably we'll want something like this too - not just having
a lot of conf/profiles/ files (like we had in the distance past a lot of files in images/) -
one for xen+nfs, one for xen-without-nfs, one for kvm+nfs, one for kvm-without-nfs,
and so on and so on - but rather allowing to have "modules" that can be listed ad-hoc -
as well as depend on each other (e.g., asking for "TCP" will require "IP" - if we ever
go as far as splitting the IP network). Actually, looking below I see you already support
that - by listing individual driver names in the command line.

Eventually we may even want application
modules (modules/* and apps/*) to specify in their module.py also the minimum drivers they
need - e.g., maybe apps/cassandra would say it needs tcp/ip, but be silent on whether it
needs kvm or xen. Or something like that. But we can discuss and/or do it later :-)

I have a few more comments inline below, so please scroll down:
Nice trick. I looked for a function to check if a file exists more directly, but couldn't find one.
You could have also used "realpath" instead of "wildcard", I think.
 
+    $(error unsupported drivers profile $(drivers_profile))
+endif
+include conf/profiles/$(arch)/$(drivers_profile).mk
+# The base profile disables all drivers unless they are explicitly enabled
+# by the profile file included in the line above. The base profile also enforces
+# certain dependencies between drivers, for example the ide driver needs pci support, etc.
+# For more details please read comments in the profile file.
+include conf/profiles/$(arch)/base.mk
+
 CROSS_PREFIX ?= $(if $(filter-out $(arch),$(host_arch)),$(arch)-linux-gnu-)
 CXX=$(CROSS_PREFIX)g++
 CC=$(CROSS_PREFIX)gcc
@@ -617,10 +636,13 @@ bsd += bsd/sys/netinet/cc/cc_cubic.o
 bsd += bsd/sys/netinet/cc/cc_htcp.o
 bsd += bsd/sys/netinet/cc/cc_newreno.o
 bsd += bsd/sys/netinet/arpcache.o
+ifeq ($(conf_drivers_xen),1)
 bsd += bsd/sys/xen/evtchn.o
+endif

 ifeq ($(arch),x64)
 $(out)/bsd/%.o: COMMON += -DXEN -DXENHVM
+ifeq ($(conf_drivers_xen),1)

A thought: if these variables will always be 1 or not exist, you could use the nicer syntax

ifdef conf_drivers_xen

with a lot fewer parentheses, dollar signs, numbers, etc. :-)
It's above, not below, and you used ifeq, not it.
What does this #define change?

 #include <osv/types.h>
 #include <osv/xen.hh>
 #include <xen/interface/xen.h>
diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc
index d0ea6a7d..03518deb 100644
--- a/arch/x64/apic.cc
+++ b/arch/x64/apic.cc
@@ -5,6 +5,7 @@
  * BSD license as described in the LICENSE file in the top-level directory.
  */

+#include <osv/drivers_config.h>

I think this include is unnecessary - you don't seem to use anything from it later in this file.
Why do you sometimes use "export" and sometimes not?
Why this "?=" everywhere?

Above I suggested to use "ifdef" instead of "ifeq". This also simplifies these instructions -
base.mk doesn't need to define everything to 0 - it just doesn't define anything!
Maybe base.mk doesn't even need to exist.
And virtio-pci.mk will just have

  conf_drivers_virtio_fs = 1

and that's it.


+```
+if the profile `virtio-pci` is selected when building the kernel like so:
+```bash
+./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-pci
+```
+The `base.mk` also enforces some dependencies between given driver and other kernel
+components. For example this line:
+```make
+ifeq ($(conf_drivers_hpet),1)
+export conf_drivers_acpi?=1
+endif
+```
+enables ACPI support if the hpet driver is selected. There is also another rule that
+enables PCI support if ACPI is selected. And so on.

I don't understand how this works :-(
When does this check happen? Is base.mk loaded last after the other profiles?
Or is this code specifically for the case where the user runs a manual "make conf_drivers=acpi=1"?

And I wonder why this needs to be in base.mk and not in the main Makefile itself.
I thought that these *.mk files should contain a Makefile. How can it contain just the *name* of another file?
Don't you need an "include" command?
Again, what does this #define help?
Nitpick: If you move the #endif one line down (to include the {), you won't need an "#else" below.
Again I wonder what does this #define help.
I see more of these in more files below, so I'll stop asking - but it's the same thing again and again.
Please add quotes on $0 - `dirname "$0"` - otherwise somewhere in your directory path there is a directory with a space in its name, this will break.
 

+
+tmp=$(mktemp)
+
+cat >$tmp <<EOL
+/* This file is generated automatically. */
+#ifndef OSV_DRIVERS_CONFIG_H
+#define OSV_DRIVERS_CONFIG_H
+
+EOL
+
+template_tmp=$(mktemp)
+cat $drivers_config_base_file | grep "export conf" | cut --delimiter=_ -f 2- | cut --delimiter=? -f 1 | \
+  sort | uniq | awk '{ printf("echo define CONF_%s $conf_%s\n", $0, $0) }' > $template_tmp
+. $template_tmp | awk '{printf("#%s\n",$0)}' >> $tmp

I don't understand why you did this by printing "echo" commands and then running them...
Not only does this seem like redundant work, it also looks scary security-wise - who knows what kind of mess someone can cause by adding ";" or "`" characters as part of these conf variables.

It seems it would be easier to do all of this in one awk script, no?
 
+rm $template_tmp
+
+cat >>$tmp <<EOL
+
+#endif
+EOL
+
+if cmp -s $tmp $output
+then
+    rm $tmp
+else
+    mkdir -p $(dirname $output)
+    mv $tmp $output
+fi

Nitpick: if this script is killed in the middle, it doesn't remove the temporary files.
 
--
2.31.1

--
You received this message because you are subscribed to the Google Groups "OSv Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/20220209021905.514779-1-jwkozaczuk%40gmail.com.

Waldek Kozaczuk

unread,
Feb 26, 2022, 4:09:56 PM2/26/22
to OSv Development
Hi,

Thanks for your feedback as always. Sorry for the late reply but I have been busy with various activities and some including improvements to the aarch64 port which I hope to be sending new patches soon.

Please note that I planning to update OSv build/publish mechanism (see https://github.com/cloudius-systems/osv/blob/master/.travis.yml#L35) to publish a number of versions of kernels with various most common combinations (the compressed loader elf is < 2MB) so that one can easily pull a version of the kernel that fits their need.

Eventually we may even want application
modules (modules/* and apps/*) to specify in their module.py also the minimum drivers they
need - e.g., maybe apps/cassandra would say it needs tcp/ip, but be silent on whether it
needs kvm or xen. Or something like that. But we can discuss and/or do it later :-)
 
Yeah. The individual drivers kind of logically are similar to modules. The difference is that they are either compiled/linked into kernel vs simply present on the filesystem.
Ideally, it would be nice to load the drivers from some filesystem. But many of those drivers need to be probed and activated earlier before we initialize VFS. The best candidate would be bootfs or something equivalent. The problem is that some drivers like console or xen code would be quite hard to support like this. We would have to initialize VFS very early, no? Also, the driver's binaries would go into bootfs which currently is defacto park of loader.elf/kernel.elf. This kind of makes the whole thing pointless. Maybe you have some clever ideas. 
Anyhow as you point out we can build on this patch and implement the improvements later.
Well, these variables actually always have a numerical value - 1 (enabled) or 0 (disabled). Having a numerical value one can also override the value in profile files with one provided in the command line. So I think it should stay like this.
It is so that the macro is_xen() in osv/xen.hh included below can be disabled accordingly (see below in the patch that changes xen.hh):

#define is_xen() (HYPERVISOR_shared_info != nullptr)

 #include <osv/types.h>
 #include <osv/xen.hh>
 #include <xen/interface/xen.h>
diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc
index d0ea6a7d..03518deb 100644
--- a/arch/x64/apic.cc
+++ b/arch/x64/apic.cc
@@ -5,6 +5,7 @@
  * BSD license as described in the LICENSE file in the top-level directory.
  */

+#include <osv/drivers_config.h>

I think this include is unnecessary - you don't seem to use anything from it later in this file.
I do indirectly by including xen.hh 3 lines later. 
You might be right. But I am not sure if your slightly different proposal would be enough to support all kinds of variations like overriding whether a given driver is included or not. Like how would I satisfy this:

scripts/build drivers_profile=virtio-pci conf_drivers_virtio_scsi=0 //The virtio-pc.mk enables conf_drivers_virtio_scsi but by setting conf_drivers_virtio_scsi=0 we override this

And maybe it does but at this point, I would have to retest all the combinations I verified to work. So I am a bit reluctant to change it as it is cosmetics.



+```
+if the profile `virtio-pci` is selected when building the kernel like so:
+```bash
+./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-pci
+```
+The `base.mk` also enforces some dependencies between given driver and other kernel
+components. For example this line:
+```make
+ifeq ($(conf_drivers_hpet),1)
+export conf_drivers_acpi?=1
+endif
+```
+enables ACPI support if the hpet driver is selected. There is also another rule that
+enables PCI support if ACPI is selected. And so on.

I don't understand how this works :-(
When does this check happen? Is base.mk loaded last after the other profiles?
Yes. 
Or is this code specifically for the case where the user runs a manual "make conf_drivers=acpi=1"?
These are for these rules that make sure that if you include hpet the acpi is included as well as it depends on it.

And I wonder why this needs to be in base.mk and not in the main Makefile itself.
I did not want to complicate the makefile too much. 
This line in the patch is somehow misrepresenting the fact that microvm.mk is simply a symbolic link to vitrtio-mmio.mk. So microvm profile is really an "alias" of  virtio-mmio.
I think I answered this next to your 1st instance of this question at the beginning of this patch.
I think I had a version of that using awk. But then I went on trying to eliminate this dependency. But given we require awk it in setup.py, I can rework it to use awk.

Waldemar Kozaczuk

unread,
Mar 7, 2022, 11:21:33 PM3/7/22
to osv...@googlegroups.com, Waldemar Kozaczuk
V2: Comparing to the previous version this one improves the gen-drivers-config-header
by using awk mechanism to evaluate environment variables. It also
addresses couple of nitpicks.

This patch introduces new build mechanism that allows creating
custom kernel with specific list of device drivers intended to target
given hypervisor. Such kernel benefits from smaller size and better
security as all unneeded code is removed. This patch partially addresses
the modularization/librarization functionality as explained by the issue
#1110 and this part of the roadmap - https://github.com/cloudius-systems/osv/wiki/Roadmap#modularizationlibrarization.
This idea was also mentioned in the P99 OSv presentation - see slide 11.

In essence, we introduce new build script and makefile parameter:
`drivers_profile`. This new parameter is intended to specify a
drivers profile which is simply a list of device drivers to be linked
into kernel with some extra functionality like PCI or ACPI these drivers
depend on. Each profile is specified in a tiny make include file (*.mk)
It is also possible to enable or disable individual drivers on top
of what given profiles defines like so:

./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=base \
conf_drivers_acpi=1 conf_drivers_virtio_fs=1 conf_drivers_virtio_net=1 conf_drivers_pvpanic=1
drivers/hpet.cc | 7 ++
drivers/pci-generic.cc | 5 ++
drivers/virtio-blk.cc | 5 ++
drivers/virtio-fs.cc | 5 ++
drivers/virtio-net.cc | 5 ++
drivers/xenclock.cc | 1 +
drivers/xenfront-xenbus.cc | 1 +
drivers/xenplatform-pci.cc | 1 +
fs/vfs/vfs_conf.cc | 7 ++
include/osv/xen.hh | 4 +
loader.cc | 9 +++
runtime.cc | 5 ++
scripts/gen-drivers-config-header | 37 +++++++++
45 files changed, 616 insertions(+), 10 deletions(-)
+ $(error unsupported drivers profile $(drivers_profile))
+endif
+include conf/profiles/$(arch)/$(drivers_profile).mk
+# The base profile disables all drivers unless they are explicitly enabled
+# by the profile file included in the line above. The base profile also enforces
+# certain dependencies between drivers, for example the ide driver needs pci support, etc.
+# For more details please read comments in the profile file.
+include conf/profiles/$(arch)/base.mk
+
CROSS_PREFIX ?= $(if $(filter-out $(arch),$(host_arch)),$(arch)-linux-gnu-)
CXX=$(CROSS_PREFIX)g++
CC=$(CROSS_PREFIX)gcc
@@ -617,10 +636,13 @@ bsd += bsd/sys/netinet/cc/cc_cubic.o
bsd += bsd/sys/netinet/cc/cc_htcp.o
bsd += bsd/sys/netinet/cc/cc_newreno.o
bsd += bsd/sys/netinet/arpcache.o
+ifeq ($(conf_drivers_xen),1)
bsd += bsd/sys/xen/evtchn.o
+endif

ifeq ($(arch),x64)
$(out)/bsd/%.o: COMMON += -DXEN -DXENHVM
+ifeq ($(conf_drivers_xen),1)
+# Using 'if ($(conf_drivers_*),1)' in the rules below is enough to include whole object
#include <osv/types.h>
#include <osv/xen.hh>
#include <xen/interface/xen.h>
diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc
index d0ea6a7d..03518deb 100644
--- a/arch/x64/apic.cc
+++ b/arch/x64/apic.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
+```
+if the profile `virtio-pci` is selected when building the kernel like so:
+```bash
+./scripts/build fs=rofs conf_hide_symbols=1 image=native-example drivers_profile=virtio-pci
+```
+The `base.mk` also enforces some dependencies between given driver and other kernel
+components. For example this line:
+```make
+ifeq ($(conf_drivers_hpet),1)
+export conf_drivers_acpi?=1
+endif
+```
+enables ACPI support if the hpet driver is selected. There is also another rule that
+enables PCI support if ACPI is selected. And so on.
index 6b67d8b7..f0828b89 100644
--- a/drivers/hpet.cc
+++ b/drivers/hpet.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
extern "C" {
#include "acpi.h"
}
@@ -15,7 +16,9 @@ extern "C" {
#include <osv/mmu.hh>
#include <osv/mmio.hh>
#include "arch.hh"
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/irqlock.hh>
#include "rtc.hh"
#include <osv/percpu.hh>
@@ -146,8 +149,10 @@ s64 hpetclock::boot_time()

void __attribute__((constructor(init_prio::hpet))) hpet_init()
{
+#if CONF_drivers_xen
XENPV_ALTERNATIVE(
{
+#endif
auto c = clock::get();

// HPET should be only used as a fallback, if no other pvclocks
@@ -178,5 +183,7 @@ void __attribute__((constructor(init_prio::hpet))) hpet_init()
else {
clock::register_clock(new hpet_32bit_clock(hpet_mmio_address));
}
+#if CONF_drivers_xen
}, {});
index 00000000..4967990a
--- /dev/null
+++ b/scripts/gen-drivers-config-header
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+if [ "$#" -ne 2 ]; then
+ echo "usage: $(basename $0) ARCH OUTPUT" >&2
+ exit 1
+fi
+
+arch=$1
+
+output=$2
+
+drivers_config_base_file=`dirname "$0"`/../conf/profiles/$arch/base.mk
+
+tmp=$(mktemp)
+
+cat >$tmp <<EOL
+/* This file is generated automatically. */
+#ifndef OSV_DRIVERS_CONFIG_H
+#define OSV_DRIVERS_CONFIG_H
+
+EOL
+
+cat $drivers_config_base_file | grep "export conf" | cut --delimiter=_ -f 2- | cut --delimiter=? -f 1 | \
+sort | uniq | awk '{ printf("#define CONF_%s %s\n", $0, ENVIRON["conf_"$0]) }' >> $tmp
+
+cat >>$tmp <<EOL
+
+#endif
+EOL
+
+if cmp -s $tmp $output
+then
+ rm $tmp
+else
+ mkdir -p $(dirname $output)
+ mv $tmp $output
+fi
--
2.31.1

Commit Bot

unread,
Mar 10, 2022, 11:28:42 PM3/10/22
to osv...@googlegroups.com, Waldemar Kozaczuk
From: Waldemar Kozaczuk <jwkoz...@gmail.com>
Committer: Waldemar Kozaczuk <jwkoz...@gmail.com>
Branch: master

build: support driver profiles
diff --git a/Makefile b/Makefile
@@ -617,19 +636,25 @@ bsd += bsd/sys/netinet/cc/cc_cubic.o
bsd += bsd/sys/netinet/cc/cc_htcp.o
bsd += bsd/sys/netinet/cc/cc_newreno.o
bsd += bsd/sys/netinet/arpcache.o
+ifeq ($(conf_drivers_xen),1)
bsd += bsd/sys/xen/evtchn.o
+endif

ifeq ($(arch),x64)
$(out)/bsd/%.o: COMMON += -DXEN -DXENHVM
+ifeq ($(conf_drivers_xen),1)
bsd += bsd/sys/xen/gnttab.o
bsd += bsd/sys/xen/xenstore/xenstore.o
bsd += bsd/sys/xen/xenbus/xenbus.o
--- a/arch/aarch64/arch-setup.cc
+++ b/arch/aarch64/arch-setup.cc
@@ -7,6 +7,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "arch-setup.hh"
#include <osv/sched.hh>
#include <osv/mempool.hh>
@@ -16,15 +17,19 @@
#include <osv/boot.hh>
#include <osv/debug.hh>
#include <osv/commands.hh>
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif

#include "arch-mmu.hh"
#include "arch-dtb.hh"

--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
.text
.align 16
.globl start_elf
@@ -31,8 +32,10 @@ start_elf:
adrp x1, dtb // store dtb (arch-setup.cc)
str x5, [x1, #:lo12:dtb]

+#if CONF_drivers_xen
mov x29, xzr
bl init_xen
+#endif

mov x29, xzr
bl premain
diff --git a/arch/aarch64/cpuid.cc b/arch/aarch64/cpuid.cc
--- a/arch/aarch64/cpuid.cc
+++ b/arch/aarch64/cpuid.cc
@@ -5,9 +5,12 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "cpuid.hh"
#include "processor.hh"
+#if CONF_drivers_xen
#include "xen.hh"
+#endif

namespace processor {

@@ -131,7 +134,9 @@ const unsigned long hwcap32()

void process_cpuid(features_type& features)
{
+#if CONF_drivers_xen
xen::get_features(features);
+#endif
}

const features_type& features()
diff --git a/arch/aarch64/xen.cc b/arch/aarch64/xen.cc
--- a/arch/aarch64/xen.cc
+++ b/arch/aarch64/xen.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#define CONF_drivers_xen 1
#include <osv/types.h>
#include <osv/xen.hh>
#include <xen/interface/xen.h>
diff --git a/arch/x64/apic.cc b/arch/x64/apic.cc
--- a/arch/x64/apic.cc
+++ b/arch/x64/apic.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "apic.hh"
#include "msr.hh"
#include <osv/xen.hh>
diff --git a/arch/x64/arch-setup.cc b/arch/x64/arch-setup.cc
--- a/arch/x64/arch-setup.cc
+++ b/arch/x64/arch-setup.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include "arch.hh"
#include "arch-cpu.hh"
#include "arch-setup.hh"
@@ -13,23 +14,31 @@
#include "processor.hh"
#include "processor-flags.h"
#include "msr.hh"
+#if CONF_drivers_xen
#include <osv/xen.hh>
+#endif
#include <osv/elf.hh>
#include <osv/types.h>
#include <alloca.h>
#include <string.h>
@@ -247,61 +261,115 @@ void arch_init_premain()
--- a/arch/x64/smp.cc
+++ b/arch/x64/smp.cc
@@ -5,17 +5,20 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#include <osv/drivers_config.h>
#include <smp.hh>
#include "processor.hh"
#include "msr.hh"
#include "apic.hh"
--- a/arch/x64/xen.cc
+++ b/arch/x64/xen.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#define CONF_drivers_xen 1
#include "xen.hh"
#include <osv/debug.hh>
#include <osv/mmu.hh>
diff --git a/conf/profiles/README.md b/conf/profiles/README.md
--- a/conf/profiles/README.md
--- a/conf/profiles/aarch64/all.mk
+++ b/conf/profiles/aarch64/all.mk
@@ -0,0 +1,5 @@
+include conf/profiles/$(arch)/virtio-mmio.mk
+include conf/profiles/$(arch)/virtio-pci.mk
+include conf/profiles/$(arch)/xen.mk
+
+conf_drivers_cadence?=1
diff --git a/conf/profiles/aarch64/base.mk b/conf/profiles/aarch64/base.mk
--- a/conf/profiles/aarch64/base.mk
--- a/conf/profiles/aarch64/microvm.mk
+++ b/conf/profiles/aarch64/microvm.mk
@@ -0,0 +1 @@
+virtio-mmio.mk
\ No newline at end of file
diff --git a/conf/profiles/aarch64/virtio-mmio.mk b/conf/profiles/aarch64/virtio-mmio.mk
--- a/conf/profiles/aarch64/virtio-mmio.mk
+++ b/conf/profiles/aarch64/virtio-mmio.mk
@@ -0,0 +1,4 @@
+conf_drivers_mmio?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_net?=1
diff --git a/conf/profiles/aarch64/virtio-pci.mk b/conf/profiles/aarch64/virtio-pci.mk
--- a/conf/profiles/aarch64/virtio-pci.mk
+++ b/conf/profiles/aarch64/virtio-pci.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_fs?=1
+conf_drivers_virtio_net?=1
+conf_drivers_virtio_rng?=1
diff --git a/conf/profiles/aarch64/xen.mk b/conf/profiles/aarch64/xen.mk
--- a/conf/profiles/aarch64/xen.mk
+++ b/conf/profiles/aarch64/xen.mk
@@ -0,0 +1,2 @@
+conf_drivers_pci?=1
+conf_drivers_xen?=1
diff --git a/conf/profiles/x64/all.mk b/conf/profiles/x64/all.mk
--- a/conf/profiles/x64/all.mk
+++ b/conf/profiles/x64/all.mk
@@ -0,0 +1,8 @@
+include conf/profiles/$(arch)/hyperv.mk
+include conf/profiles/$(arch)/vbox.mk
+include conf/profiles/$(arch)/virtio-mmio.mk
+include conf/profiles/$(arch)/virtio-pci.mk
+include conf/profiles/$(arch)/vmware.mk
+include conf/profiles/$(arch)/xen.mk
+
+conf_drivers_vga?=1
diff --git a/conf/profiles/x64/base.mk b/conf/profiles/x64/base.mk
--- a/conf/profiles/x64/base.mk
--- a/conf/profiles/x64/cloud_hypervisor.mk
+++ b/conf/profiles/x64/cloud_hypervisor.mk
@@ -0,0 +1,2 @@
+include conf/profiles/$(arch)/virtio-pci.mk
+conf_drivers_pvpanic?=1
diff --git a/conf/profiles/x64/hyperv.mk b/conf/profiles/x64/hyperv.mk
--- a/conf/profiles/x64/hyperv.mk
+++ b/conf/profiles/x64/hyperv.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_hyperv?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/microvm.mk b/conf/profiles/x64/microvm.mk
--- a/conf/profiles/x64/microvm.mk
+++ b/conf/profiles/x64/microvm.mk
@@ -0,0 +1 @@
+virtio-mmio.mk
\ No newline at end of file
diff --git a/conf/profiles/x64/vbox.mk b/conf/profiles/x64/vbox.mk
--- a/conf/profiles/x64/vbox.mk
+++ b/conf/profiles/x64/vbox.mk
@@ -0,0 +1,8 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+
+conf_drivers_ahci?=1
+conf_drivers_virtio_net?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/virtio-mmio.mk b/conf/profiles/x64/virtio-mmio.mk
--- a/conf/profiles/x64/virtio-mmio.mk
+++ b/conf/profiles/x64/virtio-mmio.mk
@@ -0,0 +1,4 @@
+conf_drivers_mmio?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_net?=1
diff --git a/conf/profiles/x64/virtio-pci.mk b/conf/profiles/x64/virtio-pci.mk
--- a/conf/profiles/x64/virtio-pci.mk
+++ b/conf/profiles/x64/virtio-pci.mk
@@ -0,0 +1,10 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+
+conf_drivers_virtio_blk?=1
+conf_drivers_virtio_scsi?=1
+conf_drivers_virtio_fs?=1
+conf_drivers_virtio_net?=1
+conf_drivers_virtio_rng?=1
+
+conf_drivers_pvpanic?=1
diff --git a/conf/profiles/x64/vmware.mk b/conf/profiles/x64/vmware.mk
--- a/conf/profiles/x64/vmware.mk
+++ b/conf/profiles/x64/vmware.mk
@@ -0,0 +1,10 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_scsi?=1
+
+conf_drivers_pvscsi?=1
+conf_drivers_vmxnet3?=1
+conf_drivers_ide?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/xen.mk b/conf/profiles/x64/xen.mk
--- a/conf/profiles/x64/xen.mk
+++ b/conf/profiles/x64/xen.mk
@@ -0,0 +1,6 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+conf_drivers_xen?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/core/xen_intr.cc b/core/xen_intr.cc
--- a/core/xen_intr.cc
+++ b/core/xen_intr.cc
@@ -5,6 +5,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include <osv/xen_intr.hh>
#include <bsd/porting/bus.h>
diff --git a/drivers/acpi.cc b/drivers/acpi.cc
--- a/drivers/xenclock.cc
+++ b/drivers/xenclock.cc
@@ -14,6 +14,7 @@
#include "string.h"
#include "cpuid.hh"
#include <osv/barrier.hh>
+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include <osv/debug.hh>
#include <osv/prio.hh>
diff --git a/drivers/xenfront-xenbus.cc b/drivers/xenfront-xenbus.cc
--- a/drivers/xenfront-xenbus.cc
+++ b/drivers/xenfront-xenbus.cc
@@ -11,6 +11,7 @@
#include "cpuid.hh"
#include <osv/barrier.hh>
#include <osv/debug.hh>
+#define CONF_drivers_xen 1
#include <osv/xen.hh>
#include "processor.hh"
#include "xenfront.hh"
diff --git a/drivers/xenplatform-pci.cc b/drivers/xenplatform-pci.cc
--- a/drivers/xenplatform-pci.cc
+++ b/drivers/xenplatform-pci.cc
@@ -6,6 +6,7 @@
* BSD license as described in the LICENSE file in the top-level directory.
*/

+#define CONF_drivers_xen 1
#include "xen.hh"
#include "xenplatform-pci.hh"

diff --git a/fs/vfs/vfs_conf.cc b/fs/vfs/vfs_conf.cc
--- a/include/osv/xen.hh
+++ b/include/osv/xen.hh
@@ -24,7 +24,11 @@ extern struct start_info* xen_start_info;
extern "C" shared_info_t *HYPERVISOR_shared_info;

#define XENPV_ALTERNATIVE(x, y) ALTERNATIVE((xen_start_info != nullptr), x, y)
+#if CONF_drivers_xen
#define is_xen() (HYPERVISOR_shared_info != nullptr)
+#else
+#define is_xen() (0)
+#endif

// We don't support 32 bit
struct xen_vcpu_info {
diff --git a/loader.cc b/loader.cc
--- a/scripts/gen-drivers-config-header
Reply all
Reply to author
Forward
0 new messages