aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/partitions/efi.c74
-rw-r--r--block/partitions/efi.h3
2 files changed, 56 insertions, 21 deletions
diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 1b499dc8fc78..e3cb4f19cf6d 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -158,7 +158,7 @@ static inline int pmbr_part_valid(gpt_mbr_record *part)
158 if (le32_to_cpu(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA) 158 if (le32_to_cpu(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA)
159 goto invalid; 159 goto invalid;
160 160
161 return 1; 161 return GPT_MBR_PROTECTIVE;
162invalid: 162invalid:
163 return 0; 163 return 0;
164} 164}
@@ -167,21 +167,48 @@ invalid:
167 * is_pmbr_valid(): test Protective MBR for validity 167 * is_pmbr_valid(): test Protective MBR for validity
168 * @mbr: pointer to a legacy mbr structure 168 * @mbr: pointer to a legacy mbr structure
169 * 169 *
170 * Description: Returns 1 if PMBR is valid, 0 otherwise. 170 * Description: Checks for a valid protective or hybrid
171 * Validity depends on two things: 171 * master boot record (MBR). The validity of a pMBR depends
172 * on all of the following properties:
172 * 1) MSDOS signature is in the last two bytes of the MBR 173 * 1) MSDOS signature is in the last two bytes of the MBR
173 * 2) One partition of type 0xEE is found 174 * 2) One partition of type 0xEE is found
175 *
176 * In addition, a hybrid MBR will have up to three additional
177 * primary partitions, which point to the same space that's
178 * marked out by up to three GPT partitions.
179 *
180 * Returns 0 upon invalid MBR, or GPT_MBR_PROTECTIVE or
181 * GPT_MBR_HYBRID depending on the device layout.
174 */ 182 */
175static int 183static int is_pmbr_valid(legacy_mbr *mbr)
176is_pmbr_valid(legacy_mbr *mbr)
177{ 184{
178 int i; 185 int i, ret = 0; /* invalid by default */
186
179 if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) 187 if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
180 return 0; 188 goto done;
189
190 for (i = 0; i < 4; i++) {
191 ret = pmbr_part_valid(&mbr->partition_record[i]);
192 if (ret == GPT_MBR_PROTECTIVE) {
193 /*
194 * Ok, we at least know that there's a protective MBR,
195 * now check if there are other partition types for
196 * hybrid MBR.
197 */
198 goto check_hybrid;
199 }
200 }
201
202 if (ret != GPT_MBR_PROTECTIVE)
203 goto done;
204check_hybrid:
181 for (i = 0; i < 4; i++) 205 for (i = 0; i < 4; i++)
182 if (pmbr_part_valid(&mbr->partition_record[i])) 206 if ((mbr->partition_record[i].os_type !=
183 return 1; 207 EFI_PMBR_OSTYPE_EFI_GPT) &&
184 return 0; 208 (mbr->partition_record[i].os_type != 0x00))
209 ret = GPT_MBR_HYBRID;
210done:
211 return ret;
185} 212}
186 213
187/** 214/**
@@ -548,17 +575,22 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
548 575
549 lastlba = last_lba(state->bdev); 576 lastlba = last_lba(state->bdev);
550 if (!force_gpt) { 577 if (!force_gpt) {
551 /* This will be added to the EFI Spec. per Intel after v1.02. */ 578 /* This will be added to the EFI Spec. per Intel after v1.02. */
552 legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL); 579 legacymbr = kzalloc(sizeof(*legacymbr), GFP_KERNEL);
553 if (legacymbr) { 580 if (!legacymbr)
554 read_lba(state, 0, (u8 *) legacymbr, 581 goto fail;
555 sizeof (*legacymbr)); 582
556 good_pmbr = is_pmbr_valid(legacymbr); 583 read_lba(state, 0, (u8 *)legacymbr, sizeof(*legacymbr));
557 kfree(legacymbr); 584 good_pmbr = is_pmbr_valid(legacymbr);
558 } 585 kfree(legacymbr);
559 if (!good_pmbr) 586
560 goto fail; 587 if (!good_pmbr)
561 } 588 goto fail;
589
590 pr_debug("Device has a %s MBR\n",
591 good_pmbr == GPT_MBR_PROTECTIVE ?
592 "protective" : "hybrid");
593 }
562 594
563 good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, 595 good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA,
564 &pgpt, &pptes); 596 &pgpt, &pptes);
diff --git a/block/partitions/efi.h b/block/partitions/efi.h
index e645ecb35bf3..7fef625c04de 100644
--- a/block/partitions/efi.h
+++ b/block/partitions/efi.h
@@ -37,6 +37,9 @@
37#define EFI_PMBR_OSTYPE_EFI 0xEF 37#define EFI_PMBR_OSTYPE_EFI 0xEF
38#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE 38#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
39 39
40#define GPT_MBR_PROTECTIVE 1
41#define GPT_MBR_HYBRID 2
42
40#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL 43#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
41#define GPT_HEADER_REVISION_V1 0x00010000 44#define GPT_HEADER_REVISION_V1 0x00010000
42#define GPT_PRIMARY_PARTITION_TABLE_LBA 1 45#define GPT_PRIMARY_PARTITION_TABLE_LBA 1