|
From: Jonathan M. M. <jon...@cm...> - 2008-04-22 00:39:11
|
Hello Joseph, tboot-devel (now that I know it exists :-), I'm hoping for some advice debugging the invocation of GETSEC[SENTER] after Linux has booted normally (without TBOOT). We invoke SENTER from a custom Linux kernel module. Our system is a D3C6100 Software Development Platform, and we are able to boot Xen with TBOOT successfully executing GETSEC[SENTER]. I.e., I believe our hardware works and the relevant BIOS settings are correct. When we invoke SENTER, the system appears to freeze. The keyboard is unresponsive and we are forced to reset the system (we've been using the reset button on the motherboard). Reading the LT.ERRORCODE register during the next boot cycle yields: 0x80000000. According to the preliminary architecture specification (from August 2007: 31516804.pdf (is there a newer version available?)) this is a processor-initiated #LegacyShutdown. From section 3.1, I gather that something caused a triple-fault during the execution of SENTER. Is this the correct interpretation of a #LegacyShutdown? We also tried some experiments with hopes of eliciting a richer failure mode. In the above experiment, TXTCR_SINIT_BASE is set to 0x7d500000 (we did not modify it; we only read this value), and we write the SINIT module (BRLK_SINIT_20070910_debug.BIN) to precisely that physical address. Here is a summary of our additional experiments (note that this is our code from within a Linux kernel module; the "TBOOT:" prefixes are there because we stole shamelessly from TBOOT :): (1) (precisely what I described above, for consistency) use TXTCR_SINIT_BASE register as-is (0x7d500000) set legitimate address of SINIT module (0x7d500000) as the argument of __getsec_senter Result: system freeze TBOOT: LT.ERRORCODE=80000000 TBOOT: processor error 0 Intel Trusted Execution Technology Preliminary Architecture Specification on page 86, Table 23 says "Legacy shutdown". In what follows, 0x00c00000 is an alternate physical address where we position the SINIT module prior to executing SENTER. 0x00cc0000 (*different*) is an invalid address, in that it does _not_ contain an SINIT module. (2) set TXTCR_SINIT_BASE register to invalid value (0x00cc0000) set invalid address (0x00000000) as the argument of __getsec_senter Result: system freeze TBOOT: LT.ERRORCODE=80000005 TBOOT: processor error 5 Intel Trusted Execution Technology Preliminary Architecture Specification on page 86, Table 23 says "Load memory type error in Authentication Code Execution Area". (3) set TXTCR_SINIT_BASE register to invalid value (0x00cc0000) set legitimate address (0x7d500000) as the argument of __getsec_senter Result:system does not freeze, it automatically reboots TBOOT: LT.ERRORCODE=c0001841 TBOOT: AC module error : acm_type=1, progress=04, error=6 --> SINIT region not completely contained within DPR (4) set TXTCR_SINIT_BASE register as 0x00c00000 (legitimate) set legitimate address (0x00c00000) as the argument of __getsec_senter Result: system freeze TBOOT: LT.ERRORCODE=80000005 TBOOT: processor error 5 (5) set TXTCR_SINIT_BASE register as 0x00c00000 (legitimate (yes, SINIT is in 2 different places in memory)) set legitimate address (0x7d500000) as the argument of __getsec_senter Result:system does not freeze, automatically reboot TBOOT: LT.ERRORCODE=c0001841 TBOOT: AC module error : acm_type=1, progress=04, error=6 --> SINIT region not completely contained within DPR We also modified TBOOT to induce a failure, just to satisfy our curiosity. If we intentionally set the page global directory to all 0s, the error code changes to c0001071: 0100 one of the rules for table address ordering was not met. I'm not sure what we're doing wrong wrt execution of SENTER. The Preliminary Architecture Specification does not provide enough detail to be certain of every aspect of system configuration required for successful launch. For example, we are calling SENTER with CR0.PG=1 (Linux typically executes with paging enabled). We disable the RLPs (responding logical processors) using the cpu-hotplug facility in Linux, which puts them into an acceptable state as far as I can tell. I'm especially concerned about assumptions the processor and / or SINIT module make with respect to the GDT before executing SENTER, and with respect to the page tables pointed-to by MLE PageTableBase. I think MLE PageTableBase should be irrelevant until execution of SINIT is almost-complete or totally completed. Any suggestions or advice would be greatly appreciated. Thanks, -Jon |
|
From: Jonathan M. M. <jon...@cm...> - 2008-04-22 00:35:08
|
Hello Joseph, tboot-devel (now that I know it exists :-), I'm hoping for some advice debugging the invocation of GETSEC[SENTER] after Linux has booted normally (without TBOOT). We invoke SENTER from a custom Linux kernel module. Our system is a D3C6100 Software Development Platform, and we are able to boot Xen with TBOOT successfully executing GETSEC[SENTER]. I.e., I believe our hardware works and the relevant BIOS settings are correct. When we invoke SENTER, the system appears to freeze. The keyboard is unresponsive and we are forced to reset the system (we've been using the reset button on the motherboard). Reading the LT.ERRORCODE register during the next boot cycle yields: 0x80000000. According to the preliminary architecture specification (from August 2007: 31516804.pdf (is there a newer version available?)) this is a processor-initiated #LegacyShutdown. From section 3.1, I gather that something caused a triple-fault during the execution of SENTER. Is this the correct interpretation of a #LegacyShutdown? We also tried some experiments with hopes of eliciting a richer failure mode. In the above experiment, TXTCR_SINIT_BASE is set to 0x7d500000 (we did not modify it; we only read this value), and we write the SINIT module (BRLK_SINIT_20070910_debug.BIN) to precisely that physical address. Here is a summary of our additional experiments (note that this is our code from within a Linux kernel module; the "TBOOT:" prefixes are there because we stole shamelessly from TBOOT :): (1) (precisely what I described above, for consistency) use TXTCR_SINIT_BASE register as-is (0x7d500000) set legitimate address of SINIT module (0x7d500000) as the argument of __getsec_senter Result: system freeze TBOOT: LT.ERRORCODE=80000000 TBOOT: processor error 0 Intel Trusted Execution Technology Preliminary Architecture Specification on page 86, Table 23 says "Legacy shutdown". In what follows, 0x00c00000 is an alternate physical address where we position the SINIT module prior to executing SENTER. 0x00cc0000 (*different*) is an invalid address, in that it does _not_ contain an SINIT module. (2) set TXTCR_SINIT_BASE register to invalid value (0x00cc0000) set invalid address (0x00000000) as the argument of __getsec_senter Result: system freeze TBOOT: LT.ERRORCODE=80000005 TBOOT: processor error 5 Intel Trusted Execution Technology Preliminary Architecture Specification on page 86, Table 23 says "Load memory type error in Authentication Code Execution Area". (3) set TXTCR_SINIT_BASE register to invalid value (0x00cc0000) set legitimate address (0x7d500000) as the argument of __getsec_senter Result:system does not freeze, it automatically reboots TBOOT: LT.ERRORCODE=c0001841 TBOOT: AC module error : acm_type=1, progress=04, error=6 --> SINIT region not completely contained within DPR (4) set TXTCR_SINIT_BASE register as 0x00c00000 (legitimate) set legitimate address (0x00c00000) as the argument of __getsec_senter Result: system freeze TBOOT: LT.ERRORCODE=80000005 TBOOT: processor error 5 (5) set TXTCR_SINIT_BASE register as 0x00c00000 (legitimate (yes, SINIT is in 2 different places in memory)) set legitimate address (0x7d500000) as the argument of __getsec_senter Result:system does not freeze, automatically reboot TBOOT: LT.ERRORCODE=c0001841 TBOOT: AC module error : acm_type=1, progress=04, error=6 --> SINIT region not completely contained within DPR We also modified TBOOT to induce a failure, just to satisfy our curiosity. If we intentionally set the page global directory to all 0s, the error code changes to c0001071: 0100 one of the rules for table address ordering was not met. I'm not sure what we're doing wrong wrt execution of SENTER. The Preliminary Architecture Specification does not provide enough detail to be certain of every aspect of system configuration required for successful launch. For example, we are calling SENTER with CR0.PG=1 (Linux typically executes with paging enabled). We disable the RLPs (responding logical processors) using the cpu-hotplug facility in Linux, which puts them into an acceptable state as far as I can tell. I'm especially concerned about assumptions the processor and / or SINIT module make with respect to the GDT before executing SENTER, and with respect to the page tables pointed-to by MLE PageTableBase. I think MLE PageTableBase should be irrelevant until execution of SINIT is almost-complete or totally completed. Any suggestions or advice would be greatly appreciated. Thanks, -Jon |
|
From: Hal F. <hal...@gm...> - 2008-04-27 03:34:06
|
Hi Jon - I have been working on something similar as a personal experiment. I have successfully launched a measured environment from a Linux device driver. It took a lot of trial and error to make it work. On my machine, an HP dc7800, the LT.ERRORCODE register is not readable after a TXT failure (the machine hangs and has to be power cycled) so that made it somewhat more difficult. Some advice I can suggest. I changed the BIOS to use only one CPU, and then booted the single-CPU version of Linux. I don't know if downing the CPUs from within Linux would accomplish the same thing, I haven't tried that yet. (I am still working on returning from the measured state back into Linux, which almost/sometimes works.) You might consider doing this to remove one of the variables. To make sure I recognized when I finally succeeded, I had my MLE start with a jump to itself, an infinite loop. This was distinguishable from the usual halt state because the display stayed on, and made sure that I didn't have a successful launch which then failed due to something in the MLE. As far as making it work, in the end it came down to careful study of the TXT manual and attempting to verify that I had everything set up correctly, especially the MTRRs and the page tables. I have a smaller memory so my sinit is at 3e500000, size 5f00. Here is how my MTRRs are set up: MTRRCAP: 0xd08 MTRR_DEF_TYPE: 0x400 Variable MTRR Base 0: 0x3e500006, Mask: 0xfffffc800 Variable MTRR Base 1: 0x3e504006, Mask: 0xfffffe800 Remaining variable MTRRs are 0 My MLE on this run was at 0x20e00000 physical address. I put the MLE page table at the beginning of this area: PDPTE[0] = 0x20e01001 PDE[0] = 09x20e02003 PTE[0] = 0x20e03003 PTE[1] = 0x20e04003 PTE[2] = 0x20e05003 I loaded the MLE code at 0x20e03000 and put the MLE header at the beginning. MLEPageTableBase was 0x20e00000. PMRLowBase is the MLE address rounded down to a 2MB boundary; PMRLowSize is 2 MB. MLEHeaderBase is 0 (the "virtual" address of the MLE header using the MLE page tables). Hopefully some of this might give you some ideas of things to try - Hal Finney |