Bug 1654490

Summary: [RFE] TPM passthrough support (libvirt)
Product: Red Hat Enterprise Linux 8 Reporter: Ademar Reis <areis>
Component: libvirtAssignee: Libvirt Maintainers <libvirt-maint>
Status: CLOSED CURRENTRELEASE QA Contact: Yanqiu Zhang <yanqzhan>
Severity: medium Docs Contact:
Priority: medium    
Version: ---CC: areis, chayang, creynold, cww, dyuan, dzheng, fjin, fmartine, jcoscia, jinzhao, juzhang, kchamart, knoel, lersek, marcandre.lureau, mkalinin, mtessun, pgozart, psztoch, rbalakri, rdoty, shipatil, virt-bugs, virt-maint, xfu, xuzhang, yafu, yalzhang, yanqzhan, yuhuang
Target Milestone: rcKeywords: Automation, FutureFeature, TestOnly
Target Release: 8.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of: 1654486
: 1668199 (view as bug list) Environment:
Last Closed: 2019-06-14 02:00:58 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1327947, 1654486    
Bug Blocks: 1359862, 1431788, 1431790, 1431792, 1519016, 1558125, 1595018, 1623566, 1668199, 1679810, 1919797    

Comment 2 Yanqiu Zhang 2018-12-28 09:31:20 UTC
Try to verify this bug on rhel8.0 with:
libvirt-daemon-4.5.0-16.module+el8+2586+bf759444.x86_64
qemu-kvm-2.12.0-51.module+el8+2608+a17c4bfe.x86_64

Steps to verify:
1. Prepare a host with tpm chip and it's enabled in bios.
# modprobe -r tpm_tis  (we can see tpm_tis is builtin)
modprobe: FATAL: Module tpm_tis is builtin.
# systemctl start tcsd
# yum install tpm_tools
# tpm_version
  TPM 1.2 Version Info:
  Chip Version:        1.2.13.12
  Spec Level:          2
  Errata Revision:     3
  TPM Vendor ID:       STM 
  Vendor Specific data: 50
  TPM Version:         01010000
  Manufacturer Info:   53544d20
# ls /dev/tpm0
/dev/tpm0

2. Start a guest without tpm, check in guest os:
# tcsd -f
TCSD TDDL ERROR: Could not find a device to open!

3.Edit guest with tpm passthrough, and try to start it:
    <tpm model='tpm-tis'>
      <backend type='passthrough'>
        <device path='/dev/tpm0'/>
      </backend>
    </tpm>

# virsh start rhel8.0-yqz 
error: Failed to start domain rhel8.0-yqz
error: Could not open TPM device /dev/tpm0: Device or resource busy

4. Stop host use for the tpm, then start guest again:
# systemctl stop tcsd
# tpm_version
Tspi_Context_Connect failed: 0x00003011 - layer=tsp, code=0011 (17), Communication failure

# virsh start rhel8.0-yqz 
Domain rhel8.0-yqz started

# ps aux|grep qemu-kvm|grep tpm
qemu      9452 29.8  6.8 3817080 537588 ?      Sl   17:06   0:14 /usr/libexec/qemu-kvm -name guest=rhel8.0-yqz,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-2-rhel8.0-yqz/master-key.aes -machine pc-q35-rhel7.6.0,accel=kvm,usb=off,vmport=off,dump-guest-core=off -cpu Haswell-noTSX-IBRS,vme=on,ss=on,f16c=on,rdrand=on,hypervisor=on,arat=on,tsc_adjust=on,umip=on,stibp=on,ssbd=on,xsaveopt=on,pdpe1gb=on,abm=on -m 1024 -realtime mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid 74e8cfa0-0beb-40ac-9662-17d5da05c52d -no-user-config -nodefaults -chardev socket,id=charmonitor,fd=30,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -global ICH9-LPC.disable_s3=1 -global ICH9-LPC.disable_s4=1 -boot strict=on -device pcie-root-port,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x2 -device pcie-root-port,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 -device pcie-root-port,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 -device pcie-root-port,port=0x13,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 -device pcie-root-port,port=0x14,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 -device pcie-root-port,port=0x15,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 -device pcie-root-port,port=0x16,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x6 -device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 -device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 -drive file=/var/lib/libvirt/images/rhel8.0-yqz.qcow2,format=qcow2,if=none,id=drive-virtio-disk0 -device virtio-blk-pci,scsi=off,bus=pci.4,addr=0x0,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -netdev tap,fd=32,id=hostnet0,vhost=on,vhostfd=33 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:3a:3d:9f,bus=pci.1,addr=0x0 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -chardev socket,id=charchannel0,fd=34,server,nowait -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 -chardev spicevmc,id=charchannel1,name=vdagent -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=com.redhat.spice.0 ********-tpmdev passthrough,id=tpm-tpm0,path=/dev/fdset/4,cancel-path=/dev/fdset/5 -add-fd set=4,fd=35 -add-fd set=5,fd=36 -device tpm-tis,tpmdev=tpm-tpm0,id=tpm0******** -device usb-tablet,id=input0,bus=usb.0,port=1 -spice port=5900,addr=127.0.0.1,disable-ticketing,seamless-migration=on -device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pcie.0,addr=0x1 -device ich9-intel-hda,id=sound0,bus=pcie.0,addr=0x1b -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -chardev spicevmc,id=charredir0,name=usbredir -device usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev spicevmc,id=charredir1,name=usbredir -device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device virtio-balloon-pci,id=balloon0,bus=pci.5,addr=0x0 -object rng-random,id=objrng0,filename=/dev/urandom -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.6,addr=0x0 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg timestamp=on

5. Check tpm in guest os:
# systemctl start tcsd
# ls /dev/tpm0
/dev/tpm0
# yum install tpm-tools
# tpm_version
host6 localhost6.localdo��  TPM 1.2 Version Info:
  Chip Version:        1.2.13.12
  Spec Level:          2
  Errata Revision:     3
  TPM Vendor ID:       STM 
  Vendor Specific data: 50
  TPM Version:         01010000
  Manufacturer Info:   53544d20

6. Try to use tpm on host again:
# tcsd -f
TCSD TDDL ERROR: Could not find a device to open!

Comment 3 Yanqiu Zhang 2018-12-28 10:12:20 UTC
Scenario 2: check default choose
1. Try to edit guest with:
    <tpm>
      <backend type='passthrough'>
      </backend>
    </tpm>
2. Check guest xml again, the default choose for model is tpm-tis, and device path is /dev/tpm0.
# virsh dumpxml rhel8.0-yqz |grep 'tpm model' -A6
    <tpm model='tpm-tis'>
      <backend type='passthrough'>
        <device path='/dev/tpm0'/>
      </backend>
    </tpm>


Scenario 3: 'tpm-crb' model when backend is tpm 1.2
From libvirt.org, "model: ... Since 4.4.0, another available choice is the tpm-crb, which should only be used when the backend device is a TPM 2.0."
1. If start guest with 'tpm-crb' model when host tpm version is 1.2:
    <tpm model='tpm-crb'>
      <backend type='passthrough'>
        <device path='/dev/tpm0'/>
      </backend>
      <alias name='tpm0'/>
    </tpm>
# ps aux|grep qemu-kvm|grep tpm
... -tpmdev passthrough,id=tpm-tpm0,path=/dev/fdset/4,cancel-path=/dev/fdset/5 -add-fd set=4,fd=35 -add-fd set=5,fd=36 -device tpm-crb,tpmdev=tpm-tpm0,id=tpm0 ...

2.Guest can be started but tpm can not be used in guest os:
# tcsd -f
TCSD TDDL ERROR: Could not find a device to open!
# dmesg|grep tpm
[    0.796479] tpm_tis MSFT0101:00: [Firmware Bug]: failed to get TPM2 ACPI table
[    0.798589] tpm_tis: probe of MSFT0101:00 failed with error -22
[    0.800107] tpm_crb MSFT0101:00: [Firmware Bug]: failed to get TPM2 ACPI table
[    0.802184] tpm_crb: probe of MSFT0101:00 failed with error -22

Comment 9 Yanqiu Zhang 2019-01-22 08:13:01 UTC
Verify this bug per comment 2 and comment 3.
Tpm2.0 backend scenarios will be tested when tpm2.0 device arrived, being tracked in new bug: https://bugzilla.redhat.com/show_bug.cgi?id=1668199

Thx.