This dir contains Linux kernel configs used by [syzbot](/docs/syzbot.md).

Configs are auto-generated by [syz-kconf](/tools/syz-kconf/kconf.go) utility from declaration file [main.yml](main.yml)
and config [fragments](bits/). [main.yml](main.yml) specifies list of target config files (instances) and their
`features`, as well as order of inclusion of config fragments and their constraints. Config fragment is used for
an instance if all fragment constraints are present in instance features and all negative constraints (`-foo`) are not
present in instance features.

For example, the following declaration file:
```
instances:
 - instance-a:	[x86_64, gcc, upstream]
 - instance-b:	[x86_64, gcc, upstream, foo]
 - instance-c:	[arm64, clang, stable]

includes:
 - always.yml: []
 - only-upstream.yml: [upstream]
 - only-clang-arm64.yml: [clang, arm64]
 - only-upstream-not-foo.yml: [upstream, -foo]
```
specifies 3 target configs (instances) and built from 4 config fragments. Here fragment `always.yml` is included first
and for all instances. Fragment `only-upstream.yml` is included next for instances that have `upstream` feature listed
(`instance-a` and `instance-b`). Fragment `only-clang-arm64.yml` is included next for instances that have both
`clang` and `arm64` listed (`instance-c`). Finally, fragment `only-upstream-not-foo.yml` is included for instances
that have `upstream` features but don't have `foo` feature listed (`instance-a`).

Config fragments can specify several aspects of the target config file. First, they can specify the kernel repository
and revision that will be used for config generation using the following syntax. There must be only one repository
specification for each instance.
```
kernel:
 repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 tag: v5.8-rc7
```

Then, config fragments can specify kernel `make` commands that will be invoked to create the base config.
For example:
```
shell:
 - make x86_64_defconfig
 - make kvm_guest.config
```

Shell commands can have constraints similar to includes, for example:
```
shell:
 - make defconfig: [-nodefconfig]
```

Then, fragments can specify text for verbatim inclusion at the end of the resulting config. `syz-kconf` does not do
anything with these string. For example:
```
verbatim: |
 CONFIG_THIS_CONFIG_DOES_NOT_EXIST_YET=y
```

Finally, fragments can specify individual config options that need to be enabled (or disabled) in the resulting config.
For example:
```
config:
 - CONFIG_WILL_BE_ENABLED
 - CONFIG_WILL_BE_DISABLED: n
 - CONFIG_WITH_INTEGER_VALUE: 10
 - CONFIG_WITH_STRING_VALUE: "foo"
```

Config options can have constraints for more precise control over target instances
(constraints can be combined with values):
```
config:
 - CONFIG_ONLY_FOR_UPSTREAM: [upstream]
 - CONFIG_STABLE_AND_ARM64: [stable, arm64]
 - CONFIG_NOT_CLANG: [-clang]
 - CONFIG_DISABLED_FOR_GCC: [n, gcc]
 - CONFIG_STRING_FOO: ["value", foo]
```

Instance features:
 - `nonoise`: disables auxiliary debug configs (lockdep, stalls, object debug, etc);
   used on instances on which we ignore all crashes except for the main debug tool (KMSAN/KCSAN/LEAK)
   and on instances that are too slow (some qemu emulation).
 - `reduced`: disables some generic (mostly arch-independent) kernel subsystems;
   used on slow qemu emulation instances since these subsystems are well testing on fast native instances.
   `syz-kconf` knows about this feature and gives it special meaning: all configs in fragments enabled
   by this feature are disabled for reduced instances.

Some features/constraints are defined by `syz-kconf` itself or have special meaning:
 - `override` on a config allows to override a previous definition of the same config (otherwise it results in an error)
 - `optional` on a config disables checking that the resulting kernel config file has the specified value for this
   config (otherwise it results in an error)
 - `weak` means both `override` and `optional`
 - `clang`/`gcc` instance feature controls what compiler is used for config generation
 - kernel arch name (`x86_64`, `arm64`, etc) instance feature controls architecture of the kernel config
 - kernel release tag is automatically added to instance features and allows to specify a minimum kernel version
   for a config (e.g. `v5.5` for a config added in that kernel release) or a maximum kernel version (e.g. `-v5.5` for
   a config removed in that kernel release)

`syz-kconf` generates 2 kernel config files for each instance: one `normal` (or full) and one `baseline`.
The `baseline` config has `-base` suffix and has `baseline` and `base-config` features added. The `baseline`
config is meant to not contain majority of subsystem configs enabled (should just boot and have debugging
configs enabled), however, that is fully controlled by config fragments based on the presence of the `baseline`
feature. In order to facilitate even smaller `-base.config` files, the `base-config` feature is automatically
set for them. Such configs are intended to be used by the config minization procedure.

The only exception to the declarative nature of the process is USB configs. They are added procedurally, see
`addUSBConfigs` function for details.

`syz-kconf` switches between `gcc` and `clang` compilers automatically and is supposed to be used with
[syz-env](/docs/contributing.md#using-syz-env), which provides correct versions of the compilers.

To update kernel configs:
 - change config fragments as necessary (e.g. add additional configs to [subsystems.yml](bits/subsystems.yml) along
   with minimal kernel version)
 - run `syz-env make configs SOURCEDIR=/path/to/existing/linux/checkout`
   (note: it will be mrproper-ed and a number of remotes will be added)
   (see [this](/docs/contributing.md#using-syz-env) on how to setup/use `syz-env`)
 - check in config fragments and changed kernel configs and send a PR
 - changes will be deployed to `syzbot` within a day after merging
