qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

tpm: Separate tpm_tis common functions from isa code

Move the device agnostic code into tpm_tis_common.c and
put the ISA device specific code into tpm_tis_isa.c

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Message-id: 20200305165149.618-4-eric.auger@redhat.com
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>

authored by

Eric Auger and committed by
Stefan Berger
ac90053d ca75c421

+271 -201
+1 -1
hw/tpm/Makefile.objs
··· 1 1 common-obj-$(CONFIG_TPM) += tpm_util.o 2 2 obj-$(call lor,$(CONFIG_TPM_TIS),$(CONFIG_TPM_CRB)) += tpm_ppi.o 3 - common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o 3 + common-obj-$(CONFIG_TPM_TIS) += tpm_tis_isa.o tpm_tis_common.o 4 4 common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o 5 5 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o 6 6 common-obj-$(CONFIG_TPM_EMULATOR) += tpm_emulator.o
+9 -200
hw/tpm/tpm_tis.c hw/tpm/tpm_tis_common.c
··· 1 1 /* 2 - * tpm_tis.c - QEMU's TPM TIS interface emulator 2 + * tpm_tis_common.c - QEMU's TPM TIS interface emulator 3 + * device agnostic functions 3 4 * 4 5 * Copyright (C) 2006,2010-2013 IBM Corporation 5 6 * ··· 21 22 * TPM TIS for TPM 2 implementation following TCG PC Client Platform 22 23 * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43 23 24 */ 24 - 25 25 #include "qemu/osdep.h" 26 26 #include "hw/irq.h" 27 27 #include "hw/isa/isa.h" ··· 38 38 #include "tpm_ppi.h" 39 39 #include "trace.h" 40 40 41 - #define TPM_TIS_NUM_LOCALITIES 5 /* per spec */ 42 - #define TPM_TIS_LOCALITY_SHIFT 12 43 - #define TPM_TIS_NO_LOCALITY 0xff 44 - 45 - #define TPM_TIS_IS_VALID_LOCTY(x) ((x) < TPM_TIS_NUM_LOCALITIES) 46 - 47 - #define TPM_TIS_BUFFER_MAX 4096 48 - 49 - typedef enum { 50 - TPM_TIS_STATE_IDLE = 0, 51 - TPM_TIS_STATE_READY, 52 - TPM_TIS_STATE_COMPLETION, 53 - TPM_TIS_STATE_EXECUTION, 54 - TPM_TIS_STATE_RECEPTION, 55 - } TPMTISState; 56 - 57 - /* locality data -- all fields are persisted */ 58 - typedef struct TPMLocality { 59 - TPMTISState state; 60 - uint8_t access; 61 - uint32_t sts; 62 - uint32_t iface_id; 63 - uint32_t inte; 64 - uint32_t ints; 65 - } TPMLocality; 66 - 67 - typedef struct TPMState { 68 - MemoryRegion mmio; 69 - 70 - unsigned char buffer[TPM_TIS_BUFFER_MAX]; 71 - uint16_t rw_offset; 72 - 73 - uint8_t active_locty; 74 - uint8_t aborting_locty; 75 - uint8_t next_locty; 76 - 77 - TPMLocality loc[TPM_TIS_NUM_LOCALITIES]; 78 - 79 - qemu_irq irq; 80 - uint32_t irq_num; 81 - 82 - TPMBackendCmd cmd; 83 - 84 - TPMBackend *be_driver; 85 - TPMVersion be_tpm_version; 86 - 87 - size_t be_buffer_size; 88 - 89 - bool ppi_enabled; 90 - TPMPPI ppi; 91 - } TPMState; 92 - 93 - typedef struct TPMStateISA { 94 - /*< private >*/ 95 - ISADevice parent_obj; 96 - 97 - /*< public >*/ 98 - TPMState state; /* not a QOM object */ 99 - } TPMStateISA; 100 - 101 - #define TPM_TIS_ISA(obj) OBJECT_CHECK(TPMStateISA, (obj), TYPE_TPM_TIS_ISA) 41 + #include "tpm_tis.h" 102 42 103 43 #define DEBUG_TIS 0 104 44 ··· 288 228 /* 289 229 * Callback from the TPM to indicate that the response was received. 290 230 */ 291 - static void tpm_tis_request_completed(TPMState *s, int ret) 231 + void tpm_tis_request_completed(TPMState *s, int ret) 292 232 { 293 233 uint8_t locty = s->cmd.locty; 294 234 uint8_t l; ··· 827 767 } 828 768 } 829 769 830 - static const MemoryRegionOps tpm_tis_memory_ops = { 770 + const MemoryRegionOps tpm_tis_memory_ops = { 831 771 .read = tpm_tis_mmio_read, 832 772 .write = tpm_tis_mmio_write, 833 773 .endianness = DEVICE_LITTLE_ENDIAN, ··· 840 780 /* 841 781 * Get the TPMVersion of the backend device being used 842 782 */ 843 - static enum TPMVersion tpm_tis_get_tpm_version(TPMState *s) 783 + enum TPMVersion tpm_tis_get_tpm_version(TPMState *s) 844 784 { 845 785 if (tpm_backend_had_startup_error(s->be_driver)) { 846 786 return TPM_VERSION_UNSPEC; ··· 853 793 * This function is called when the machine starts, resets or due to 854 794 * S3 resume. 855 795 */ 856 - static void tpm_tis_reset(TPMState *s) 796 + void tpm_tis_reset(TPMState *s) 857 797 { 858 798 int c; 859 799 ··· 898 838 899 839 /* persistent state handling */ 900 840 901 - static int tpm_tis_pre_save(TPMState *s) 841 + int tpm_tis_pre_save(TPMState *s) 902 842 { 903 843 uint8_t locty = s->active_locty; 904 844 ··· 916 856 return 0; 917 857 } 918 858 919 - static const VMStateDescription vmstate_locty = { 859 + const VMStateDescription vmstate_locty = { 920 860 .name = "tpm-tis/locty", 921 861 .version_id = 0, 922 862 .fields = (VMStateField[]) { ··· 930 870 } 931 871 }; 932 872 933 - /* ISA */ 934 - 935 - static int tpm_tis_pre_save_isa(void *opaque) 936 - { 937 - TPMStateISA *isadev = opaque; 938 - 939 - return tpm_tis_pre_save(&isadev->state); 940 - } 941 - 942 - static const VMStateDescription vmstate_tpm_tis_isa = { 943 - .name = "tpm-tis", 944 - .version_id = 0, 945 - .pre_save = tpm_tis_pre_save_isa, 946 - .fields = (VMStateField[]) { 947 - VMSTATE_BUFFER(state.buffer, TPMStateISA), 948 - VMSTATE_UINT16(state.rw_offset, TPMStateISA), 949 - VMSTATE_UINT8(state.active_locty, TPMStateISA), 950 - VMSTATE_UINT8(state.aborting_locty, TPMStateISA), 951 - VMSTATE_UINT8(state.next_locty, TPMStateISA), 952 - 953 - VMSTATE_STRUCT_ARRAY(state.loc, TPMStateISA, TPM_TIS_NUM_LOCALITIES, 0, 954 - vmstate_locty, TPMLocality), 955 - 956 - VMSTATE_END_OF_LIST() 957 - } 958 - }; 959 - 960 - static void tpm_tis_isa_request_completed(TPMIf *ti, int ret) 961 - { 962 - TPMStateISA *isadev = TPM_TIS_ISA(ti); 963 - TPMState *s = &isadev->state; 964 - 965 - tpm_tis_request_completed(s, ret); 966 - } 967 - 968 - static enum TPMVersion tpm_tis_isa_get_tpm_version(TPMIf *ti) 969 - { 970 - TPMStateISA *isadev = TPM_TIS_ISA(ti); 971 - TPMState *s = &isadev->state; 972 - 973 - return tpm_tis_get_tpm_version(s); 974 - } 975 - 976 - static void tpm_tis_isa_reset(DeviceState *dev) 977 - { 978 - TPMStateISA *isadev = TPM_TIS_ISA(dev); 979 - TPMState *s = &isadev->state; 980 - 981 - return tpm_tis_reset(s); 982 - } 983 - 984 - static Property tpm_tis_isa_properties[] = { 985 - DEFINE_PROP_UINT32("irq", TPMStateISA, state.irq_num, TPM_TIS_IRQ), 986 - DEFINE_PROP_TPMBE("tpmdev", TPMStateISA, state.be_driver), 987 - DEFINE_PROP_BOOL("ppi", TPMStateISA, state.ppi_enabled, true), 988 - DEFINE_PROP_END_OF_LIST(), 989 - }; 990 - 991 - static void tpm_tis_isa_initfn(Object *obj) 992 - { 993 - TPMStateISA *isadev = TPM_TIS_ISA(obj); 994 - TPMState *s = &isadev->state; 995 - 996 - memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops, 997 - s, "tpm-tis-mmio", 998 - TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT); 999 - } 1000 - 1001 - static void tpm_tis_isa_realizefn(DeviceState *dev, Error **errp) 1002 - { 1003 - TPMStateISA *isadev = TPM_TIS_ISA(dev); 1004 - TPMState *s = &isadev->state; 1005 - 1006 - if (!tpm_find()) { 1007 - error_setg(errp, "at most one TPM device is permitted"); 1008 - return; 1009 - } 1010 - 1011 - if (!s->be_driver) { 1012 - error_setg(errp, "'tpmdev' property is required"); 1013 - return; 1014 - } 1015 - if (s->irq_num > 15) { 1016 - error_setg(errp, "IRQ %d is outside valid range of 0 to 15", 1017 - s->irq_num); 1018 - return; 1019 - } 1020 - 1021 - isa_init_irq(ISA_DEVICE(dev), &s->irq, s->irq_num); 1022 - 1023 - memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)), 1024 - TPM_TIS_ADDR_BASE, &s->mmio); 1025 - 1026 - if (s->ppi_enabled) { 1027 - tpm_ppi_init(&s->ppi, isa_address_space(ISA_DEVICE(dev)), 1028 - TPM_PPI_ADDR_BASE, OBJECT(dev)); 1029 - } 1030 - } 1031 - 1032 - static void tpm_tis_isa_class_init(ObjectClass *klass, void *data) 1033 - { 1034 - DeviceClass *dc = DEVICE_CLASS(klass); 1035 - TPMIfClass *tc = TPM_IF_CLASS(klass); 1036 - 1037 - device_class_set_props(dc, tpm_tis_isa_properties); 1038 - dc->vmsd = &vmstate_tpm_tis_isa; 1039 - tc->model = TPM_MODEL_TPM_TIS; 1040 - dc->realize = tpm_tis_isa_realizefn; 1041 - dc->reset = tpm_tis_isa_reset; 1042 - tc->request_completed = tpm_tis_isa_request_completed; 1043 - tc->get_version = tpm_tis_isa_get_tpm_version; 1044 - } 1045 - 1046 - static const TypeInfo tpm_tis_isa_info = { 1047 - .name = TYPE_TPM_TIS_ISA, 1048 - .parent = TYPE_ISA_DEVICE, 1049 - .instance_size = sizeof(TPMStateISA), 1050 - .instance_init = tpm_tis_isa_initfn, 1051 - .class_init = tpm_tis_isa_class_init, 1052 - .interfaces = (InterfaceInfo[]) { 1053 - { TYPE_TPM_IF }, 1054 - { } 1055 - } 1056 - }; 1057 - 1058 - static void tpm_tis_isa_register(void) 1059 - { 1060 - type_register_static(&tpm_tis_isa_info); 1061 - } 1062 - 1063 - type_init(tpm_tis_isa_register)
+91
hw/tpm/tpm_tis.h
··· 1 + /* 2 + * tpm_tis.h - QEMU's TPM TIS common header 3 + * 4 + * Copyright (C) 2006,2010-2013 IBM Corporation 5 + * 6 + * Authors: 7 + * Stefan Berger <stefanb@us.ibm.com> 8 + * David Safford <safford@us.ibm.com> 9 + * 10 + * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at> 11 + * 12 + * This work is licensed under the terms of the GNU GPL, version 2 or later. 13 + * See the COPYING file in the top-level directory. 14 + * 15 + * Implementation of the TIS interface according to specs found at 16 + * http://www.trustedcomputinggroup.org. This implementation currently 17 + * supports version 1.3, 21 March 2013 18 + * In the developers menu choose the PC Client section then find the TIS 19 + * specification. 20 + * 21 + * TPM TIS for TPM 2 implementation following TCG PC Client Platform 22 + * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43 23 + */ 24 + #ifndef TPM_TPM_TIS_H 25 + #define TPM_TPM_TIS_H 26 + 27 + #include "qemu/osdep.h" 28 + #include "sysemu/tpm_backend.h" 29 + #include "tpm_ppi.h" 30 + 31 + #define TPM_TIS_NUM_LOCALITIES 5 /* per spec */ 32 + #define TPM_TIS_LOCALITY_SHIFT 12 33 + #define TPM_TIS_NO_LOCALITY 0xff 34 + 35 + #define TPM_TIS_IS_VALID_LOCTY(x) ((x) < TPM_TIS_NUM_LOCALITIES) 36 + 37 + #define TPM_TIS_BUFFER_MAX 4096 38 + 39 + typedef enum { 40 + TPM_TIS_STATE_IDLE = 0, 41 + TPM_TIS_STATE_READY, 42 + TPM_TIS_STATE_COMPLETION, 43 + TPM_TIS_STATE_EXECUTION, 44 + TPM_TIS_STATE_RECEPTION, 45 + } TPMTISState; 46 + 47 + /* locality data -- all fields are persisted */ 48 + typedef struct TPMLocality { 49 + TPMTISState state; 50 + uint8_t access; 51 + uint32_t sts; 52 + uint32_t iface_id; 53 + uint32_t inte; 54 + uint32_t ints; 55 + } TPMLocality; 56 + 57 + typedef struct TPMState { 58 + MemoryRegion mmio; 59 + 60 + unsigned char buffer[TPM_TIS_BUFFER_MAX]; 61 + uint16_t rw_offset; 62 + 63 + uint8_t active_locty; 64 + uint8_t aborting_locty; 65 + uint8_t next_locty; 66 + 67 + TPMLocality loc[TPM_TIS_NUM_LOCALITIES]; 68 + 69 + qemu_irq irq; 70 + uint32_t irq_num; 71 + 72 + TPMBackendCmd cmd; 73 + 74 + TPMBackend *be_driver; 75 + TPMVersion be_tpm_version; 76 + 77 + size_t be_buffer_size; 78 + 79 + bool ppi_enabled; 80 + TPMPPI ppi; 81 + } TPMState; 82 + 83 + extern const VMStateDescription vmstate_locty; 84 + extern const MemoryRegionOps tpm_tis_memory_ops; 85 + 86 + int tpm_tis_pre_save(TPMState *s); 87 + void tpm_tis_reset(TPMState *s); 88 + enum TPMVersion tpm_tis_get_tpm_version(TPMState *s); 89 + void tpm_tis_request_completed(TPMState *s, int ret); 90 + 91 + #endif /* TPM_TPM_TIS_H */
+170
hw/tpm/tpm_tis_isa.c
··· 1 + /* 2 + * tpm_tis_isa.c - QEMU's TPM TIS ISA Device 3 + * 4 + * Copyright (C) 2006,2010-2013 IBM Corporation 5 + * 6 + * Authors: 7 + * Stefan Berger <stefanb@us.ibm.com> 8 + * David Safford <safford@us.ibm.com> 9 + * 10 + * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at> 11 + * 12 + * This work is licensed under the terms of the GNU GPL, version 2 or later. 13 + * See the COPYING file in the top-level directory. 14 + * 15 + * Implementation of the TIS interface according to specs found at 16 + * http://www.trustedcomputinggroup.org. This implementation currently 17 + * supports version 1.3, 21 March 2013 18 + * In the developers menu choose the PC Client section then find the TIS 19 + * specification. 20 + * 21 + * TPM TIS for TPM 2 implementation following TCG PC Client Platform 22 + * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43 23 + */ 24 + 25 + #include "qemu/osdep.h" 26 + #include "hw/isa/isa.h" 27 + #include "hw/qdev-properties.h" 28 + #include "migration/vmstate.h" 29 + #include "tpm_util.h" 30 + #include "tpm_tis.h" 31 + 32 + typedef struct TPMStateISA { 33 + /*< private >*/ 34 + ISADevice parent_obj; 35 + 36 + /*< public >*/ 37 + TPMState state; /* not a QOM object */ 38 + } TPMStateISA; 39 + 40 + #define TPM_TIS_ISA(obj) OBJECT_CHECK(TPMStateISA, (obj), TYPE_TPM_TIS_ISA) 41 + 42 + static int tpm_tis_pre_save_isa(void *opaque) 43 + { 44 + TPMStateISA *isadev = opaque; 45 + 46 + return tpm_tis_pre_save(&isadev->state); 47 + } 48 + 49 + static const VMStateDescription vmstate_tpm_tis_isa = { 50 + .name = "tpm-tis", 51 + .version_id = 0, 52 + .pre_save = tpm_tis_pre_save_isa, 53 + .fields = (VMStateField[]) { 54 + VMSTATE_BUFFER(state.buffer, TPMStateISA), 55 + VMSTATE_UINT16(state.rw_offset, TPMStateISA), 56 + VMSTATE_UINT8(state.active_locty, TPMStateISA), 57 + VMSTATE_UINT8(state.aborting_locty, TPMStateISA), 58 + VMSTATE_UINT8(state.next_locty, TPMStateISA), 59 + 60 + VMSTATE_STRUCT_ARRAY(state.loc, TPMStateISA, TPM_TIS_NUM_LOCALITIES, 0, 61 + vmstate_locty, TPMLocality), 62 + 63 + VMSTATE_END_OF_LIST() 64 + } 65 + }; 66 + 67 + static void tpm_tis_isa_request_completed(TPMIf *ti, int ret) 68 + { 69 + TPMStateISA *isadev = TPM_TIS_ISA(ti); 70 + TPMState *s = &isadev->state; 71 + 72 + tpm_tis_request_completed(s, ret); 73 + } 74 + 75 + static enum TPMVersion tpm_tis_isa_get_tpm_version(TPMIf *ti) 76 + { 77 + TPMStateISA *isadev = TPM_TIS_ISA(ti); 78 + TPMState *s = &isadev->state; 79 + 80 + return tpm_tis_get_tpm_version(s); 81 + } 82 + 83 + static void tpm_tis_isa_reset(DeviceState *dev) 84 + { 85 + TPMStateISA *isadev = TPM_TIS_ISA(dev); 86 + TPMState *s = &isadev->state; 87 + 88 + return tpm_tis_reset(s); 89 + } 90 + 91 + static Property tpm_tis_isa_properties[] = { 92 + DEFINE_PROP_UINT32("irq", TPMStateISA, state.irq_num, TPM_TIS_IRQ), 93 + DEFINE_PROP_TPMBE("tpmdev", TPMStateISA, state.be_driver), 94 + DEFINE_PROP_BOOL("ppi", TPMStateISA, state.ppi_enabled, true), 95 + DEFINE_PROP_END_OF_LIST(), 96 + }; 97 + 98 + static void tpm_tis_isa_initfn(Object *obj) 99 + { 100 + TPMStateISA *isadev = TPM_TIS_ISA(obj); 101 + TPMState *s = &isadev->state; 102 + 103 + memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops, 104 + s, "tpm-tis-mmio", 105 + TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT); 106 + } 107 + 108 + static void tpm_tis_isa_realizefn(DeviceState *dev, Error **errp) 109 + { 110 + TPMStateISA *isadev = TPM_TIS_ISA(dev); 111 + TPMState *s = &isadev->state; 112 + 113 + if (!tpm_find()) { 114 + error_setg(errp, "at most one TPM device is permitted"); 115 + return; 116 + } 117 + 118 + if (!s->be_driver) { 119 + error_setg(errp, "'tpmdev' property is required"); 120 + return; 121 + } 122 + if (s->irq_num > 15) { 123 + error_setg(errp, "IRQ %d is outside valid range of 0 to 15", 124 + s->irq_num); 125 + return; 126 + } 127 + 128 + isa_init_irq(ISA_DEVICE(dev), &s->irq, s->irq_num); 129 + 130 + memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)), 131 + TPM_TIS_ADDR_BASE, &s->mmio); 132 + 133 + if (s->ppi_enabled) { 134 + tpm_ppi_init(&s->ppi, isa_address_space(ISA_DEVICE(dev)), 135 + TPM_PPI_ADDR_BASE, OBJECT(dev)); 136 + } 137 + } 138 + 139 + static void tpm_tis_isa_class_init(ObjectClass *klass, void *data) 140 + { 141 + DeviceClass *dc = DEVICE_CLASS(klass); 142 + TPMIfClass *tc = TPM_IF_CLASS(klass); 143 + 144 + device_class_set_props(dc, tpm_tis_isa_properties); 145 + dc->vmsd = &vmstate_tpm_tis_isa; 146 + tc->model = TPM_MODEL_TPM_TIS; 147 + dc->realize = tpm_tis_isa_realizefn; 148 + dc->reset = tpm_tis_isa_reset; 149 + tc->request_completed = tpm_tis_isa_request_completed; 150 + tc->get_version = tpm_tis_isa_get_tpm_version; 151 + } 152 + 153 + static const TypeInfo tpm_tis_isa_info = { 154 + .name = TYPE_TPM_TIS_ISA, 155 + .parent = TYPE_ISA_DEVICE, 156 + .instance_size = sizeof(TPMStateISA), 157 + .instance_init = tpm_tis_isa_initfn, 158 + .class_init = tpm_tis_isa_class_init, 159 + .interfaces = (InterfaceInfo[]) { 160 + { TYPE_TPM_IF }, 161 + { } 162 + } 163 + }; 164 + 165 + static void tpm_tis_isa_register(void) 166 + { 167 + type_register_static(&tpm_tis_isa_info); 168 + } 169 + 170 + type_init(tpm_tis_isa_register)