mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 10:14:55 +00:00
cgpt: Add a callback to allow override of GPT entry priority
This can be used by implementations that want to request vboot to favor a particular kernel entry for booting without affecting the checks for rollback protection and image verification. CQ-DEPEND=CL:274716, CL:274932, CL:275171 BUG=None BRANCH=None TEST=Compiles successfully. make -j runtests successful. Change-Id: I6a4600020354f5d4118c17f083c353c2585c4181 Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://chromium-review.googlesource.com/274558 Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Commit-Queue: Nicolas Boichat <drinkcat@chromium.org> Trybot-Ready: Nicolas Boichat <drinkcat@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
04e2338857
commit
7a1c0d1ec8
2
Makefile
2
Makefile
@@ -459,6 +459,7 @@ HOSTLIB_SRCS = \
|
|||||||
firmware/lib/vboot_nvstorage.c \
|
firmware/lib/vboot_nvstorage.c \
|
||||||
firmware/stub/tpm_lite_stub.c \
|
firmware/stub/tpm_lite_stub.c \
|
||||||
firmware/stub/utility_stub.c \
|
firmware/stub/utility_stub.c \
|
||||||
|
firmware/stub/vboot_api_stub.c \
|
||||||
firmware/stub/vboot_api_stub_disk.c \
|
firmware/stub/vboot_api_stub_disk.c \
|
||||||
firmware/stub/vboot_api_stub_init.c \
|
firmware/stub/vboot_api_stub_init.c \
|
||||||
firmware/stub/vboot_api_stub_sf.c \
|
firmware/stub/vboot_api_stub_sf.c \
|
||||||
@@ -487,6 +488,7 @@ TINYHOSTLIB_SRCS = \
|
|||||||
firmware/lib/cgptlib/crc32.c \
|
firmware/lib/cgptlib/crc32.c \
|
||||||
firmware/lib/gpt_misc.c \
|
firmware/lib/gpt_misc.c \
|
||||||
firmware/lib/utility_string.c \
|
firmware/lib/utility_string.c \
|
||||||
|
firmware/stub/vboot_api_stub.c \
|
||||||
firmware/stub/vboot_api_stub_disk.c \
|
firmware/stub/vboot_api_stub_disk.c \
|
||||||
firmware/stub/vboot_api_stub_sf.c \
|
firmware/stub/vboot_api_stub_sf.c \
|
||||||
firmware/stub/utility_stub.c \
|
firmware/stub/utility_stub.c \
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "gpt.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Error codes */
|
/* Error codes */
|
||||||
|
|
||||||
@@ -1057,4 +1059,16 @@ VbError_t VbUnlockDevice(void);
|
|||||||
*/
|
*/
|
||||||
VbError_t VbLockDevice(void);
|
VbError_t VbLockDevice(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the firmware wants to override GPT entry priority.
|
||||||
|
*
|
||||||
|
* In case of kernel entry, check if there is an override of priority
|
||||||
|
* available. This is used to select a particular partition to boot in the
|
||||||
|
* current boot cycle. Rollback protection, image verification and all other
|
||||||
|
* checks in LoadKernel still remain the same.
|
||||||
|
*
|
||||||
|
* @param e Gpt Entry to check for priority override.
|
||||||
|
* @return 0 if no override, 1-15 for override priority.
|
||||||
|
*/
|
||||||
|
uint8_t VbExOverrideGptEntryPriority(const GptEntry *e);
|
||||||
#endif /* VBOOT_REFERENCE_VBOOT_API_H_ */
|
#endif /* VBOOT_REFERENCE_VBOOT_API_H_ */
|
||||||
|
|||||||
@@ -370,6 +370,12 @@ int GetEntrySuccessful(const GptEntry *e)
|
|||||||
|
|
||||||
int GetEntryPriority(const GptEntry *e)
|
int GetEntryPriority(const GptEntry *e)
|
||||||
{
|
{
|
||||||
|
int ret = VbExOverrideGptEntryPriority(e);
|
||||||
|
|
||||||
|
/* Ensure that the override priority is valid. */
|
||||||
|
if ((ret > 0) && (ret < 16))
|
||||||
|
return ret;
|
||||||
|
|
||||||
return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
|
return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
|
||||||
CGPT_ATTRIBUTE_PRIORITY_OFFSET;
|
CGPT_ATTRIBUTE_PRIORITY_OFFSET;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,3 +168,8 @@ int VbExLegacy(void)
|
|||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t VbExOverrideGptEntryPriority(const GptEntry *e)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,6 +53,18 @@ static const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS;
|
|||||||
const char *progname = "CGPT-TEST";
|
const char *progname = "CGPT-TEST";
|
||||||
const char *command = "TEST";
|
const char *command = "TEST";
|
||||||
|
|
||||||
|
static int override_priority = 0;
|
||||||
|
static int override_counter = 0;
|
||||||
|
|
||||||
|
uint8_t VbExOverrideGptEntryPriority(const GptEntry *e)
|
||||||
|
{
|
||||||
|
if (override_counter == 0)
|
||||||
|
return override_priority;
|
||||||
|
|
||||||
|
override_counter--;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy a random-for-this-program-only Guid into the dest. The num parameter
|
* Copy a random-for-this-program-only Guid into the dest. The num parameter
|
||||||
* completely determines the Guid.
|
* completely determines the Guid.
|
||||||
@@ -1064,16 +1076,49 @@ static int EntryAttributeGetSetTest(void)
|
|||||||
EXPECT(0xFFF0FFFFFFFFFFFFULL == e->attrs.whole);
|
EXPECT(0xFFF0FFFFFFFFFFFFULL == e->attrs.whole);
|
||||||
EXPECT(0 == GetEntryPriority(e));
|
EXPECT(0 == GetEntryPriority(e));
|
||||||
|
|
||||||
|
e->attrs.whole = 0x0000000000000000ULL;
|
||||||
|
SetEntryPriority(e, 15);
|
||||||
|
override_priority = 10;
|
||||||
|
EXPECT(0x000F000000000000ULL == e->attrs.whole);
|
||||||
|
EXPECT(10 == GetEntryPriority(e));
|
||||||
|
e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
|
SetEntryPriority(e, 0);
|
||||||
|
EXPECT(0xFFF0FFFFFFFFFFFFULL == e->attrs.whole);
|
||||||
|
EXPECT(10 == GetEntryPriority(e));
|
||||||
|
override_priority = 0;
|
||||||
|
|
||||||
e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL;
|
e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
EXPECT(1 == GetEntrySuccessful(e));
|
EXPECT(1 == GetEntrySuccessful(e));
|
||||||
EXPECT(15 == GetEntryPriority(e));
|
EXPECT(15 == GetEntryPriority(e));
|
||||||
EXPECT(15 == GetEntryTries(e));
|
EXPECT(15 == GetEntryTries(e));
|
||||||
|
|
||||||
|
override_priority = 10;
|
||||||
|
e->attrs.whole = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
|
EXPECT(1 == GetEntrySuccessful(e));
|
||||||
|
EXPECT(10 == GetEntryPriority(e));
|
||||||
|
EXPECT(15 == GetEntryTries(e));
|
||||||
|
override_priority = 0;
|
||||||
|
|
||||||
e->attrs.whole = 0x0123000000000000ULL;
|
e->attrs.whole = 0x0123000000000000ULL;
|
||||||
EXPECT(1 == GetEntrySuccessful(e));
|
EXPECT(1 == GetEntrySuccessful(e));
|
||||||
EXPECT(2 == GetEntryTries(e));
|
EXPECT(2 == GetEntryTries(e));
|
||||||
EXPECT(3 == GetEntryPriority(e));
|
EXPECT(3 == GetEntryPriority(e));
|
||||||
|
|
||||||
|
override_priority = 10;
|
||||||
|
e->attrs.whole = 0x0123000000000000ULL;
|
||||||
|
EXPECT(1 == GetEntrySuccessful(e));
|
||||||
|
EXPECT(2 == GetEntryTries(e));
|
||||||
|
EXPECT(10 == GetEntryPriority(e));
|
||||||
|
override_priority = 0;
|
||||||
|
|
||||||
|
/* Invalid priority */
|
||||||
|
override_priority = 100;
|
||||||
|
e->attrs.whole = 0x0123000000000000ULL;
|
||||||
|
EXPECT(1 == GetEntrySuccessful(e));
|
||||||
|
EXPECT(2 == GetEntryTries(e));
|
||||||
|
EXPECT(3 == GetEntryPriority(e));
|
||||||
|
override_priority = 0;
|
||||||
|
|
||||||
return TEST_OK;
|
return TEST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1307,6 +1352,38 @@ static int GptUpdateTest(void)
|
|||||||
return TEST_OK;
|
return TEST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int GptOverridePriorityTest(void)
|
||||||
|
{
|
||||||
|
GptData *gpt = GetEmptyGptData();
|
||||||
|
GptEntry *e = (GptEntry *)(gpt->primary_entries);
|
||||||
|
uint64_t start, size;
|
||||||
|
|
||||||
|
/* Tries=nonzero is attempted just like success, but tries=0 isn't */
|
||||||
|
BuildTestGptData(gpt);
|
||||||
|
FillEntry(e + KERNEL_A, 1, 4, 1, 0);
|
||||||
|
FillEntry(e + KERNEL_B, 1, 3, 0, 2);
|
||||||
|
FillEntry(e + KERNEL_X, 1, 2, 0, 2);
|
||||||
|
RefreshCrc32(gpt);
|
||||||
|
GptInit(gpt);
|
||||||
|
gpt->modified = 0; /* Nothing modified yet */
|
||||||
|
|
||||||
|
override_counter = 1;
|
||||||
|
override_priority = 15;
|
||||||
|
|
||||||
|
/* Kernel returned should be B instead of A */
|
||||||
|
EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size));
|
||||||
|
EXPECT(KERNEL_B == gpt->current_kernel);
|
||||||
|
|
||||||
|
override_counter = 0;
|
||||||
|
override_priority = 0;
|
||||||
|
|
||||||
|
/* Now, we should get A */
|
||||||
|
EXPECT(GPT_SUCCESS == GptNextKernelEntry(gpt, &start, &size));
|
||||||
|
EXPECT(KERNEL_A == gpt->current_kernel);
|
||||||
|
|
||||||
|
return TEST_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give an invalid kernel type, and expect GptUpdateKernelEntry() returns
|
* Give an invalid kernel type, and expect GptUpdateKernelEntry() returns
|
||||||
* GPT_ERROR_INVALID_UPDATE_TYPE.
|
* GPT_ERROR_INVALID_UPDATE_TYPE.
|
||||||
@@ -1514,6 +1591,7 @@ int main(int argc, char *argv[])
|
|||||||
{ TEST_CASE(GetNextPrioTest), },
|
{ TEST_CASE(GetNextPrioTest), },
|
||||||
{ TEST_CASE(GetNextTriesTest), },
|
{ TEST_CASE(GetNextTriesTest), },
|
||||||
{ TEST_CASE(GptUpdateTest), },
|
{ TEST_CASE(GptUpdateTest), },
|
||||||
|
{ TEST_CASE(GptOverridePriorityTest), },
|
||||||
{ TEST_CASE(UpdateInvalidKernelTypeTest), },
|
{ TEST_CASE(UpdateInvalidKernelTypeTest), },
|
||||||
{ TEST_CASE(DuplicateUniqueGuidTest), },
|
{ TEST_CASE(DuplicateUniqueGuidTest), },
|
||||||
{ TEST_CASE(TestCrc32TestVectors), },
|
{ TEST_CASE(TestCrc32TestVectors), },
|
||||||
|
|||||||
Reference in New Issue
Block a user