Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion grub-core/loader/i386/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ grub_linux_boot (void)
slparams.lz_base = (grub_uint32_t) get_virtual_current_address (ch);
slparams.lz_size = grub_skinit_get_sl_size ();

err = grub_skinit_boot_prepare (&slparams);
err = grub_skinit_boot_prepare (&slparams, GRUB_SKINIT_PROTO_LINUX);

if (err != GRUB_ERR_NONE)
return err;
Expand Down
50 changes: 34 additions & 16 deletions grub-core/loader/i386/skinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct lz_tag_boot_linux {
struct lz_tag_boot_mb2 {
struct lz_tag_hdr hdr;
grub_uint32_t mbi;
grub_uint32_t kernel_entry;
grub_uint32_t kernel_entry;
grub_uint32_t kernel_size;
} __attribute__ (( packed ));

Expand Down Expand Up @@ -91,7 +91,7 @@ static inline void *next_tag(struct lz_tag_tags_size *tags)
}

grub_err_t
grub_skinit_boot_prepare (struct grub_slaunch_params *slparams)
grub_skinit_boot_prepare (struct grub_slaunch_params *slparams, grub_uint8_t pr)
{
void *lz_base = (void *)(grub_addr_t) slparams->lz_base;
grub_memset (lz_base, 0, GRUB_SKINIT_SLB_SIZE);
Expand Down Expand Up @@ -130,20 +130,38 @@ grub_skinit_boot_prepare (struct grub_slaunch_params *slparams)
}

/* Boot protocol data */
struct lz_tag_boot_linux *b = next_tag(tags);
b->hdr.type = LZ_TAG_BOOT_LINUX;
b->hdr.len = sizeof(struct lz_tag_boot_linux);
b->zero_page = (grub_uint32_t)slparams->params;
tags->size += b->hdr.len;

if (slparams->tpm_evt_log_size != 0) {
struct lz_tag_evtlog *e = next_tag(tags);
e->hdr.type = LZ_TAG_EVENT_LOG;
e->hdr.len = sizeof(struct lz_tag_evtlog);
e->address = slparams->tpm_evt_log_base;
e->size = slparams->tpm_evt_log_size;
tags->size += e->hdr.len;
}
if (pr == GRUB_SKINIT_PROTO_LINUX)
{
struct lz_tag_boot_linux *b = next_tag(tags);
b->hdr.type = LZ_TAG_BOOT_LINUX;
b->hdr.len = sizeof(struct lz_tag_boot_linux);
b->zero_page = (grub_uint32_t)slparams->params;
tags->size += b->hdr.len;
}
else if (pr == GRUB_SKINIT_PROTO_MB2)
{
struct lz_tag_boot_mb2 *b = next_tag(tags);
b->hdr.type = LZ_TAG_BOOT_MB2;
b->hdr.len = sizeof(struct lz_tag_boot_mb2);
b->mbi = (grub_uint32_t)slparams->params;
/* When 0, LZ will parse image load base from MBI */
b->kernel_entry = 0;
/* When 0, LZ will parse ELF symbols from MBI */
b->kernel_size = 0;
tags->size += b->hdr.len;
}
else
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown boot protocol");

if (slparams->tpm_evt_log_size != 0)
{
struct lz_tag_evtlog *e = next_tag(tags);
e->hdr.type = LZ_TAG_EVENT_LOG;
e->hdr.len = sizeof(struct lz_tag_evtlog);
e->address = slparams->tpm_evt_log_base;
e->size = slparams->tpm_evt_log_size;
tags->size += e->hdr.len;
}

/* Mark end of tags */
struct lz_tag_hdr *end = next_tag(tags);
Expand Down
63 changes: 63 additions & 0 deletions grub-core/loader/multiboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <grub/i18n.h>
#if defined (__i386__) || defined (__x86_64__)
#include <grub/i386/slaunch.h>
#include <grub/i386/skinit.h>
#endif

GRUB_MOD_LICENSE ("GPLv3+");
Expand Down Expand Up @@ -166,6 +167,68 @@ normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
{
state.edi = SLP_NONE;

#ifdef GRUB_USE_MULTIBOOT2
if (grub_slaunch_platform_type () == SLP_AMD_SKINIT)
{
static struct grub_slaunch_params slparams;
grub_relocator_chunk_t ch;
grub_err_t err;

state.edi = SLP_AMD_SKINIT;

slparams.params = state.ebx;

grub_get_drtm_evt_log (&slparams);
if (slparams.tpm_evt_log_size == 0)
{
err = grub_relocator_alloc_chunk_align (rel, &ch, 0x1000000,
0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE,
GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, GRUB_PAGE_SIZE,
GRUB_RELOCATOR_PREFERENCE_NONE, 1);

if (err != GRUB_ERR_NONE)
{
grub_error (err, "cannot alloc memory for TPM event log");
return;
}

slparams.tpm_evt_log_base = get_physical_target_address (ch);
slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE;

grub_memset (get_virtual_current_address (ch), 0,
slparams.tpm_evt_log_size);
}

grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = %x\n",
(unsigned long) slparams.tpm_evt_log_base,
(unsigned) slparams.tpm_evt_log_size);

/* Contrary to the TXT, on AMD we do not have vendor-provided blobs in
* reserved memory, we are using normal RAM */
err = grub_relocator_alloc_chunk_align (rel, &ch,
0, (0xffffffff - GRUB_SKINIT_SLB_SIZE),
GRUB_SKINIT_SLB_SIZE,
GRUB_SKINIT_SLB_ALIGN,
GRUB_RELOCATOR_PREFERENCE_LOW, 1);

if (err != GRUB_ERR_NONE)
{
grub_error (err, "cannot alloc memory for SLB");
return;
}

slparams.lz_base = (grub_uint32_t) get_virtual_current_address (ch);
slparams.lz_size = grub_skinit_get_sl_size ();

err = grub_skinit_boot_prepare (&slparams, GRUB_SKINIT_PROTO_MB2);

if (err != GRUB_ERR_NONE)
return;

state.eax = get_physical_target_address (ch);
}
#endif

grub_relocator32_boot (rel, state, 0);
}
#else
Expand Down
6 changes: 5 additions & 1 deletion include/grub/i386/skinit.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@

#include <grub/i386/slaunch.h>

grub_err_t grub_skinit_boot_prepare (struct grub_slaunch_params *slparams);
#define GRUB_SKINIT_PROTO_LINUX 1
#define GRUB_SKINIT_PROTO_MB2 2

grub_err_t grub_skinit_boot_prepare (struct grub_slaunch_params *slparams,
grub_uint8_t proto);

static inline grub_uint16_t grub_skinit_get_sl_size (void)
{
Expand Down