nvstorage: Add kernel max rollforward NV storage field

This just adds the kernel_max_rollforward field to the nvstorage
libraries and crossystem.  The firmware does not use it yet; that's
coming in a subsequent CL.

16 of the fields's 32 bits are taken from unused bytes of the kernel
field.  This has no effect on existing usage.

BUG=chromium:783997
BRANCH=none
TEST=make runtests
     Also manual testing.  In a root shell:
     	crossystem kernel_max_rollforward --> Should default to 0

	crossystem kernel_max_rollforward=0xfffffffe
	crossystem kernel_max_rollforward --> Should be 0xfffffffe

     (Note that setting it to 0xffffffff is indistinguishable from the
     -1 value that the crossystem library uses to indicate error, so
     0xffffffff isn't actually usable as a max rollforward limit.  But
     0xfffffffe is, and if we ever get so close to the limit that we
     need to use 0xffffffff, something has already gone horribly wrong
     with our versioning strategy...)

Change-Id: I008f412e6ed3c0b59beb9881268585af69d1ff2e
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/765572
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Randall Spangler
2017-10-20 12:38:40 -07:00
committed by chrome-bot
parent 6014de9844
commit 4aaaeca130
9 changed files with 76 additions and 29 deletions

View File

@@ -121,10 +121,7 @@ uint32_t vb2_nv_get(struct vb2_context *ctx, enum vb2_nv_param param)
return p[VB2_NV_OFFS_LOCALIZATION];
case VB2_NV_KERNEL_FIELD:
return (p[VB2_NV_OFFS_KERNEL]
| (p[VB2_NV_OFFS_KERNEL + 1] << 8)
| (p[VB2_NV_OFFS_KERNEL + 2] << 16)
| (p[VB2_NV_OFFS_KERNEL + 3] << 24));
return p[VB2_NV_OFFS_KERNEL1] | (p[VB2_NV_OFFS_KERNEL2] << 8);
case VB2_NV_DEV_BOOT_USB:
return GETBIT(VB2_NV_OFFS_DEV, VB2_NV_DEV_FLAG_USB);
@@ -175,6 +172,12 @@ uint32_t vb2_nv_get(struct vb2_context *ctx, enum vb2_nv_param param)
case VB2_NV_BATTERY_CUTOFF_REQUEST:
return GETBIT(VB2_NV_OFFS_MISC, VB2_NV_MISC_BATTERY_CUTOFF);
case VB2_NV_KERNEL_MAX_ROLLFORWARD:
return (p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD1]
| (p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD2] << 8)
| (p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD3] << 16)
| (p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD4] << 24));
}
/*
@@ -280,10 +283,8 @@ void vb2_nv_set(struct vb2_context *ctx,
break;
case VB2_NV_KERNEL_FIELD:
p[VB2_NV_OFFS_KERNEL] = (uint8_t)(value);
p[VB2_NV_OFFS_KERNEL + 1] = (uint8_t)(value >> 8);
p[VB2_NV_OFFS_KERNEL + 2] = (uint8_t)(value >> 16);
p[VB2_NV_OFFS_KERNEL + 3] = (uint8_t)(value >> 24);
p[VB2_NV_OFFS_KERNEL1] = (uint8_t)(value);
p[VB2_NV_OFFS_KERNEL2] = (uint8_t)(value >> 8);
break;
case VB2_NV_DEV_BOOT_USB:
@@ -356,6 +357,13 @@ void vb2_nv_set(struct vb2_context *ctx,
case VB2_NV_BATTERY_CUTOFF_REQUEST:
SETBIT(VB2_NV_OFFS_MISC, VB2_NV_MISC_BATTERY_CUTOFF);
break;
case VB2_NV_KERNEL_MAX_ROLLFORWARD:
p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD1] = (uint8_t)(value);
p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD2] = (uint8_t)(value >> 8);
p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD3] = (uint8_t)(value >> 16);
p[VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD4] = (uint8_t)(value >> 24);
break;
}
/*

View File

@@ -42,7 +42,7 @@ enum vb2_nv_param {
* 8-bit value.
*/
VB2_NV_LOCALIZATION_INDEX,
/* Field reserved for kernel/user-mode use; 32-bit value. */
/* Field reserved for kernel/user-mode use; 16-bit value. */
VB2_NV_KERNEL_FIELD,
/* Allow booting from USB in developer mode. 0=no, 1=yes. */
VB2_NV_DEV_BOOT_USB,
@@ -94,10 +94,15 @@ enum vb2_nv_param {
VB2_NV_FASTBOOT_UNLOCK_IN_FW,
/* Boot system when AC detected (0=no, 1=yes). */
VB2_NV_BOOT_ON_AC_DETECT,
/* Try to update the EC-RO image after updating the EC-RW image(0=no, 1=yes). */
/*
* Try to update the EC-RO image after updating the EC-RW image
* (0=no, 1=yes).
*/
VB2_NV_TRY_RO_SYNC,
/* Cut off battery and shutdown on next boot. */
VB2_NV_BATTERY_CUTOFF_REQUEST,
/* Maximum kernel version to roll forward to */
VB2_NV_KERNEL_MAX_ROLLFORWARD,
};
/* Set default boot in developer mode */

View File

@@ -29,8 +29,12 @@ enum vb2_nv_offset {
VB2_NV_OFFS_RECOVERY_SUBCODE = 6,
VB2_NV_OFFS_BOOT2 = 7,
VB2_NV_OFFS_MISC = 8,
/* Offsets 9-10 are currently unused */
VB2_NV_OFFS_KERNEL = 11, /* 11-14; field is 32 bits */
VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD1 = 9, /* bits 0-7 of 32 */
VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD2 = 10, /* bits 8-15 of 32 */
VB2_NV_OFFS_KERNEL1 = 11, /* bits 0-7 of 16 */
VB2_NV_OFFS_KERNEL2 = 12, /* bits 8-15 of 16 */
VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD3 = 13, /* bits 16-23 of 32 */
VB2_NV_OFFS_KERNEL_MAX_ROLLFORWARD4 = 14, /* bits 24-31 of 32 */
/* CRC must be last field */
VB2_NV_OFFS_CRC = 15
};

View File

@@ -122,8 +122,11 @@ typedef enum VbNvParam {
VBNV_TRY_RO_SYNC,
/*
* Finish mode transition (if requested), perform battery cut-off and
* shutdown in next boot. */
* shutdown in next boot.
*/
VBNV_BATTERY_CUTOFF_REQUEST,
/* Maximum kernel version to roll forward to */
VBNV_KERNEL_MAX_ROLLFORWARD,
} VbNvParam;
/* Set default boot in developer mode */

View File

@@ -66,7 +66,14 @@
#define MISC_TRY_RO_SYNC 0x04
#define MISC_BATTERY_CUTOFF_REQUEST 0x08
#define KERNEL_FIELD_OFFSET 11
#define KERNEL_MAX_ROLLFORWARD1_OFFSET 9 /* Low bits */
#define KERNEL_MAX_ROLLFORWARD2_OFFSET 10
#define KERNEL_MAX_ROLLFORWARD3_OFFSET 13
#define KERNEL_MAX_ROLLFORWARD4_OFFSET 14 /* High bits */
#define KERNEL_FIELD1_OFFSET 11 /* Low bits */
#define KERNEL_FIELD2_OFFSET 12 /* Low bits */
#define CRC_OFFSET 15
int VbNvSetup(VbNvContext *context)
@@ -141,10 +148,8 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest)
return 0;
case VBNV_KERNEL_FIELD:
*dest = (raw[KERNEL_FIELD_OFFSET]
| (raw[KERNEL_FIELD_OFFSET + 1] << 8)
| (raw[KERNEL_FIELD_OFFSET + 2] << 16)
| (raw[KERNEL_FIELD_OFFSET + 3] << 24));
*dest = (raw[KERNEL_FIELD1_OFFSET]
| (raw[KERNEL_FIELD2_OFFSET] << 8));
return 0;
case VBNV_DEV_BOOT_USB:
@@ -237,6 +242,13 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest)
? 1 : 0;
return 0;
case VBNV_KERNEL_MAX_ROLLFORWARD:
*dest = (raw[KERNEL_MAX_ROLLFORWARD1_OFFSET]
| (raw[KERNEL_MAX_ROLLFORWARD2_OFFSET] << 8)
| (raw[KERNEL_MAX_ROLLFORWARD3_OFFSET] << 16)
| (raw[KERNEL_MAX_ROLLFORWARD4_OFFSET] << 24));
return 0;
default:
return 1;
}
@@ -306,10 +318,8 @@ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value)
break;
case VBNV_KERNEL_FIELD:
raw[KERNEL_FIELD_OFFSET] = (uint8_t)(value);
raw[KERNEL_FIELD_OFFSET + 1] = (uint8_t)(value >> 8);
raw[KERNEL_FIELD_OFFSET + 2] = (uint8_t)(value >> 16);
raw[KERNEL_FIELD_OFFSET + 3] = (uint8_t)(value >> 24);
raw[KERNEL_FIELD1_OFFSET] = (uint8_t)(value);
raw[KERNEL_FIELD2_OFFSET] = (uint8_t)(value >> 8);
break;
case VBNV_DEV_BOOT_USB:
@@ -469,6 +479,13 @@ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value)
raw[MISC_OFFSET] &= ~MISC_BATTERY_CUTOFF_REQUEST;
break;
case VBNV_KERNEL_MAX_ROLLFORWARD:
raw[KERNEL_MAX_ROLLFORWARD1_OFFSET] = (uint8_t)(value);
raw[KERNEL_MAX_ROLLFORWARD2_OFFSET] = (uint8_t)(value >> 8);
raw[KERNEL_MAX_ROLLFORWARD3_OFFSET] = (uint8_t)(value >> 16);
raw[KERNEL_MAX_ROLLFORWARD4_OFFSET] = (uint8_t)(value >> 24);
break;
default:
return 1;
}

View File

@@ -72,14 +72,14 @@ static const char *fw_results[] = {"unknown", "trying", "success", "failure"};
static const char *default_boot[] = {"disk", "usb", "legacy"};
/* Masks for kern_nv usage by kernel. */
#define KERN_NV_FWUPDATE_TRIES_MASK 0x0000000F
#define KERN_NV_BLOCK_DEVMODE_FLAG 0x00000010
#define KERN_NV_TPM_ATTACK_FLAG 0x00000020
#define KERN_NV_FWUPDATE_TRIES_MASK 0x000F
#define KERN_NV_BLOCK_DEVMODE_FLAG 0x0010
#define KERN_NV_TPM_ATTACK_FLAG 0x0020
/* If you want to use the remaining currently-unused bits in kern_nv
* for something kernel-y, define a new field (the way we did for
* fwupdate_tries). Don't just modify kern_nv directly, because that
* makes it too easy to accidentally corrupt other sub-fields. */
#define KERN_NV_CURRENTLY_UNUSED 0xFFFFFFC0
#define KERN_NV_CURRENTLY_UNUSED 0xFFC0
/* Return true if the FWID starts with the specified string. */
int FwidStartsWith(const char *start)
@@ -523,6 +523,8 @@ int VbGetSystemPropertyInt(const char *name)
value = VbGetNvStorage(VBNV_RECOVERY_SUBCODE);
} else if (!strcasecmp(name,"wipeout_request")) {
value = VbGetNvStorage(VBNV_FW_REQ_WIPEOUT);
} else if (!strcasecmp(name,"kernel_max_rollforward")) {
value = VbGetNvStorage(VBNV_KERNEL_MAX_ROLLFORWARD);
}
/* Other parameters */
else if (!strcasecmp(name,"cros_debug")) {
@@ -716,6 +718,8 @@ int VbSetSystemPropertyInt(const char *name, int value)
return VbSetNvStorage_WithBackup(VBNV_TRY_RO_SYNC, value);
} else if (!strcasecmp(name, "battery_cutoff_request")) {
return VbSetNvStorage(VBNV_BATTERY_CUTOFF_REQUEST, value);
} else if (!strcasecmp(name,"kernel_max_rollforward")) {
return VbSetNvStorage(VBNV_KERNEL_MAX_ROLLFORWARD, value);
}
return -1;

View File

@@ -41,7 +41,7 @@ static struct nv_field nvfields[] = {
{VB2_NV_RECOVERY_REQUEST, 0, 0x42, 0xED, "recovery request"},
{VB2_NV_RECOVERY_SUBCODE, 0, 0x56, 0xAC, "recovery subcode"},
{VB2_NV_LOCALIZATION_INDEX, 0, 0x69, 0xB0, "localization index"},
{VB2_NV_KERNEL_FIELD, 0, 0x12345678, 0xFEDCBA98, "kernel field"},
{VB2_NV_KERNEL_FIELD, 0, 0x1234, 0xFEDC, "kernel field"},
{VB2_NV_DEV_BOOT_USB, 0, 1, 0, "dev boot usb"},
{VB2_NV_DEV_BOOT_LEGACY, 0, 1, 0, "dev boot legacy"},
{VB2_NV_DEV_BOOT_SIGNED_ONLY, 0, 1, 0, "dev boot custom"},
@@ -56,6 +56,8 @@ static struct nv_field nvfields[] = {
{VB2_NV_FASTBOOT_UNLOCK_IN_FW, 0, 1, 0, "fastboot unlock in fw"},
{VB2_NV_BOOT_ON_AC_DETECT, 0, 1, 0, "boot on ac detect"},
{VB2_NV_TRY_RO_SYNC, 0, 1, 0, "try read only software sync"},
{VB2_NV_KERNEL_MAX_ROLLFORWARD, 0, 0x12345678, 0xFEDCBA98,
"kernel max rollforward"},
{0, 0, 0, 0, NULL}
};

View File

@@ -29,7 +29,7 @@ static VbNvField nvfields[] = {
{VBNV_TRY_B_COUNT, 0, 6, 15, "try B count"},
{VBNV_RECOVERY_REQUEST, 0, 0x42, 0xED, "recovery request"},
{VBNV_LOCALIZATION_INDEX, 0, 0x69, 0xB0, "localization index"},
{VBNV_KERNEL_FIELD, 0, 0x12345678, 0xFEDCBA98, "kernel field"},
{VBNV_KERNEL_FIELD, 0, 0x1234, 0xFEDC, "kernel field"},
{VBNV_DEV_BOOT_USB, 0, 1, 0, "dev boot usb"},
{VBNV_DEV_BOOT_LEGACY, 0, 1, 0, "dev boot legacy"},
{VBNV_DEV_BOOT_SIGNED_ONLY, 0, 1, 0, "dev boot custom"},
@@ -49,6 +49,8 @@ static VbNvField nvfields[] = {
{VBNV_FASTBOOT_UNLOCK_IN_FW, 0, 1, 0, "fastboot unlock in firmware"},
{VBNV_BOOT_ON_AC_DETECT, 0, 1, 0, "boot on ac detect"},
{VBNV_TRY_RO_SYNC, 0, 1, 0, "try read only software sync"},
{VBNV_KERNEL_MAX_ROLLFORWARD, 0, 0x12345678, 0xFEDCBA98,
"kernel max rollforward"},
{0, 0, 0, 0, NULL}
};

View File

@@ -70,7 +70,9 @@ const Param sys_param_list[] = {
{"fw_prev_result", IS_STRING, "Firmware result of previous boot (vboot2)"},
{"hwid", IS_STRING, "Hardware ID"},
{"inside_vm", 0, "Running in a VM?"},
{"kern_nv", 0, "Non-volatile field for kernel use", "0x%08x"},
{"kern_nv", 0, "Non-volatile field for kernel use", "0x%04x"},
{"kernel_max_rollforward", CAN_WRITE, "Max kernel version to store into TPM",
"0x%08x"},
{"kernkey_vfy", IS_STRING, "Type of verification done on kernel key block"},
{"loc_idx", CAN_WRITE, "Localization index for firmware screens (writable)"},
{"mainfw_act", IS_STRING, "Active main firmware"},