void begin_launch(multiboot_info_t *mbi)
{
    unsigned long apicbase;
    tb_error_t err;

    g_mbi = ( g_mbi == NULL ) ? mbi : g_mbi;  /* save for post launch */

    /* on pre-SENTER boot, copy command line to buffer in tboot image
       (so that it will be measured); buffer must be 0 -filled */
    if ( !is_launched() & !s3_flag ) {
        memset(g_cmdline, '\0', sizeof(g_cmdline));
        if ( g_mbi->flags & MBI_CMDLINE ) {
            /* don't include path in cmd line */
            const char *cmdline = skip_filename((char *)g_mbi->cmdline);
            if ( cmdline != NULL )
                strncpy(g_cmdline, cmdline, sizeof(g_cmdline)-1);
        }
    }

    /* always parse cmdline */
    tboot_parse_cmdline();

    /* initialize all logging targets */
    early_printk_init();

    printk("******************* TBOOT *******************\n");
    printk("   %s\n", TBOOT_CHANGESET);
    printk("*********************************************\n");

    printk("command line: %s\n", g_cmdline);
    if ( s3_flag )
        printk("resume from S3\n");

    /* clear resume vector on S3 resume so any resets will not use it */
    if ( !is_launched() & s3_flag )
        set_s3_resume_vector(&_tboot_shared.acpi_sinfo, 0);

    /* we should only be executing on the BSP */
    rdmsrl(MSR_IA32_APICBASE, apicbase);
    if ( !(apicbase & MSR_IA32_APICBASE_BSP) ) {
        printk("entry processor is not BSP\n");
        apply_policy(TB_ERR_FATAL);
    }

    /* we need to make sure this is a (TXT-) capable platform before using */
    /* any of the features, incl. those required to check if the environment */
    /* has already been launched */

    /* make TPM ready for measured launch */
    if ( !is_tpm_ready(0) )
        apply_policy(TB_ERR_TPM_NOT_READY);

    /* read tboot policy from TPM-NV (will use default if none in TPM-NV) */
    err = set_policy();
    apply_policy(err);

    /* need to verify that platform supports TXT before we can check error */
    /* (this includes TPM support) */
    err = supports_txt();
    apply_policy(err);

    /* print any errors on last boot, which must be from TXT launch */
    txt_get_error();

    /* need to verify that platform can perform measured launch */
    err = verify_platform();
    apply_policy(err);

    /* ensure there are modules */
    if ( !verify_mbi(g_mbi) )
        apply_policy(TB_ERR_FATAL);

    /* this is being called post-measured launch */
    if ( is_launched() )
        post_launch();

    /* make the CPU ready for measured launch */
    if ( !prepare_cpu() )
        apply_policy(TB_ERR_FATAL);

    /* do s3 launch directly, if is a s3 resume */
    if ( s3_flag ) {
        txt_s3_launch_environment();
        printk("we should never get here\n");
        apply_policy(TB_ERR_FATAL);
    }

    /* check for error from previous boot */
    printk("checking previous errors on the last boot.\n\t");
    if ( was_last_boot_error() )
        printk("last boot has error.\n");
    else
        printk("last boot has no error.\n");

    if ( !prepare_tpm() )
        apply_policy(TB_ERR_TPM_NOT_READY);

    /* launch the measured environment */
    err = launch_environment(mbi);
    apply_policy(err);
}

void s3_launch(void)
{
    /* restore backed-up s3 wakeup page */
    restore_saved_s3_wakeup_page();

    /* remove DMAR table if necessary */
    remove_vtd_dmar_table();

    /* verify saved hash integrity and re-extend PCRs */
    if ( !verify_integrity() )
        apply_policy(TB_ERR_S3_INTEGRITY);

    /* need to re-initialize this */
    _tboot_shared.num_in_wfs = atomic_read(&ap_wfs_count);

    print_tboot_shared(&_tboot_shared);

    _prot_to_real(g_post_k_s3_state.kernel_s3_resume_vector);
}

Reply via email to