From: Joseph C. <jos...@in...> - 2010-05-20 22:28:32
|
changeset 9c733d6c3f40 in /var/www/tboot.hg details: tboot.hg?cmd=changeset;node=9c733d6c3f40 description: Fix bug where some e820 configurations would case recent USB-related fix code to reserve too much memory The recent change to not DMA protect USB buffers has a bug where, for some e820 configurations, it will reserve most of the free memory as being above the last reserved region. This change fixes that and optimizes the reserving of the VT-d truncation memory so that it doesn't re-walk the e820 table. Signed-off-by: Joseph Cihula <jos...@in...> diffstat: tboot/txt/txt.c | 56 ++++++-------------------------------------------------- tboot/txt/verify.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 50 deletions(-) diffs (144 lines): diff -r b3e5cb3811a2 -r 9c733d6c3f40 tboot/txt/txt.c --- a/tboot/txt/txt.c Thu May 20 08:53:59 2010 -0700 +++ b/tboot/txt/txt.c Thu May 20 13:21:52 2010 -0700 @@ -459,38 +459,6 @@ printk("all APs in wait-for-sipi\n"); } -static bool reserve_vtd_delta_mem(txt_heap_t *txt_heap) -{ - uint64_t min_lo_ram, max_lo_ram, min_hi_ram, max_hi_ram; - uint64_t base, length; - - if ( !get_ram_ranges(&min_lo_ram, &max_lo_ram, &min_hi_ram, &max_hi_ram) ) - return false; - - os_sinit_data_t *os_sinit_data = get_os_sinit_data_start(txt_heap); - - if ( max_lo_ram != (os_sinit_data->vtd_pmr_lo_base + - os_sinit_data->vtd_pmr_lo_size) ) { - base = os_sinit_data->vtd_pmr_lo_base + os_sinit_data->vtd_pmr_lo_size; - length = max_lo_ram - base; - printk("reserving 0x%Lx - 0x%Lx, which was truncated for VT-d\n", - base, base + length); - if ( !e820_reserve_ram(base, length) ) - return false; - } - if ( max_hi_ram != (os_sinit_data->vtd_pmr_hi_base + - os_sinit_data->vtd_pmr_hi_size) ) { - base = os_sinit_data->vtd_pmr_hi_base + os_sinit_data->vtd_pmr_hi_size; - length = max_hi_ram - base; - printk("reserving 0x%Lx - 0x%Lx, which was truncated for VT-d\n", - base, base + length); - if ( !e820_reserve_ram(base, length) ) - return false; - } - - return true; -} - bool txt_is_launched(void) { txt_sts_t sts; @@ -756,10 +724,6 @@ tb_error_t txt_protect_mem_regions(void) { uint64_t base, size; - txt_heap_t* txt_heap; - sinit_mle_data_t *sinit_mle_data; - sinit_mdr_t *mdrs_base; - uint32_t num_mdrs; /* * TXT has 2 regions of RAM that need to be reserved for use by only the @@ -793,11 +757,12 @@ /* ensure that memory not marked as good RAM by the MDRs is RESERVED in the e820 table */ - txt_heap = get_txt_heap(); - sinit_mle_data = get_sinit_mle_data_start(txt_heap); - num_mdrs = sinit_mle_data->num_mdrs; - mdrs_base = (sinit_mdr_t *)(((void *)sinit_mle_data - sizeof(uint64_t)) + - sinit_mle_data->mdrs_off); + txt_heap_t* txt_heap = get_txt_heap(); + sinit_mle_data_t *sinit_mle_data = get_sinit_mle_data_start(txt_heap); + uint32_t num_mdrs = sinit_mle_data->num_mdrs; + sinit_mdr_t *mdrs_base = (sinit_mdr_t *)(((void *)sinit_mle_data + - sizeof(uint64_t)) + + sinit_mle_data->mdrs_off); printk("verifying e820 table against SINIT MDRs: "); if ( !verify_e820_map(mdrs_base, num_mdrs) ) { printk("verification failed.\n"); @@ -805,15 +770,6 @@ } printk("verification succeeded.\n"); - /* if vtd_pmr_lo/hi sizes rounded to 2MB granularity are less than the - max_lo/hi_ram values determined from the e820 table, then we must - reserve the differences in e820 table so that unprotected memory is - not used by the kernel */ - if ( !s3_flag && !reserve_vtd_delta_mem(txt_heap) ) { - printk("failed to reserve VT-d PMR delta memory\n"); - return TB_ERR_POST_LAUNCH_VERIFICATION; - } - return TB_ERR_NONE; } diff -r b3e5cb3811a2 -r 9c733d6c3f40 tboot/txt/verify.c --- a/tboot/txt/verify.c Thu May 20 08:53:59 2010 -0700 +++ b/tboot/txt/verify.c Thu May 20 13:21:52 2010 -0700 @@ -203,6 +203,36 @@ return TB_ERR_TXT_NOT_SUPPORTED; } +static bool reserve_vtd_delta_mem(uint64_t min_lo_ram, uint64_t max_lo_ram, + uint64_t min_hi_ram, uint64_t max_hi_ram) +{ + uint64_t base, length; + + txt_heap_t* txt_heap = get_txt_heap(); + os_sinit_data_t *os_sinit_data = get_os_sinit_data_start(txt_heap); + + if ( max_lo_ram != (os_sinit_data->vtd_pmr_lo_base + + os_sinit_data->vtd_pmr_lo_size) ) { + base = os_sinit_data->vtd_pmr_lo_base + os_sinit_data->vtd_pmr_lo_size; + length = max_lo_ram - base; + printk("reserving 0x%Lx - 0x%Lx, which was truncated for VT-d\n", + base, base + length); + if ( !e820_reserve_ram(base, length) ) + return false; + } + if ( max_hi_ram != (os_sinit_data->vtd_pmr_hi_base + + os_sinit_data->vtd_pmr_hi_size) ) { + base = os_sinit_data->vtd_pmr_hi_base + os_sinit_data->vtd_pmr_hi_size; + length = max_hi_ram - base; + printk("reserving 0x%Lx - 0x%Lx, which was truncated for VT-d\n", + base, base + length); + if ( !e820_reserve_ram(base, length) ) + return false; + } + + return true; +} + static bool verify_vtd_pmrs(txt_heap_t *txt_heap) { os_sinit_data_t *os_sinit_data, tmp_os_sinit_data; @@ -227,6 +257,16 @@ if ( !get_ram_ranges(&min_lo_ram, &max_lo_ram, &min_hi_ram, &max_hi_ram) ) return false; + + /* if vtd_pmr_lo/hi sizes rounded to 2MB granularity are less than the + max_lo/hi_ram values determined from the e820 table, then we must + reserve the differences in e820 table so that unprotected memory is + not used by the kernel */ + if ( !reserve_vtd_delta_mem(min_lo_ram, max_lo_ram, min_hi_ram, + max_hi_ram) ) { + printk("failed to reserve VT-d PMR delta memory\n"); + return false; + } } /* compare to current values */ |