diff --git a/block/partitions/efi.c b/block/partitions/efi.c index 4bf0f97..b33671d 100644 --- a/block/partitions/efi.c +++ b/block/partitions/efi.c @@ -348,23 +348,32 @@ * @lba is the logical block address of the GPT header to test * @gpt is a GPT header ptr, filled on return. * @ptes is a PTEs ptr, filled on return. + * @ignored is filled on return with 1 if this is an IGNOREME GPT, + * 0 otherwise. May be NULL. * * Description: returns 1 if valid, 0 on error. * If valid, returns pointers to newly allocated GPT header and PTEs. */ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, - gpt_header **gpt, gpt_entry **ptes) + gpt_header **gpt, gpt_entry **ptes, int *ignored) { u32 crc, origcrc; u64 lastlba; + if (ignored) + *ignored = 0; if (!ptes) return 0; if (!(*gpt = alloc_read_gpt_header(state, lba))) return 0; /* Check the GUID Partition Table signature */ - if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) { + if (le64_to_cpu((*gpt)->signature) == GPT_HEADER_SIGNATURE_IGNORED) { + pr_debug("GUID Partition Table at LBA %llu marked IGNOREME\n"); + if (ignored) + *ignored = 1; + goto fail; + } else if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) { pr_debug("GUID Partition Table Header signature is wrong:" "%lld != %lld\n", (unsigned long long)le64_to_cpu((*gpt)->signature), @@ -592,7 +601,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt, gpt_entry **ptes) { - int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; + int good_pgpt = 0, good_agpt = 0, good_pmbr = 0, pgpt_ignored = 0; gpt_header *pgpt = NULL, *agpt = NULL; gpt_entry *pptes = NULL, *aptes = NULL; legacy_mbr *legacymbr; @@ -622,19 +631,20 @@ } good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, - &pgpt, &pptes); + &pgpt, &pptes, &pgpt_ignored); if (good_pgpt) good_agpt = is_gpt_valid(state, le64_to_cpu(pgpt->alternate_lba), - &agpt, &aptes); - if (!good_agpt && force_gpt) - good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes); + &agpt, &aptes, NULL); + if (!good_agpt && (force_gpt || pgpt_ignored)) + good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes, NULL); /* The obviously unsuccessful case */ if (!good_pgpt && !good_agpt) goto fail; - compare_gpts(pgpt, agpt, lastlba); + if (!pgpt_ignored) + compare_gpts(pgpt, agpt, lastlba); /* The good cases */ if (good_pgpt) { @@ -651,7 +661,8 @@ *ptes = aptes; kfree(pgpt); kfree(pptes); - pr_warn("Primary GPT is invalid, using alternate GPT.\n"); + pr_warn("Primary GPT is %s, using alternate GPT.\n", + pgpt_ignored ? "being ignored" : "invalid"); return 1; } diff --git a/block/partitions/efi.h b/block/partitions/efi.h index 4efcafb..3a13ef9 100644 --- a/block/partitions/efi.h +++ b/block/partitions/efi.h @@ -40,7 +40,8 @@ #define GPT_MBR_PROTECTIVE 1 #define GPT_MBR_HYBRID 2 -#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL +#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL /* 'EFI PART' */ +#define GPT_HEADER_SIGNATURE_IGNORED 0x454d45524f4e4749ULL /* 'IGNOREME' */ #define GPT_HEADER_REVISION_V1 0x00010000 #define GPT_PRIMARY_PARTITION_TABLE_LBA 1