Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e88a90b
init: add DPS root partition type UUID capability
vincent-mailhol Jun 15, 2026
0f7d570
alpha: define DPS root partition type UUID
vincent-mailhol Jun 15, 2026
6c7a9ce
arc: define DPS root partition type UUID
vincent-mailhol Jun 15, 2026
4828268
arm: define DPS root partition type UUID
vincent-mailhol Jun 15, 2026
e3ba699
arm64: define DPS root partition type UUID
vincent-mailhol Jun 15, 2026
45a87a2
loongarch: define DPS root partition type UUID
vincent-mailhol Jun 15, 2026
b6c0b0c
mips: define DPS root partition type UUIDs
vincent-mailhol Jun 15, 2026
dae7471
parisc: define DPS root partition type UUID
vincent-mailhol Jun 15, 2026
916933f
powerpc: define DPS root partition type UUIDs
vincent-mailhol Jun 15, 2026
8889951
riscv: define DPS root partition type UUIDs
vincent-mailhol Jun 15, 2026
d8621b0
s390: define DPS root partition type UUIDs
vincent-mailhol Jun 15, 2026
abb89a4
x86: define DPS root partition type UUIDs
vincent-mailhol Jun 15, 2026
266e574
block: store GPT partition type UUID
vincent-mailhol Jun 15, 2026
de2b98e
block: add early_lookup_bdev_by_type_uuid()
vincent-mailhol Jun 15, 2026
0d7573d
block: store GPT attributes as a raw value
vincent-mailhol Jun 15, 2026
3f59c39
block: don't discover partition with DPS no-auto GPT attribute
vincent-mailhol Jun 15, 2026
82e6c91
init: factor out root device lookup into lookup_root_device()
vincent-mailhol Jun 15, 2026
c23a96d
init: discover root by DPS partition type UUID
vincent-mailhol Jun 15, 2026
b9f42a2
docs: document discoverable root partitions
vincent-mailhol Jun 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions Documentation/admin-guide/discoverable-root.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.. SPDX-License-Identifier: GPL-2.0

.. _discoverable_root:

Discoverable root partitions
============================

On EFI systems using a supported architecture, the kernel can discover the root
block device from GPT partition type UUID metadata on the disk containing the
active EFI System Partition.

This follows the `Discoverable Partitions Specification`_ which defines a list
of architecture-specific root partition type UUIDs.

Specifying ``root=`` on the kernel command line takes precedence and entirely
disables this automatic root partition discovery.

The disk to search is identified by the Boot Loader Interface
``LoaderDevicePartUUID`` EFI variable. If multiple partitions on that disk match
the architecture root partition type UUID, the kernel selects the first match in
block device enumeration order. Systems should not expose multiple eligible root
partitions unless that ordering is intended.

Partitions marked with the DPS ``no-auto`` GPT attribute are skipped. This
allows a partition with an otherwise discoverable type UUID to opt out from
automatic discovery.

The DPS read-only attribute is not enforced by kernel root discovery. The
root filesystem is mounted read-only by default unless ``rw`` is specified,
and user space remains responsible for later remount policy.

.. _Discoverable Partitions Specification:
https://uapi-group.org/specifications/specs/discoverable_partitions_specification/
1 change: 1 addition & 0 deletions Documentation/admin-guide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Booting the kernel

bootconfig
kernel-parameters
discoverable-root
efi-stub
initrd

Expand Down
5 changes: 5 additions & 0 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6699,6 +6699,11 @@ Kernel parameters
ramdisk, "nfs" and "cifs" for root on a network file
system, or "mtd" and "ubi" for mounting from raw flash.

If this option is omitted, the kernel may try to
discover the root block device from the GPT partition
type UUID metadata when additional requirements are met.
See Documentation/admin-guide/discoverable-root.rst.

rootdelay= [KNL] Delay (in seconds) to pause before attempting to
mount the root filesystem

Expand Down
1 change: 1 addition & 0 deletions arch/alpha/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ config ALPHA
select ARCH_32BIT_USTAT_F_TINODE
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DMA_OPS if PCI
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select ARCH_MODULE_NEEDS_WEAK_PER_CPU if SMP
Expand Down
8 changes: 8 additions & 0 deletions arch/alpha/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_ALPHA_DPS_ROOT_H
#define _ASM_ALPHA_DPS_ROOT_H

#define DPS_ROOT_PARTITION_TYPE_UUID "6523f8ae-3eb1-4e2a-a05a-18b695ae656f"

#endif /* _ASM_ALPHA_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config ARC
select ARCH_HAS_CACHE_LINE_SIZE
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SETUP_DMA_OPS
select ARCH_HAS_SYNC_DMA_FOR_CPU
Expand Down
8 changes: 8 additions & 0 deletions arch/arc/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_ARC_DPS_ROOT_H
#define _ASM_ARC_DPS_ROOT_H

#define DPS_ROOT_PARTITION_TYPE_UUID "d27f46ed-2919-4cb8-bd25-9531f3c16534"

#endif /* _ASM_ARC_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ config ARM
select ARCH_HAS_DMA_ALLOC if MMU
select ARCH_HAS_DMA_OPS
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KEEPINITRD
Expand Down
8 changes: 8 additions & 0 deletions arch/arm/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_ARM_DPS_ROOT_H
#define _ASM_ARM_DPS_ROOT_H

#define DPS_ROOT_PARTITION_TYPE_UUID "69dad710-2ce4-4e3c-b16c-21a1d49abed3"

#endif /* _ASM_ARM_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ config ARM64
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DMA_OPS if XEN
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
Expand Down
8 changes: 8 additions & 0 deletions arch/arm64/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_ARM64_DPS_ROOT_H
#define _ASM_ARM64_DPS_ROOT_H

#define DPS_ROOT_PARTITION_TYPE_UUID "b921b045-1df0-41c3-af44-4c6f280d3fae"

#endif /* _ASM_ARM64_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/loongarch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ config LOONGARCH
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KCOV
Expand Down
8 changes: 8 additions & 0 deletions arch/loongarch/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_LOONGARCH_DPS_ROOT_H
#define _ASM_LOONGARCH_DPS_ROOT_H

#define DPS_ROOT_PARTITION_TYPE_UUID "77055800-792c-4f94-b39a-98c91b762bb6"

#endif /* _ASM_LOONGARCH_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config MIPS
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL if !64BIT
select ARCH_HAS_DMA_OPS if MACH_JAZZ
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KCOV
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if !EVA
Expand Down
20 changes: 20 additions & 0 deletions arch/mips/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_MIPS_DPS_ROOT_H
#define _ASM_MIPS_DPS_ROOT_H

#ifdef CONFIG_CPU_LITTLE_ENDIAN
#ifdef CONFIG_64BIT
#define DPS_ROOT_PARTITION_TYPE_UUID "700bda43-7a34-4507-b179-eeb93d7a7ca3"
#else
#define DPS_ROOT_PARTITION_TYPE_UUID "37c58c8a-d913-4156-a25f-48b1b64e07f0"
#endif
#else
#ifdef CONFIG_64BIT
#define DPS_ROOT_PARTITION_TYPE_UUID "d113af76-80ef-41b4-bdb6-0cff4d3d4a25"
#else
#define DPS_ROOT_PARTITION_TYPE_UUID "e9434544-6e2c-47cc-bae2-12d6deafb44c"
#endif
#endif

#endif /* _ASM_MIPS_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/parisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ config PARISC
select ARCH_STACKWALK
select ARCH_HAS_CACHE_LINE_SIZE
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select HAVE_RELIABLE_STACKTRACE
select RTC_CLASS
select RTC_DRV_GENERIC
Expand Down
8 changes: 8 additions & 0 deletions arch/parisc/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_PARISC_DPS_ROOT_H
#define _ASM_PARISC_DPS_ROOT_H

#define DPS_ROOT_PARTITION_TYPE_UUID "1aacdb3b-5444-4138-bd9e-e5c2239b2346"

#endif /* _ASM_PARISC_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ config PPC
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_MAP_DIRECT if PPC_PSERIES
select ARCH_HAS_DMA_OPS if PPC64
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE if ARCH_SUPPORTS_HUGETLBFS
Expand Down
16 changes: 16 additions & 0 deletions arch/powerpc/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_POWERPC_DPS_ROOT_H
#define _ASM_POWERPC_DPS_ROOT_H

#ifdef CONFIG_PPC64
#ifdef CONFIG_CPU_LITTLE_ENDIAN
#define DPS_ROOT_PARTITION_TYPE_UUID "c31c45e6-3f39-412e-80fb-4809c4980599"
#else
#define DPS_ROOT_PARTITION_TYPE_UUID "912ade1d-a839-4913-8964-a10eee08fbd2"
#endif
#else
#define DPS_ROOT_PARTITION_TYPE_UUID "1de3f1ef-fa98-47b5-8dcd-4a860a654d78"
#endif

#endif /* _ASM_POWERPC_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ config RISCV
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_ELF_CORE_EFLAGS if BINFMT_ELF && ELF_CORE
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
Expand Down
12 changes: 12 additions & 0 deletions arch/riscv/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_RISCV_DPS_ROOT_H
#define _ASM_RISCV_DPS_ROOT_H

#ifdef CONFIG_64BIT
#define DPS_ROOT_PARTITION_TYPE_UUID "72ec70a6-cf74-40e6-bd49-4bda08e8f224"
#else
#define DPS_ROOT_PARTITION_TYPE_UUID "60d5a7fe-8e7d-435c-b714-3dd8162144e1"
#endif

#endif /* _ASM_RISCV_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/s390/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ config S390
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_OPS if PCI
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORCE_DMA_UNENCRYPTED
select ARCH_HAS_FORTIFY_SOURCE
Expand Down
12 changes: 12 additions & 0 deletions arch/s390/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_S390_DPS_ROOT_H
#define _ASM_S390_DPS_ROOT_H

#ifdef CONFIG_64BIT
#define DPS_ROOT_PARTITION_TYPE_UUID "5eead9a9-fe09-4a1e-a1d7-520d00531306"
#else
#define DPS_ROOT_PARTITION_TYPE_UUID "08a7acea-624c-4a20-91e8-6e0fa67d23f9"
#endif

#endif /* _ASM_S390_DPS_ROOT_H */
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ config X86
select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_OPS if GART_IOMMU || XEN
select ARCH_HAS_DPS_ROOT_PARTITION_TYPE_UUID
select ARCH_HAS_EARLY_DEBUG if KGDB
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_EXECMEM_ROX if X86_64 && STRICT_MODULE_RWX
Expand Down
12 changes: 12 additions & 0 deletions arch/x86/include/asm/dps_root.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _ASM_X86_DPS_ROOT_H
#define _ASM_X86_DPS_ROOT_H

#ifdef CONFIG_X86_64
#define DPS_ROOT_PARTITION_TYPE_UUID "4f68bce3-e8cd-4db1-96e7-fbcaf984b709"
#else
#define DPS_ROOT_PARTITION_TYPE_UUID "44479540-f297-41b2-9af7-d131d5f0458a"
#endif

#endif /* _ASM_X86_DPS_ROOT_H */
1 change: 1 addition & 0 deletions block/blk.h
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ void blk_free_ext_minor(unsigned int minor);
#define ADDPART_FLAG_RAID 1
#define ADDPART_FLAG_WHOLEDISK 2
#define ADDPART_FLAG_READONLY 4
#define ADDPART_FLAG_NO_AUTO 8
int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
sector_t length);
int bdev_del_partition(struct gendisk *disk, int partno);
Expand Down
68 changes: 65 additions & 3 deletions block/early-lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
*/
#include <linux/blkdev.h>
#include <linux/ctype.h>
#include <linux/uuid.h>

struct uuidcmp {
const char *uuid;
int len;
struct gendisk *disk;
};

/**
Expand Down Expand Up @@ -45,13 +47,11 @@ static int __init match_dev_by_uuid(struct device *dev, const void *data)
*/
static int __init devt_from_partuuid(const char *uuid_str, dev_t *devt)
{
struct uuidcmp cmp;
struct uuidcmp cmp = { .uuid = uuid_str };
struct device *dev = NULL;
int offset = 0;
char *slash;

cmp.uuid = uuid_str;

slash = strchr(uuid_str, '/');
/* Check for optional partition number offset attributes. */
if (slash) {
Expand Down Expand Up @@ -252,6 +252,68 @@ int __init early_lookup_bdev(const char *name, dev_t *devt)
return devt_from_devnum(name, devt);
}

#ifdef CONFIG_DPS_ROOT_AUTO_DISCOVERY
/**
* match_dev_by_type_uuid - callback for finding a partition using its type UUID
* @dev: device passed in by the caller
* @data: opaque pointer to the desired struct uuidcmp to match
*
* Returns: 1 if the device matches, and 0 otherwise.
*/
static int __init match_dev_by_type_uuid(struct device *dev, const void *data)
{
struct block_device *bdev = dev_to_bdev(dev);
const struct uuidcmp *cmp = data;

return bdev->bd_disk == cmp->disk && bdev->bd_meta_info &&
!bdev_test_flag(bdev, BD_NO_AUTO_DISCOVERY) &&
!strcasecmp(cmp->uuid, bdev->bd_meta_info->type_uuid);
}

/**
* early_lookup_bdev_by_type_uuid - look up a partition by its type UUID
* @type_uuid: partition type UUID to search for
* @efi_partuuid: partition UUID identifying the active EFI partition
* @devt: matching dev_t result
*
* This helper follows the Discoverable Partitions Specification rules. It uses
* @efi_partuuid to find the disk containing the active EFI System Partition,
* then searches only partitions on that disk for the partition type UUID
* specified by @type_uuid.
*
* Returns: 0 on success or a negative error code on failure.
*/
int __init early_lookup_bdev_by_type_uuid(const char *type_uuid,
const char *efi_partuuid, dev_t *devt)
{
struct uuidcmp efi_cmp = {
.uuid = efi_partuuid,
.len = UUID_STRING_LEN,
};
struct uuidcmp type_cmp = {
.uuid = type_uuid,
};
struct device *efi_dev;
struct device *type_dev;

efi_dev = class_find_device(&block_class, NULL, &efi_cmp,
&match_dev_by_uuid);
if (!efi_dev)
return -ENODEV;

type_cmp.disk = dev_to_disk(efi_dev);
type_dev = class_find_device(&block_class, NULL, &type_cmp,
&match_dev_by_type_uuid);
put_device(efi_dev);
if (!type_dev)
return -ENODEV;

*devt = type_dev->devt;
put_device(type_dev);
return 0;
}
#endif

static char __init *bdevt_str(dev_t devt, char *buf)
{
if (MAJOR(devt) <= 0xff && MINOR(devt) <= 0xff) {
Expand Down
2 changes: 2 additions & 0 deletions block/partitions/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,

if (flags & ADDPART_FLAG_READONLY)
bdev_set_flag(bdev, BD_READ_ONLY);
if (flags & ADDPART_FLAG_NO_AUTO)
bdev_set_flag(bdev, BD_NO_AUTO_DISCOVERY);

/* everything is up and running, commence */
err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
Expand Down
3 changes: 3 additions & 0 deletions block/partitions/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,9 +739,12 @@ int efi_partition(struct parsed_partitions *state)
/* If this is a RAID volume, tell md */
if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID))
state->parts[i + 1].flags = ADDPART_FLAG_RAID;
if (le64_to_cpu(ptes[i].attributes) & GPT_ATTRIBUTE_NO_AUTO)
state->parts[i + 1].flags |= ADDPART_FLAG_NO_AUTO;

info = &state->parts[i + 1].info;
efi_guid_to_str(&ptes[i].unique_partition_guid, info->uuid);
efi_guid_to_str(&ptes[i].partition_type_guid, info->type_uuid);

/* Naively convert UTF16-LE to 7 bits. */
label_max = min(ARRAY_SIZE(info->volname) - 1,
Expand Down
Loading
Loading