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); } |