* Re: [Xense-devel] [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support
@ 2007-04-12 21:07 Jonathan M. McCune
2007-04-12 21:52 ` Cihula, Joseph
2007-07-11 20:51 ` [RFC][PATCH][0/2] Intel(r) Trusted Execution Technology Jonathan M. McCune
0 siblings, 2 replies; 6+ messages in thread
From: Jonathan M. McCune @ 2007-04-12 21:07 UTC (permalink / raw)
To: xense-devel, xen-devel; +Cc: leendert, joseph.cihula, Stefan Berger
Hello,
Has any more work been done on this front? The message below is
from Sept. 2006. In particular, the LT/TXT Technology Enabling
Platform (TEP) is now available from MPC Corp. Where can one
obtain an appropriate AC SINIT module (i.e., like
lpg_sinit_20050831_pae.auth.bin below)? I would like to begin
using Xen with TXT support.
Thanks,
-Jon
This patch adds SMP support to the previous version. Since that has not
been merged I have included it in this patch. This should apply cleanly
to the tip. Below is the text of the original submittal, slightly
updated.
Attached is a preliminary patch that adds Intel(R) LaGrande Technology
(LT) (Safer Mode Extensions - SMX) support to Xen. While there are
still several enhancements needed for complete support, we feel that it
is sufficiently complete for an initial public posting to expose to the
community.
LaGrande Technology in Brief:
-----------------------------
o Provides dynamic root of trust for measurement (DRTM)
o DMA protection
o Data protection in case of improper shutdown
For more information on LT, see the Intel LaGrande Technology website:
http://www.intel.com/technology/security/.
This site also has a link to the LT preliminary specification (an
updated version that reflects the functionlaity of this code will be
available later this week).
The LT functionality this code adds is:
---------------------------------------
o Measured Launch. If the processor is detected as being LT-capable
and enabled then the code will attempt to perform a measured launch. If
the processor is (not capable) or (capable but not enabled) or (capable
and enabled but the launch process fails (missing SINIT, corrupted data,
etc.)) then it will fall-through to a non-LT boot.
o Teardown of measured environment. When Xen exits the LT environment
will be torn down properly.
o Reset data protection. LT HW prevents access to secrets if the
system is reset without clearing them from memory (as part of a LT
teardown). This code will support this by setting the flag indicating
that memory should be so protected during the measured launch and
clearing the flag just before teardown.
o Protection of LT memory ranges. LT reserves certain regions of RAM
for its use and also defines several MMIO regions. These regions are
protected from use by any domains (including dom0). Note that there a
sub-regions of the MMIO space that are left accessible to dom0 (LT
public configuration space, TPM localities 0,1).
Patch breakdown:
----------------
Config.mk - add INTEL_SMX build config
xen/Rules.mk - adds '-DCONFIG_SMX' compile flag if INTEL_SMX=y
xen/arch/x86/Makefile - add arch/x86/smx dir to build
xen/arch/x86/boot/x86_32.S - hook startup to launch LT
environmentxen/arch/x86/setup.c - initialize fixmap entries for LT
config reg space
xen/arch/x86/domain_build.c - protect LT private config space
xen/arch/x86/e820.c - support for E820_PROTECTED mem type
xen/arch/x86/hvm/vmx/vmx.c - support new LT/VMX IA32_FEATURE_CONTROL_MSR
flag
xen/arch/x86/mm.c - support for E820_PROTECTED mem type
xen/arch/x86/setup.c - hook to reserve LT RAM regions and initialize
fixmap entries for LT config reg space
xen/arch/x86/shutdown.c - hook shutdown to teardown LT environment
xen/common/domctl.c - prevent XEN_DOMCTL_iomem_permission from being
able to map LT private config space
xen/include/asm-x86/cpufeature.h - adds new SMX feature flag
xen/include/asm-x86/e820.h - export print_e820_memory_map()
xen/include/asm-x86/fixmap.h - adds fixmap entries for LT config reg
space
xen/include/asm-x86/msr.h - adds new VMX and SMX MSR flags
xen/include/asm-x86/processor.h - adds new CR4 SMX flag
xen/include/public/hvm/e820.h - add E820_PROTECTED mem type
xen/arch/x86/smx/Makefile - self explanatory
xen/arch/x86/smx/acmod.c - LT Authenticated Code (AC) module support fns
xen/arch/x86/smx/early_printk.c - serial printk() for early in boot
process
xen/arch/x86/smx/errors.c - error parsing/display fns
xen/arch/x86/smx/mtrrs.c - MTRR handling for AC module launch
xen/arch/x86/smx/smx.c - main LT/SMX fns and entry points
xen/arch/x86/smx/tpm.c - basic TPM support fns
xen/include/asm-x86/smx/* - headers for SMX/LT fns
This code has been developed and tested on Intel Software Development
Platform (SDP) 3 systems (available under NDA via the Intel Premier
Support channel). It will be updated to work with the LT Technology
Enabling Platform (TEP) that will be publicly available this fall.
Instructions for use:
---------------------
o By default, the functionality is disabled in the build. It can be
enabled by changing the INTEL_SMX flag to 'y' in Config.mk.
o The SINIT AC module (available with SDP3 systems) must be added to
the grub.conf boot config as the last module, e.g.:
...
module /initrd-2.6.16.13-xen.img
module /lpg_sinit_20050831_pae.auth.bin
o Progress of the LT launch process is indicated via debug printk's to
COM1 (hardcoded). These appear before the normal "(XEN)" output and are
prefixed by "SMX:". The code (in early_printk.c) does not initialize
the COM port so this needs to be done by GRUB - grub.conf should have:
serial --speed=115200 --unit=0
terminal console serial
Caveats / Notes:
----------------
o x86_64 is not supported yet (IA64 does not support LT at this time).
o The code only measures the hypervisor (and its command line), which
is not the complete TCB.
o It doesn't cap (extend with invalid value) the dynamic TPM PCRs when
the LT environment is torn down. Instead it disables the BIOS reboot
option so that any shutdown/reboot will have to reset the platform and
the TPM.
o TPM locality 2 is not protected. The defined behavior for access to
unpermitted localities is for reads to return 0xff's and writes to be
dropped. This will require mapping pages from locality 3 or 4 into the
locality 2 range.
o No DMA protection has been implemented in this patch. SDP3 only
supports the NoDMA table for DMA protection and this will be superseded
by VT-d. VT-d support for LT will be added after it is added for the
general case.
These limitations will be addressed in subsequent patches.
There was a presentation on the code at the Xen Summit. More
information on LT is available at
http://www.intel.com/technology/security/. Comments and feedback are
welcome at any time.
Joseph Cihula
(Linux) Software Security Architect
Open Source Technology Center
Intel Corp.
*** These opinions are not necessarily those of my employer ***
^ permalink raw reply [flat|nested] 6+ messages in thread* RE: [Xense-devel] [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support
2007-04-12 21:07 [Xense-devel] [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support Jonathan M. McCune
@ 2007-04-12 21:52 ` Cihula, Joseph
2007-07-11 20:51 ` [RFC][PATCH][0/2] Intel(r) Trusted Execution Technology Jonathan M. McCune
1 sibling, 0 replies; 6+ messages in thread
From: Cihula, Joseph @ 2007-04-12 21:52 UTC (permalink / raw)
To: Jonathan M. McCune, xense-devel, xen-devel; +Cc: leendert, Stefan Berger
Jonathan M. McCune <mailto:jonmccune@cmu.edu> scribbled on Thursday,
April 12, 2007 2:07 PM:
> Hello,
>
> Has any more work been done on this front? The message below is
> from Sept. 2006. In particular, the LT/TXT Technology Enabling
> Platform (TEP) is now available from MPC Corp. Where can one
> obtain an appropriate AC SINIT module (i.e., like
> lpg_sinit_20050831_pae.auth.bin below)? I would like to begin
> using Xen with TXT support.
>
> Thanks,
> -Jon
>
A very timely email indeed. We are putting the finishing touches on a
re-design of the TXT support patch per feedback that we received last
year. In addition to breaking the code out into a separate module that
executes before Xen, it will include support for both 32 and 64 bit Xen
and fix some of the TBD's. We're expecting to have it ready in the week
or two (cross-your-fingers before/during the Xen Summit).
As to getting the SINIT AC Module for the MPC TEP system, the person
here who works with MPC tells me that it should be on a CD included with
the system. If this is not the case, please let me know, but I will
send it to you just in case.
Joe
>
>
>
> This patch adds SMP support to the previous version. Since that has
> not
> been merged I have included it in this patch. This should apply
> cleanly
> to the tip. Below is the text of the original submittal, slightly
> updated.
>
> Attached is a preliminary patch that adds Intel(R) LaGrande Technology
> (LT) (Safer Mode Extensions - SMX) support to Xen. While there are
> still several enhancements needed for complete support, we feel that
> it
> is sufficiently complete for an initial public posting to expose to
> the
> community.
>
>
> LaGrande Technology in Brief:
> -----------------------------
> o Provides dynamic root of trust for measurement (DRTM)
> o DMA protection
> o Data protection in case of improper shutdown
>
> For more information on LT, see the Intel LaGrande Technology website:
> http://www.intel.com/technology/security/.
> This site also has a link to the LT preliminary specification (an
> updated version that reflects the functionlaity of this code will be
> available later this week).
>
>
> The LT functionality this code adds is:
> ---------------------------------------
> o Measured Launch. If the processor is detected as being LT-capable
> and enabled then the code will attempt to perform a measured launch.
> If
> the processor is (not capable) or (capable but not enabled) or
> (capable
> and enabled but the launch process fails (missing SINIT, corrupted
> data,
> etc.)) then it will fall-through to a non-LT boot.
> o Teardown of measured environment. When Xen exits the LT
> environment
> will be torn down properly.
> o Reset data protection. LT HW prevents access to secrets if the
> system is reset without clearing them from memory (as part of a LT
> teardown). This code will support this by setting the flag indicating
> that memory should be so protected during the measured launch and
> clearing the flag just before teardown.
> o Protection of LT memory ranges. LT reserves certain regions of RAM
> for its use and also defines several MMIO regions. These regions are
> protected from use by any domains (including dom0). Note that there a
> sub-regions of the MMIO space that are left accessible to dom0 (LT
> public configuration space, TPM localities 0,1).
>
>
> Patch breakdown:
> ----------------
> Config.mk - add INTEL_SMX build config
> xen/Rules.mk - adds '-DCONFIG_SMX' compile flag if INTEL_SMX=y
> xen/arch/x86/Makefile - add arch/x86/smx dir to build
> xen/arch/x86/boot/x86_32.S - hook startup to launch LT
> environmentxen/arch/x86/setup.c - initialize fixmap entries for LT
> config reg space
> xen/arch/x86/domain_build.c - protect LT private config space
> xen/arch/x86/e820.c - support for E820_PROTECTED mem type
> xen/arch/x86/hvm/vmx/vmx.c - support new LT/VMX
> IA32_FEATURE_CONTROL_MSR
> flag
> xen/arch/x86/mm.c - support for E820_PROTECTED mem type
> xen/arch/x86/setup.c - hook to reserve LT RAM regions and initialize
> fixmap entries for LT config reg space
> xen/arch/x86/shutdown.c - hook shutdown to teardown LT environment
> xen/common/domctl.c - prevent XEN_DOMCTL_iomem_permission from being
> able to map LT private config space
> xen/include/asm-x86/cpufeature.h - adds new SMX feature flag
> xen/include/asm-x86/e820.h - export print_e820_memory_map()
> xen/include/asm-x86/fixmap.h - adds fixmap entries for LT config reg
> space
> xen/include/asm-x86/msr.h - adds new VMX and SMX MSR flags
> xen/include/asm-x86/processor.h - adds new CR4 SMX flag
> xen/include/public/hvm/e820.h - add E820_PROTECTED mem type
> xen/arch/x86/smx/Makefile - self explanatory
> xen/arch/x86/smx/acmod.c - LT Authenticated Code (AC) module support
> fns xen/arch/x86/smx/early_printk.c - serial printk() for early in
> boot
> process
> xen/arch/x86/smx/errors.c - error parsing/display fns
> xen/arch/x86/smx/mtrrs.c - MTRR handling for AC module launch
> xen/arch/x86/smx/smx.c - main LT/SMX fns and entry points
> xen/arch/x86/smx/tpm.c - basic TPM support fns
> xen/include/asm-x86/smx/* - headers for SMX/LT fns
>
>
> This code has been developed and tested on Intel Software Development
> Platform (SDP) 3 systems (available under NDA via the Intel Premier
> Support channel). It will be updated to work with the LT Technology
> Enabling Platform (TEP) that will be publicly available this fall.
>
>
> Instructions for use:
> ---------------------
> o By default, the functionality is disabled in the build. It can be
> enabled by changing the INTEL_SMX flag to 'y' in Config.mk.
> o The SINIT AC module (available with SDP3 systems) must be added to
> the grub.conf boot config as the last module, e.g.:
> ...
> module /initrd-2.6.16.13-xen.img
> module /lpg_sinit_20050831_pae.auth.bin
> o Progress of the LT launch process is indicated via debug printk's
> to
> COM1 (hardcoded). These appear before the normal "(XEN)" output and
> are
> prefixed by "SMX:". The code (in early_printk.c) does not initialize
> the COM port so this needs to be done by GRUB - grub.conf should have:
> serial --speed=115200 --unit=0
> terminal console serial
>
>
> Caveats / Notes:
> ----------------
> o x86_64 is not supported yet (IA64 does not support LT at this
> time).
> o The code only measures the hypervisor (and its command line), which
> is not the complete TCB.
> o It doesn't cap (extend with invalid value) the dynamic TPM PCRs
> when
> the LT environment is torn down. Instead it disables the BIOS reboot
> option so that any shutdown/reboot will have to reset the platform and
> the TPM.
> o TPM locality 2 is not protected. The defined behavior for access
> to
> unpermitted localities is for reads to return 0xff's and writes to be
> dropped. This will require mapping pages from locality 3 or 4 into
> the
> locality 2 range.
> o No DMA protection has been implemented in this patch. SDP3 only
> supports the NoDMA table for DMA protection and this will be
> superseded
> by VT-d. VT-d support for LT will be added after it is added for the
> general case.
>
> These limitations will be addressed in subsequent patches.
>
> There was a presentation on the code at the Xen Summit. More
> information on LT is available at
> http://www.intel.com/technology/security/. Comments and feedback are
> welcome at any time.
>
>
> Joseph Cihula
> (Linux) Software Security Architect
> Open Source Technology Center
> Intel Corp.
>
> *** These opinions are not necessarily those of my employer ***
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC][PATCH][0/2] Intel(r) Trusted Execution Technology
2007-04-12 21:07 [Xense-devel] [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support Jonathan M. McCune
2007-04-12 21:52 ` Cihula, Joseph
@ 2007-07-11 20:51 ` Jonathan M. McCune
2007-07-12 13:40 ` Jonathan M. McCune
1 sibling, 1 reply; 6+ messages in thread
From: Jonathan M. McCune @ 2007-07-11 20:51 UTC (permalink / raw)
To: xense-devel, xen-devel, joseph.cihula, junkoi2004
Hi Joseph, Jun, Xen developers,
I'm trying to get this patch to build, but I've encountered some difficulty.
Applying the patch to today's tip results in three failures which I was able
to correct manually. I also tried an older changeset (15369) from the day Jun
reported success, and txt-xen-0608_01-xen.patch applied with `patch -p1 -F 3`.
txt-xen-0608_02-sboot.patch applied successfully in both cases.
I tried both gcc 4.1.2 and 3.4.6. The failure is the same both ways.
If I disable the TXT patch (CONFIG_TXT ?= n in Config.mk), Xen builds successfully.
Here is the compilation step that fails:
gcc -D__ASSEMBLY__ -O2 -fomit-frame-pointer -m32 -march=i686 -DNDEBUG -Wall -Wstrict-prototypes -Wno-unused-value -Wdeclaration-after-statement -nostdinc -fno-builtin -fno-common -fno-strict-aliasing -iwithprefix include -Werror -Wno-pointer-arith -pipe -I/export/txt/xen-unstable.hg-15369-sboot/xen/include -I/export/txt/xen-unstable.hg-15369-sboot/xen/include/asm-x86/mach-generic -I/export/txt/xen-unstable.hg-15369-sboot/xen/include/asm-x86/mach-default -msoft-float -fno-stack-protector -DCONFIG_X86_PAE=1 -g -D__XEN__ -DCONFIG_TXT -c head.S -o head.o
trampoline.S: Assembler messages:
trampoline.S:49: Error: junk `(trampoline_cpu_started)' after expression
trampoline.S:51: Error: junk `(idt_48)' after expression
trampoline.S:52: Error: junk `(gdt_48)' after expression
make[4]: *** [head.o] Error 1
make[4]: Leaving directory `/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86/boot'
make[3]: *** [/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86/boot/built_in.o] Error 2
make[3]: Leaving directory `/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86'
make[2]: *** [/export/txt/xen-unstable.hg-15369-sboot/xen/xen] Error 2
make[2]: Leaving directory `/export/txt/xen-unstable.hg-15369-sboot/xen'
make[1]: *** [install] Error 2
make[1]: Leaving directory `/export/txt/xen-unstable.hg-15369-sboot/xen'
make: *** [install-xen] Error 2
The lines of trampoline.S that trigger this error are not changed by the patches,
so I'm at a bit of a loss as to what is causing the error. Those three symbols
are inside a bootsym() macro which is itself defined in trampoline.S. The macro
is not complicated, and makes reference to a symbol from head.S (from whence
trampoline.S is included).
Help is greatly appreciated.
Thanks,
-Jon
Hi Joseph,
I compiled TXT patch with the latest unstable, and it works well. I
mean my machine boot wtih /sboot.gz in grub file, and Xen runs like
normal. Sweet!
Few questions:
- Now, how can I confirm that TXT is actully running on my machine?
- What to do next to take the advantage of TXT? Any application for it?
Thanks,
Jun
On 6/9/07, Cihula, Joseph <joseph.cihula@xxxxxxxxx> wrote:
Attached is a preliminary patch that adds Intel(r) Trusted Execution
Technology (Intel(r) TXT) support to Xen. Intel(r) TXT was formerly
known by the codename LaGrande Technology (LT).
This version of the patch (the previous version was posted last year)
re-factors the Intel(r) TXT code into a separate module/binary that is
passed as the 'kernel' to GRUB and which then launches Xen itself (after
having performed the measured launch).
This patch supports all of the Xen processor modes
(32bit/32bitPAE/64bit) and supports multi-core/thread systems. It will
run on either an Intel LT SDV3 or on the Intel(r) TXT TEP (Technology
Enabling Platform) from MPC.
Intel(r) TXT in Brief:
----------------------
o Provides dynamic root of trust for measurement (DRTM)
o DMA protection (on SDV3/TEP platforms only)
o Data protection in case of improper shutdown
For more information, see http://www.intel.com/technology/security/.
This site also has a link to the Intel(r) TXT Preliminary Architecture
Specification.
Overview of Patch Functionality:
--------------------------------
o Measured Launch. If the processor is detected as being TXT-capable
and enabled then the code will attempt to perform a measured launch. If
the measured launch process fails (processor is not capable, TXT is not
enabled, missing SINIT, corrupted data, etc.)) then it will fall-through
to a non-TXT boot of Xen.
o Teardown of measured environment. When Xen exits the measured
environment will be torn down properly.
o Reset data protection. Intel(r) TXT HW prevents access to secrets if
the system is reset without clearing them from memory (as part of a TXT
teardown). This code will support this by setting the flag indicating
that memory should be so protected during the measured launch and
clearing the flag just before teardown.
o Protection of TXT memory ranges. Intel(r) TXT reserves certain
regions of RAM for its use and also defines several MMIO regions. These
regions (excluding the TXT public configuration space) are protected
from use by any domains (including dom0).
Patch Contents:
---------------
txt-xen-0608_01-xen.patch - the changes to Xen for Intel(r) TXT support
txt-xen-0608_02-sboot.patch - the new sboot module that performs the
measured launch
Instructions for use:
---------------------
o By default, the functionality is disabled in the build. It can be
enabled by changing the INTEL_TXT flag to 'y' in Config.mk.
o The new sboot module must be added as the 'kernel' and xen made a
'module'. The SINIT AC module (available with SDV3 and TEP systems)
must be added to the grub.conf boot config as the last module, e.g.:
title Xen 3.1.0 w/ Intel(r) Trusted Execution Technology
kernel /sboot.gz
module /xen.gz dom0_mem=524288 com1=115200,8n1
module /vmlinuz-2.6.18-xen root=/dev/VolGroup00/LogVol00
ro
module /initrd-2.6.18-xen.img
module /lpg_sinit_20050831_pae.auth.bin
o Progress of the launch process is indicated via debug printk's to
COM1 (hardcoded). These appear before the normal "(XEN)" output and are
prefixed by "SBOOT:". The code (in early_printk.c) does not initialize
the COM port so this needs to be done by GRUB - grub.conf should have:
serial --speed=115200 --unit=0
terminal console serial
Interesting Items of Note:
--------------------------
o A Xen that is not compiled for Intel(r) TXT can still be launched by
sboot, however it will not protect any of the TXT memory nor sboot
itself. Further, it will not be able to use any threads or cores beyond
the BSP. And it will hang on reboot/shutdown.
o A Xen compiled for Intel(r) TXT can be used without sboot and will
simply detect that it was not launched in a measured environment and
behave as normal.
o The patch defines two new E820 types, E820_PROTECTED and
E820_MLE_SHARED. sboot will copy and alter the e820 table provided by
GRUB to "reserve" its own memory plus the TXT memory regions. These are
marked as E820_PROTECTED so that the patched Xen code can prevent them
from being assigned to dom0. The E820_MLE_SHARED type is for a single
page that sboot reserves for communication (sharing) with Xen. The
patched Xen code will look for this page when parsing the e820 table and
uses its presence as the indicator that a measured launch took place
(the e820 table is not altered if the measured launch fails for any
reason).
o sboot is always built 32bit and runs in protected mode without PAE or
paging enabled. sboot lives at (copies itself to) 0x70000. This seems
like a safe location so far, but is not a good long-term location. We'd
like to discuss moving Xen a little higher to allow sboot to live at
0x100000--this is a separate thread.
o Because a proper teardown requires turning off VMX on every
core/thread before executing GETSEC[SEXIT], some changes were made to
the Xen shutdown code. An initial commonization of the reboot and
shutdown routines was done so that this new code would only have to be
put in one place. Future patches will commonize the other routines in
Xen that shutdown or reboot the system, such that they will also perform
a teardown of the measured environment.
o The code requires that VT be enabled as well as TXT. This is because
the mechanism for bringing up the APs uses VMX to create a mini-VM in
order to trap on INIT-SIPI-SIPI.
o Currently only sboot is measured. We plan to extend this to xen and
dom0 in the future.
o The patch doesn't cap (extend with invalid value) the dynamic TPM
PCRs when the measured environment is torn down. This will be added
when we have a method for re-entering sboot on shutdown implemented.
o No DMA protection has been implemented in this patch. SDV3/TEP only
support the NoDMA table for DMA protection and this is superseded by
VT-d. VT-d support will be added shortly, though it will only be
available on new platforms.
Comments and feedback are very welcome. We'd especially like to see a
discussion about what changes are required for this code to be merged
into the -unstable tree.
We have many enhancements planned, as well as support for newer TXT
Software Development Platforms (SDPs).
Joseph Cihula
Jimmy Wei
Shane Wang
Zhai Edwin
Open Source Technology Center
Intel Corp.
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [RFC][PATCH][0/2] Intel(r) Trusted Execution Technology
2007-07-11 20:51 ` [RFC][PATCH][0/2] Intel(r) Trusted Execution Technology Jonathan M. McCune
@ 2007-07-12 13:40 ` Jonathan M. McCune
2007-07-12 16:54 ` Cihula, Joseph
0 siblings, 1 reply; 6+ messages in thread
From: Jonathan M. McCune @ 2007-07-12 13:40 UTC (permalink / raw)
To: xense-devel, xen-devel; +Cc: joseph.cihula, junkoi2004
Hello again,
I made a mistake counting line numbers. The macro that was causing
problems was SYM_TRAMP_PHYS, which was removed somewhere between
changeset 15331 and 15364. I have successfully built and used the TXT
patch with changeset 15331.
Sorry for the spam,
-Jon
Jonathan M. McCune wrote:
> Hi Joseph, Jun, Xen developers,
>
> I'm trying to get this patch to build, but I've encountered some
> difficulty. Applying the patch to today's tip results in three failures
> which I was able to correct manually. I also tried an older changeset
> (15369) from the day Jun reported success, and txt-xen-0608_01-xen.patch
> applied with `patch -p1 -F 3`. txt-xen-0608_02-sboot.patch applied
> successfully in both cases.
>
> I tried both gcc 4.1.2 and 3.4.6. The failure is the same both ways.
>
> If I disable the TXT patch (CONFIG_TXT ?= n in Config.mk), Xen builds
> successfully.
>
> Here is the compilation step that fails:
>
> gcc -D__ASSEMBLY__ -O2 -fomit-frame-pointer -m32 -march=i686 -DNDEBUG
> -Wall -Wstrict-prototypes -Wno-unused-value
> -Wdeclaration-after-statement -nostdinc -fno-builtin -fno-common
> -fno-strict-aliasing -iwithprefix include -Werror -Wno-pointer-arith
> -pipe -I/export/txt/xen-unstable.hg-15369-sboot/xen/include
> -I/export/txt/xen-unstable.hg-15369-sboot/xen/include/asm-x86/mach-generic
> -I/export/txt/xen-unstable.hg-15369-sboot/xen/include/asm-x86/mach-default
> -msoft-float -fno-stack-protector -DCONFIG_X86_PAE=1 -g -D__XEN__
> -DCONFIG_TXT -c head.S -o head.o
> trampoline.S: Assembler messages:
> trampoline.S:49: Error: junk `(trampoline_cpu_started)' after expression
> trampoline.S:51: Error: junk `(idt_48)' after expression
> trampoline.S:52: Error: junk `(gdt_48)' after expression
> make[4]: *** [head.o] Error 1
> make[4]: Leaving directory
> `/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86/boot'
> make[3]: ***
> [/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86/boot/built_in.o]
> Error 2
> make[3]: Leaving directory
> `/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86'
> make[2]: *** [/export/txt/xen-unstable.hg-15369-sboot/xen/xen] Error 2
> make[2]: Leaving directory `/export/txt/xen-unstable.hg-15369-sboot/xen'
> make[1]: *** [install] Error 2
> make[1]: Leaving directory `/export/txt/xen-unstable.hg-15369-sboot/xen'
> make: *** [install-xen] Error 2
>
> The lines of trampoline.S that trigger this error are not changed by the
> patches, so I'm at a bit of a loss as to what is causing the error.
> Those three symbols are inside a bootsym() macro which is itself defined
> in trampoline.S. The macro is not complicated, and makes reference to a
> symbol from head.S (from whence trampoline.S is included).
>
> Help is greatly appreciated.
>
> Thanks,
> -Jon
>
>
>
>
>
>
>
>
> Hi Joseph,
>
> I compiled TXT patch with the latest unstable, and it works well. I
> mean my machine boot wtih /sboot.gz in grub file, and Xen runs like
> normal. Sweet!
>
> Few questions:
> - Now, how can I confirm that TXT is actully running on my machine?
> - What to do next to take the advantage of TXT? Any application for it?
>
> Thanks,
> Jun
>
>
> On 6/9/07, Cihula, Joseph <joseph.cihula@xxxxxxxxx> wrote:
>
> Attached is a preliminary patch that adds Intel(r) Trusted Execution
> Technology (Intel(r) TXT) support to Xen. Intel(r) TXT was formerly
> known by the codename LaGrande Technology (LT).
>
> This version of the patch (the previous version was posted last year)
> re-factors the Intel(r) TXT code into a separate module/binary that is
> passed as the 'kernel' to GRUB and which then launches Xen itself (after
> having performed the measured launch).
>
> This patch supports all of the Xen processor modes
> (32bit/32bitPAE/64bit) and supports multi-core/thread systems. It will
> run on either an Intel LT SDV3 or on the Intel(r) TXT TEP (Technology
> Enabling Platform) from MPC.
>
>
> Intel(r) TXT in Brief:
> ----------------------
> o Provides dynamic root of trust for measurement (DRTM)
> o DMA protection (on SDV3/TEP platforms only)
> o Data protection in case of improper shutdown
>
> For more information, see http://www.intel.com/technology/security/.
> This site also has a link to the Intel(r) TXT Preliminary Architecture
> Specification.
>
>
> Overview of Patch Functionality:
> --------------------------------
> o Measured Launch. If the processor is detected as being TXT-capable
> and enabled then the code will attempt to perform a measured launch. If
> the measured launch process fails (processor is not capable, TXT is not
> enabled, missing SINIT, corrupted data, etc.)) then it will fall-through
> to a non-TXT boot of Xen.
>
> o Teardown of measured environment. When Xen exits the measured
> environment will be torn down properly.
>
> o Reset data protection. Intel(r) TXT HW prevents access to secrets if
> the system is reset without clearing them from memory (as part of a TXT
> teardown). This code will support this by setting the flag indicating
> that memory should be so protected during the measured launch and
> clearing the flag just before teardown.
>
> o Protection of TXT memory ranges. Intel(r) TXT reserves certain
> regions of RAM for its use and also defines several MMIO regions. These
> regions (excluding the TXT public configuration space) are protected
> from use by any domains (including dom0).
>
>
> Patch Contents:
> ---------------
> txt-xen-0608_01-xen.patch - the changes to Xen for Intel(r) TXT support
> txt-xen-0608_02-sboot.patch - the new sboot module that performs the
> measured launch
>
>
> Instructions for use:
> ---------------------
> o By default, the functionality is disabled in the build. It can be
> enabled by changing the INTEL_TXT flag to 'y' in Config.mk.
>
> o The new sboot module must be added as the 'kernel' and xen made a
> 'module'. The SINIT AC module (available with SDV3 and TEP systems)
> must be added to the grub.conf boot config as the last module, e.g.:
> title Xen 3.1.0 w/ Intel(r) Trusted Execution Technology
> kernel /sboot.gz
> module /xen.gz dom0_mem=524288 com1=115200,8n1
> module /vmlinuz-2.6.18-xen root=/dev/VolGroup00/LogVol00
> ro
> module /initrd-2.6.18-xen.img
> module /lpg_sinit_20050831_pae.auth.bin
>
> o Progress of the launch process is indicated via debug printk's to
> COM1 (hardcoded). These appear before the normal "(XEN)" output and are
> prefixed by "SBOOT:". The code (in early_printk.c) does not initialize
> the COM port so this needs to be done by GRUB - grub.conf should have:
> serial --speed=115200 --unit=0
> terminal console serial
>
>
> Interesting Items of Note:
> --------------------------
> o A Xen that is not compiled for Intel(r) TXT can still be launched by
> sboot, however it will not protect any of the TXT memory nor sboot
> itself. Further, it will not be able to use any threads or cores beyond
> the BSP. And it will hang on reboot/shutdown.
>
> o A Xen compiled for Intel(r) TXT can be used without sboot and will
> simply detect that it was not launched in a measured environment and
> behave as normal.
>
> o The patch defines two new E820 types, E820_PROTECTED and
> E820_MLE_SHARED. sboot will copy and alter the e820 table provided by
> GRUB to "reserve" its own memory plus the TXT memory regions. These are
> marked as E820_PROTECTED so that the patched Xen code can prevent them
> from being assigned to dom0. The E820_MLE_SHARED type is for a single
> page that sboot reserves for communication (sharing) with Xen. The
> patched Xen code will look for this page when parsing the e820 table and
> uses its presence as the indicator that a measured launch took place
> (the e820 table is not altered if the measured launch fails for any
> reason).
>
> o sboot is always built 32bit and runs in protected mode without PAE or
> paging enabled. sboot lives at (copies itself to) 0x70000. This seems
> like a safe location so far, but is not a good long-term location. We'd
> like to discuss moving Xen a little higher to allow sboot to live at
> 0x100000--this is a separate thread.
>
> o Because a proper teardown requires turning off VMX on every
> core/thread before executing GETSEC[SEXIT], some changes were made to
> the Xen shutdown code. An initial commonization of the reboot and
> shutdown routines was done so that this new code would only have to be
> put in one place. Future patches will commonize the other routines in
> Xen that shutdown or reboot the system, such that they will also perform
> a teardown of the measured environment.
>
> o The code requires that VT be enabled as well as TXT. This is because
> the mechanism for bringing up the APs uses VMX to create a mini-VM in
> order to trap on INIT-SIPI-SIPI.
>
> o Currently only sboot is measured. We plan to extend this to xen and
> dom0 in the future.
>
> o The patch doesn't cap (extend with invalid value) the dynamic TPM
> PCRs when the measured environment is torn down. This will be added
> when we have a method for re-entering sboot on shutdown implemented.
>
> o No DMA protection has been implemented in this patch. SDV3/TEP only
> support the NoDMA table for DMA protection and this is superseded by
> VT-d. VT-d support will be added shortly, though it will only be
> available on new platforms.
>
>
>
> Comments and feedback are very welcome. We'd especially like to see a
> discussion about what changes are required for this code to be merged
> into the -unstable tree.
>
> We have many enhancements planned, as well as support for newer TXT
> Software Development Platforms (SDPs).
>
>
> Joseph Cihula
> Jimmy Wei
> Shane Wang
> Zhai Edwin
>
> Open Source Technology Center
> Intel Corp.
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [RFC][PATCH][0/2] Intel(r) Trusted Execution Technology
2007-07-12 13:40 ` Jonathan M. McCune
@ 2007-07-12 16:54 ` Cihula, Joseph
0 siblings, 0 replies; 6+ messages in thread
From: Cihula, Joseph @ 2007-07-12 16:54 UTC (permalink / raw)
To: Jonathan M. McCune, xense-devel, xen-devel; +Cc: junkoi2004
Jonathan M. McCune <mailto:jonmccune@cmu.edu> scribbled on Thursday,
July 12, 2007 9:41 PM:
> Hello again,
>
> I made a mistake counting line numbers. The macro that was causing
> problems was SYM_TRAMP_PHYS, which was removed somewhere between
> changeset 15331 and 15364. I have successfully built and used the TXT
> patch with changeset 15331.
Glad to hear it. In the original patch I forgot to mention which
changeset it was based on (15200). I'm glad to see that it works on a
bit later version as well.
>
> Sorry for the spam,
> -Jon
>
>
> Jonathan M. McCune wrote:
>> Hi Joseph, Jun, Xen developers,
>>
>> I'm trying to get this patch to build, but I've encountered some
>> difficulty. Applying the patch to today's tip results in three
>> failures which I was able to correct manually. I also tried an
>> older changeset (15369) from the day Jun reported success, and
>> txt-xen-0608_01-xen.patch applied with `patch -p1 -F 3`.
>> txt-xen-0608_02-sboot.patch applied successfully in both cases.
>>
>> I tried both gcc 4.1.2 and 3.4.6. The failure is the same both ways.
>>
>> If I disable the TXT patch (CONFIG_TXT ?= n in Config.mk), Xen
>> builds successfully.
>>
>> Here is the compilation step that fails:
>>
>> gcc -D__ASSEMBLY__ -O2 -fomit-frame-pointer -m32 -march=i686 -DNDEBUG
>> -Wall -Wstrict-prototypes -Wno-unused-value
>> -Wdeclaration-after-statement -nostdinc -fno-builtin -fno-common
>> -fno-strict-aliasing -iwithprefix include -Werror -Wno-pointer-arith
>> -pipe -I/export/txt/xen-unstable.hg-15369-sboot/xen/include
>>
-I/export/txt/xen-unstable.hg-15369-sboot/xen/include/asm-x86/mach-gener
ic
>>
-I/export/txt/xen-unstable.hg-15369-sboot/xen/include/asm-x86/mach-defau
lt
>> -msoft-float -fno-stack-protector -DCONFIG_X86_PAE=1 -g -D__XEN__
>> -DCONFIG_TXT -c head.S -o head.o
>> trampoline.S: Assembler messages:
>> trampoline.S:49: Error: junk `(trampoline_cpu_started)' after
>> expression trampoline.S:51: Error: junk `(idt_48)' after expression
>> trampoline.S:52: Error: junk `(gdt_48)' after expression
>> make[4]: *** [head.o] Error 1
>> make[4]: Leaving directory
>> `/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86/boot'
>> make[3]: ***
>>
[/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86/boot/built_in.o]
>> Error 2 make[3]: Leaving directory
>> `/export/txt/xen-unstable.hg-15369-sboot/xen/arch/x86'
>> make[2]: *** [/export/txt/xen-unstable.hg-15369-sboot/xen/xen] Error
>> 2 make[2]: Leaving directory
>> `/export/txt/xen-unstable.hg-15369-sboot/xen' make[1]: *** [install]
>> Error 2
>> make[1]: Leaving directory
>> `/export/txt/xen-unstable.hg-15369-sboot/xen' make: ***
>> [install-xen] Error 2
>>
>> The lines of trampoline.S that trigger this error are not changed by
>> the patches, so I'm at a bit of a loss as to what is causing the
>> error. Those three symbols are inside a bootsym() macro which is
>> itself defined in trampoline.S. The macro is not complicated, and
>> makes reference to a symbol from head.S (from whence trampoline.S is
>> included).
>>
>> Help is greatly appreciated.
>>
>> Thanks,
>> -Jon
>>
>>
>>
>>
>>
>>
>>
>>
>> Hi Joseph,
>>
>> I compiled TXT patch with the latest unstable, and it works well. I
>> mean my machine boot wtih /sboot.gz in grub file, and Xen runs like
>> normal. Sweet!
>>
>> Few questions:
>> - Now, how can I confirm that TXT is actully running on my machine?
>> - What to do next to take the advantage of TXT? Any application for
>> it?
>>
>> Thanks,
>> Jun
>>
>>
>> On 6/9/07, Cihula, Joseph <joseph.cihula@xxxxxxxxx> wrote:
>>
>> Attached is a preliminary patch that adds Intel(r) Trusted Execution
>> Technology (Intel(r) TXT) support to Xen. Intel(r) TXT was formerly
>> known by the codename LaGrande Technology (LT).
>>
>> This version of the patch (the previous version was posted last year)
>> re-factors the Intel(r) TXT code into a separate module/binary that
>> is passed as the 'kernel' to GRUB and which then launches Xen itself
>> (after having performed the measured launch).
>>
>> This patch supports all of the Xen processor modes
>> (32bit/32bitPAE/64bit) and supports multi-core/thread systems. It
>> will run on either an Intel LT SDV3 or on the Intel(r) TXT TEP
>> (Technology Enabling Platform) from MPC.
>>
>>
>> Intel(r) TXT in Brief:
>> ----------------------
>> o Provides dynamic root of trust for measurement (DRTM)
>> o DMA protection (on SDV3/TEP platforms only)
>> o Data protection in case of improper shutdown
>>
>> For more information, see http://www.intel.com/technology/security/.
>> This site also has a link to the Intel(r) TXT Preliminary
>> Architecture Specification.
>>
>>
>> Overview of Patch Functionality:
>> --------------------------------
>> o Measured Launch. If the processor is detected as being
>> TXT-capable and enabled then the code will attempt to perform a
>> measured launch. If the measured launch process fails (processor is
>> not capable, TXT is not enabled, missing SINIT, corrupted data,
>> etc.)) then it will fall-through to a non-TXT boot of Xen.
>>
>> o Teardown of measured environment. When Xen exits the measured
>> environment will be torn down properly.
>>
>> o Reset data protection. Intel(r) TXT HW prevents access to
>> secrets if the system is reset without clearing them from memory (as
>> part of a TXT teardown). This code will support this by setting the
>> flag indicating that memory should be so protected during the
>> measured launch and clearing the flag just before teardown.
>>
>> o Protection of TXT memory ranges. Intel(r) TXT reserves certain
>> regions of RAM for its use and also defines several MMIO regions.
>> These regions (excluding the TXT public configuration space) are
>> protected from use by any domains (including dom0).
>>
>>
>> Patch Contents:
>> ---------------
>> txt-xen-0608_01-xen.patch - the changes to Xen for Intel(r) TXT
>> support txt-xen-0608_02-sboot.patch - the new sboot module that
>> performs the measured launch
>>
>>
>> Instructions for use:
>> ---------------------
>> o By default, the functionality is disabled in the build. It can be
>> enabled by changing the INTEL_TXT flag to 'y' in Config.mk.
>>
>> o The new sboot module must be added as the 'kernel' and xen made a
>> 'module'. The SINIT AC module (available with SDV3 and TEP systems)
>> must be added to the grub.conf boot config as the last module, e.g.:
>> title Xen 3.1.0 w/ Intel(r) Trusted Execution Technology
>> kernel /sboot.gz
>> module /xen.gz dom0_mem=524288 com1=115200,8n1
>> module /vmlinuz-2.6.18-xen
>> root=/dev/VolGroup00/LogVol00 ro module
>> /initrd-2.6.18-xen.img module
>> /lpg_sinit_20050831_pae.auth.bin
>>
>> o Progress of the launch process is indicated via debug printk's to
>> COM1 (hardcoded). These appear before the normal "(XEN)" output and
>> are prefixed by "SBOOT:". The code (in early_printk.c) does not
>> initialize the COM port so this needs to be done by GRUB - grub.conf
>> should have: serial --speed=115200 --unit=0
>> terminal console serial
>>
>>
>> Interesting Items of Note:
>> --------------------------
>> o A Xen that is not compiled for Intel(r) TXT can still be launched
>> by sboot, however it will not protect any of the TXT memory nor sboot
>> itself. Further, it will not be able to use any threads or cores
>> beyond the BSP. And it will hang on reboot/shutdown.
>>
>> o A Xen compiled for Intel(r) TXT can be used without sboot and will
>> simply detect that it was not launched in a measured environment and
>> behave as normal.
>>
>> o The patch defines two new E820 types, E820_PROTECTED and
>> E820_MLE_SHARED. sboot will copy and alter the e820 table provided
>> by GRUB to "reserve" its own memory plus the TXT memory regions.
>> These are marked as E820_PROTECTED so that the patched Xen code can
>> prevent them from being assigned to dom0. The E820_MLE_SHARED type
>> is for a single page that sboot reserves for communication (sharing)
>> with Xen. The patched Xen code will look for this page when parsing
>> the e820 table and uses its presence as the indicator that a
>> measured launch took place (the e820 table is not altered if the
>> measured launch fails for any reason).
>>
>> o sboot is always built 32bit and runs in protected mode without
>> PAE or paging enabled. sboot lives at (copies itself to) 0x70000.
>> This seems like a safe location so far, but is not a good long-term
>> location. We'd like to discuss moving Xen a little higher to allow
>> sboot to live at 0x100000--this is a separate thread.
>>
>> o Because a proper teardown requires turning off VMX on every
>> core/thread before executing GETSEC[SEXIT], some changes were made to
>> the Xen shutdown code. An initial commonization of the reboot and
>> shutdown routines was done so that this new code would only have to
>> be put in one place. Future patches will commonize the other
>> routines in Xen that shutdown or reboot the system, such that they
>> will also perform a teardown of the measured environment.
>>
>> o The code requires that VT be enabled as well as TXT. This is
>> because the mechanism for bringing up the APs uses VMX to create a
>> mini-VM in order to trap on INIT-SIPI-SIPI.
>>
>> o Currently only sboot is measured. We plan to extend this to xen
>> and dom0 in the future.
>>
>> o The patch doesn't cap (extend with invalid value) the dynamic TPM
>> PCRs when the measured environment is torn down. This will be added
>> when we have a method for re-entering sboot on shutdown implemented.
>>
>> o No DMA protection has been implemented in this patch. SDV3/TEP
>> only support the NoDMA table for DMA protection and this is
>> superseded by VT-d. VT-d support will be added shortly, though it
>> will only be available on new platforms.
>>
>>
>>
>> Comments and feedback are very welcome. We'd especially like to see
>> a discussion about what changes are required for this code to be
>> merged into the -unstable tree.
>>
>> We have many enhancements planned, as well as support for newer TXT
>> Software Development Platforms (SDPs).
>>
>>
>> Joseph Cihula
>> Jimmy Wei
>> Shane Wang
>> Zhai Edwin
>>
>> Open Source Technology Center
>> Intel Corp.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support
@ 2006-09-22 19:00 Cihula, Joseph
2006-09-23 17:01 ` [Xense-devel] " Leendert Van Doorn
0 siblings, 1 reply; 6+ messages in thread
From: Cihula, Joseph @ 2006-09-22 19:00 UTC (permalink / raw)
To: xen-devel, xense-devel
[-- Attachment #1: Type: text/plain, Size: 6267 bytes --]
This patch adds SMP support to the previous version. Since that has not
been merged I have included it in this patch. This should apply cleanly
to the tip. Below is the text of the original submittal, slightly
updated.
Attached is a preliminary patch that adds Intel(R) LaGrande Technology
(LT) (Safer Mode Extensions - SMX) support to Xen. While there are
still several enhancements needed for complete support, we feel that it
is sufficiently complete for an initial public posting to expose to the
community.
LaGrande Technology in Brief:
-----------------------------
o Provides dynamic root of trust for measurement (DRTM)
o DMA protection
o Data protection in case of improper shutdown
For more information on LT, see the Intel LaGrande Technology website:
http://www.intel.com/technology/security/.
This site also has a link to the LT preliminary specification (an
updated version that reflects the functionlaity of this code will be
available later this week).
The LT functionality this code adds is:
---------------------------------------
o Measured Launch. If the processor is detected as being LT-capable
and enabled then the code will attempt to perform a measured launch. If
the processor is (not capable) or (capable but not enabled) or (capable
and enabled but the launch process fails (missing SINIT, corrupted data,
etc.)) then it will fall-through to a non-LT boot.
o Teardown of measured environment. When Xen exits the LT environment
will be torn down properly.
o Reset data protection. LT HW prevents access to secrets if the
system is reset without clearing them from memory (as part of a LT
teardown). This code will support this by setting the flag indicating
that memory should be so protected during the measured launch and
clearing the flag just before teardown.
o Protection of LT memory ranges. LT reserves certain regions of RAM
for its use and also defines several MMIO regions. These regions are
protected from use by any domains (including dom0). Note that there a
sub-regions of the MMIO space that are left accessible to dom0 (LT
public configuration space, TPM localities 0,1).
Patch breakdown:
----------------
Config.mk - add INTEL_SMX build config
xen/Rules.mk - adds '-DCONFIG_SMX' compile flag if INTEL_SMX=y
xen/arch/x86/Makefile - add arch/x86/smx dir to build
xen/arch/x86/boot/x86_32.S - hook startup to launch LT
environmentxen/arch/x86/setup.c - initialize fixmap entries for LT
config reg space
xen/arch/x86/domain_build.c - protect LT private config space
xen/arch/x86/e820.c - support for E820_PROTECTED mem type
xen/arch/x86/hvm/vmx/vmx.c - support new LT/VMX IA32_FEATURE_CONTROL_MSR
flag
xen/arch/x86/mm.c - support for E820_PROTECTED mem type
xen/arch/x86/setup.c - hook to reserve LT RAM regions and initialize
fixmap entries for LT config reg space
xen/arch/x86/shutdown.c - hook shutdown to teardown LT environment
xen/common/domctl.c - prevent XEN_DOMCTL_iomem_permission from being
able to map LT private config space
xen/include/asm-x86/cpufeature.h - adds new SMX feature flag
xen/include/asm-x86/e820.h - export print_e820_memory_map()
xen/include/asm-x86/fixmap.h - adds fixmap entries for LT config reg
space
xen/include/asm-x86/msr.h - adds new VMX and SMX MSR flags
xen/include/asm-x86/processor.h - adds new CR4 SMX flag
xen/include/public/hvm/e820.h - add E820_PROTECTED mem type
xen/arch/x86/smx/Makefile - self explanatory
xen/arch/x86/smx/acmod.c - LT Authenticated Code (AC) module support fns
xen/arch/x86/smx/early_printk.c - serial printk() for early in boot
process
xen/arch/x86/smx/errors.c - error parsing/display fns
xen/arch/x86/smx/mtrrs.c - MTRR handling for AC module launch
xen/arch/x86/smx/smx.c - main LT/SMX fns and entry points
xen/arch/x86/smx/tpm.c - basic TPM support fns
xen/include/asm-x86/smx/* - headers for SMX/LT fns
This code has been developed and tested on Intel Software Development
Platform (SDP) 3 systems (available under NDA via the Intel Premier
Support channel). It will be updated to work with the LT Technology
Enabling Platform (TEP) that will be publicly available this fall.
Instructions for use:
---------------------
o By default, the functionality is disabled in the build. It can be
enabled by changing the INTEL_SMX flag to 'y' in Config.mk.
o The SINIT AC module (available with SDP3 systems) must be added to
the grub.conf boot config as the last module, e.g.:
...
module /initrd-2.6.16.13-xen.img
module /lpg_sinit_20050831_pae.auth.bin
o Progress of the LT launch process is indicated via debug printk's to
COM1 (hardcoded). These appear before the normal "(XEN)" output and are
prefixed by "SMX:". The code (in early_printk.c) does not initialize
the COM port so this needs to be done by GRUB - grub.conf should have:
serial --speed=115200 --unit=0
terminal console serial
Caveats / Notes:
----------------
o x86_64 is not supported yet (IA64 does not support LT at this time).
o The code only measures the hypervisor (and its command line), which
is not the complete TCB.
o It doesn't cap (extend with invalid value) the dynamic TPM PCRs when
the LT environment is torn down. Instead it disables the BIOS reboot
option so that any shutdown/reboot will have to reset the platform and
the TPM.
o TPM locality 2 is not protected. The defined behavior for access to
unpermitted localities is for reads to return 0xff's and writes to be
dropped. This will require mapping pages from locality 3 or 4 into the
locality 2 range.
o No DMA protection has been implemented in this patch. SDP3 only
supports the NoDMA table for DMA protection and this will be superseded
by VT-d. VT-d support for LT will be added after it is added for the
general case.
These limitations will be addressed in subsequent patches.
There was a presentation on the code at the Xen Summit. More
information on LT is available at
http://www.intel.com/technology/security/. Comments and feedback are
welcome at any time.
Joseph Cihula
(Linux) Software Security Architect
Open Source Technology Center
Intel Corp.
*** These opinions are not necessarily those of my employer ***
[-- Attachment #2: intel_lagrande_tech_smp.patch --]
[-- Type: application/octet-stream, Size: 116160 bytes --]
# HG changeset patch
# User root@jcihula-lt32.bj.intel.com
# Date 1158811157 -28800
# Node ID 0b39e8a32d1f15b910285dbe8d4b258d38424a77
# Parent 041be3f6b38e05f904d240630c18cadb1259317b
Adds Intel(R) LaGrande Technology (LT) Safer Mode Extensions (SMX) support
Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>
Signed-off-by: Burzin Daruwala <burzin.daruwala@intel.com>
diff -r 041be3f6b38e -r 0b39e8a32d1f Config.mk
--- a/Config.mk Tue Sep 19 14:26:47 2006 +0100
+++ b/Config.mk Thu Sep 21 11:59:17 2006 +0800
@@ -7,6 +7,13 @@ XEN_COMPILE_ARCH ?= $(shell uname -m
-e s/ppc/powerpc/)
XEN_TARGET_ARCH ?= $(XEN_COMPILE_ARCH)
XEN_TARGET_X86_PAE ?= n
+
+# LaGrande Technology (LT) Safer Mode Extensions (SMX)
+INTEL_SMX ?= n
+# TBD: fix for x86_64
+ifeq ($(x86_64),y)
+INTEL_SMX := n
+endif
# Tools to run on system hosting the build
HOSTCC = gcc
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/Rules.mk
--- a/xen/Rules.mk Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/Rules.mk Thu Sep 21 11:59:17 2006 +0800
@@ -57,6 +57,7 @@ CFLAGS-$(crash_debug) += -DCRASH_DEBUG
CFLAGS-$(crash_debug) += -DCRASH_DEBUG
CFLAGS-$(perfc) += -DPERF_COUNTERS
CFLAGS-$(perfc_arrays) += -DPERF_ARRAYS
+CFLAGS-$(INTEL_SMX) += -DCONFIG_SMX
ifneq ($(max_phys_cpus),)
CFLAGS-y += -DMAX_PHYS_CPUS=$(max_phys_cpus)
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/Makefile Thu Sep 21 11:59:17 2006 +0800
@@ -2,6 +2,7 @@ subdir-y += cpu
subdir-y += cpu
subdir-y += genapic
subdir-y += hvm
+subdir-$(INTEL_SMX) += smx
subdir-y += mm
subdir-y += oprofile
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/boot/x86_32.S Thu Sep 21 11:59:17 2006 +0800
@@ -9,6 +9,11 @@
.text
+#ifdef CONFIG_SMX
+ .global __start
+ .global _smx_wakeup
+#endif
+
ENTRY(start)
ENTRY(stext)
ENTRY(_stext)
@@ -43,7 +48,30 @@ 3: in %dx,%al
mov $7,%al
stosb # Write an attribute to the VGA framebuffer
jmp 1b
-
+
+#ifdef CONFIG_SMX
+/*
+ * entry point for GETSEC[WAKEUP]
+ */
+_smx_wakeup:
+ # get initial APIC ID for this processor
+ mov $0x01,%eax
+ xor %ebx,%ebx
+ cpuid
+ shr $24,%ebx
+ and $0xff,%ebx
+
+ /* wait for BSP to set _smp_resume w/ cpu # to bring up */
+spin_restart:
+ pause
+ cmp %ebx,(_smp_resume-__PAGE_OFFSET)
+ jne spin_restart
+
+ movl $0xA5A5A5A5, %ebx # Flag an SMP trampoline
+
+ jmp __start
+#endif
+
__start:
/* Set up a few descriptors: on entry only CS is guaranteed good. */
lgdt %cs:nopaging_gdt_descr-__PAGE_OFFSET
@@ -71,7 +99,16 @@ 1: lss stack_start-__PAGE_OFFSE
cmp $(SECONDARY_CPU_FLAG),%ebx
je start_paging
-
+
+#ifdef CONFIG_SMX
+ /* if this is a re-start due to SENTER then eax was cleared, so */
+ /* set it back */
+ cmp $0x01,(_senter_start-__PAGE_OFFSET)
+ jne skip_set
+ mov $0x2BADB002,%eax
+
+skip_set:
+#endif
/* Check for Multiboot bootloader */
cmp $0x2BADB002,%eax
jne not_multiboot
@@ -86,6 +123,16 @@ 1: lss stack_start-__PAGE_OFFSE
/* Save the Multiboot info structure for later use. */
add $__PAGE_OFFSET,%ebx
push %ebx
+
+#ifdef CONFIG_SMX
+ /* call measured launch code */
+ call start_smx
+
+ /* after SENTER, ebx is cleared, so start_smx returns saved value */
+ /* which we move back to ebx */
+ mov %eax,%ebx
+ push %ebx
+#endif
#ifdef CONFIG_X86_PAE
/* Initialize low and high mappings of all memory with 2MB pages */
@@ -200,7 +247,7 @@ ENTRY(stack_start)
.globl gdt
ALIGN
-
+
.word 0
idt_descr:
.word 256*8-1
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/domain_build.c Thu Sep 21 11:59:17 2006 +0800
@@ -26,6 +26,10 @@
#include <asm/desc.h>
#include <asm/i387.h>
#include <asm/shadow.h>
+#ifdef CONFIG_SMX
+#include <asm/smx/smx.h>
+#include <asm/smx/config_regs.h>
+#endif
#include <public/version.h>
#include <public/elfnote.h>
@@ -848,6 +852,25 @@ int construct_dom0(struct domain *d,
rc |= iomem_deny_access(dom0, mfn, mfn);
}
+#ifdef CONFIG_SMX
+ if ( smx_in_prot_env() ) {
+ /*
+ * remove permissions for LT private config register space and
+ * all of LT device memory except TPM localities 0,1
+ */
+
+ /* private config regs */
+ mfn = paddr_to_pfn(LT_PRIV_CONFIG_REGS_BASE);
+ rc |= iomem_deny_access(dom0, mfn, mfn + NR_LT_CONFIG_PAGES - 1);
+
+ /*
+ * TBD: access to non-available device memory needs to return 0xff
+ * so we will need to map a page of 0xff's to all ranges except for
+ * TPM localities 0,1
+ */
+ }
+#endif
+
BUG_ON(rc != 0);
return 0;
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/e820.c
--- a/xen/arch/x86/e820.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/e820.c Thu Sep 21 11:59:17 2006 +0800
@@ -31,7 +31,7 @@ static void __init add_memory_region(uns
}
} /* add_memory_region */
-static void __init print_e820_memory_map(struct e820entry *map, int entries)
+void __init print_e820_memory_map(struct e820entry *map, int entries)
{
int i;
@@ -51,6 +51,11 @@ static void __init print_e820_memory_map
case E820_NVS:
printk("(ACPI NVS)\n");
break;
+#ifdef CONFIG_SMX
+ case E820_PROTECTED:
+ printk("(PROTECTED)\n");
+ break;
+#endif
default: printk("type %u\n", map[i].type);
break;
}
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Sep 21 11:59:17 2006 +0800
@@ -777,7 +777,8 @@ int start_vmx(void)
if ( eax & IA32_FEATURE_CONTROL_MSR_LOCK )
{
- if ( (eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON) == 0x0 )
+ if ( (eax & (IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_OUT_SMX |
+ IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX) ) == 0x0)
{
printk("VMX disabled by Feature Control MSR.\n");
return 0;
@@ -787,7 +788,7 @@ int start_vmx(void)
{
wrmsr(IA32_FEATURE_CONTROL_MSR,
IA32_FEATURE_CONTROL_MSR_LOCK |
- IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON, 0);
+ IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_OUT_SMX, 0);
}
if ( !check_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/mm.c Thu Sep 21 11:59:17 2006 +0800
@@ -215,7 +215,12 @@ void arch_init_memory(void)
/* Any areas not specified as RAM by the e820 map are considered I/O. */
for ( i = 0, pfn = 0; i < e820.nr_map; i++ )
{
+#ifdef CONFIG_SMX
+ if ( e820.map[i].type != E820_RAM &&
+ e820.map[i].type != E820_PROTECTED )
+#else
if ( e820.map[i].type != E820_RAM )
+#endif
continue;
/* Every page from cursor to start of next RAM region is I/O. */
rstart_pfn = PFN_UP(e820.map[i].addr);
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/setup.c Thu Sep 21 11:59:17 2006 +0800
@@ -25,6 +25,9 @@
#include <asm/desc.h>
#include <asm/shadow.h>
#include <asm/e820.h>
+#ifdef CONFIG_SMX
+#include <asm/smx/smx.h>
+#endif
#include <acm/acm_hooks.h>
extern void dmi_scan_machine(void);
@@ -328,6 +331,25 @@ void __init __start_xen(multiboot_info_t
"(truncated length fields).\n");
max_page = init_e820(e820_raw, &e820_raw_nr);
+
+#ifdef CONFIG_SMX
+ if ( smx_in_prot_env() ) {
+ /*
+ * set the LT memory regions to be reserved/protected regardless of
+ * what BIOS may have set them to, since we don't trust BIOS
+ */
+
+ /* we can't let execution continue if the LT memory regions */
+ /* haven't been protected */
+ /* TBD: we could just teardown the protected environment */
+ if ( smx_reserve_memory(&e820) == -1 ) {
+ printk("SMX: e820 map too small to protect LT memory regions\n");
+ EARLY_FAIL();
+ }
+ printk(KERN_INFO "Physical RAM map after LT regions added:\n");
+ print_e820_memory_map(e820.map, e820.nr_map);
+ }
+#endif
modules_length = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;
@@ -559,6 +581,20 @@ void __init __start_xen(multiboot_info_t
if ( opt_watchdog )
watchdog_enable();
+#ifdef CONFIG_SMX
+ if ( smx_in_prot_env() ) {
+ /*
+ * initialize the fixmap entries for LT pub/priv config regs
+ */
+ for ( i = 0; i < NR_LT_CONFIG_PAGES; i++ ) {
+ set_fixmap_nocache(FIX_LT_PUB_CONFIG_REGS_BASE + i,
+ LT_PUB_CONFIG_REGS_BASE + i*PAGE_SIZE);
+ set_fixmap_nocache(FIX_LT_PRIV_CONFIG_REGS_BASE + i,
+ LT_PRIV_CONFIG_REGS_BASE + i*PAGE_SIZE);
+ }
+ }
+#endif
+
/* initialize access control security module */
acm_init(&initrdidx, mbi, initial_images_start);
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/shutdown.c
--- a/xen/arch/x86/shutdown.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/shutdown.c Thu Sep 21 11:59:17 2006 +0800
@@ -21,6 +21,9 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/mpspec.h>
+#ifdef CONFIG_SMX
+#include <asm/smx/smx.h>
+#endif
/* reboot_str: comma-separated list of reboot options. */
static char __initdata reboot_str[10] = "";
@@ -49,6 +52,20 @@ void machine_halt(void)
watchdog_disable();
console_start_sync();
smp_call_function(__machine_halt, NULL, 1, 0);
+
+#ifdef CONFIG_SMX
+ /* clear any sensitive info in BSP (if in protected env) */
+ smx_scrub_proc();
+
+ /* clear any sensitive info in memory (if in protected env) */
+ smx_scrub_mem();
+
+ hvm_disable();
+
+ /* teardown the protected environment (if any) */
+ smx_teardown(true);
+#endif
+
__machine_halt(NULL);
}
@@ -212,17 +229,42 @@ void machine_restart(char * __unused)
/* Send IPI to the boot CPU (logical cpu 0). */
on_selected_cpus(cpumask_of_cpu(0), (void *)machine_restart,
NULL, 1, 0);
+#ifndef CONFIG_SMX
+ printk("SMX: !!! should not be here\n");
+ /* we will rely on smp_send_stop() to shutdown VT/LT on APs */
for ( ; ; )
safe_halt();
+#endif
}
/*
* Stop all CPUs and turn off local APICs and the IO-APIC, so
* other OSs see a clean IRQ state.
*/
- smp_send_stop();
+ smp_send_stop(true);
disable_IO_APIC();
+
+#ifdef CONFIG_SMX
+ /* clear any sensitive info in BSP (if in protected env) */
+ smx_scrub_proc();
+
+ /* clear any sensitive info in memory (if in protected env) */
+ smx_scrub_mem();
+#endif
+
hvm_disable();
+
+#ifdef CONFIG_SMX
+ /* teardown the protected environment (if any) */
+ smx_teardown(true);
+
+ /* TBD: eventually cap PCRs and allow restart without reboot, but until */
+ /* then prevent restart without platform reboot that clears PCRs */
+ /* regardless of whether we actually launched the protected environment */
+ reboot_thru_bios = 0;
+
+ machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
+#endif
/* Rebooting needs to touch the page at absolute address 0. */
*((unsigned short *)__va(0x472)) = reboot_mode;
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/smp.c Thu Sep 21 11:59:17 2006 +0800
@@ -21,6 +21,9 @@
#include <asm/smpboot.h>
#include <asm/hardirq.h>
#include <asm/ipi.h>
+#ifdef CONFIG_SMX
+#include <asm/smx/smx.h>
+#endif
#include <mach_apic.h>
/*
@@ -307,14 +310,36 @@ static void stop_this_cpu (void *dummy)
local_irq_disable();
disable_local_APIC();
+ if ( dummy != NULL ) {
+ bool is_shutdown;
+
+ /* this routine (smp_send_stop()) is also used by gdb handler to */
+ /* temporarily stop APs; in that case we won't teardown VT */
+ is_shutdown = *(bool *)dummy;
+ if ( is_shutdown ) {
+#ifdef CONFIG_SMX
+ /* clear any sensitive info in processor (if in protected env) */
+ smx_scrub_proc();
+#endif
+ hvm_disable();
+#ifdef CONFIG_SMX
+ smx_teardown(false);
+#endif
+ }
+ }
+
for ( ; ; )
__asm__ __volatile__ ( "hlt" );
}
-void smp_send_stop(void)
-{
+void smp_send_stop(bool is_shutdown)
+{
+ static bool s_is_shutdown;
+
+ s_is_shutdown = is_shutdown;
+
/* Stop all other CPUs in the system. */
- smp_call_function(stop_this_cpu, NULL, 1, 0);
+ smp_call_function(stop_this_cpu, &s_is_shutdown, 1, 0);
local_irq_disable();
disable_local_APIC();
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/arch/x86/smpboot.c Thu Sep 21 11:59:17 2006 +0800
@@ -49,6 +49,9 @@
#include <asm/div64.h>
#include <asm/flushtlb.h>
#include <asm/msr.h>
+#ifdef CONFIG_SMX
+#include <asm/smx/smx.h>
+#endif
#include <mach_apic.h>
#include <mach_wakecpu.h>
#include <smpboot_hooks.h>
@@ -920,10 +923,24 @@ static int __devinit do_boot_cpu(int api
smpboot_setup_warm_reset_vector(start_eip);
+#ifdef CONFIG_SMX
+ /*
+ * once protected environment has been launched we cannot
+ * use INIT-SIPI-SIPI to restart APs, which are in spin loop
+ */
+ if ( smx_in_prot_env() ) {
+ /* wakeup_secondary() would do this */
+ atomic_set(&init_deasserted, 1);
+ boot_error = smx_rlp_restart(cpu);
+ }
+ else
+ boot_error = wakeup_secondary_cpu(apicid, start_eip);
+#else
/*
* Starting actual IPI sequence...
*/
boot_error = wakeup_secondary_cpu(apicid, start_eip);
+#endif
if (!boot_error) {
/*
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/common/domctl.c
--- a/xen/common/domctl.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/common/domctl.c Thu Sep 21 11:59:17 2006 +0800
@@ -19,6 +19,10 @@
#include <xen/iocap.h>
#include <xen/guest_access.h>
#include <asm/current.h>
+#ifdef CONFIG_SMX
+#include <asm/smx/smx.h>
+#include <asm/smx/config_regs.h>
+#endif
#include <public/domctl.h>
#include <acm/acm_hooks.h>
@@ -619,12 +623,45 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
case XEN_DOMCTL_iomem_permission:
{
struct domain *d;
+#ifdef CONFIG_SMX
+ unsigned long prot_mfn_s;
+ unsigned long prot_mfn_e;
+#endif
unsigned long mfn = op->u.iomem_permission.first_mfn;
unsigned long nr_mfns = op->u.iomem_permission.nr_mfns;
ret = -EINVAL;
if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */
break;
+
+#ifdef CONFIG_SMX
+ if ( smx_in_prot_env() ) {
+ /*
+ * we need to prohibit mapping LT private config registers and
+ * all of LT device memory except TPM localities 0,1
+ */
+
+ /* private config regs */
+ prot_mfn_s = paddr_to_pfn(LT_PRIV_CONFIG_REGS_BASE);
+ prot_mfn_e = prot_mfn_s + NR_LT_CONFIG_PAGES;
+ if ( mfn >= prot_mfn_s && mfn < prot_mfn_e ) {
+ printk("SMX: DOM0_IOMEM_PERMISSION attempt to access LT "
+ "region (mfn=%lx, nr_mfns=%lx)\n", mfn, nr_mfns);
+ break;
+ }
+ if ( mfn < prot_mfn_s && (mfn + nr_mfns) > prot_mfn_s ) {
+ printk("SMX: DOM0_IOMEM_PERMISSION attempt to access LT "
+ "region (mfn=%lx, nr_mfns=%lx)\n", mfn, nr_mfns);
+ break;
+ }
+
+ /*
+ * TBD: access to non-available device memory needs to return 0xff
+ * so we will need to map a page of 0xff's to all ranges except for
+ * TPM localities 0,1
+ */
+ }
+#endif
ret = -ESRCH;
d = find_domain_by_id(op->domain);
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/common/gdbstub.c
--- a/xen/common/gdbstub.c Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/common/gdbstub.c Thu Sep 21 11:59:17 2006 +0800
@@ -510,7 +510,7 @@ __trap_to_gdb(struct cpu_user_regs *regs
gdb_ctx->connected = 1;
}
- smp_send_stop();
+ smp_send_stop(false);
/* Try to make things a little more stable by disabling
interrupts while we're here. */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/cpufeature.h
--- a/xen/include/asm-x86/cpufeature.h Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/include/asm-x86/cpufeature.h Thu Sep 21 11:59:17 2006 +0800
@@ -76,6 +76,7 @@
#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */
#define X86_FEATURE_DSCPL (4*32+ 4) /* CPL Qualified Debug Store */
#define X86_FEATURE_VMXE (4*32+ 5) /* Virtual Machine Extensions */
+#define X86_FEATURE_SMXE (4*32+ 6) /* Safer Mode Extensions */
#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */
#define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */
#define X86_FEATURE_CID (4*32+10) /* Context ID */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/e820.h
--- a/xen/include/asm-x86/e820.h Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/include/asm-x86/e820.h Thu Sep 21 11:59:17 2006 +0800
@@ -11,6 +11,7 @@ struct e820map {
};
extern unsigned long init_e820(struct e820entry *, int *);
+extern void print_e820_memory_map(struct e820entry *, int);
extern struct e820map e820;
#endif /*__E820_HEADER*/
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/fixmap.h
--- a/xen/include/asm-x86/fixmap.h Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/include/asm-x86/fixmap.h Thu Sep 21 11:59:17 2006 +0800
@@ -16,6 +16,10 @@
#include <asm/apicdef.h>
#include <asm/acpi.h>
#include <asm/page.h>
+#ifdef CONFIG_SMX
+#include <asm/smx/smx.h>
+#include <asm/smx/config_regs.h>
+#endif
/*
* Here we define all the compile-time 'special' virtual
@@ -36,6 +40,11 @@ enum fixed_addresses {
FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
FIX_HPET_BASE,
FIX_CYCLONE_TIMER,
+#ifdef CONFIG_SMX
+ FIX_LT_PRIV_CONFIG_REGS_BASE,
+ FIX_LT_PUB_CONFIG_REGS_BASE = FIX_LT_PRIV_CONFIG_REGS_BASE + NR_LT_CONFIG_PAGES,
+ FIX_LT_CONFIG_REGS_END = FIX_LT_PUB_CONFIG_REGS_BASE + NR_LT_CONFIG_PAGES,
+#endif
__end_of_fixed_addresses
};
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/msr.h
--- a/xen/include/asm-x86/msr.h Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/include/asm-x86/msr.h Thu Sep 21 11:59:17 2006 +0800
@@ -116,9 +116,13 @@ static inline void wrmsrl(unsigned int m
#define MSR_IA32_VMX_CR0_FIXED1 0x487
#define MSR_IA32_VMX_CR4_FIXED0 0x488
#define MSR_IA32_VMX_CR4_FIXED1 0x489
-#define IA32_FEATURE_CONTROL_MSR 0x3a
-#define IA32_FEATURE_CONTROL_MSR_LOCK 0x1
-#define IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON 0x4
+
+#define IA32_FEATURE_CONTROL_MSR 0x3a
+#define IA32_FEATURE_CONTROL_MSR_LOCK 0x1
+#define IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX 0x2
+#define IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_OUT_SMX 0x4
+#define IA32_FEATURE_CONTROL_MSR_SENTER_PARAM_CTL 0x7f00
+#define IA32_FEATURE_CONTROL_MSR_ENABLE_SENTER 0x8000
/* AMD/K8 specific MSRs */
#define MSR_EFER 0xc0000080 /* extended feature register */
@@ -145,8 +149,10 @@ static inline void wrmsrl(unsigned int m
/* Intel MSRs. Some also available on other CPUs */
#define MSR_IA32_PLATFORM_ID 0x17
-#define MSR_MTRRcap 0x0fe
-#define MSR_IA32_BBL_CR_CTL 0x119
+#define MSR_MTRRcap 0x0fe
+#define MSR_IA32_MTRRCAP MSR_MTRRcap
+#define MSR_IA32_MTRR_DEF_TYPE 0x2ff
+#define MSR_IA32_BBL_CR_CTL 0x119
#define MSR_IA32_SYSENTER_CS 0x174
#define MSR_IA32_SYSENTER_ESP 0x175
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/include/asm-x86/processor.h Thu Sep 21 11:59:17 2006 +0800
@@ -80,6 +80,7 @@
#define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */
#define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
#define X86_CR4_VMXE 0x2000 /* enable VMX */
+#define X86_CR4_SMXE 0x4000 /* enable SMX */
/*
* Trap/fault mnemonics.
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/public/hvm/e820.h
--- a/xen/include/public/hvm/e820.h Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/include/public/hvm/e820.h Thu Sep 21 11:59:17 2006 +0800
@@ -12,6 +12,11 @@
#define E820_SHARED_PAGE 17
#define E820_XENSTORE 18
#define E820_BUFFERED_IO 19
+
+#ifdef CONFIG_SMX
+/* SMX extended E820 type */
+#define E820_PROTECTED 30 /* memory only available to hypervisor */
+#endif
/* E820 location in HVM virtual address space. */
#define E820_MAP_PAGE 0x00090000
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/xen/smp.h
--- a/xen/include/xen/smp.h Tue Sep 19 14:26:47 2006 +0100
+++ b/xen/include/xen/smp.h Thu Sep 21 11:59:17 2006 +0800
@@ -6,6 +6,7 @@
* Alan Cox. <alan@redhat.com>
*/
+#include <stdbool.h>
#include <xen/config.h>
#ifdef CONFIG_SMP
@@ -20,7 +21,7 @@
/*
* stops all CPUs but the current one:
*/
-extern void smp_send_stop(void);
+extern void smp_send_stop(bool is_shutdown);
extern void smp_send_event_check_mask(cpumask_t mask);
#define smp_send_event_check_cpu(cpu) \
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smx/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/smx/Makefile Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,6 @@
+obj-y += smx.o
+obj-y += mtrrs.o
+obj-y += acmod.o
+obj-y += tpm.o
+obj-y += errors.o
+obj-y += early_printk.o
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smx/acmod.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/smx/acmod.c Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,321 @@
+/*
+ * acmod.c: support functions for use of LT Authenticated Code (AC) Modules
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/flushtlb.h>
+#include <asm/smx/smx.h>
+#include <asm/smx/acmod.h>
+#include <asm/smx/mtrrs.h>
+
+#define DEBUG_SMX 1
+
+#undef printk
+#ifdef DEBUG_SMX
+#define printk early_serial_printk
+#else
+#define printk(_f , _a...)
+#endif
+
+#define ACM_MEM_TYPE_UC 0x0100
+#define ACM_MEM_TYPE_WC 0x0200
+#define ACM_MEM_TYPE_WT 0x1000
+#define ACM_MEM_TYPE_WP 0x2000
+#define ACM_MEM_TYPE_WB 0x4000
+
+/* this is arbitrary and can be increased when needed */
+#define MAX_SUPPORTED_ACM_VERSIONS 16
+
+typedef struct {
+ struct {
+ u32 mask;
+ u32 version;
+ } acm_versions[MAX_SUPPORTED_ACM_VERSIONS];
+ int n_versions;
+ u32 acm_max_size;
+ u32 acm_mem_types;
+ u32 senter_controls;
+} getsec_parameters_t;
+
+#define DEF_ACM_MAX_SIZE 0x8000
+#define DEF_ACM_VER_MASK 0xffffffff
+#define DEF_ACM_VER_SUPPORTED 0x00
+#define DEF_ACM_MEM_TYPES ACM_MEM_TYPE_UC
+#define DEF_SENTER_CTRLS 0x00
+
+static int get_parameters(getsec_parameters_t *params)
+{
+ unsigned long cr4;
+ u32 index, eax, ebx, ecx;
+ int param_type;
+
+ /* sanity check because GETSEC[PARAMETERS] will fail if not set */
+ cr4 = read_cr4();
+ if ( !(cr4 & X86_CR4_SMXE) ) {
+ printk("SMX: SMXE not enabled, can't read parameters\n");
+ return -1;
+ }
+
+ memset(params, 0, sizeof(*params));
+ params->acm_max_size = DEF_ACM_MAX_SIZE;
+ params->acm_mem_types = DEF_ACM_MEM_TYPES;
+ params->senter_controls = DEF_SENTER_CTRLS;
+ index = 0;
+ do {
+ __getsec_parameters(index++, ¶m_type, &eax, &ebx, &ecx);
+ /* the code generated for a 'switch' statement doesn't work in this */
+ /* environment, so use if/else blocks instead */
+ if ( param_type == 0 )
+ ;
+ else if ( param_type == 1 ) {
+ if ( params->n_versions == MAX_SUPPORTED_ACM_VERSIONS )
+ printk("SMX: number of supported ACM version exceeds "
+ "MAX_SUPPORTED_ACM_VERSIONS\n");
+ else {
+ params->acm_versions[params->n_versions].mask = ebx;
+ params->acm_versions[params->n_versions].version = ecx;
+ params->n_versions++;
+ }
+ }
+ else if ( param_type == 2 )
+ params->acm_max_size = eax & 0xffffffe0;
+ else if ( param_type == 3 )
+ params->acm_mem_types = eax & 0xffffffe0;
+ else if ( param_type == 4 )
+ params->senter_controls = (eax & 0x00007fff) >> 8;
+ else {
+ printk("SMX: unknown GETSEC[PARAMETERS] type: %d\n", param_type);
+ param_type = 0; /* set so that we break out of the loop */
+ }
+ } while ( param_type != 0 );
+
+ if ( params->n_versions == 0 ) {
+ params->acm_versions[0].mask = DEF_ACM_VER_MASK;
+ params->acm_versions[0].version = DEF_ACM_VER_SUPPORTED;
+ params->n_versions = 1;
+ }
+
+ return 0;
+}
+
+void dump_acm_hdr(acm_hdr_t *hdr, const char *mod_name)
+{
+ printk("SMX: AC module header dump for %s:\n",
+ (mod_name == NULL) ? "?" : mod_name);
+ printk("SMX: \ttype %x\n", hdr->module_type);
+ printk("SMX: \tlength %x\n", hdr->header_len);
+ printk("SMX: \tversion %x\n", hdr->header_ver);
+ printk("SMX: \tid %x\n", hdr->module_id);
+ printk("SMX: \tvendor %x\n", hdr->module_vendor);
+ printk("SMX: \tdate %08x\n", hdr->date);
+ printk("SMX: \tsize %x\n", hdr->size);
+ printk("SMX: \tentry point %08x:%08x\n", hdr->seg_sel, hdr->entry_point);
+}
+
+int is_acmod(void *acmod_base)
+{
+ acm_hdr_t *acm_hdr;
+
+ acm_hdr = (acm_hdr_t *)acmod_base;
+
+ /* just check module_type */
+ if ( acm_hdr->module_type != ACM_VALID_MOD_TYPE ) {
+ dump_acm_hdr(acm_hdr, (const char *)__pa("INVALID MODULE"));
+ return 0;
+ }
+ else
+ return 1;
+}
+
+/*
+ * Do some AC module sanity checks because any violations will cause
+ * an LT.RESET. Instead detect these, print a desriptive message,
+ * and skip SENTER/ENTERACCS
+ */
+int verify_acmod(void *acmod_base)
+{
+ acm_hdr_t *acm_hdr;
+ getsec_parameters_t params;
+ u32 size;
+
+ if ( !is_acmod(acmod_base) ) {
+ printk("SMX: not a valid AC module\n");
+ return -1;
+ }
+
+ acm_hdr = (acm_hdr_t *)acmod_base;
+ size = acm_hdr->size * 4; /* hdr size is in dwords, we want bytes */
+
+ /*
+ * AC mod must start on 4k page boundary
+ */
+
+ if ( (unsigned long)acmod_base & 0xfff ) {
+ printk("SMX: AC mod base not 4K aligned (%p)\n", acmod_base);
+ return -1;
+ }
+ printk("SMX: AC mod base alignment OK\n");
+
+ /* AC mod size must:
+ * - be multiple of 64
+ * - greater than ???
+ * - less than max supported size for this processor
+ */
+
+ if ( (size == 0) ||
+ ((size % 64) != 0) ) {
+ printk("SMX: AC mod size %x bogus\n", size);
+ return -1;
+ }
+
+ if ( get_parameters(¶ms) == -1 ) {
+ printk("SMX: get_parameters() failed\n");
+ return -1;
+ }
+
+ if ( size > params.acm_max_size ) {
+ printk("SMX: AC mod size too large: %x (max=%x)\n", size,
+ params.acm_max_size);
+ return -1;
+ }
+
+ printk("SMX: AC mod size OK\n");
+
+ /*
+ * perform checks on AC mod structure
+ */
+
+ /* print it for debugging */
+ dump_acm_hdr(acm_hdr, (const char *)__pa("SINIT"));
+
+ /* entry point is offset from base addr so make sure it is within module */
+ if ( acm_hdr->entry_point >= size ) {
+ printk("SMX: AC mod entry (%08x) >= AC mod size (%08x)\n",
+ acm_hdr->entry_point, size);
+ return -1;
+ }
+
+ if ( !acm_hdr->seg_sel || /* invalid selector */
+ (acm_hdr->seg_sel & 0x07) || /* LDT, PL!=0 */
+ (acm_hdr->seg_sel + 8 > acm_hdr->gdt_limit) ) {
+ printk("SMX: AC mod selector [%04x] bogus\n", acm_hdr->seg_sel);
+ return -1;
+ }
+
+ /* TBD: verify that AC mod matches with chipset */
+
+ return 0;
+}
+
+/*
+ * this must be done for each processor so that all have the same
+ * memory types
+ */
+int set_mtrrs_for_acmod(void *acmod_base, u32 acmod_size)
+{
+ unsigned long eflags;
+ unsigned long cr0, cr4;
+
+ /*
+ * need to do some things before we start changing MTRRs
+ *
+ * since this will modify some of the MTRRs, they should be saved first
+ * so that they can be restored once the AC mod is done
+ */
+
+ /* disable interrupts */
+ __save_flags(eflags);
+ __cli();
+
+ /* save CR0 then disable cache (CRO.CD=1, CR0.NW=0) */
+ cr0 = read_cr0();
+ write_cr0((cr0 & ~X86_CR0_NW) | X86_CR0_CD);
+
+ /* flush caches */
+ wbinvd();
+
+ /* save CR4 and disable global pages (CR4.PGE=0) */
+ cr4 = read_cr4();
+ write_cr4(cr4 & ~X86_CR4_PGE);
+
+ /* flush TLBs */
+ local_flush_tlb();
+
+ /* disable MTRRs */
+ set_all_mtrrs(false);
+
+ /*
+ * now set MTRRs for AC mod and rest of memory
+ */
+ set_mem_type(acmod_base, acmod_size, MTRR_TYPE_WRBACK);
+
+ /*
+ * now undo some of earlier changes and enable our new settings
+ */
+
+ /* flush caches */
+ wbinvd();
+
+ /* flush TLBs */
+ local_flush_tlb();
+
+ /* enable MTRRs */
+ set_all_mtrrs(true);
+
+ /* restore CR0 (cacheing) */
+ write_cr0(cr0);
+
+ /* restore CR4 (global pages) */
+ write_cr4(cr4);
+
+ /* enable interrupts */
+ __restore_flags(eflags);
+
+ return 0;
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smx/early_printk.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/smx/early_printk.c Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,254 @@
+/*
+ * early_printk.c: printk to serial for very early boot stages
+ *
+ * Copyright (c) 2006, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <asm/io.h>
+#include <xen/lib.h>
+#include <asm/processor.h>
+
+/*
+ * re-written parsing and formatting fns that don't rely on static data
+ */
+
+static int isdigit( int c )
+{
+ if ( c >= '0' && c <= '9' )
+ return 1;
+ else
+ return 0;
+}
+
+static char dec_digit( unsigned int i )
+{
+ return ('0' + i);
+}
+
+static char hex_digit( unsigned int i )
+{
+ if ( i < 10 )
+ return dec_digit( i );
+ return ('a' + (i-10));
+}
+
+static void fmt_val( char *str, size_t size, unsigned long long arg, int is_dec )
+{
+ char buf[128];
+ char *str2 = str;
+ char *s;
+
+ memset( buf, '\0', sizeof(buf) );
+
+ s = buf;
+ do {
+ if ( is_dec ) {
+ *s++ = dec_digit( (unsigned int)(arg % 10) );
+ arg = arg / 10;
+ }
+ else {
+ *s++ = hex_digit( (unsigned int)(arg & 0x0f) );
+ arg = arg >> 4;
+ }
+ } while ( arg != 0 );
+
+ /* buf is reversed string, so reverse copy */
+ s--;
+ while ( s >= buf && size > 0 ) {
+ *str2++ = *s--;
+ size--;
+ }
+}
+
+static void parse_fmt(char *str, size_t size, const char **pfmt, va_list *pap)
+{
+ const char *fmt = *pfmt;
+ int is_hex=0, is_dec=0, is_ptr=0, is_long=0, is_longlong=0, is_string=0;
+ int fill_size=0, fill_char=' ';
+ unsigned long long arg=0;
+ char buf[128];
+
+ fmt++; /* skip '%' */
+
+ /* width specifiers */
+ if ( isdigit( *fmt ) ) {
+ if ( *fmt == '0' ) {
+ fill_char = '0';
+ fmt++;
+ }
+ fill_size = simple_strtol(fmt, NULL, 10);
+ while ( isdigit( *fmt ) )
+ fmt++;
+ }
+
+ /* parse format specifier */
+ if ( *fmt == 'L' ) {
+ is_longlong = 1;
+ fmt++;
+ }
+ else if ( *fmt == 'l' ) {
+ is_long = 1;
+ fmt++;
+ }
+ if ( *fmt == 'd' )
+ is_dec = 1;
+ else if ( *fmt == 's' )
+ is_string = 1;
+ else if ( *fmt == 'p' )
+ is_ptr = 1;
+ else /* 'x' */
+ is_hex = 1;
+ fmt++;
+
+ /* get param converted to type */
+ if ( is_longlong )
+ arg = (unsigned long long)va_arg( *pap, unsigned long long );
+ else if ( is_long )
+ arg = (unsigned long long)va_arg( *pap, unsigned long );
+ else if ( is_ptr )
+ arg = (unsigned long long)(unsigned long)va_arg( *pap, void* );
+ else if ( is_string )
+ arg = (unsigned long long)(unsigned long)va_arg( *pap, char* );
+ else
+ arg = (unsigned long long)va_arg( *pap, unsigned int );
+
+ /* handle neg # */
+ if ( is_dec && (signed long long)arg < 0 ) {
+ *str++ = '-';
+ size--;
+ arg = (unsigned long long)(-(signed long long)arg);
+ }
+ /* and %p */
+ else if ( is_ptr && size > 2 ) {
+ *str++ = '0'; *str++ = 'x';
+ size -= 2;
+ }
+
+ memset( buf, '\0', sizeof(buf) );
+ if ( is_string )
+ strncpy( buf, (const char *)(unsigned long)arg, sizeof(buf)-1);
+ else
+ fmt_val( buf, sizeof(buf), arg, is_dec );
+
+ if ( fill_size < strlen( buf ) )
+ fill_size = 0;
+ else
+ fill_size = fill_size - strlen( buf );
+
+ if ( strlen( buf ) + fill_size < size ) {
+ memset( str, fill_char, fill_size );
+ strcpy( str + fill_size, buf );
+ }
+
+ /* move pfmt foreward */
+ *pfmt = fmt;
+}
+
+static int early_vscnprintf(char *str, size_t size, const char *fmt,
+ va_list ap)
+{
+ int n = 0;
+
+ while ( *fmt != '\0' && n < size-1 ) {
+ if ( *fmt == '%' ) {
+ char buf[256];
+ int sn;
+
+ memset( buf, '\0', sizeof(buf) );
+
+ parse_fmt( buf, sizeof(buf), &fmt, &ap );
+
+ sn = strlen( buf );
+ if ( sn > (size-n-1) )
+ sn = size - n - 1;
+ strncpy( str, buf, sn );
+ n += sn; str += sn;
+ }
+ else {
+ *str++ = *fmt++;
+ n++;
+ }
+ }
+ return n;
+}
+
+/*
+ * serial support from linux.../arch/x86_64/kernel/early_printk.c
+ *
+ * this code does not initialize the serial port and assumes COM1, so
+ * it will only display if GRUB has been configured for output to COM1
+ */
+
+#define early_serial_base 0x3f8 /* ttyS0 */
+
+#define XMTRDY 0x20
+
+#define DLAB 0x80
+
+#define TXR 0 /* Transmit register (WRITE) */
+#define RXR 0 /* Receive register (READ) */
+#define IER 1 /* Interrupt Enable */
+#define IIR 2 /* Interrupt ID */
+#define FCR 2 /* FIFO control */
+#define LCR 3 /* Line control */
+#define MCR 4 /* Modem control */
+#define LSR 5 /* Line Status */
+#define MSR 6 /* Modem Status */
+#define DLL 0 /* Divisor Latch Low */
+#define DLH 1 /* Divisor latch High */
+
+static int early_serial_putc(unsigned char ch)
+{
+ unsigned timeout = 0xffff;
+ while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
+ cpu_relax();
+ outb(ch, early_serial_base + TXR);
+ return timeout ? 0 : -1;
+}
+
+static void early_serial_write(const char *s, unsigned int n)
+{
+ while (*s && n-- > 0) {
+ early_serial_putc(*s);
+ if (*s == '\n')
+ early_serial_putc('\r');
+ s++;
+ }
+}
+
+void early_serial_printk(const char *fmt, ...)
+{
+ char buf[512];
+ int n;
+ va_list ap;
+
+ memset(buf, '\0', sizeof(buf));
+ va_start(ap, fmt);
+ n = early_vscnprintf(buf, 512, (const char *)__pa(fmt), ap);
+ early_serial_write(buf, n);
+ va_end(ap);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smx/errors.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/smx/errors.c Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,108 @@
+/*
+ * errors.c: display LT error codes
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <asm/smx/smx.h>
+#include <asm/smx/config_regs.h>
+
+
+#define DEBUG_SMX 1
+#undef printk
+#ifdef DEBUG_SMX
+#define printk early_serial_printk
+#else
+#define printk(_f , _a...) /**/
+#endif
+
+/*
+ * format of LT.ERRORCODE's type field when its src field is 0
+ */
+typedef union {
+ u16 _raw;
+ struct {
+ u16 type : 4; /* 0000=BIOS ACM, 0001=SINIT, 0010-1111=reserved */
+ u16 progress : 6;
+ u16 error : 4;
+ u16 reserved : 1;
+ };
+} acmod_error_t;
+
+void display_errors(void)
+{
+ lt_crash_t err;
+ lt_ests_t ests;
+ lt_e2sts_t e2sts;
+ acmod_error_t acmod_err;
+
+ /*
+ * display LT.CRASH error
+ */
+ err = (lt_crash_t)read_pub_config_reg(LTCR_LT_CRASH);
+ printk("SMX: LT.CRASH=%Lx\n", err._raw);
+
+ /* AC module error (don't know how to parse other errors) */
+ if ( err.valid && err.src == 0 ) {
+ acmod_err = (acmod_error_t)(u16)(err.type);
+ printk("SMX: AC module error : type=%x, progress=%02x, error=%x\n",
+ (u32)acmod_err.type, (u32)acmod_err.progress,
+ (u32)acmod_err.error);
+ }
+
+ /*
+ * display LT.ESTS error
+ */
+ ests = (lt_ests_t)read_pub_config_reg(LTCR_LT_ESTS);
+ printk("SMX: LT.ESTS=%Lx\n", ests._raw);
+
+ /*
+ * display LT.E2STS error
+ * - only valid if LT.WAKE-ERROR.STS set in LT.STS reg
+ */
+ if ( ests.lt_wake_error_sts ) {
+ e2sts = (lt_e2sts_t)read_pub_config_reg(LTCR_LT_E2STS);
+ printk("SMX: LT.E2STS=%Lx\n", e2sts._raw);
+ }
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smx/mtrrs.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/smx/mtrrs.c Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,204 @@
+/*
+ * mtrrs.c: LT support functions for manipulating MTRRs
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/msr.h>
+#include <asm/flushtlb.h>
+#include <asm/bitops.h>
+#include <asm/smx/smx.h>
+#include <asm/smx/mtrrs.h>
+
+#define DEBUG_SMX 1
+
+#undef printk
+#ifdef DEBUG_SMX
+#define printk early_serial_printk
+#else
+#define printk(_f , _a...)
+#endif
+
+void save_mtrrs(mtrr_state_t *saved_state)
+{
+ mtrr_cap_t mtrr_cap;
+ int ndx;
+
+ /* IA32_MTRR_DEF_TYPE MSR */
+ rdmsrl(MSR_IA32_MTRR_DEF_TYPE, saved_state->mtrr_def_type.raw);
+
+ /* number variable MTTRRs */
+ rdmsrl(MSR_IA32_MTRRCAP, mtrr_cap.raw);
+ if ( mtrr_cap.vcnt > MAX_VARIABLE_MTRRS ) {
+ /* print warning but continue saving what we can */
+ /* (set_mem_type() won't exceed the array, so we're safe doing this) */
+ printk("SMX: actual # var MTRRs (%d) > MAX_VARIABLE_MTRRS (%d)\n",
+ mtrr_cap.vcnt, MAX_VARIABLE_MTRRS);
+ saved_state->num_var_mtrrs = MAX_VARIABLE_MTRRS;
+ }
+ else
+ saved_state->num_var_mtrrs = mtrr_cap.vcnt;
+
+ /* physmask's and physbase's */
+ for ( ndx = 0; ndx < saved_state->num_var_mtrrs; ndx++ ) {
+ rdmsrl(MTRR_PHYS_MASK0_MSR + ndx*2,
+ saved_state->mtrr_physmasks[ndx].raw);
+ rdmsrl(MTRR_PHYS_BASE0_MSR + ndx*2,
+ saved_state->mtrr_physbases[ndx].raw);
+ }
+}
+
+void restore_mtrrs(mtrr_state_t *saved_state)
+{
+ int ndx;
+
+ /* TBD: we need to check these for validity (e.g. overlaping regions */
+ /* with invalid memory type combinations and variable MTRRs describing */
+ /* non-contiguous memory regions) */
+
+ /* IA32_MTRR_DEF_TYPE MSR */
+ wrmsrl(MSR_IA32_MTRR_DEF_TYPE, saved_state->mtrr_def_type.raw);
+
+ /* physmask's and physbase's */
+ for ( ndx = 0; ndx < saved_state->num_var_mtrrs; ndx++ ) {
+ wrmsrl(MTRR_PHYS_MASK0_MSR + ndx*2,
+ saved_state->mtrr_physmasks[ndx].raw);
+ wrmsrl(MTRR_PHYS_BASE0_MSR + ndx*2,
+ saved_state->mtrr_physbases[ndx].raw);
+ }
+}
+
+/*
+ * set the memory type for specified range (base to base+size)
+ * to mem_type and everything else to UC
+ */
+int set_mem_type(void *base, u32 size, u32 mem_type)
+{
+ int num_pages;
+ int ndx;
+ mtrr_def_type_t mtrr_def_type;
+ mtrr_cap_t mtrr_cap;
+ mtrr_physmask_t mtrr_physmask;
+ mtrr_physbase_t mtrr_physbase;
+
+ /*
+ * disable all fixed MTRRs
+ * set default type to UC
+ */
+ rdmsrl(MSR_IA32_MTRR_DEF_TYPE, mtrr_def_type.raw);
+ mtrr_def_type.fe = 0;
+ mtrr_def_type.type = MTRR_TYPE_UNCACHABLE;
+ wrmsrl(MSR_IA32_MTRR_DEF_TYPE, mtrr_def_type.raw);
+
+ /*
+ * initially disable all variable MTRRs (we'll enable the ones we use)
+ */
+ rdmsrl(MSR_IA32_MTRRCAP, mtrr_cap.raw);
+ for ( ndx = 0; ndx < mtrr_cap.vcnt; ndx++ ) {
+ rdmsrl(MTRR_PHYS_MASK0_MSR + ndx*2, mtrr_physmask.raw);
+ mtrr_physmask.v = 0;
+ wrmsrl(MTRR_PHYS_MASK0_MSR + ndx*2, mtrr_physmask.raw);
+ }
+
+ /*
+ * map all AC module pages as mem_type
+ */
+
+ num_pages = (size + PAGE_SIZE) >> PAGE_SHIFT;
+ ndx = 0;
+
+ printk("SMX: setting MTRRs for acmod: base=%p, size=%x, num_pages=%d\n",
+ base, size, num_pages);
+
+ while ( num_pages > 0 ) {
+ u32 pages_in_range;
+
+ /* set the base of the current MTRR */
+ rdmsrl(MTRR_PHYS_BASE0_MSR + ndx*2, mtrr_physbase.raw);
+ mtrr_physbase.base = (unsigned long)base >> PAGE_SHIFT;
+ mtrr_physbase.type = mem_type;
+ wrmsrl(MTRR_PHYS_BASE0_MSR + ndx*2, mtrr_physbase.raw);
+
+ /*
+ * calculate MTRR mask
+ * MTRRs can map pages in power of 2
+ * may need to use multiple MTRRS to map all of region
+ */
+ pages_in_range = 1 << (fls(num_pages) - 1);
+
+ rdmsrl(MTRR_PHYS_MASK0_MSR + ndx*2, mtrr_physmask.raw);
+ mtrr_physmask.mask = ~(pages_in_range - 1);
+ mtrr_physmask.v = 1;
+ wrmsrl(MTRR_PHYS_MASK0_MSR + ndx*2, mtrr_physmask.raw);
+
+ /* prepare for the next loop depending on number of pages
+ * We figure out from the above how many pages could be used in this
+ * mtrr. Then we decrement the count, increment the base,
+ * increment the mtrr we are dealing with, and if num_pages is
+ * still not zero, we do it again.
+ */
+ base += (pages_in_range * PAGE_SIZE);
+ num_pages -= pages_in_range;
+ ndx++;
+ if ( ndx == mtrr_cap.vcnt ) {
+ printk("SMX: exceeded number of var MTRRs when mapping range\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* enable/disable all MTRRs */
+void set_all_mtrrs(bool enable)
+{
+ mtrr_def_type_t mtrr_def_type;
+
+ rdmsrl(MSR_IA32_MTRR_DEF_TYPE, mtrr_def_type.raw);
+ mtrr_def_type.e = enable ? 1 : 0;
+ wrmsrl(MSR_IA32_MTRR_DEF_TYPE, mtrr_def_type.raw);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smx/smx.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/smx/smx.c Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,1062 @@
+/*
+ * smx.c: LT support functions and main entry points
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/multiboot.h>
+#include <xen/smp.h>
+#include <asm/processor.h>
+#include <asm/fixmap.h>
+#include <asm/page.h>
+#include <asm/msr.h>
+#include <asm/ipi.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/delay.h>
+#include <asm/smx/smx.h>
+#include <asm/smx/config_regs.h>
+#include <asm/smx/acmod.h>
+
+
+#define DEBUG_SMX 1
+
+extern void * _text; /* start of text section */
+extern void * __start; /* Xen entry point in x86_{32,64}.S */
+extern void * _smx_wakeup; /* RLP join address for GETSEC[WAKEUP] */
+
+/*
+ * flag to indicate when start_smx() is about to call SENTER
+ * used to determine if start_smx() is called first time or re-entry
+ * initialize to -1 so that it is not put in .bss (because .bss gets
+ * cleared each time before calling start_smx())
+ *
+ * use this instead of reading LT.STS.SENTER_DONE_STS config reg
+ * to allow for possiblity that we were called already in a protected
+ * environment; we need to know if our code launched it or not
+ */
+int _senter_start = -1;
+
+
+/*
+ * this is the structure whose addr we'll put in LT heap
+ */
+static mvmm_hdr_t _mvmm_hdr = {
+ /* fixed values for ver 1.0 */
+ guid : {0x9082ac5a, 0x74a7476f, 0xa2555c0f, 0x42b651cb},
+ length : sizeof(mvmm_hdr_t),
+ version : 0x00010000,
+ entry_point : 0x00000000, /* will be filled in later */
+ req_mem_size : 0, /* Xen doesn't use this */
+ features : 0x00000000
+};
+
+
+/*
+ * we need to save these values in order to use when modifying the e820 map
+ * to reserve the LT regions because this gets done after paging has been
+ * enabled but before the fixmap has been initialized with the LT config
+ * registers regions, so the current code for reading the registers directly
+ * won't work at that time
+ */
+static struct lt_memory_regions_t {
+ u64 heap_base, heap_size;
+ u64 sinit_base, sinit_size;
+ u64 nodma_base, nodma_size;
+} _lt_memory_regions;
+
+
+/*
+ * misc. data that needs to be measured along with the hypervisor because
+ * it affects hypervisor security
+ * more items may be added over time
+ * we need to give it a default value to prevent it from being in bss
+ */
+#define MAX_XEN_CMD_LINE 1024
+static struct misc_measured_data_t {
+ char cmdline[MAX_XEN_CMD_LINE];
+} _misc_measured_data = {""};
+
+
+/*
+ * MVMM Join structure for bringing RLPs out of SENTER wait state
+ */
+static mvmm_join_t _mvmm_join;
+
+
+/*
+ * cpu # for processor/core/thread to bring out of post GETSEC[WAKEUP]
+ * spin loop as part of SMP startup routine
+ */
+int _smp_resume = -1;
+
+
+/*
+ * # cpu's (APs)
+ * during boot will increment to reflect total #
+ * during shutdown will decrement until all have shutdown
+ */
+static atomic_t _nr_cpus;
+
+
+unsigned long smx_rlp_restart(int cpu)
+{
+ printk("SMX: restarting cpu %d\n", cpu);
+
+ /* we are assuming that all cpus we want to start will start */
+ atomic_inc(&_nr_cpus);
+
+ _smp_resume = cpu;
+
+ return 0;
+}
+
+/* clear processor state of any secrets */
+void smx_scrub_proc(void)
+{
+ /* only scrub if we setup the environment */
+ if ( _senter_start != 1 )
+ return;
+
+ /* we don't have any secrets to clear, however */
+ ;
+}
+
+void smx_scrub_mem(void)
+{
+ /* only peform mem scrub if we setup the environment */
+ if ( _senter_start != 1 )
+ return;
+
+ /* scrub any secrets by clearing the memory */
+ /* we don't have any secrets to scrub, however */
+ ;
+
+ /* flush chipset caches and buffers */
+ write_priv_config_reg(LTCR_LT_CMD_FLUSH_WB, 0x01);
+ printk("SMX: memory scubbed\n");
+
+ /* TBD: cap dynamic PCRs (17, 18) */
+
+ /* set LT.CMD.NO-SECRETS flag */
+ write_priv_config_reg(LTCR_LT_CMD_NO_SECRETS, 0x01);
+ read_priv_config_reg(LTCR_LT_E2STS); /* just a fence, so ignore return */
+ printk("SMX: secrets flag cleared\n");
+
+ /* close LT private config space */
+ read_priv_config_reg(LTCR_LT_E2STS); /* fence */
+ write_priv_config_reg(LTCR_LT_CMD_CLOSE_PRIVATE, 0x01);
+ read_pub_config_reg(LTCR_LT_E2STS); /* fence */
+ printk("SMX: private config space closed\n");
+}
+
+void smx_teardown(bool is_bsp)
+{
+ int timeout = 10;
+
+ /* only peform teardown if we setup the environment */
+ if ( _senter_start != 1 )
+ return;
+
+ /* APs increment _nr_cpus_shutting_down so that BSP can wait on it */
+ if ( !is_bsp ) {
+ atomic_dec(&_nr_cpus);
+ return;
+ }
+
+ /* BSP needs to wait until all APs have gone through shutdown (disabled */
+ /* VMX, etc.) before calling GETSEC[SEXIT] else will hang */
+ /* but we won't wait forever */
+ while ( atomic_read(&_nr_cpus) != 0 && timeout > 0 ) {
+ /* if not all APs have shutdown, wait a little */
+ udelay(5);
+ timeout--;
+ }
+
+ /* don't call SEXIT if not all APs have shutdown, since it will just */
+ /* fault anyway, and this will hang system */
+ if ( timeout != 0 ) {
+ /* call GETSEC[SEXIT] */
+ __getsec_sexit();
+ printk("SMX: GETSEC[SEXIT] protected environment torn down\n");
+
+ /* since we've torn down the environment, clear _senter_start flag */
+ _senter_start = -1;
+ }
+ else
+ printk("SMX: timeout before all APs shutdown; not doing SEXIT\n");
+}
+
+static void dump_sinit_mdrs(lt_heap_data_hdr_t *lt_heap_data_hdr)
+{
+ sinit_mvmm_data_v1_t *sinit_mvmm_data;
+ sinit_mdr_t *mdr;
+ int i;
+ static char *mem_types[] = {"GOOD", "SMM OVERLAY", "SMM NON-OVERLAY",
+ "PCIE CONFIG SPACE", "PROTECTED"};
+
+ if ( lt_heap_data_hdr->version != 0x01 ) {
+ printk("SMX: SINIT to MVMM data version incompatible (%x)\n",
+ lt_heap_data_hdr->version);
+ return;
+ }
+
+ sinit_mvmm_data = (sinit_mvmm_data_v1_t *)lt_heap_data_hdr;
+
+ for ( i = 0; i < sinit_mvmm_data->num_mdrs; i++ ) {
+ mdr = sinit_mvmm_data->mdrs + i;
+ printk("SMX: mdr[%d] :\n", i);
+ printk("SMX: \tstart = %08x:%08x\n", mdr->start_hi, mdr->start_lo);
+ printk("SMX: \tlength = %x%x\n", mdr->length_hi, mdr->length_lo);
+ if ( mdr->mem_type < sizeof(mem_types)/sizeof(mem_types[0]) )
+ printk("SMX: \tmem_type = %s\n", mem_types[mdr->mem_type]);
+ else
+ printk("SMX: \tmem_type = %d\n", (int)mdr->mem_type);
+ }
+}
+
+static int insert_after_region(struct e820map *e820, int pos,
+ uint64_t addr, uint64_t size,
+ uint32_t type)
+{
+ int i;
+
+ /* no more room */
+ if ( e820->nr_map + 1 >= E820MAX )
+ return -1;
+
+ /* shift (copy) everything up one entry */
+ for (i = e820->nr_map - 1; i > pos; i--)
+ e820->map[i+1] = e820->map[i];
+
+ /* now add our entry */
+ e820->map[pos+1].addr = addr;
+ e820->map[pos+1].size = size;
+ e820->map[pos+1].type = type;
+
+ e820->nr_map++;
+
+ return 0;
+}
+
+static void remove_region(struct e820map *e820, int pos)
+{
+ int i;
+
+ /* shift (copy) everything down one entry */
+ for (i = pos; i < e820->nr_map - 1; i++)
+ e820->map[i] = e820->map[i+1];
+
+ e820->nr_map--;
+}
+
+static int separate_region(struct e820map *e820, uint64_t new_addr,
+ uint64_t new_size)
+{
+ int i;
+ uint64_t addr, size;
+ uint32_t type;
+
+ if ( new_size == 0 )
+ return 0;
+
+ /* find where our region belongs in the table and insert it */
+ for (i = 0; i < e820->nr_map; i++) {
+ addr = e820->map[i].addr;
+ size = e820->map[i].size;
+ type = e820->map[i].type;
+ /* is our region at the beginning of the current map region? */
+ if ( new_addr == addr ) {
+ if ( insert_after_region(e820, i-1, new_addr, new_size,
+ E820_PROTECTED) == -1 )
+ return -1;
+ break;
+ }
+ /* are we w/in the current map region? */
+ else if ( new_addr > addr && new_addr < (addr + size) ) {
+ if ( insert_after_region(e820, i, new_addr, new_size,
+ E820_PROTECTED) == -1 )
+ return -1;
+ /* fixup current region */
+ e820->map[i].size = new_addr - e820->map[i].addr;
+ i++; /* adjust to always be that of our region */
+ /* insert a copy of current region (before adj) after us so */
+ /* that rest of code can be common with previous case */
+ if ( insert_after_region(e820, i, addr, size, type) == -1 )
+ return -1;
+ break;
+ }
+ /* is our region in a gap in the map? */
+ else if ( addr > new_addr ) {
+ if ( insert_after_region(e820, i-1, new_addr, new_size,
+ E820_PROTECTED) == -1 )
+ return -1;
+ break;
+ }
+ }
+ /* if we reached the end of the map without finding an overlapping */
+ /* region, insert us at the end (note that this test won't trigger */
+ /* for the second case above because the insert() will have incremented */
+ /* nr_map and so i++ will still be less) */
+ if ( i == e820->nr_map ) {
+ if ( insert_after_region(e820, i-1, new_addr, new_size,
+ E820_PROTECTED) == -1 )
+ return -1;
+ return 0;
+ }
+
+ i++; /* move to entry after our inserted one (we're not at end yet) */
+
+ /* did we split the (formerly) previous region? */
+ if ( (new_addr >= e820->map[i].addr) &&
+ ((new_addr + new_size) < (e820->map[i].addr + e820->map[i].size)) ) {
+ /* then adjust the current region (adj size first) */
+ e820->map[i].size = (e820->map[i].addr + e820->map[i].size) -
+ (new_addr + new_size);
+ e820->map[i].addr = new_addr + new_size;
+ return 0;
+ }
+
+ /* if our region completely covers any existing regions, delete them */
+ while ( (i < e820->nr_map) && ((new_addr + new_size) >=
+ (e820->map[i].addr + e820->map[i].size)) )
+ remove_region(e820, i);
+
+ /* finally, if our region partially overlaps an existing region, */
+ /* then truncate the exiting region */
+ if ( (i < e820->nr_map) && ((new_addr + new_size) > e820->map[i].addr) )
+ e820->map[i].addr = new_addr + new_size;
+
+ return 0;
+}
+
+int smx_reserve_memory(struct e820map *e820)
+{
+ struct lt_memory_regions_t *lt_mem_regions;
+ u64 base, size;
+ lt_heap_t *lt_heap;
+ lt_heap_data_hdr_t *lt_heap_data_hdr;
+
+ /*
+ * LT has three regions of RAM that need to be reserved for use by only the
+ * hypervisor; not even dom0 should have access:
+ * LT heap, SINIT AC module, NoDMA table
+ */
+
+ lt_mem_regions = (struct lt_memory_regions_t *)&_lt_memory_regions;
+
+ /* LT heap */
+ base = lt_mem_regions->heap_base;
+ size = lt_mem_regions->heap_size;
+ printk("SMX: protecting LT heap (%Lx - %Lx) in e820 table\n", base,
+ (base + size - 1));
+ if ( separate_region(e820, base, size) == -1 )
+ return -1;
+
+ /* SINIT */
+ base = lt_mem_regions->sinit_base;
+ size = lt_mem_regions->sinit_size;
+ printk("SMX: protecting SINIT (%Lx - %Lx) in e820 table\n", base,
+ (base + size - 1));
+ if ( separate_region(e820, base, size) == -1 )
+ return -1;
+
+ /* NoDMA table */
+ base = lt_mem_regions->nodma_base;
+ size = lt_mem_regions->nodma_size;
+ printk("SMX: protecting NoDMA table (%Lx - %Lx) in e820 table\n", base,
+ (base + size - 1));
+ if ( separate_region(e820, base, size) == -1 )
+ return -1;
+
+ /* TBD: we will need to parse sinit_mvmm_data.mdrs records and ensure */
+ /* that we don't use inappropriate memory for domains */
+ /* (we can't use get_heap() because fixmap isn't setup yet) */
+ lt_heap = (lt_heap_t *)(unsigned long)lt_mem_regions->heap_base;
+ lt_heap_data_hdr = get_sinit_mvmm_data_start(lt_heap);
+ dump_sinit_mdrs(lt_heap_data_hdr);
+
+ return 0;
+}
+
+/* put after teardown fns because those use std printk() */
+#undef printk
+#ifdef DEBUG_SMX
+#define printk early_serial_printk
+#else
+#define printk(_f , _a...) /**/
+#endif
+
+
+bool smx_in_prot_env(void)
+{
+ return (_senter_start != 1) ? false : true;
+}
+
+u32 config_reg_base_addr(u32 base_phys)
+{
+ unsigned long cr0;
+ int idx;
+
+ cr0 = read_cr0();
+
+ /* if paging has been enabled then must use fixmap */
+ if ( cr0 & X86_CR0_PG ) {
+ idx = (base_phys - LT_PUB_CONFIG_REGS_BASE) >> PAGE_SHIFT;
+ return fix_to_virt(FIX_LT_PUB_CONFIG_REGS_BASE + idx);
+ }
+ /* else can use physical addr directly */
+ else
+ return base_phys;
+}
+
+/*
+ * sets up LT heap
+ */
+static lt_heap_t *setup_lt_heap(void *ptab_base)
+{
+ lt_heap_t *lt_heap;
+ os_mvmm_data_v1_t *os_mvmm_data;
+ os_sinit_data_v1_t *os_sinit_data;
+
+ lt_heap = get_lt_heap();
+
+ /*
+ * BIOS to OS/loader data already setup by BIOS
+ */
+
+ /*
+ * OS/loader to MVMM data
+ */
+ os_mvmm_data = (os_mvmm_data_v1_t *)get_os_mvmm_data_start(lt_heap);
+ *get_data_size_addr(os_mvmm_data) = sizeof(*os_mvmm_data) + sizeof(u64);
+ memset(os_mvmm_data, 0, sizeof(*os_mvmm_data));
+ os_mvmm_data->version = 0x01;
+
+ /*
+ * OS/loader to SINIT data
+ */
+ os_sinit_data = (os_sinit_data_v1_t *)get_os_sinit_data_start(lt_heap);
+ *get_data_size_addr(os_sinit_data) = sizeof(*os_sinit_data) + sizeof(u64);
+ memset(os_sinit_data, 0, sizeof(*os_sinit_data));
+ os_sinit_data->version = 0x01;
+ /* this is phys addr */
+ os_sinit_data->mvmm_ptab_lo = (u32)ptab_base;
+ os_sinit_data->mvmm_ptab_hi = 0;
+ os_sinit_data->mvmm_size_lo = (u32)__pa(&_end) - (u32)__pa(&_text);
+ os_sinit_data->mvmm_size_hi = 0;
+ /* this is linear addr (offset from MVMM base) of mvmm header */
+ os_sinit_data->mvmm_hdr_base_lo = (u32)&_mvmm_hdr - (u32)&_text;
+ os_sinit_data->mvmm_hdr_base_hi = 0;
+
+ /*
+ * SINIT to MVMM data will be setup by SINIT
+ */
+
+ return lt_heap;
+}
+
+/* MVMM page table can only contain 4k pages */
+#define MVMM_PAGE_SHIFT 12
+#define MVMM_PAGE_SIZE (1L << PAGE_SHIFT)
+#define MVMM_PAGE_MASK (~(PAGE_SIZE-1))
+
+/* LT uses PAE format page table for MVMM page table */
+typedef u64 mvmm_pfn_t;
+
+#define MVMM_NUM_PTES (MVMM_PAGE_SIZE / sizeof(mvmm_pfn_t))
+
+/* page dir/table entry is phys addr + P + R/W + PWT */
+#define MVMM_MAKE_PDTE(addr) (((u64)(unsigned long)addr & MVMM_PAGE_MASK) \
+ | 0x01)
+
+/* page directory/table */
+typedef struct {
+ mvmm_pfn_t pdtes[MVMM_NUM_PTES];
+} mvmm_pg_dirtab_t;
+
+/* MVMM page table */
+typedef struct {
+ mvmm_pfn_t pg_dir_ptr[4];
+} mvmm_ptab_t;
+
+static void *build_mvmm_pagetable(multiboot_info_t *mbi)
+{
+ void *mvmm_addr, *mvmm_end;
+ void *next_ptab_pg; /* page to use for next page dir or page table */
+ mvmm_ptab_t *ptab_base;
+ u32 ptab_size, mvmm_size;
+ mvmm_pfn_t *pde, *pte;
+ mvmm_pg_dirtab_t *pd, *pt;
+ struct misc_measured_data_t *misc_data;
+
+ /*
+ * requirements of MVMM page tables:
+ * - must be in PAE format
+ * - 4k pages
+ * - breadth-first traversal must have increasing phys addrs
+ * - all addrs must be: <640k or >1M, not overlap w/ device mem, <top mem
+ * - page dirs must be in lower phys addr than page tables
+ * - page dir ptr table must be in lower phys addr than page dirs
+ *
+ * phys addr of page dir and MVMM size stored in LT heap
+ * xen hypervisor already contig and in increasing phys addr order
+ */
+ /* TBD: need to add dom0 kernel, dom0 initrd, ACM policy */
+
+ mvmm_addr = (void *)__pa(&_text);
+ mvmm_end = (void *)__pa(&_end);
+ mvmm_size = mvmm_end - mvmm_addr;
+ printk("SMX: MVMM start=%p, end=%p, size=%x\n", mvmm_addr, mvmm_end,
+ mvmm_size);
+
+#define BAD_MVMM_MEM_LO 0x0a0000
+#define BAD_MVMM_MEM_HI 0x100000
+ /* MVMM can't be in [640k, 1M) (it's sufficient just to check mvmm_addr */
+ /* against 1M, since the hypervisor wouldn't fit below 640K anyway) */
+ if ( (unsigned long)mvmm_addr < BAD_MVMM_MEM_HI ) {
+ printf("SMX: MVMM spans [640k, 1M) region which is not permitted\n");
+ return NULL;
+ }
+ /* nor can it be >4GB */
+ if ( (unsigned long)mvmm_end > 0xffffffff ) {
+ printf("SMX: MVMM is above 4GB which is not permitted\n");
+ return NULL;
+ }
+
+ /* make copy of misc. data that needs to be measured */
+ misc_data = (struct misc_measured_data_t *)__pa(&_misc_measured_data);
+ memset(misc_data->cmdline, 0, MAX_XEN_CMD_LINE);
+ strncpy( misc_data->cmdline, (char *)mbi->cmdline, MAX_XEN_CMD_LINE-1);
+
+ /* calculate size needed for page table */
+ ptab_size = (mvmm_size >> MVMM_PAGE_SHIFT) /* # pages = # pte's */
+ * sizeof(mvmm_pfn_t) /* => size of pte's */
+ + MVMM_PAGE_SIZE /* + 1 page dir */
+ + MVMM_PAGE_SIZE; /* + page dir ptr table */
+ /* round up to nearest page */
+ ptab_size = (ptab_size + MVMM_PAGE_SIZE) & MVMM_PAGE_MASK;
+
+ /* place ptab_base below BAD_MVMM_MEM_LO */
+ ptab_base = (void *)((BAD_MVMM_MEM_LO - ptab_size) & MVMM_PAGE_MASK);
+
+ memset(ptab_base, 0, MVMM_PAGE_SIZE);
+ printk("SMX: ptab_size=%x, ptab_base=%p\n", ptab_size, ptab_base);
+
+ /* only 1 page dir */
+ pd = (void *)ptab_base + MVMM_PAGE_SIZE;
+ memset(pd, 0, MVMM_PAGE_SIZE);
+
+ /* only use first entry in page dir ptr table */
+ ptab_base->pg_dir_ptr[0] = MVMM_MAKE_PDTE(pd);
+ /* printk("SMX: pg_dir_ptr[0]=%Lx, pd=%p\n", ptab_base->pg_dir_ptr[0],
+ pd); */
+
+ next_ptab_pg = (void *)pd + MVMM_PAGE_SIZE;
+
+ /* outer loop is page dir (will break when reach end of MVMM) */
+ for ( pde = pd->pdtes; pde < (pd->pdtes + MVMM_PAGE_SIZE); pde++ ) {
+ pt = next_ptab_pg;
+ memset(pt, 0, MVMM_PAGE_SIZE);
+
+ next_ptab_pg += PAGE_SIZE;
+
+ *pde = MVMM_MAKE_PDTE(pt);
+ /* printk("SMX: *pde=%Lx, pt=%p\n", *pde, pt); */
+
+ /* inner loop is page table (will break when reach end of MVMM) */
+ for ( pte = pt->pdtes; pte < (pt->pdtes + MVMM_PAGE_SIZE); pte++ ) {
+ *pte = MVMM_MAKE_PDTE(mvmm_addr);
+ /* printk("SMX: *pte=%Lx, mvmm_addr=%p\n", *pte, mvmm_addr); */
+
+ mvmm_addr += PAGE_SIZE;
+
+ /* last page added to table, so exit all loops */
+ if ( mvmm_addr >= mvmm_end )
+ goto table_done;
+ }
+ }
+ printk("SMX: MVMM size exceeded page table size--not possible!\n");
+ return NULL;
+
+ table_done:
+ return ptab_base;
+}
+
+/*
+ * Verify that processor is LT-capable and enabled.
+ * Do some processor-related sanity checks here before calling SENTER
+ * because any violations will cause an LT.RESET. Instead detect these,
+ * print a desriptive message, and skip LT protected launch.
+ */
+static int verify_processor_state(void)
+{
+ unsigned long eflags;
+ unsigned long cr0, cr4;
+ u32 eax, edx;
+ unsigned int cpu_capability[NCAPINTS];
+ capabilities_t cap;
+ lt_sts_t sts;
+ u64 mcg_cap, mcg_stat;
+ int i;
+
+ /*
+ * verify processor is capable of SMX
+ */
+ /* Xen only fills x86_capability word 0 */
+ cpu_capability[4] = cpuid_ecx(1);
+ if ( !(test_bit(X86_FEATURE_SMXE, cpu_capability)) ) {
+ printk("SMX: CPU does not support SMX\n");
+ return -1;
+ }
+
+ printk("SMX: processor is SMX-capable\n");
+
+ /* no need to verify VMX capability at this time */
+
+ /*
+ * ensure that SMX is enabled by feature control MSR
+ *
+ * enable VMX after SMX but disable VMX outside of SMX
+ * - this is most secure launch since it prevents full (transparent)
+ * virtualzation if LT launch is disabled or fails
+ * - BIOS or bootloader should really have set and locked it
+ */
+
+ rdmsr(IA32_FEATURE_CONTROL_MSR, eax, edx);
+
+ if ( eax & IA32_FEATURE_CONTROL_MSR_LOCK ) {
+ printk("SMX: IA32_FEATURE_CONTROL_MSR is locked (%x)\n", eax);
+ printk("SMX: \tIA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX=%d\n",
+ (eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX) ? 1 : 0);
+ printk("SMX: \tIA32_FEATURE_CONTROL_MSR_ENABLE_VMX_OUT_SMX=%d\n",
+ (eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_OUT_SMX) ? 1 : 0);
+ if ( (eax & IA32_FEATURE_CONTROL_MSR_ENABLE_SENTER) == 0x00 ) {
+ printk("SMX: SENTER disabled by feature control MSR\n");
+ return -1;
+ }
+ }
+ else {
+ printk("SMX: IA32_FEATURE_CONTROL_MSR_LOCK is not locked (%x)\n", eax);
+ /*
+ * for testing purposes we enable VMX outside of SMX as well so that
+ * if there was some error in the LT boot, VMX will continue to work
+ */
+ /* eax &= ~(u32)IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_OUT_SMX; */
+ eax |= IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX |
+ IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_OUT_SMX |
+ IA32_FEATURE_CONTROL_MSR_ENABLE_SENTER |
+ IA32_FEATURE_CONTROL_MSR_SENTER_PARAM_CTL |
+ IA32_FEATURE_CONTROL_MSR_LOCK;
+ wrmsr(IA32_FEATURE_CONTROL_MSR, eax, 0);
+ printk("SMX: IA32_FEATURE_CONTROL_MSR set to %x\n", eax);
+ }
+
+ /*
+ * check that not in VMX mode
+ */
+ cr4 = read_cr4();
+ printk("SMX: cr4=%lx\n", cr4);
+ if ( cr4 & X86_CR4_VMXE ) {
+ printk("SMX: already in VMX mode\n");
+ return -1;
+ }
+
+ /*
+ * enable SMX
+ */
+
+ write_cr4(cr4 | X86_CR4_SMXE);
+ /* set_in_cr4() would normally do this but it won't work properly
+ * until paging is enabled, so set this manually
+ * this is needed because cr4 will get re-set to it by x86_32.S
+ */
+ *((unsigned long*)__pa(&mmu_cr4_features)) |= X86_CR4_SMXE;
+
+ printk("SMX: SMX is enabled\n");
+
+ /*
+ * verify that an LT-capable chipset is present and
+ * check that all needed SMX capabilities are supported
+ */
+
+ cap = __getsec_capabilities(0);
+ if ( !cap.chipset_present ) {
+ printk("SMX: LT chipset not present\n");
+ return -1;
+ }
+ if ( !(cap.senter && cap.sexit && cap.parameters && cap.smctrl
+ && cap.wakeup) ) {
+ printk("SMX: insufficient SMX capabilities (%x)\n", cap._raw);
+ return -1;
+ }
+
+ printk("SMX: LT chipset and all needed capabilities present\n");
+
+ /*
+ * verify/set cr0 and EFLAGS pre-conditions for GETSEC[SENTER]
+ */
+
+ cr0 = read_cr0();
+ printk("SMX: cr0=%lx\n", cr0);
+
+ /* must be in protected mode (CR0.PE=1) */
+ if ( !(cr0 & X86_CR0_PE) ) {
+ printk("SMX: CR0.PE not set\n");
+ cr0 |= X86_CR0_PE;
+ }
+
+ /* cache must be enabled */
+ if ( cr0 & X86_CR0_CD ) {
+ printk("SMX: CR0.CD set\n");
+ cr0 &= ~X86_CR0_CD;
+ }
+ if ( cr0 & X86_CR0_NW ) {
+ printk("SMX: CR0.NW set\n");
+ cr0 &= ~X86_CR0_NW;
+ }
+
+ /* native FPU error reporting must be enabled for proper */
+ /* interaction behavior */
+ if ( !(cr0 & X86_CR0_NE) ) {
+ printk("SMX: CR0.NE not set\n");
+ cr0 |= X86_CR0_NE;
+ }
+
+ write_cr0(cr0);
+
+ /* cannot be in virtual-8086 mode (EFLAGS.VM=1) */
+ __save_flags(eflags);
+ if ( eflags & X86_EFLAGS_VM ) {
+ printk("SMX: EFLAGS.VM set\n");
+ __restore_flags(eflags | X86_EFLAGS_VM);
+ }
+
+ printk("SMX: CR0 and EFLAGS OK\n");
+
+ /*
+ * verify that we're not already in a protected environment
+ */
+ sts = (lt_sts_t)read_pub_config_reg(LTCR_LT_STS);
+ if ( sts.senter_done_sts ) {
+ printk("SMX: already in protected environment\n");
+ return -1;
+ }
+
+ /*
+ * verify all machine check status registers are clear
+ */
+
+ /* no machine check in progress (IA32_MCG_STATUS.MCIP=1)*/
+ rdmsrl(MSR_IA32_MCG_STATUS, mcg_stat);
+ if ( mcg_stat & 0x04 ) {
+ printk("SMX: machine check in progress\n");
+ return -1;
+ }
+
+ /* all machine check regs are clear */
+ rdmsrl(MSR_IA32_MCG_CAP, mcg_cap);
+ for (i = 0; i < (mcg_cap & 0xff); i++) {
+ rdmsrl(MSR_IA32_MC0_STATUS + 4*i, mcg_stat);
+ if ( mcg_stat & (1ULL << 63) ) {
+ printk("SMX: MCG[%d] = %Lx ERROR\n", i, mcg_stat);
+ return -1;
+ }
+ }
+
+ printk("SMX: no machine check errors\n");
+
+ /* all is well with the processor state */
+ printk("SMX: verify_processor_state() passed\n");
+
+ return 0;
+}
+
+/*
+ * Restore previous MTRRs and do other cleanup stuff here
+ *
+ * @return multiboot_info_t structure for use by Xen
+ */
+multiboot_info_t* restore_os_state(void)
+{
+ multiboot_info_t *mbi;
+ lt_heap_t *lt_heap;
+ os_mvmm_data_v1_t *os_mvmm_data;
+ struct lt_memory_regions_t *lt_mem_regions;
+
+ printk("SMX: restoring OS state\n");
+
+ /* clear error config registers so that we start fresh */
+ write_priv_config_reg(LTCR_LT_CRASH, 0x00000000);
+ write_priv_config_reg(LTCR_LT_ESTS, 0xffffffff); /* write 1's to clear */
+
+ /* save the LT memory regions info for use in fixing-up e820 map */
+ lt_mem_regions = (struct lt_memory_regions_t *)__pa(&_lt_memory_regions);
+ lt_mem_regions->heap_base = read_pub_config_reg(LTCR_LT_HEAP_BASE);
+ lt_mem_regions->heap_size = read_pub_config_reg(LTCR_LT_HEAP_SIZE);
+ lt_mem_regions->sinit_base = read_pub_config_reg(LTCR_LT_SINIT_BASE);
+ lt_mem_regions->sinit_size = read_pub_config_reg(LTCR_LT_SINIT_SIZE);
+ lt_mem_regions->nodma_base = read_pub_config_reg(LTCR_LT_NODMA_BASE);
+ /* size encoding is 0=128k, 1=256k, 2=512k, ... = 128k*2^val, so convert */
+ lt_mem_regions->nodma_size = read_pub_config_reg(LTCR_LT_NODMA_SIZE);
+ lt_mem_regions->nodma_size = 0x20000ULL << lt_mem_regions->nodma_size;
+
+ /* get saved OS state (os_mvmm_data_t) from LT heap */
+ lt_heap = get_lt_heap();
+ os_mvmm_data = (os_mvmm_data_v1_t *)get_os_mvmm_data_start(lt_heap);
+
+ /* restore pre-SENTER MTRRs that were overwritten for SINIT launch */
+ restore_mtrrs(&(os_mvmm_data->saved_mtrr_state));
+
+ /* enable SMIs */
+ __getsec_smctrl();
+
+ /* always set the LT.CMD.SECRETS flag */
+ /* TBD: we really don't have any secrets yet, so we could skip this */
+ /* or we could provide an API to allow domains to set it if they have */
+ /* secrets */
+ write_priv_config_reg(LTCR_LT_CMD_SECRETS, 0x01);
+ read_priv_config_reg(LTCR_LT_E2STS); /* just a fence, so ignore return */
+ printk("SMX: set LT.CMD.SECRETS flag\n");
+
+ /* restore mbi */
+ mbi = os_mvmm_data->mbi;
+
+ /* copy back the command line that we saved and measured */
+ strcpy((char *)mbi->cmdline, ((struct misc_measured_data_t *)
+ __pa(&_misc_measured_data))->cmdline);
+
+ /* decrement module count so that SINIT is not counted as Dom0's initrd */
+ mbi->mods_count--;
+
+ /* __start is expecting mbi to be virt addr, so convert it */
+ mbi = (multiboot_info_t *)__va(mbi);
+
+ /* push mbi onto the stack so that it can be restored to ebx */
+ return mbi;
+}
+
+static void *copy_sinit(void *src_base, u32 src_size)
+{
+ void *dest_base;
+ u32 dest_size;
+ acm_hdr_t *acm_hdr;
+ lt_heap_t *lt_heap;
+ lt_heap_data_hdr_t *lt_heap_data_hdr;
+ bios_os_data_v0_t *bios_os_data;
+
+ /* get BIOS-reserved region from LT.SINIT.BASE config reg */
+ dest_base = (void *)(unsigned long)read_pub_config_reg(LTCR_LT_SINIT_BASE);
+ dest_size = (u32)read_pub_config_reg(LTCR_LT_SINIT_SIZE);
+
+ /* make sure it fits */
+ if ( dest_size < src_size ) {
+ printk("SMX: BIOS-reserved SINIT size (%x) is too small for loaded "
+ "SINIT (%x)\n", dest_size, src_size);
+ return NULL;
+ }
+
+ /* check size of loaded module against internal size */
+ acm_hdr = (acm_hdr_t *)src_base;
+ if ( (acm_hdr->size * 4) != src_size ) {
+ printk("SMX: loaded SINIT size (%x) not same as internal size (%x)\n",
+ src_size, acm_hdr->size);
+ return NULL;
+ }
+
+ /* check if BIOS already loaded an SINIT module there */
+ /* (but replace it even if it has been loaded) */
+ lt_heap = get_lt_heap();
+ lt_heap_data_hdr = get_bios_os_data_start(lt_heap);
+ if ( lt_heap_data_hdr->version != 0x00 ) {
+ printk("SMX: BIOS to OS data version incompatible (%x)\n",
+ lt_heap_data_hdr->version);
+ return NULL;
+ }
+ bios_os_data = (bios_os_data_v0_t *)lt_heap_data_hdr;
+ if ( bios_os_data->bios_sinit_size != 0 ) {
+ printk("SMX: BIOS has already loaded an SINIT module\n");
+ dump_acm_hdr(dest_base, (const char *)__pa("BIOS SINIT"));
+ /* assume our SINIT is newer and replace BIOS's */
+ }
+
+ memcpy(dest_base, src_base, src_size);
+
+ printk("SMX: copied SINIT (size=%x) to %p\n", src_size, dest_base);
+
+ return dest_base;
+}
+
+static void smx_wakeup_cpus(void)
+{
+ struct Xgt_desc_struct gdt;
+ u16 cs;
+ mvmm_join_t *mvmm_join;
+
+ /* RLPs will use our GDT and CS */
+ __asm__ __volatile__ ("sgdt (%0) \n" :: "a"(&gdt) : "memory");
+ __asm__ __volatile__ ("movl %%cs, %0\n" : "=r"(cs));
+
+ mvmm_join = (mvmm_join_t *)__pa(&_mvmm_join);
+ mvmm_join->entry_point = __pa(&_smx_wakeup);
+ mvmm_join->seg_sel = cs;
+ mvmm_join->gdt_base = __pa(gdt.address);
+ mvmm_join->gdt_limit = gdt.size;
+
+ printk("SMX: _mvmm_join.entry_point = %x\n", mvmm_join->entry_point);
+ printk("SMX: _mvmm_join.seg_sel = %x\n", mvmm_join->seg_sel);
+ printk("SMX: _mvmm_join.gdt_base = %x\n", mvmm_join->gdt_base);
+ printk("SMX: _mvmm_join.gdt_limit = %x\n", mvmm_join->gdt_limit);
+
+ write_priv_config_reg(LTCR_LT_MVMM_JOIN, __pa(&_mvmm_join));
+
+ printk("SMX: joining RLPs to MVMM with GETSEC[WAKEUP]\n");
+ __getsec_wakeup();
+
+ printk("SMX: GETSEC[WAKEUP] completed\n");
+}
+
+multiboot_info_t* start_smx(multiboot_info_t *mbi)
+{
+ module_t *sinit_mod;
+ void *sinit_base;
+ u32 sinit_size;
+ lt_heap_t *lt_heap;
+ os_mvmm_data_v1_t *os_mvmm_data;
+ void *mvmm_ptab_base;
+ mvmm_hdr_t *mvmm_hdr;
+ multiboot_info_t *virt_mbi;
+ atomic_t *nr_cpus;
+
+ /*
+ * check if this is being called as part of the SENTER re-start and
+ * if so, wakeup RLPs then call restore_os_state()
+ */
+ if ( *((int *)__pa(&_senter_start)) == 1 ) {
+ smx_wakeup_cpus();
+ return restore_os_state();
+ }
+
+ /* clear SENTER flag */
+ *((int *)__pa(&_senter_start)) = -1;
+
+ /* clear # cpus */
+ nr_cpus = (atomic_t *)__pa(&_nr_cpus);
+ atomic_set(nr_cpus, 0);
+
+ printk("SMX: start_smx()\n");
+
+ /* check if there was an error on last boot and print it */
+ display_errors();
+
+ /* the mbi we get is adjusted to be at virt addr, so covert back to phys */
+ virt_mbi = mbi;
+ mbi = (multiboot_info_t *)__pa(mbi);
+
+ /* check that we have at least one multiboot module - SINIT */
+ if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) ) {
+ printk("SMX: no SINIT module provided\n");
+ return virt_mbi;
+ }
+
+ /* verify the processor is LT capable and enabled */
+ if ( verify_processor_state() == -1 )
+ return virt_mbi;
+
+ /*
+ * copy SINIT to memory reserved for it by BIOS
+ */
+ /* expect SINIT to be last of GRUB modules */
+ sinit_mod = (module_t *)(mbi->mods_addr);
+ sinit_base = (void *)sinit_mod[mbi->mods_count-1].mod_start;
+ sinit_size = sinit_mod[mbi->mods_count-1].mod_end -
+ (unsigned long)sinit_base;
+ /* check if this is really an SINIT AC module */
+ if ( !is_acmod(sinit_base) ) {
+ printk("SMX: could not find SINIT AC module\n");
+ return virt_mbi;
+ }
+ /* copy it */
+ sinit_base = copy_sinit(sinit_base, sinit_size);
+ if ( sinit_base == NULL )
+ return virt_mbi;
+
+ /* verify things are nominally OK */
+ if ( (verify_acmod(sinit_base) == -1) ||
+ (verify_tpm_ready() == -1) )
+ return virt_mbi;
+
+ /* set the MVMM entry point in the MVMM header */
+ /* entry point is relative to beginning of MVMM */
+ mvmm_hdr = (mvmm_hdr_t *)__pa(&_mvmm_hdr);
+ mvmm_hdr->entry_point = (u32)__pa(&__start) - (u32)__pa(&_text);
+ printk("SMX: MVMM entry point = %x\n", mvmm_hdr->entry_point);
+
+ /* create MVMM page table */
+ mvmm_ptab_base = build_mvmm_pagetable(mbi);
+ if ( mvmm_ptab_base == NULL )
+ return virt_mbi;
+
+ /* setup LT heap */
+ lt_heap = setup_lt_heap(mvmm_ptab_base);
+ os_mvmm_data = (os_mvmm_data_v1_t *)get_os_mvmm_data_start(lt_heap);
+
+ /* save mbi */
+ os_mvmm_data->mbi = mbi;
+
+ /* save MTRRs before we alter them for SINIT launch */
+ save_mtrrs(&(os_mvmm_data->saved_mtrr_state));
+
+ /* set MTRRs properly for AC module (SINIT) */
+ set_mtrrs_for_acmod(sinit_base, sinit_size);
+
+ /* set flag that we're about to do SENTER */
+ *((int *)__pa(&_senter_start)) = 1;
+
+ printk("SMX: executing GETSEC[SENTER]...\n");
+ __getsec_senter((u32)sinit_base, sinit_size);
+ printk("SMX: ERROR--we should not get here!\n");
+ return virt_mbi;
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/arch/x86/smx/tpm.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/smx/tpm.c Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,164 @@
+/*
+ * tpm.c: TPM-related support functions for LT
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/smx/smx.h>
+
+
+#define DEBUG_SMX 1
+
+#undef printk
+#ifdef DEBUG_SMX
+#define printk early_serial_printk
+#else
+#define printk(_f , _a...) /**/
+#endif
+
+/*
+ * TPM registers and data structures
+ *
+ * register values are offsets from each locality base
+ * see {read,write}_tpm_reg() for data struct format
+ */
+
+/* TPM_ACCESS_x */
+#define TPM_REG_ACCESS 0x00
+typedef union {
+ u8 _raw[1]; /* 1-byte reg */
+ struct {
+ u8 tpm_establishment : 1; /* RO, 0=T/OS has been established
+ before */
+ u8 request_use : 1; /* RW, 1=locality is requesting TPM use */
+ u8 pending_request : 1; /* RO, 1=other locality is requesting
+ TPM usage */
+ u8 seize : 1; /* WO, 1=seize locality */
+ u8 been_seized : 1; /* RW, 1=locality seized while active */
+ u8 active_locality : 1; /* RW, 1=locality is active */
+ u8 reserved : 1;
+ u8 tpm_reg_valid_sts : 1; /* RO, 1=other bits are valid */
+ } __attribute__ ((packed));
+} tpm_reg_access_t;
+
+/* TPM_STS_x */
+#define TPM_REG_STS 0x18
+typedef union {
+ u8 _raw[3]; /* 3-byte reg */
+ struct {
+ u8 reserved1 : 1;
+ u8 response_retry : 1; /* WO, 1=re-send response */
+ u8 reserved2 : 1;
+ u8 expect : 1; /* RO, 1=more data for command expected */
+ u8 data_avail : 1; /* RO, 0=no more data for response */
+ u8 tpm_go : 1; /* WO, 1=execute sent command */
+ u8 command_ready : 1; /* RW, 1=TPM ready to receive new cmd */
+ u8 sts_valid : 1; /* RO, 1=data_avail and expect bits are
+ valid */
+ u16 burst_count : 16; /* RO, # read/writes bytes before wait */
+ } __attribute__ ((packed));
+} tpm_reg_sts_t;
+
+/*
+ * assumes that all reg types follow above format:
+ * - packed
+ * - member named '_raw' which is array whose size is that of data to read
+ */
+#define read_tpm_reg(locality, reg, pdata) \
+ _read_tpm_reg(locality, reg, (pdata)->_raw, sizeof(*(pdata)))
+
+#define write_tpm_reg(locality, reg, pdata) \
+ _write_tpm_reg(locality, reg, (pdata)->_raw, sizeof(*(pdata)))
+
+
+static void _read_tpm_reg(int locality, u32 reg, u8 *_raw, size_t size)
+{
+ size_t i;
+ for ( i = 0; i < size; i++ )
+ _raw[i] = readb((TPM_LOCALITY_BASE_N(locality) | reg) + i);
+}
+
+static void _write_tpm_reg(int locality, u32 reg, u8 *_raw, size_t size)
+{
+ size_t i;
+ for ( i = 0; i < size; i++ )
+ writeb(_raw[i], (TPM_LOCALITY_BASE_N(locality) | reg) + i);
+}
+
+
+/* ensure TPM is ready to accept commands */
+int verify_tpm_ready()
+{
+ tpm_reg_access_t reg_acc;
+ tpm_reg_sts_t reg_sts;
+
+ /*
+ * must ensure TPM_ACCESS_0.activeLocality bit is clear
+ * (: locality is not active)
+ */
+ read_tpm_reg(0, TPM_REG_ACCESS, ®_acc);
+ if ( reg_acc.active_locality != 0 ) {
+ /* make inactive by writing a 1 */
+ reg_acc.active_locality = 1;
+ write_tpm_reg(0, TPM_REG_ACCESS, ®_acc);
+ }
+
+ /*
+ * read TPM status register to check if it is ready to accept a command
+ * we can do this for locality 2 and assume same for other localities
+ * we will not wait on it--if it is not ready then error
+ */
+ read_tpm_reg(2, TPM_REG_STS, ®_sts);
+ if ( !reg_sts.command_ready ) {
+ printk("SMX: TPM is not ready for commands\n");
+ return -1;
+ }
+
+ printk("SMX: TPM is ready\n");
+
+ return 0;
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/smx/acmod.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/smx/acmod.h Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,88 @@
+/*
+ * acmod.h: LT Authenticated Code (AC) Modules -related definitions
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_X86_SMX_ACMOD_H__
+#define __ASM_X86_SMX_ACMOD_H__
+
+#include <asm/types.h>
+
+/*
+ * authenticated code (AC) module header (ver 0.0)
+ */
+
+typedef struct {
+ u32 module_type;
+ u32 header_len;
+ u32 header_ver;
+ u32 module_id;
+ u32 module_vendor;
+ u32 date;
+ u32 size;
+ u32 reserved1;
+ u32 code_control;
+ u32 error_entry_point;
+ u32 gdt_limit;
+ u32 gdt_base;
+ u32 seg_sel;
+ u32 entry_point;
+ u8 reserved2[64];
+ u32 key_size;
+ u32 scratch_size;
+ u8 rsa2048_pubkey[256];
+ u32 pub_exp;
+ u8 rsa2048_sig[256];
+ u32 scratch[143];
+ u8 user_area[];
+} acm_hdr_t;
+
+/* value of mod_type field for valid AC module */
+#define ACM_VALID_MOD_TYPE 0x02
+
+extern void dump_acm_hdr(acm_hdr_t *hdr, const char *mod_name);
+extern int verify_acmod(void *acmod_base);
+extern int set_mtrrs_for_acmod(void *acmod_base, u32 acmod_size);
+extern int is_acmod(void *acmod_base);
+
+#endif /* __ASM_X86_SMX_ACMOD_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/smx/config_regs.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/smx/config_regs.h Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,189 @@
+/*
+ * mtrrs.c: LT configuration register -related definitions
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_X86_SMX_CONFIG_REGS_H__
+#define __ASM_X86_SMX_CONFIG_REGS_H__
+
+/*
+ * LT configuration registers (offsets from LT_{PUB, PRIV}_CONFIG_REGS_BASE)
+ */
+
+#define LT_PUB_CONFIG_REGS_BASE 0xfed30000
+#define LT_PRIV_CONFIG_REGS_BASE 0xfed20000
+
+/* # pages for each config regs space - used by fixmap */
+#define NR_LT_CONFIG_PAGES ((LT_PUB_CONFIG_REGS_BASE - \
+ LT_PRIV_CONFIG_REGS_BASE) >> \
+ PAGE_SHIFT)
+
+#define LTCR_LT_STS 0x0000
+#define LTCR_LT_ESTS 0x0008
+#define LTCR_LT_CRASH 0x0030
+#define LTCR_LT_CMD_SYS_RESET 0x0038
+#define LTCR_LT_CMD_OPEN_PRIVATE 0x0040
+#define LTCR_LT_CMD_CLOSE_PRIVATE 0x0048
+#define LTCR_LT_CMD_FLUSH_WB 0x0258
+#define LTCR_LT_NODMA_BASE 0x0260
+#define LTCR_LT_NODMA_SIZE 0x0268
+#define LTCR_LT_SINIT_BASE 0x0270
+#define LTCR_LT_SINIT_SIZE 0x0278
+#define LTCR_LT_MVMM_JOIN 0x0290
+#define LTCR_LT_HEAP_BASE 0x0300
+#define LTCR_LT_HEAP_SIZE 0x0308
+#define LTCR_LT_CMD_SECRETS 0x08e0
+#define LTCR_LT_CMD_NO_SECRETS 0x08e8
+#define LTCR_LT_E2STS 0x08f0
+
+/*
+ * format of LT.CRASH register
+ */
+typedef union {
+ u64 _raw;
+ struct {
+ u64 type : 15; /* src-specific error code */
+ u64 src : 1; /* 0=AC module */
+ u64 reserved : 14;
+ u64 external : 1; /* 0=from proc, 1=from external SW */
+ u64 valid : 1; /* 1=valid */
+ };
+} lt_crash_t;
+
+/*
+ * format of LT.ESTS register
+ */
+typedef union {
+ u64 _raw;
+ struct {
+ u64 reserved1 : 1;
+ u64 lt_rogue_sts : 1;
+ u64 bm_write_attack : 1;
+ u64 bm_read_attack : 1;
+ u64 fsb_write_attack : 1;
+ u64 fsb_read_attack : 1;
+ u64 lt_wake_error_sts : 1;
+ u64 reserved2 : 1;
+ };
+} lt_ests_t;
+
+/*
+ * format of LT.E2STS register
+ */
+typedef union {
+ u64 _raw;
+ struct {
+ u64 lt_slp_entry_error_sts : 1;
+ u64 lt_secrets_sts : 1;
+ u64 lt_block_mem_sts : 1;
+ u64 lt_reset_sts : 1;
+ };
+} lt_e2sts_t;
+
+/*
+ * format of LT.STS register
+ */
+typedef union {
+ u64 _raw;
+ struct {
+ u64 senter_done_sts : 1;
+ u64 sexit_done_sts : 1;
+ u64 reserved1 : 2;
+ u64 lt_mem_unlock_sts : 1;
+ u64 lt_nodma_en_sts : 1;
+ u64 lt_mem_config_lock_sts : 1;
+ u64 lt_private_open_sts : 1;
+ u64 reserved2 : 1;
+ u64 lt_nodma_cache_sts : 1;
+ u64 lt_nodma_table_prot_sts : 1;
+ u64 lt_mem_config_ok_sts : 1;
+ };
+} lt_sts_t;
+
+
+/*
+ * fns to read/write LT config regs
+ */
+
+/* returns proper addr (virt from fixmap or phys) depending on proc mode */
+extern u32 config_reg_base_addr(u32 base_phys);
+
+static inline u64 read_config_reg(u32 config_regs_base, u32 reg)
+{
+ /* these are MMIO so make sure compiler doesn't optimize */
+ return *(volatile u64 *)(config_reg_base_addr(config_regs_base) + reg);
+}
+
+static inline void write_config_reg(u32 config_regs_base, u32 reg, u64 val)
+{
+ /* these are MMIO so make sure compiler doesn't optimize */
+ *(volatile u64 *)(config_reg_base_addr(config_regs_base) + reg) = val;
+}
+
+static inline u64 read_pub_config_reg(u32 reg)
+{
+ return read_config_reg(LT_PUB_CONFIG_REGS_BASE, reg);
+}
+
+static inline void write_pub_config_reg(u32 reg, u64 val)
+{
+ write_config_reg(LT_PUB_CONFIG_REGS_BASE, reg, val);
+}
+
+static inline u64 read_priv_config_reg(u32 reg)
+{
+ return read_config_reg(LT_PRIV_CONFIG_REGS_BASE, reg);
+}
+
+static inline void write_priv_config_reg(u32 reg, u64 val)
+{
+ write_config_reg(LT_PRIV_CONFIG_REGS_BASE, reg, val);
+}
+
+/* this is a common use with annoying casting, so make it an inline */
+static inline lt_heap_t *get_lt_heap(void)
+{
+ return (lt_heap_t *)(unsigned long)read_pub_config_reg(LTCR_LT_HEAP_BASE);
+}
+
+#endif /* __ASM_X86_SMX_CONFIG_REGS_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/smx/mtrrs.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/smx/mtrrs.h Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,124 @@
+/*
+ * mtrrs.c: LT MTRR-related definitions
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_X86_SMX_MTRRS_H__
+#define __ASM_X86_SMX_MTRRS_H__
+
+#include <asm/mtrr.h>
+
+enum var_mtrr_t {
+ MTRR_PHYS_BASE0_MSR = 0x200,
+ MTRR_PHYS_MASK0_MSR = 0x201,
+ MTRR_PHYS_BASE1_MSR = 0x202,
+ MTRR_PHYS_MASK1_MSR = 0x203,
+ MTRR_PHYS_BASE2_MSR = 0x204,
+ MTRR_PHYS_MASK2_MSR = 0x205,
+ MTRR_PHYS_BASE3_MSR = 0x206,
+ MTRR_PHYS_MASK3_MSR = 0x207,
+ MTRR_PHYS_BASE4_MSR = 0x208,
+ MTRR_PHYS_MASK4_MSR = 0x209,
+ MTRR_PHYS_BASE5_MSR = 0x20A,
+ MTRR_PHYS_MASK5_MSR = 0x20B,
+ MTRR_PHYS_BASE6_MSR = 0x20C,
+ MTRR_PHYS_MASK6_MSR = 0x20D,
+ MTRR_PHYS_BASE7_MSR = 0x20E,
+ MTRR_PHYS_MASK7_MSR = 0x20F
+};
+
+typedef union {
+ u64 raw;
+ struct {
+ u64 vcnt : 8; /* num variable MTRR pairs */
+ u64 fix : 1; /* fixed range MTRRs are supported */
+ u64 reserved1 : 1;
+ u64 wc : 1; /* write-combining mem type supported */
+ u64 reserved2 : 53;
+ };
+} mtrr_cap_t;
+
+typedef union {
+ u64 raw;
+ struct {
+ u64 type : 8;
+ u64 reserved1 : 2;
+ u64 fe : 1; /* fixed MTRR enable */
+ u64 e : 1; /* (all) MTRR enable */
+ u64 reserved2 : 52;
+ };
+} mtrr_def_type_t;
+
+typedef union {
+ u64 raw;
+ struct {
+ u64 type : 8;
+ u64 reserved1 : 4;
+ u64 base : 24;
+ u64 reserved2 : 28;
+ };
+} mtrr_physbase_t;
+
+typedef union {
+ u64 raw;
+ struct {
+ u64 reserved1 : 11;
+ u64 v : 1; /* valid */
+ u64 mask : 24;
+ u64 reserved2 : 28;
+ };
+} mtrr_physmask_t;
+
+/* current procs only have 8, so this should hold us for a while */
+#define MAX_VARIABLE_MTRRS 16
+
+typedef struct {
+ mtrr_def_type_t mtrr_def_type;
+ int num_var_mtrrs;
+ mtrr_physbase_t mtrr_physbases[MAX_VARIABLE_MTRRS];
+ mtrr_physmask_t mtrr_physmasks[MAX_VARIABLE_MTRRS];
+} mtrr_state_t;
+
+
+#endif /*__ASM_X86_SMX_MTRRS_H__ */
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 041be3f6b38e -r 0b39e8a32d1f xen/include/asm-x86/smx/smx.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/smx/smx.h Thu Sep 21 11:59:17 2006 +0800
@@ -0,0 +1,365 @@
+/*
+ * smx.h: LT SMX architecture-related definitions
+ *
+ * Copyright (c) 2003-2006, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_X86_SMX_SMX_H__
+#define __ASM_X86_SMX_SMX_H__
+
+#include <stdbool.h>
+#include <xen/types.h>
+#include <xen/multiboot.h>
+#include <asm/e820.h>
+#include <asm/smx/mtrrs.h>
+
+/*
+ * LT device space
+ */
+
+#define TPM_LOCALITY_BASE 0xfed40000
+#define NR_TPM_LOCALITY_PAGES ((TPM_LOCALITY_1 - TPM_LOCALITY_0) >> \
+ PAGE_SHIFT)
+
+#define TPM_LOCALITY_0 TPM_LOCALITY_BASE
+#define TPM_LOCALITY_1 (TPM_LOCALITY_BASE | 0x1000)
+#define TPM_LOCALITY_2 (TPM_LOCALITY_BASE | 0x2000)
+/* these localities (3+4) are mostly not usable by Xen */
+#define TPM_LOCALITY_3 (TPM_LOCALITY_BASE | 0x3000)
+#define TPM_LOCALITY_4 (TPM_LOCALITY_BASE | 0x4000)
+
+#define TPM_LOCALITY_BASE_N(n) (TPM_LOCALITY_BASE | ((n) << 12))
+
+
+/*
+ * data-passing structures contained in LT heap:
+ * - BIOS to OS/loader
+ * - OS/loader to MVMM
+ * - OS/loader to SINIT
+ * - SINIT to MVMM
+ */
+
+/*
+ * BIOS to OS/loader structure
+ * - not used by current Xen
+ */
+typedef struct {
+ u32 version; /* will be 0x00 */
+ u32 bios_sinit_size;
+} bios_os_data_v0_t;
+
+/*
+ * OS/loader to MVMM structure v1
+ * - private to Xen (so can be any format we need)
+ */
+typedef struct {
+ u32 version; /* will be 0x01 */
+ mtrr_state_t saved_mtrr_state; /* saved prior to changes for SINIT */
+ multiboot_info_t *mbi; /* needs to be restored to ebx */
+} os_mvmm_data_v1_t;
+
+/*
+ * OS/loader to SINIT structure v1
+ */
+typedef struct {
+ u32 version; /* will be 0x01 */
+ u32 reserved;
+ u32 mvmm_ptab_lo;
+ u32 mvmm_ptab_hi;
+ u32 mvmm_size_lo;
+ u32 mvmm_size_hi;
+ u32 mvmm_hdr_base_lo;
+ u32 mvmm_hdr_base_hi;
+} os_sinit_data_v1_t;
+
+/*
+ * SINIT to MVMM structure v1
+ */
+#define MDR_MEMTYPE_GOOD 0x00
+#define MDR_MEMTYPE_SMM_OVERLAY 0x01
+#define MDR_MEMTYPE_SMM_NONOVERLAY 0x02
+#define MDR_MEMTYPE_PCIE_CONFIG_SPACE 0x03
+#define MDR_MEMTYPE_PROTECTED 0x04
+
+typedef struct __attribute__ ((packed)) {
+ u32 start_lo;
+ u32 start_hi;
+ u32 length_lo;
+ u32 length_hi;
+ u8 mem_type;
+ u8 reserved[7];
+} sinit_mdr_t;
+
+typedef struct {
+ u32 version; /* will be 0x01 */
+ u32 num_mdrs;
+ sinit_mdr_t mdrs[];
+} sinit_mvmm_data_v1_t;
+
+
+/*
+ * LT heap data format and field accessor fns
+ */
+
+/*
+ * offset length field
+ * ------ ------ -----
+ * 0 8 bios_os_data_size
+ * 8 bios_os_data_size - 8 bios_os_data
+ *
+ * bios_os_data_size 8 os_mvmm_data_size
+ * bios_os_data_size + os_mvmm_data_size - 8 os_mvmm_data
+ * 8
+ *
+ * bios_os_data_size + 8 os_sinit_data_size
+ * os_mvmm_data_size
+ * bios_os_data_size + os_sinit_data_size - 8 os_sinit_data
+ * os_mvmm_data_size +
+ * 8
+ *
+ * bios_os_data_size + 8 sinit_mvmm_data_size
+ * os_mvmm_data_size +
+ * os_sinit_data_size
+ * bios_os_data_size + sinit_mvmm_data_size - 8 sinit_mvmm_data
+ * os_mvmm_data_size +
+ * os_sinit_data_size +
+ * 8
+ */
+
+typedef void lt_heap_t;
+
+typedef struct {
+ u32 version;
+} lt_heap_data_hdr_t;
+
+static inline u64 *get_data_size_addr(void *data_start)
+{
+ return (u64 *)(data_start - sizeof(u64));
+}
+
+static inline u64 get_bios_os_data_size(lt_heap_t *lt_heap)
+{
+ return *(u64 *)lt_heap;
+}
+
+static inline lt_heap_data_hdr_t *get_bios_os_data_start(lt_heap_t *lt_heap)
+{
+ return (lt_heap_data_hdr_t *)((char*)lt_heap + sizeof(u64));
+}
+
+static inline u64 get_os_mvmm_data_size(lt_heap_t *lt_heap)
+{
+ return *(u64 *)(lt_heap + get_bios_os_data_size(lt_heap));
+}
+
+static inline lt_heap_data_hdr_t *get_os_mvmm_data_start(lt_heap_t *lt_heap)
+{
+ return (lt_heap_data_hdr_t *)(lt_heap + get_bios_os_data_size(lt_heap) +
+ sizeof(u64));
+}
+
+static inline u64 get_os_sinit_data_size(lt_heap_t *lt_heap)
+{
+ return *(u64 *)(lt_heap + get_bios_os_data_size(lt_heap) +
+ get_os_mvmm_data_size(lt_heap));
+}
+
+static inline lt_heap_data_hdr_t *get_os_sinit_data_start(lt_heap_t *lt_heap)
+{
+ return (lt_heap_data_hdr_t *)(lt_heap + get_bios_os_data_size(lt_heap) +
+ get_os_mvmm_data_size(lt_heap) +
+ sizeof(u64));
+}
+
+static inline u64 get_sinit_mvmm_data_size(lt_heap_t *lt_heap)
+{
+ return *(u64 *)(lt_heap + get_bios_os_data_size(lt_heap) +
+ get_os_mvmm_data_size(lt_heap) +
+ get_os_sinit_data_size(lt_heap));
+}
+
+static inline lt_heap_data_hdr_t *get_sinit_mvmm_data_start(lt_heap_t *lt_heap)
+{
+ return (lt_heap_data_hdr_t *)(lt_heap + get_bios_os_data_size(lt_heap) +
+ get_os_mvmm_data_size(lt_heap) +
+ get_os_sinit_data_size(lt_heap) +
+ sizeof(u64));
+}
+
+
+/*
+ * MVMM header structure
+ * describes an MVMM for SINIT and OS/loader SW
+ */
+typedef struct {
+ u32 guid[4];
+ u32 length;
+ u32 version;
+ u32 entry_point;
+ u32 req_mem_size;
+ u32 features;
+} mvmm_hdr_t;
+
+
+/*
+ * RLP JOIN structure for GETSEC[WAKEUP]
+ */
+typedef struct {
+ u32 gdt_limit;
+ u32 gdt_base;
+ u32 seg_sel; /* cs (ds, es, ss are seg_sel+8) */
+ u32 entry_point; /* phys addr */
+} mvmm_join_t;
+
+/*
+ * GETSEC[] instructions
+ */
+
+/* GETSEC instruction opcode */
+#define IA32_GETSEC_OPCODE ".byte 0x0f,0x37"
+
+/* GETSEC leaf function codes */
+#define IA32_GETSEC_CAPABILITIES 0
+#define IA32_GETSEC_SENTER 4
+#define IA32_GETSEC_SEXIT 5
+#define IA32_GETSEC_PARAMETERS 6
+#define IA32_GETSEC_SMCTRL 7
+#define IA32_GETSEC_WAKEUP 8
+
+/*
+ * GETSEC[] leaf functions
+ */
+
+typedef union {
+ u32 _raw;
+ struct {
+ u32 chipset_present : 1;
+ u32 undefined1 : 1;
+ u32 enteraccs : 1;
+ u32 exitac : 1;
+ u32 senter : 1;
+ u32 sexit : 1;
+ u32 parameters : 1;
+ u32 smctrl : 1;
+ u32 wakeup : 1;
+ u32 undefined9 : 22;
+ u32 extended_leafs : 1;
+ };
+} capabilities_t;
+
+static inline capabilities_t __getsec_capabilities(u32 index)
+{
+ u32 cap;
+ __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
+ : "=a"(cap)
+ : "a"(IA32_GETSEC_CAPABILITIES), "b"(index));
+ return (capabilities_t)cap;
+}
+
+static inline void __getsec_senter(u32 sinit_base, u32 sinit_size)
+{
+ __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
+ :
+ : "a"(IA32_GETSEC_SENTER),
+ "b"(sinit_base),
+ "c"(sinit_size),
+ "d"(0x0));
+}
+
+static inline void __getsec_sexit(void)
+{
+ __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
+ : : "a"(IA32_GETSEC_SEXIT));
+}
+
+static inline void __getsec_wakeup(void)
+{
+ __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
+ : : "a"(IA32_GETSEC_WAKEUP));
+}
+
+static inline void __getsec_smctrl(void)
+{
+ __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
+ : : "a"(IA32_GETSEC_SMCTRL), "b"(0x0));
+}
+
+static inline void __getsec_parameters(u32 index, int* param_type,
+ u32* peax, u32* pebx, u32* pecx)
+{
+ u32 eax=0, ebx=0, ecx=0;
+ __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
+ : "=a"(eax), "=b"(ebx), "=c"(ecx)
+ : "a"(IA32_GETSEC_PARAMETERS), "b"(index));
+
+ if ( param_type != NULL ) *param_type = eax & 0x1f;
+ if ( peax != NULL ) *peax = eax;
+ if ( pebx != NULL ) *pebx = ebx;
+ if ( pecx != NULL ) *pecx = ecx;
+}
+
+
+/* used for debugging in very early boot environment */
+void early_serial_printk(const char *fmt, ...);
+
+/* used in shutdown.c */
+extern void smx_scrub_proc(void);
+extern void smx_scrub_mem(void);
+extern void smx_teardown(bool is_bsp);
+
+/* manage MTRRs for launch of AC module (SINIT) */
+void save_mtrrs(mtrr_state_t *saved_state);
+void restore_mtrrs(mtrr_state_t *saved_state);
+int set_mem_type(void *base, u32 size, u32 mem_type);
+void set_all_mtrrs(bool enable);
+
+int smx_reserve_memory(struct e820map *map);
+
+bool smx_in_prot_env(void);
+
+unsigned long smx_rlp_restart(int cpu);
+
+void display_errors(void);
+
+int verify_tpm_ready(void);
+
+#endif /* __ASM_X86_SMX_SMX_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [Xense-devel] [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support
2006-09-22 19:00 [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support Cihula, Joseph
@ 2006-09-23 17:01 ` Leendert Van Doorn
0 siblings, 0 replies; 6+ messages in thread
From: Leendert Van Doorn @ 2006-09-23 17:01 UTC (permalink / raw)
To: Cihula, Joseph; +Cc: xen-devel, xense-devel
I'm not sure how many people experimented with this code yet, but there is
a dependency that isn't articulated in its README.
For me to make this work, I had to compile Xen with PAE support (set
XEN_TARGET_X86_PAE=y in Config.mk) and use the PAE version of the SINIT
authenticated code module (lpg_sinit_20050831_pae.auth.bin). Using a
non-PAE version of Xen and lpg_sinit_20050831.auth.bin caused SENTER to
fail and reset the machine.
Some of the comments in the code seem to suggest that it expects the mvmm
to be in PAE mode, so it is probably an assumption in the code.
Leendert
-----------------------
Dr. Leendert van Doorn
Senior Manager - Secure Systems and Tools
IBM T.J. Watson Research Center
"Cihula, Joseph"
<joseph.cihula@in
tel.com> To
Sent by: <xen-devel@lists.xensource.com>,
xense-devel-bounc <xense-devel@lists.xensource.com>
es@lists.xensourc cc
e.com
Subject
[Xense-devel] [RFC][PATCH][UPDATED]
09/22/2006 03:00 Intel(R) LaGrande Technology
PM support
This patch adds SMP support to the previous version. Since that has not
been merged I have included it in this patch. This should apply cleanly
to the tip. Below is the text of the original submittal, slightly
updated.
Attached is a preliminary patch that adds Intel(R) LaGrande Technology
(LT) (Safer Mode Extensions - SMX) support to Xen. While there are
still several enhancements needed for complete support, we feel that it
is sufficiently complete for an initial public posting to expose to the
community.
LaGrande Technology in Brief:
-----------------------------
o Provides dynamic root of trust for measurement (DRTM)
o DMA protection
o Data protection in case of improper shutdown
For more information on LT, see the Intel LaGrande Technology website:
http://www.intel.com/technology/security/.
This site also has a link to the LT preliminary specification (an
updated version that reflects the functionlaity of this code will be
available later this week).
The LT functionality this code adds is:
---------------------------------------
o Measured Launch. If the processor is detected as being LT-capable
and enabled then the code will attempt to perform a measured launch. If
the processor is (not capable) or (capable but not enabled) or (capable
and enabled but the launch process fails (missing SINIT, corrupted data,
etc.)) then it will fall-through to a non-LT boot.
o Teardown of measured environment. When Xen exits the LT environment
will be torn down properly.
o Reset data protection. LT HW prevents access to secrets if the
system is reset without clearing them from memory (as part of a LT
teardown). This code will support this by setting the flag indicating
that memory should be so protected during the measured launch and
clearing the flag just before teardown.
o Protection of LT memory ranges. LT reserves certain regions of RAM
for its use and also defines several MMIO regions. These regions are
protected from use by any domains (including dom0). Note that there a
sub-regions of the MMIO space that are left accessible to dom0 (LT
public configuration space, TPM localities 0,1).
Patch breakdown:
----------------
Config.mk - add INTEL_SMX build config
xen/Rules.mk - adds '-DCONFIG_SMX' compile flag if INTEL_SMX=y
xen/arch/x86/Makefile - add arch/x86/smx dir to build
xen/arch/x86/boot/x86_32.S - hook startup to launch LT
environmentxen/arch/x86/setup.c - initialize fixmap entries for LT
config reg space
xen/arch/x86/domain_build.c - protect LT private config space
xen/arch/x86/e820.c - support for E820_PROTECTED mem type
xen/arch/x86/hvm/vmx/vmx.c - support new LT/VMX IA32_FEATURE_CONTROL_MSR
flag
xen/arch/x86/mm.c - support for E820_PROTECTED mem type
xen/arch/x86/setup.c - hook to reserve LT RAM regions and initialize
fixmap entries for LT config reg space
xen/arch/x86/shutdown.c - hook shutdown to teardown LT environment
xen/common/domctl.c - prevent XEN_DOMCTL_iomem_permission from being
able to map LT private config space
xen/include/asm-x86/cpufeature.h - adds new SMX feature flag
xen/include/asm-x86/e820.h - export print_e820_memory_map()
xen/include/asm-x86/fixmap.h - adds fixmap entries for LT config reg
space
xen/include/asm-x86/msr.h - adds new VMX and SMX MSR flags
xen/include/asm-x86/processor.h - adds new CR4 SMX flag
xen/include/public/hvm/e820.h - add E820_PROTECTED mem type
xen/arch/x86/smx/Makefile - self explanatory
xen/arch/x86/smx/acmod.c - LT Authenticated Code (AC) module support fns
xen/arch/x86/smx/early_printk.c - serial printk() for early in boot
process
xen/arch/x86/smx/errors.c - error parsing/display fns
xen/arch/x86/smx/mtrrs.c - MTRR handling for AC module launch
xen/arch/x86/smx/smx.c - main LT/SMX fns and entry points
xen/arch/x86/smx/tpm.c - basic TPM support fns
xen/include/asm-x86/smx/* - headers for SMX/LT fns
This code has been developed and tested on Intel Software Development
Platform (SDP) 3 systems (available under NDA via the Intel Premier
Support channel). It will be updated to work with the LT Technology
Enabling Platform (TEP) that will be publicly available this fall.
Instructions for use:
---------------------
o By default, the functionality is disabled in the build. It can be
enabled by changing the INTEL_SMX flag to 'y' in Config.mk.
o The SINIT AC module (available with SDP3 systems) must be added to
the grub.conf boot config as the last module, e.g.:
...
module /initrd-2.6.16.13-xen.img
module /lpg_sinit_20050831_pae.auth.bin
o Progress of the LT launch process is indicated via debug printk's to
COM1 (hardcoded). These appear before the normal "(XEN)" output and are
prefixed by "SMX:". The code (in early_printk.c) does not initialize
the COM port so this needs to be done by GRUB - grub.conf should have:
serial --speed=115200 --unit=0
terminal console serial
Caveats / Notes:
----------------
o x86_64 is not supported yet (IA64 does not support LT at this time).
o The code only measures the hypervisor (and its command line), which
is not the complete TCB.
o It doesn't cap (extend with invalid value) the dynamic TPM PCRs when
the LT environment is torn down. Instead it disables the BIOS reboot
option so that any shutdown/reboot will have to reset the platform and
the TPM.
o TPM locality 2 is not protected. The defined behavior for access to
unpermitted localities is for reads to return 0xff's and writes to be
dropped. This will require mapping pages from locality 3 or 4 into the
locality 2 range.
o No DMA protection has been implemented in this patch. SDP3 only
supports the NoDMA table for DMA protection and this will be superseded
by VT-d. VT-d support for LT will be added after it is added for the
general case.
These limitations will be addressed in subsequent patches.
There was a presentation on the code at the Xen Summit. More
information on LT is available at
http://www.intel.com/technology/security/. Comments and feedback are
welcome at any time.
Joseph Cihula
(Linux) Software Security Architect
Open Source Technology Center
Intel Corp.
*** These opinions are not necessarily those of my employer ***
[attachment "intel_lagrande_tech_smp.patch" deleted by Leendert Van
Doorn/Watson/IBM] _______________________________________________
Xense-devel mailing list
Xense-devel@lists.xensource.com
http://lists.xensource.com/xense-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-07-12 16:54 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-12 21:07 [Xense-devel] [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support Jonathan M. McCune
2007-04-12 21:52 ` Cihula, Joseph
2007-07-11 20:51 ` [RFC][PATCH][0/2] Intel(r) Trusted Execution Technology Jonathan M. McCune
2007-07-12 13:40 ` Jonathan M. McCune
2007-07-12 16:54 ` Cihula, Joseph
-- strict thread matches above, loose matches on Subject: below --
2006-09-22 19:00 [RFC][PATCH][UPDATED] Intel(R) LaGrande Technology support Cihula, Joseph
2006-09-23 17:01 ` [Xense-devel] " Leendert Van Doorn
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.