copy reboot parameters in host_command_reboot()

Currently host_command_reboot() casts the supplied buffer and access
it directly. This works until about half-way thru the function when
the same buffer potentially gets overwritten when sending the response
code to the host.

This CL gets around that by copying the reboot parameters into a
separate buffer.

Signed-off-by: David Hendricks <dhendrix@chromium.org>
BUG=none
TEST=Tested using 'ectool reboot_ec' on Snow (see below)

Before, EC console displayed "[Executing host reboot command]" and
ectool showed no actual change (reboot command was being overwritten
with EC_REBOOT_CANCEL):
localhost ~ # ectool version | grep 'Firmware copy'
Firmware copy: RO
localhost ~ # ectool reboot_ec A
localhost ~ # ectool version | grep 'Firmware copy'
Firmware copy: RO

With the patch applied, the EC console shows the EC boot-up messages
and ectool confirms that the jump took place:
localhost ~ # ectool version | grep 'Firmware copy'
Firmware copy: RO
localhost ~ # ectool reboot_ec A
localhost ~ # ectool version | grep 'Firmware copy'
Firmware copy: A

Change-Id: I8aca8d468d1125c3fb8d320ec0fb79d2822b0b20
Reviewed-on: https://gerrit.chromium.org/gerrit/26998
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Tested-by: David Hendricks <dhendrix@chromium.org>
Commit-Ready: David Hendricks <dhendrix@chromium.org>
This commit is contained in:
David Hendricks
2012-07-09 18:18:19 -07:00
committed by Gerrit
parent 37b295fd6e
commit 29af184eb7

View File

@@ -761,15 +761,21 @@ DECLARE_HOST_COMMAND(EC_CMD_GET_BOARD_VERSION, host_command_get_board_version);
int host_command_reboot(uint8_t *data, int *resp_size)
{
struct ec_params_reboot_ec *p = (struct ec_params_reboot_ec *)data;
struct ec_params_reboot_ec p;
if (p->cmd == EC_REBOOT_CANCEL) {
/*
* Ensure reboot parameters don't get clobbered when the response
* is sent in case data argument points to the host tx/rx buffer.
*/
memcpy(&p, data, sizeof(p));
if (p.cmd == EC_REBOOT_CANCEL) {
/* Cancel pending reboot */
reboot_at_shutdown = EC_REBOOT_CANCEL;
return EC_RES_SUCCESS;
} else if (p->flags & EC_REBOOT_FLAG_ON_AP_SHUTDOWN) {
} else if (p.flags & EC_REBOOT_FLAG_ON_AP_SHUTDOWN) {
/* Store request for processing at chipset shutdown */
reboot_at_shutdown = p->cmd;
reboot_at_shutdown = p.cmd;
return EC_RES_SUCCESS;
}
@@ -786,7 +792,7 @@ int host_command_reboot(uint8_t *data, int *resp_size)
#endif
CPUTS("[Executing host reboot command]\n");
switch (handle_pending_reboot(p->cmd)) {
switch (handle_pending_reboot(p.cmd)) {
case EC_SUCCESS:
return EC_RES_SUCCESS;
case EC_ERROR_INVAL: