qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
To: Igor Mammedov <imammedo@redhat.com>
Cc: kevin@koconnor.net, stefanb@us.ibm.com, qemu-devel@nongnu.org,
	quan.xu@intel.com, mst@redhat.com
Subject: Re: [Qemu-devel] [PATCH v2 3/6] Support Physical Presence Interface Spec
Date: Fri, 15 May 2015 14:24:18 -0400	[thread overview]
Message-ID: <555639D2.3070608@linux.vnet.ibm.com> (raw)
In-Reply-To: <20150515171332.7ae7813f@nial.brq.redhat.com>

On 05/15/2015 11:13 AM, Igor Mammedov wrote:
> On Fri,  8 May 2015 12:15:17 -0400
> Stefan Berger <stefanb@linux.vnet.ibm.com> wrote:
>
>> For automated management of a TPM device, implement the TCG Physical Presence
>> Interface Specification that allows a root user on Linux (for example) to set
>> an opcode for a sequence of TPM operations that the BIOS is supposed to execute
>> upon reboot of the physical or virtual machine. A sequence of operations may for
>> example involve giving up ownership of the TPM and activating and enabling the
>> device.
>>
>> The sequences of operations are defined in table 2 in the specs to be found
>> at the following link:
>>
>> http://www.trustedcomputinggroup.org/resources/tcg_physical_presence_interface_specification
>>
>> As an example, in recent versions of Linux the opcode (5) can be set as
>> follows:
>>
>> cd /sys/devices/pnp0/00\:04/ppi
>>
>> echo 5 > request
>>
>> This ACPI implementation assumes that the underlying firmware (SeaBIOS)
>> has 'thrown an anchor' into the f-segment. The anchor is identified by
>> two signatures (TCG_MAGIC) surrounding a 64bit pointer. The structure
>> in the f-segment is write-protected and holds a pointer to a structure
>> in high memmory area where the ACPI code writes the opcode into and
>> where it can read the last response from the BIOS.
>>
>> The supported opcodes are 1-11, 14, and 21-22. (see table 2 in spec)
>> Also '0' is supported to 'clear' an intention.
>>
>>
>> Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
>> Cc: Michael Tsirkin <mst@redhat.com>
>> Cc: Kevin O'Connor <kevin@koconnor.net>
>> ---
>>   hw/i386/ssdt-tpm.dsl  | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   include/hw/acpi/tpm.h |  20 ++++++
>>   2 files changed, 209 insertions(+)
>>
> Ditto, please redo below ASL using C AML API.
> API might not have all ASL ops you've used here but you can
> reuse some from following series
>   "Generate ACPI v5.1 tables and expose them to guest over fw_cfg on ARM"
> and add missing ones.
>
>
>> diff --git a/hw/i386/ssdt-tpm.dsl b/hw/i386/ssdt-tpm.dsl
>> index 75d9691..7d28899 100644
>> --- a/hw/i386/ssdt-tpm.dsl
>> +++ b/hw/i386/ssdt-tpm.dsl
>> @@ -38,6 +38,195 @@ DefinitionBlock (
>>               Method (_STA, 0, NotSerialized) {
>>                   Return (0x0F)
>>               }
>> +
>> +            OperationRegion (TTIS, SystemMemory,
>> +                             TPM_TIS_ADDR_BASE, TPM_TIS_ADDR_SIZE)
>> +
>> +            // Define TPM Debug register
>> +            Field(TTIS, AnyAcc, NoLock, Preserve) {
>> +                Offset (0xf90),
>> +                TDBG, 32        // QEMU TIS Debug
> I don't see it being used here,
> What do you need it for?

I used it for debugging. Removed it.


>
>> +            }
>> +
>> +            // Last accepted opcode
>> +            NAME(OP, Zero)
>> +
>> +            // The base address in TIS 'RAM' where we exchange
>> +            // data with the BIOS
>> +            Name(ADDR, 0xfed40fa0)
>> +
>> +            // Write given opcode into 'RAM'
>> +            Method (WRAM, 1, NotSerialized) {
>> +                // Write to high memory pointed to by ADDR
>> +                OperationRegion (HIGH, SystemMemory, ADDR, TPM_PPI_STRUCT_SIZE)
> dynamic OperationRegion-s are better to be avoided, Windows can't/doesn't check
> its correctness at table load time.
> Put it at device scope so that guest OS would notice address collisions
> if there would be any.


Done.

>
>> +                Field(HIGH, AnyAcc, NoLock, Preserve) {
>> +                   SIG1, 32,
>> +                   SIZE, 16,
>> +                   CODE, 8
>> +                }
>> +                If (LAnd(
>> +                    LEqual(SIG1, TCG_MAGIC),
>> +                    LGreaterEqual(SIZE, 1))
>> +                ) {
>> +                    // Write opcode for BIOS to find
>> +                    Store(Arg0, CODE)
>> +                    // Remember last opcode in CODE
>> +                    Store(Arg0, OP)
>> +                    Return ( 0 )
>> +                }
>> +                Return ( 1 )
>> +            }
>> +
>> +            // read data from 'RAM'
>> +            Method (RRAM, 0, NotSerialized) {
>> +                Name (OPRE, Package(3) { 1, 0, 0})
>> +                // Read from memory pointed to by ADDR
>> +                OperationRegion (HIGH, SystemMemory, ADDR, TPM_PPI_STRUCT_SIZE)
> with OperationRegion at device scope you can drop this.

Ok.

>
>> +                Field(HIGH, AnyAcc, NoLock, Preserve) {
>> +                   SIG1, 32,
>> +                   SIZE, 16,
>> +                   CODE, 8,
>> +                   SUCC, 8,
>> +                   CODO, 8,
>> +                   RESP, 32
>> +                }
>> +                // Check signature and sufficient space
>> +                If (LAnd(
>> +                    LEqual(SIG1, TCG_MAGIC),
> using SIG1 seems to be redundant now, the same goes for BIOS part.
> Why just not drop it?


As a marker that the memory was initialized by the TPM?



>> +                    LGreaterEqual(SIZE, 7)
>> +                )) {
>> +                    Store(SUCC, Index(OPRE, 0))
>> +                    Store(CODO, Index(OPRE, 1))
>> +                    Store(RESP, Index(OPRE, 2))
>> +                }
>> +                return (OPRE)
>> +            }
>> +
>> +            Method (_DSM, 4, NotSerialized) {
>> +                If (LEqual (Arg0, ToUUID("3DDDFAA6-361B-4EB4-A424-8D10089D1653"))) {
>> +
>> +                    // only supporting API revision 1
>> +                    If (LNotEqual (Arg1, 1)) {
>> +                        Return (Buffer (1) {0})
>> +                    }
>> +
>> +                    Store(ToInteger(Arg2), Local0)
>> +                    // standard DSM query function
>> +                    If (LEqual (Local0, 0)) {
>> +                        Return (Buffer () {0xFF, 0x01})
>> +                    }
>> +
>> +                    // interface version
>> +                    If (LEqual (Local0, 1)) {
>> +                        Return ("1.2")
>> +                    }
>> +
>> +                    // submit TPM operation
>> +                    If (LEqual (Local0, 2)) {
>> +                        // get opcode from package
>> +                        Store(DerefOf(Index(Arg3, 0)), Local0)
>> +                        // check for supported opcode
>> +                        // supported opcodes: 0, 1-11, 14, 21-22
>> +                        If (LOr(
>> +                              LOr(
>> +                                LAnd(
>> +                                  LGreaterEqual(Local0, 0),
>> +                                  LLessEqual(Local0, 11)
>> +                                ),
>> +                                LEqual(Local0, 14)
>> +                              ),
>> +                                LAnd(
>> +                                  LGreaterEqual(Local0, 21),
>> +                                  LLessEqual(Local0, 22)
>> +                                )
>> +                            ))
>> +                        {
>> +                            // Write the OP into TPM NVRAM
>> +                            Store(WRAM ( Local0 ), Local1)
>> +                            return (Local1)
>> +                        } else {
>> +                            Return (1)
>> +                        }
>> +                    }
>> +
>> +                    // get pending TPM operation
>> +                    If (LEqual (Local0, 3)) {
>> +                        NAME(PEOP, Package(2) { 0, 0 })
>> +
>> +                        Store ( 0 , Index(PEOP, 0))
>> +                        Store ( OP, Index(PEOP, 1))
>> +
>> +                        Return (PEOP)
>> +                    }
>> +
>> +                    // action to transition to pre-OS env.
>> +                    If (LEqual (Local0, 4)) {
>> +                        return (2) // Requiring reboot
>> +                    }
>> +
>> +                    // get pre-OS TPM operation response
>> +                    If (LEqual (Local0, 5)) {
>> +                        Store (RRAM(), Local0)
>> +                        return ( Local0 )
>> +                    }
>> +
>> +                    // preferred user language
>> +                    If (LEqual (Local0, 6)) {
>> +                        return (3) // Not implemented
>> +                    }
>> +
>> +                    // submit TPM operation v2
>> +                    If (LEqual (Local0, 7)) {
>> +                        Store(DerefOf(Index(Arg3, 0)), Local0)
>> +                        // supported opcodes: 0, 1-11, 14, 21-22
> check looks like the same as above, split out into a separate function?

Split out into CKOP().

>
>> +                        If (LOr(
>> +                              LOr(
>> +                                LAnd(
>> +                                  LGreaterEqual(Local0, 0),
>> +                                  LLessEqual(Local0, 11)
>> +                                ),
>> +                                LEqual(Local0, 14)
>> +                              ),
>> +                              LAnd(
>> +                                LGreaterEqual(Local0, 21),
>> +                                LLessEqual(Local0, 22)
>> +                              )
>> +                            ))
>> +                        {
>> +                            // Write the OP into TPM NVRAM
>> +                            Store(WRAM ( Local0 ), Local1)
>> +                            return (Local1)
>> +                        } else {
>> +                            Return (1)
>> +                        }
>> +                    }
>> +
>> +                    // get user confirmation status
>> +                    If (LEqual (Local0, 8)) {
>> +                        Store(DerefOf(Index(Arg3,0)), Local0)
>> +                        // supported opcodes: 0, 1-11, 14, 21-22
> ditto


Fixed.

  reply	other threads:[~2015-05-15 18:24 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-08 16:15 [Qemu-devel] [PATCH v2 0/6] Extend TPM support with a QEMU-external TPM Stefan Berger
2015-05-08 16:15 ` [Qemu-devel] [PATCH v2 1/6] Provide support for the CUSE TPM Stefan Berger
2015-05-08 16:15 ` [Qemu-devel] [PATCH v2 2/6] Introduce RAM location in vendor specific area in TIS Stefan Berger
2015-05-08 16:15 ` [Qemu-devel] [PATCH v2 3/6] Support Physical Presence Interface Spec Stefan Berger
2015-05-08 18:02   ` Stefan Berger
2015-05-15 15:13   ` Igor Mammedov
2015-05-15 18:24     ` Stefan Berger [this message]
2015-05-22  0:20     ` Stefan Berger
2015-05-08 16:15 ` [Qemu-devel] [PATCH v2 4/6] Introduce condition to notifiy waiters of completed command Stefan Berger
2015-05-08 16:15 ` [Qemu-devel] [PATCH v2 5/6] Introduce condition in TPM backend for notification Stefan Berger
2015-05-08 16:15 ` [Qemu-devel] [PATCH v2 6/6] Add support for VM suspend/resume for TPM TIS Stefan Berger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=555639D2.3070608@linux.vnet.ibm.com \
    --to=stefanb@linux.vnet.ibm.com \
    --cc=imammedo@redhat.com \
    --cc=kevin@koconnor.net \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quan.xu@intel.com \
    --cc=stefanb@us.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).