diff --git a/devicemodel/hw/pci/gvt.c b/devicemodel/hw/pci/gvt.c index 0ce97b66d..ae03f7e7c 100644 --- a/devicemodel/hw/pci/gvt.c +++ b/devicemodel/hw/pci/gvt.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "dm.h" #include "pci_core.h" @@ -39,7 +38,7 @@ struct pci_gvt { int host_config_fd; FILE *gvt_file; /* PCI config space */ - uint8_t *host_config; + uint8_t host_config[PCI_REGMAX+1]; int instance_created; }; @@ -87,16 +86,10 @@ pci_gvt_read(struct vmctx *ctx, int vcpu, struct pci_vdev *pi, static int gvt_init_config(struct pci_gvt *gvt) { - int ret, len; + int ret; char name[PATH_MAX]; uint8_t cap_ptr = 0; - gvt->host_config = calloc(1, 256); - if (!gvt->host_config) { - perror("gvt:calloc host config failed\n"); - return -1; - } - snprintf(name, sizeof(name), "/sys/bus/pci/devices/%04x:%02x:%02x.%x/config", gvt->addr.domain, gvt->addr.bus, gvt->addr.slot, @@ -107,12 +100,13 @@ gvt_init_config(struct pci_gvt *gvt) return -1; } - len = 256; - ret = pread(gvt->host_config_fd, gvt->host_config, len, 0); - if (ret < len) { - ret = ret < 0 ? -errno : -EFAULT; - perror("failed to read host device config space"); - return ret; + ret = pread(gvt->host_config_fd, gvt->host_config, PCI_REGMAX+1, 0); + + close(gvt->host_config_fd); + + if (ret <= PCI_REGMAX) { + perror("failed to read host device config space\n"); + return -1; } /* initialize config space */ @@ -145,18 +139,31 @@ gvt_init_config(struct pci_gvt *gvt) /* processor graphics control register */ pci_set_cfgdata16(gvt->gvt_pi, 0x52, gvt->host_config[0x52]); + /* Alloc resource only and no need to register bar for gvt */ ret = pci_emul_alloc_bar(gvt->gvt_pi, 0, PCIBAR_MEM32, 16 * 1024 * 1024); - assert(ret == 0); + if (ret != 0) { + fprintf(stderr, + "allocate gvt pci bar[0] failed\n"); + return -1; + } + /* same as host, but guest only use partition of it by ballon */ ret = pci_emul_alloc_bar(gvt->gvt_pi, 2, PCIBAR_MEM32, 256 * 1024 * 1024); - assert(ret == 0); + if (ret != 0) { + fprintf(stderr, + "allocate gvt pci bar[2] failed\n"); + return -1; + } + /* same as host, lagecy vga usage */ ret = pci_emul_alloc_bar(gvt->gvt_pi, 4, PCIBAR_IO, 64); - assert(ret == 0); - - close(gvt->host_config_fd); + if (ret != 0) { + fprintf(stderr, + "allocate gvt pci bar[4] failed\n"); + return -1; + } return 0; } @@ -179,7 +186,8 @@ gvt_create_instance(struct pci_gvt *gvt) if (gvt_low_gm_sz <= 0 || gvt_high_gm_sz <= 0 || gvt_fence_sz <= 0) { WPRINTF(("GVT: %s failed: invalid parameters!\n", __func__)); - abort(); + fclose(gvt->gvt_file); + return -EINVAL; } /* The format of the string is: @@ -240,6 +248,7 @@ pci_gvt_init(struct vmctx *ctx, struct pci_vdev *pi, char *opts) return -1; } + gvt->instance_created = 0; gvt->addr.domain = 0; gvt->addr.bus = pi->bus; gvt->addr.slot = pi->slot; @@ -251,25 +260,28 @@ pci_gvt_init(struct vmctx *ctx, struct pci_vdev *pi, char *opts) ret = gvt_init_config(gvt); + if (ret) + goto fail; + ret = gvt_create_instance(gvt); - return ret; + if(!ret) + return ret; +fail: + perror("GVT: init failed\n"); + free(gvt); + return -1; } void pci_gvt_deinit(struct vmctx *ctx, struct pci_vdev *pi, char *opts) { - int ret; struct pci_gvt *gvt = pi->arg; + int ret = 0; if (gvt) { - if (gvt->host_config) { - /* Free the allocated host_config */ - free(gvt->host_config); - gvt->host_config = NULL; - } - - ret = gvt_destroy_instance(gvt); + if (gvt->instance_created) + ret = gvt_destroy_instance(gvt); if (ret) WPRINTF(("GVT: %s: failed: errno=%d\n", __func__, ret));