From: Davidlohr Bueso <davidlohr@hp.com>
To: Andrew Morton <akpm@linux-foundation.org>, Jens Axboe <axboe@kernel.dk>
Cc: Matt Domsch <Matt_Domsch@dell.com>, Jim Hull <jim.hull@hp.com>,
Karel Zak <kzak@redhat.com>, Peter Jones <pjones@redhat.com>,
Chegu Vinod <chegu_vinod@hp.com>,
Aswin Chandramouleeswaran <aswin@hp.com>,
linux-kernel@vger.kernel.org, Davidlohr Bueso <davidlohr@hp.com>
Subject: [PATCH 4/8] partitions/efi: detect hybrid MBRs
Date: Mon, 5 Aug 2013 22:21:12 -0700 [thread overview]
Message-ID: <1375766476-4204-5-git-send-email-davidlohr@hp.com> (raw)
In-Reply-To: <1375766476-4204-1-git-send-email-davidlohr@hp.com>
One of the biggest problems with GPT is compatibility with older,
non-GPT systems. The problem is addressed by creating hybrid mbrs,
an extension, or variant, of the traditional protective mbr. This
contains, apart from the 0xEE partition, up three additional
primary partitions that point to the same space marked by up to
three GPT partitions. The result is that legacy OSs can see the
three required MBR partitions and at the same time ignore the
GPT-aware partitions that protect the GPT structures.
While hybrid MBRs are hacks, workarounds and simply not part of the
GPT standard, they do exist and we have no way around them. For instance,
by default, OSX creates a hybrid scheme when using multi-OS booting.
In order for Linux to properly discover protective MBRs, it must be
made aware of devices that have hybrid MBRs. No functionality is
changed by this patch, just a debug message informing the user of the
MBR scheme that is being used.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
---
block/partitions/efi.c | 72 +++++++++++++++++++++++++++++++++++---------------
block/partitions/efi.h | 3 +++
2 files changed, 54 insertions(+), 21 deletions(-)
diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 331cd1c..4bf8165 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -158,7 +158,7 @@ static inline int pmbr_part_valid(gpt_record *part)
if (le32_to_cpu(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA)
goto invalid;
- return 1;
+ return GPT_MBR_PROTECTIVE;
invalid:
return 0;
}
@@ -167,21 +167,47 @@ invalid:
* is_pmbr_valid(): test Protective MBR for validity
* @mbr: pointer to a legacy mbr structure
*
- * Description: Returns 1 if PMBR is valid, 0 otherwise.
- * Validity depends on two things:
+ * Description: Checks for a valid protective or hybrid
+ * master boot record (MBR). The validity of a pMBR depends
+ * on all of the following properties:
* 1) MSDOS signature is in the last two bytes of the MBR
* 2) One partition of type 0xEE is found
+ *
+ * In addition, a hybrid MBR will have up to three additional
+ * primary partitions, which point to the same space that's
+ * marked out by up to three GPT partitions.
+ *
+ * Returns 0 upon invalid MBR, or GPT_MBR_PROTECTIVE or
+ * GPT_MBR_HYBRID depending on the device layout.
*/
-static int
-is_pmbr_valid(legacy_mbr *mbr)
+static int is_pmbr_valid(legacy_mbr *mbr)
{
- int i;
+ int i, ret = 0; /* invalid by default */
+
if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
- return 0;
+ goto done;
+
+ for (i = 0; i < 4; i++) {
+ ret = pmbr_part_valid(&mbr->partition_record[i]);
+ if (ret == GPT_MBR_PROTECTIVE) {
+ /*
+ * Ok, we at least know that there's a protective MBR,
+ * now check if there are other partition types for
+ * hybrid MBR.
+ */
+ goto check_hybrid;
+ }
+ }
+
+ if (ret != GPT_MBR_PROTECTIVE)
+ goto done;
+check_hybrid:
for (i = 0; i < 4; i++)
- if (pmbr_part_valid(&mbr->partition_record[i]))
- return 1;
- return 0;
+ if ((mbr->partition_record[i].os_type != EFI_PMBR_OSTYPE_EFI_GPT) &&
+ (mbr->partition_record[i].os_type != 0x00))
+ ret = GPT_MBR_HYBRID;
+done:
+ return ret;
}
/**
@@ -548,17 +574,21 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
lastlba = last_lba(state->bdev);
if (!force_gpt) {
- /* This will be added to the EFI Spec. per Intel after v1.02. */
- legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
- if (legacymbr) {
- read_lba(state, 0, (u8 *) legacymbr,
- sizeof (*legacymbr));
- good_pmbr = is_pmbr_valid(legacymbr);
- kfree(legacymbr);
- }
- if (!good_pmbr)
- goto fail;
- }
+ /* This will be added to the EFI Spec. per Intel after v1.02. */
+ legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
+ if (!legacymbr)
+ goto fail;
+
+ read_lba(state, 0, (u8 *) legacymbr, sizeof (*legacymbr));
+ good_pmbr = is_pmbr_valid(legacymbr);
+ kfree(legacymbr);
+
+ if (!good_pmbr)
+ goto fail;
+
+ pr_debug("Device has a %s MBR\n",
+ good_pmbr == GPT_MBR_PROTECTIVE ? "protective" : "hybrid");
+ }
good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA,
&pgpt, &pptes);
diff --git a/block/partitions/efi.h b/block/partitions/efi.h
index 46cf1a4..e9741de 100644
--- a/block/partitions/efi.h
+++ b/block/partitions/efi.h
@@ -37,6 +37,9 @@
#define EFI_PMBR_OSTYPE_EFI 0xEF
#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
+#define GPT_MBR_PROTECTIVE 1
+#define GPT_MBR_HYBRID 2
+
#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
#define GPT_HEADER_REVISION_V1 0x00010000
#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
--
1.7.11.7
next prev parent reply other threads:[~2013-08-06 5:29 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-06 5:21 [PATCH 0/8] partitions/efi: detect hybrid mbrs Davidlohr Bueso
2013-08-06 5:21 ` [PATCH 1/8] partitions/efi: use lba-aware partition records Davidlohr Bueso
2013-09-02 10:10 ` Karel Zak
2013-09-03 5:01 ` Davidlohr Bueso
2013-08-06 5:21 ` [PATCH 2/8] partitions/efi: check pmbr record's starting lba Davidlohr Bueso
2013-08-06 5:21 ` [PATCH 3/8] partitions/efi: do not require gpt partition to begin at sector 1 Davidlohr Bueso
2013-08-06 5:21 ` Davidlohr Bueso [this message]
2013-08-06 5:21 ` [PATCH 5/8] partitions/efi: account for pmbr size in lba Davidlohr Bueso
2013-08-06 5:21 ` [PATCH 6/8] partitions/efi: compare first and last usable LBAs Davidlohr Bueso
2013-08-06 5:21 ` [PATCH 7/8] partitions/efi: delete annoying emacs style comments Davidlohr Bueso
2013-08-06 5:21 ` [PATCH 8/8] partitions/efi: some style cleanups Davidlohr Bueso
2013-08-06 21:16 ` [PATCH 0/8] partitions/efi: detect hybrid mbrs Andrew Morton
2013-08-06 22:39 ` Davidlohr Bueso
2013-08-15 16:59 ` Davidlohr Bueso
2013-08-15 19:29 ` Andrew Morton
2013-08-16 1:37 ` Davidlohr Bueso
2013-09-02 10:33 ` Karel Zak
2013-09-03 12:33 ` Matt Fleming
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1375766476-4204-5-git-send-email-davidlohr@hp.com \
--to=davidlohr@hp.com \
--cc=Matt_Domsch@dell.com \
--cc=akpm@linux-foundation.org \
--cc=aswin@hp.com \
--cc=axboe@kernel.dk \
--cc=chegu_vinod@hp.com \
--cc=jim.hull@hp.com \
--cc=kzak@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=pjones@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®