Changeset 81402 in vbox
- Timestamp:
- Oct 21, 2019 12:23:24 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r81348 r81402 884 884 { 885 885 PVIRTIOSTATE pVirtio = *PDMINS_2_DATA(pDevIns, PVIRTIOSTATE *); 886 RT_NOREF(pPciDev, cb); 887 888 uint64_t uWindowOff = (uint64_t)uAddress - (uint64_t)pVirtio->pPciCfgCap->uPciCfgData; 889 if (uWindowOff < sizeof(uint32_t)) 886 RT_NOREF(pPciDev); 887 888 LogFlowFunc(("pDevIns=%p pPciDev=%p uAddress=%#x cb=%u pu32Value=%p\n", 889 pDevIns, pPciDev, uAddress, cb, pu32Value)); 890 if (uAddress == pVirtio->uPciCfgDataOff) 891 { 892 /* 893 * VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability 894 * whereby the guest driver can specify a bar, offset, and length via the PCI configuration space 895 * (the virtio_pci_cfg_cap capability), and access data items. 896 */ 897 uint32_t uLength = pVirtio->pPciCfgCap->pciCap.uLength; 898 uint32_t uOffset = pVirtio->pPciCfgCap->pciCap.uOffset; 899 uint8_t uBar = pVirtio->pPciCfgCap->pciCap.uBar; 900 901 if ( (uLength != 1 && uLength != 2 && uLength != 4) 902 || cb != uLength 903 || uBar != VIRTIO_REGION_PCI_CAP) 904 { 905 Log2Func(("Guest read virtio_pci_cfg_cap.pci_cfg_data using mismatching config. Ignoring\n")); 906 *pu32Value = UINT32_MAX; 907 return VINF_SUCCESS; 908 } 909 910 int rc = virtioR3MmioRead(pDevIns, NULL, pVirtio->pGcPhysPciCapBase + uOffset, pu32Value, cb); 911 Log2Func(("virtio: Guest read virtio_pci_cfg_cap.pci_cfg_data, bar=%d, offset=%d, length=%d, result=%d -> %Rrc\n", 912 uBar, uOffset, uLength, *pu32Value, rc)); 913 return rc; 914 } 915 return VINF_PDM_PCI_DO_DEFAULT; 916 } 917 918 /** 919 * @callback_method_impl{FNPCICONFIGWRITE} 920 */ 921 static DECLCALLBACK(VBOXSTRICTRC) virtioR3PciConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, 922 uint32_t uAddress, unsigned cb, uint32_t u32Value) 923 { 924 PVIRTIOSTATE pVirtio = *PDMINS_2_DATA(pDevIns, PVIRTIOSTATE *); 925 RT_NOREF(pPciDev); 926 927 LogFlowFunc(("pDevIns=%p pPciDev=%p uAddress=%#x cb=%u u32Value=%#x\n", 928 pDevIns, pPciDev, uAddress, cb, u32Value)); 929 if (uAddress == pVirtio->uPciCfgDataOff) 890 930 { 891 931 /* VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability … … 897 937 uint8_t uBar = pVirtio->pPciCfgCap->pciCap.uBar; 898 938 899 AssertReturn(uLength == 1 || uLength == 2 || uLength == 4, VERR_INVALID_PARAMETER); 900 AssertReturn(cb + uWindowOff <= uLength, VERR_INVALID_PARAMETER); 901 902 *pu32Value = 0xffffffff; 903 if (uBar == VIRTIO_REGION_PCI_CAP) 904 { 905 uint32_t pu32tmp = 0; 906 virtioR3MmioRead(pDevIns, NULL, (RTGCPHYS)((uint32_t)pVirtio->pGcPhysPciCapBase + uOffset), &pu32tmp, uLength); 907 memcpy(pu32Value + uWindowOff, &pu32tmp + uWindowOff, cb); 908 Log2Func(("virtio: Guest read virtio_pci_cfg_cap.pci_cfg_data, bar=%d, offset=%d, length=%d, result=%d\n", 909 uBar, uOffset, uLength, *pu32Value)); 910 } 911 else 912 Log2Func(("Guest read virtio_pci_cfg_cap.pci_cfg_data using unconfigured BAR. Ignoring")); 913 return VINF_SUCCESS; 914 } 915 return VINF_PDM_PCI_DO_DEFAULT; 916 } 917 918 /** 919 * @callback_method_impl{FNPCICONFIGWRITE} 920 */ 921 static DECLCALLBACK(VBOXSTRICTRC) virtioR3PciConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, 922 uint32_t uAddress, unsigned cb, uint32_t u32Value) 923 { 924 PVIRTIOSTATE pVirtio = *PDMINS_2_DATA(pDevIns, PVIRTIOSTATE *); 925 RT_NOREF(pPciDev, cb); 926 927 uint64_t uWindowOff = (uint64_t)uAddress - (uint64_t)pVirtio->pPciCfgCap->uPciCfgData; 928 if (uWindowOff < sizeof(uint32_t)) 929 { 930 /* VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability 931 * whereby the guest driver can specify a bar, offset, and length via the PCI configuration space 932 * (the virtio_pci_cfg_cap capability), and access data items. */ 933 934 uint32_t uLength = pVirtio->pPciCfgCap->pciCap.uLength; 935 uint32_t uOffset = pVirtio->pPciCfgCap->pciCap.uOffset; 936 uint8_t uBar = pVirtio->pPciCfgCap->pciCap.uBar; 937 938 AssertReturn(uLength == 1 || uLength == 2 || uLength == 4, VERR_INVALID_PARAMETER); 939 AssertReturn(cb == uLength && uWindowOff == 0, VERR_INVALID_PARAMETER); 940 941 if (uBar == VIRTIO_REGION_PCI_CAP) 942 { 943 Assert(uLength <= sizeof(u32Value)); 944 virtioR3MmioWrite(pDevIns, NULL, (RTGCPHYS)((uint32_t)pVirtio->pGcPhysPciCapBase + uOffset), &u32Value, uLength); 945 } 946 else 947 { 948 Log2Func(("Guest wrote virtio_pci_cfg_cap.pci_cfg_data using unconfigured BAR. Ignoring")); 939 if ( (uLength != 1 && uLength != 2 && uLength != 4) 940 || cb != uLength 941 || uBar != VIRTIO_REGION_PCI_CAP) 942 { 943 Log2Func(("Guest write virtio_pci_cfg_cap.pci_cfg_data using mismatching config. Ignoring\n")); 949 944 return VINF_SUCCESS; 950 945 } 951 Log2Func(("Guest wrote virtio_pci_cfg_cap.pci_cfg_data, bar=%d, offset=%x, length=%x, value=%d\n", 952 uBar, uOffset, uLength, u32Value)); 953 return VINF_SUCCESS; 946 947 int rc = virtioR3MmioWrite(pDevIns, NULL, pVirtio->pGcPhysPciCapBase + uOffset, &u32Value, cb); 948 Log2Func(("Guest wrote virtio_pci_cfg_cap.pci_cfg_data, bar=%d, offset=%x, length=%x, value=%d -> %Rrc\n", 949 uBar, uOffset, uLength, u32Value, rc)); 950 return rc; 954 951 } 955 952 return VINF_PDM_PCI_DO_DEFAULT; … … 1173 1170 * initializing. */ 1174 1171 1172 pVirtio->uPciCfgDataOff = pCfg->uCapNext + RT_OFFSETOF(VIRTIO_PCI_CFG_CAP_T, uPciCfgData); 1175 1173 pCfg = (PVIRTIO_PCI_CAP_T)&pPciDev->abConfig[pCfg->uCapNext]; 1176 1174 pCfg->uCfgType = VIRTIO_PCI_CAP_PCI_CFG;
Note:
See TracChangeset
for help on using the changeset viewer.