123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- From a49bd34de33ab54a1cbfdaae121dbaf99648d3b6 Mon Sep 17 00:00:00 2001
- From: Julius Werner <jwerner@chromium.org>
- Date: Wed, 20 Apr 2016 15:20:00 -0700
- Subject: [PATCH] CHROMIUM: block: partitions: efi: Add support for IGNOREME
- GPT signature
- This patch adds support for a special GPT header signature marker (using
- the string 'IGNOREME' instead of the spec's 'EFI PART'). This tells the
- kernel to ignore this GPT completely and look at the other one instead.
- Since the kernel always prefers the primary GPT anyway, all we really
- need to do effectively is to check whether the primary GPT is marked
- 'IGNOREME' and force evaluation of the secondary one in that case.
- Signed-off-by: Julius Werner <jwerner@chromium.org>
- Reviewed-on: https://chromium-review.googlesource.com/340080
- Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
- An earlier attempt to upstream an alternative solution:
- https://patchwork.kernel.org/patch/8933841/
- mka@: added missing param 'lba' to log message and resolved minor
- conflicts.
- BUG=chromium:941638, chrome-os-partner:52595
- TEST=Booted on Minnie with 'IGNOREME' primary GPT
- Change-Id: Ibaee639fac9fa2f04b8836ef153c95b7d0b045a4
- Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
- Reviewed-on: https://chromium-review.googlesource.com/1531701
- Reviewed-by: Douglas Anderson <dianders@chromium.org>
- Reviewed-by: Julius Werner <jwerner@chromium.org>
- [rebase515(groeck):
- Squash:
- FIXUP: partitions/efi: Support non-standard GPT location
- (API change)
- ]
- Signed-off-by: Guenter Roeck <groeck@google.com>
- ---
- block/partitions/efi.c | 33 +++++++++++++++++++++++----------
- block/partitions/efi.h | 3 ++-
- 2 files changed, 25 insertions(+), 11 deletions(-)
- diff --git a/block/partitions/efi.c b/block/partitions/efi.c
- index 7ca5c4c374d4..102d2587bdb3 100644
- --- a/block/partitions/efi.c
- +++ b/block/partitions/efi.c
- @@ -328,23 +328,33 @@ static gpt_header *alloc_read_gpt_header(struct parsed_partitions *state,
- * @lba: logical block address of the GPT header to test
- * @gpt: GPT header ptr, filled on return.
- * @ptes: 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, pt_size;
-
- + 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",
- + lba);
- + 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),
- @@ -581,7 +591,7 @@ compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba)
- 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;
- @@ -613,13 +623,14 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
- }
-
- 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);
-
- if (!good_agpt && force_gpt && fops->alternative_gpt_sector) {
- sector_t agpt_sector;
- @@ -628,14 +639,15 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
- err = fops->alternative_gpt_sector(disk, &agpt_sector);
- if (!err)
- good_agpt = is_gpt_valid(state, agpt_sector,
- - &agpt, &aptes);
- + &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) {
- @@ -652,7 +664,8 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
- *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 8cc2b88d0aa8..fcf65ebbaa85 100644
- --- a/block/partitions/efi.h
- +++ b/block/partitions/efi.h
- @@ -27,7 +27,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
-
- --
- 2.36.1
|