Skip to content

Commit 026250f

Browse files
donshengEddie Dong
authored andcommitted
HV: centralize the pci cfg read/write sanity checking code
Do the pci cfg read/write sanity checking before the request is dispatched to submodules, so that the checking is centralized rather than scattered across multiple files/places Tracked-On: #2534 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent a403128 commit 026250f

File tree

5 files changed

+32
-36
lines changed

5 files changed

+32
-36
lines changed

hypervisor/dm/vpci/hostbridge.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,6 @@ void vdev_hostbridge_deinit(__unused const struct pci_vdev *vdev)
9191
int32_t vdev_hostbridge_cfgread(const struct pci_vdev *vdev, uint32_t offset,
9292
uint32_t bytes, uint32_t *val)
9393
{
94-
/* Assumption: access needed to be aligned on 1/2/4 bytes */
95-
if ((offset & (bytes - 1U)) != 0U) {
96-
*val = 0xFFFFFFFFU;
97-
return -EINVAL;
98-
}
99-
10094
*val = pci_vdev_read_cfg(vdev, offset, bytes);
10195

10296
return 0;
@@ -105,11 +99,6 @@ int32_t vdev_hostbridge_cfgread(const struct pci_vdev *vdev, uint32_t offset,
10599
int32_t vdev_hostbridge_cfgwrite(struct pci_vdev *vdev, uint32_t offset,
106100
uint32_t bytes, uint32_t val)
107101
{
108-
/* Assumption: access needed to be aligned on 1/2/4 bytes */
109-
if ((offset & (bytes - 1U)) != 0U) {
110-
return -EINVAL;
111-
}
112-
113102
if (!pci_bar_access(offset)) {
114103
pci_vdev_write_cfg(vdev, offset, bytes, val);
115104
}

hypervisor/dm/vpci/msi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ static int32_t vmsi_remap(const struct pci_vdev *vdev, bool enable)
118118
int32_t vmsi_cfgread(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val)
119119
{
120120
int32_t ret;
121+
121122
/* For PIO access, we emulate Capability Structures only */
122123
if (msicap_access(vdev, offset)) {
123124
*val = pci_vdev_read_cfg(vdev, offset, bytes);

hypervisor/dm/vpci/pci_pt.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,6 @@ void vdev_pt_deinit(const struct pci_vdev *vdev)
105105
int32_t vdev_pt_cfgread(const struct pci_vdev *vdev, uint32_t offset,
106106
uint32_t bytes, uint32_t *val)
107107
{
108-
/* Assumption: access needed to be aligned on 1/2/4 bytes */
109-
if ((offset & (bytes - 1U)) != 0U) {
110-
*val = 0xFFFFFFFFU;
111-
return -EINVAL;
112-
}
113-
114108
/* PCI BARs is emulated */
115109
if (pci_bar_access(offset)) {
116110
*val = pci_vdev_read_cfg(vdev, offset, bytes);
@@ -184,11 +178,6 @@ static void vdev_pt_cfgwrite_bar(struct pci_vdev *vdev, uint32_t offset,
184178
int32_t vdev_pt_cfgwrite(struct pci_vdev *vdev, uint32_t offset,
185179
uint32_t bytes, uint32_t val)
186180
{
187-
/* Assumption: access needed to be aligned on 1/2/4 bytes */
188-
if ((offset & (bytes - 1U)) != 0U) {
189-
return -EINVAL;
190-
}
191-
192181
/* PCI BARs are emulated */
193182
if (pci_bar_access(offset)) {
194183
vdev_pt_cfgwrite_bar(vdev, offset, bytes, val);

hypervisor/dm/vpci/sharing_mode.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void sharing_mode_cfgread(__unused struct acrn_vpci *vpci, union pci_bdf bdf,
5050
vdev = sharing_mode_find_vdev_sos(bdf);
5151

5252
/* vdev == NULL: Could be hit for PCI enumeration from guests */
53-
if ((vdev == NULL) || ((bytes != 1U) && (bytes != 2U) && (bytes != 4U))) {
53+
if (vdev == NULL) {
5454
*val = ~0U;
5555
} else {
5656
if ((vmsi_cfgread(vdev, offset, bytes, val) != 0)
@@ -67,15 +67,13 @@ void sharing_mode_cfgwrite(__unused struct acrn_vpci *vpci, union pci_bdf bdf,
6767
{
6868
struct pci_vdev *vdev;
6969

70-
if ((bytes == 1U) || (bytes == 2U) || (bytes == 4U)) {
71-
vdev = sharing_mode_find_vdev_sos(bdf);
72-
if (vdev != NULL) {
73-
if ((vmsi_cfgwrite(vdev, offset, bytes, val) != 0)
74-
&& (vmsix_cfgwrite(vdev, offset, bytes, val) != 0)
75-
) {
76-
/* Not handled by any handlers, passthru to physical device */
77-
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
78-
}
70+
vdev = sharing_mode_find_vdev_sos(bdf);
71+
if (vdev != NULL) {
72+
if ((vmsi_cfgwrite(vdev, offset, bytes, val) != 0)
73+
&& (vmsix_cfgwrite(vdev, offset, bytes, val) != 0)
74+
) {
75+
/* Not handled by any handlers, passthru to physical device */
76+
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
7977
}
8078
}
8179
}

hypervisor/dm/vpci/vpci.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ static void pci_cfgaddr_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes
6767
}
6868
}
6969

70+
static inline bool vpci_is_valid_access_offset(uint32_t offset, uint32_t bytes)
71+
{
72+
return ((offset & (bytes - 1U)) == 0U);
73+
}
74+
75+
static inline bool vpci_is_valid_access_byte(uint32_t bytes)
76+
{
77+
return ((bytes == 1U) || (bytes == 2U) || (bytes == 4U));
78+
}
79+
80+
static inline bool vpci_is_valid_access(uint32_t offset, uint32_t bytes)
81+
{
82+
return (vpci_is_valid_access_byte(bytes) && vpci_is_valid_access_offset(offset, bytes));
83+
}
84+
7085
static uint32_t pci_cfgdata_io_read(struct acrn_vm *vm, uint16_t addr, size_t bytes)
7186
{
7287
struct acrn_vpci *vpci = &vm->vpci;
@@ -75,11 +90,13 @@ static uint32_t pci_cfgdata_io_read(struct acrn_vm *vm, uint16_t addr, size_t by
7590
uint32_t val = ~0U;
7691

7792
if (pi->cached_enable) {
93+
if (vpci_is_valid_access(pi->cached_reg + offset, bytes)) {
7894
#ifdef CONFIG_PARTITION_MODE
79-
partition_mode_cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val);
95+
partition_mode_cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val);
8096
#else
81-
sharing_mode_cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val);
97+
sharing_mode_cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val);
8298
#endif
99+
}
83100
pci_cfg_clear_cache(pi);
84101
}
85102

@@ -93,11 +110,13 @@ static void pci_cfgdata_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes
93110
uint16_t offset = addr - PCI_CONFIG_DATA;
94111

95112
if (pi->cached_enable) {
113+
if (vpci_is_valid_access(pi->cached_reg + offset, bytes)) {
96114
#ifdef CONFIG_PARTITION_MODE
97-
partition_mode_cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val);
115+
partition_mode_cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val);
98116
#else
99-
sharing_mode_cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val);
117+
sharing_mode_cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val);
100118
#endif
119+
}
101120
pci_cfg_clear_cache(pi);
102121
}
103122
}

0 commit comments

Comments
 (0)