Merge remote-tracking branch 'mst/for_anthony' into staging
This commit is contained in:
commit
81e34a2401
6
hw/pci.c
6
hw/pci.c
@ -1145,8 +1145,7 @@ uint32_t pci_default_read_config(PCIDevice *d,
|
||||
uint32_t address, int len)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
assert(len == 1 || len == 2 || len == 4);
|
||||
len = MIN(len, pci_config_size(d) - address);
|
||||
|
||||
memcpy(&val, d->config + address, len);
|
||||
return le32_to_cpu(val);
|
||||
}
|
||||
@ -1154,9 +1153,8 @@ uint32_t pci_default_read_config(PCIDevice *d,
|
||||
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
|
||||
{
|
||||
int i, was_irq_disabled = pci_irq_disabled(d);
|
||||
uint32_t config_size = pci_config_size(d);
|
||||
|
||||
for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) {
|
||||
for (i = 0; i < l; val >>= 8, ++i) {
|
||||
uint8_t wmask = d->wmask[addr + i];
|
||||
uint8_t w1cmask = d->w1cmask[addr + i];
|
||||
assert(!(wmask & w1cmask));
|
||||
|
@ -47,17 +47,33 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, uint32_t addr)
|
||||
return pci_find_device(bus, bus_num, devfn);
|
||||
}
|
||||
|
||||
void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
|
||||
uint32_t limit, uint32_t val, uint32_t len)
|
||||
{
|
||||
assert(len <= 4);
|
||||
pci_dev->config_write(pci_dev, addr, val, MIN(len, limit - addr));
|
||||
}
|
||||
|
||||
uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
|
||||
uint32_t limit, uint32_t len)
|
||||
{
|
||||
assert(len <= 4);
|
||||
return pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
|
||||
}
|
||||
|
||||
void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
|
||||
{
|
||||
PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr);
|
||||
uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1);
|
||||
|
||||
if (!pci_dev)
|
||||
if (!pci_dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
PCI_DPRINTF("%s: %s: addr=%02" PRIx32 " val=%08" PRIx32 " len=%d\n",
|
||||
__func__, pci_dev->name, config_addr, val, len);
|
||||
pci_dev->config_write(pci_dev, config_addr, val, len);
|
||||
pci_host_config_write_common(pci_dev, config_addr, PCI_CONFIG_SPACE_SIZE,
|
||||
val, len);
|
||||
}
|
||||
|
||||
uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
|
||||
@ -66,12 +82,12 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
|
||||
uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1);
|
||||
uint32_t val;
|
||||
|
||||
assert(len == 1 || len == 2 || len == 4);
|
||||
if (!pci_dev) {
|
||||
return ~0x0;
|
||||
}
|
||||
|
||||
val = pci_dev->config_read(pci_dev, config_addr, len);
|
||||
val = pci_host_config_read_common(pci_dev, config_addr,
|
||||
PCI_CONFIG_SPACE_SIZE, len);
|
||||
PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
|
||||
__func__, pci_dev->name, config_addr, val, len);
|
||||
|
||||
|
@ -40,6 +40,12 @@ struct PCIHostState {
|
||||
PCIBus *bus;
|
||||
};
|
||||
|
||||
/* common internal helpers for PCI/PCIe hosts, cut off overflows */
|
||||
void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
|
||||
uint32_t limit, uint32_t val, uint32_t len);
|
||||
uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
|
||||
uint32_t limit, uint32_t len);
|
||||
|
||||
void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
|
||||
uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
|
||||
|
||||
|
@ -56,23 +56,39 @@ static void pcie_mmcfg_data_write(PCIBus *s,
|
||||
uint32_t mmcfg_addr, uint32_t val, int len)
|
||||
{
|
||||
PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
|
||||
uint32_t addr;
|
||||
uint32_t limit;
|
||||
|
||||
if (!pci_dev)
|
||||
if (!pci_dev) {
|
||||
return;
|
||||
|
||||
pci_dev->config_write(pci_dev,
|
||||
PCIE_MMCFG_CONFOFFSET(mmcfg_addr), val, len);
|
||||
}
|
||||
addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr);
|
||||
limit = pci_config_size(pci_dev);
|
||||
if (limit <= addr) {
|
||||
/* conventional pci device can be behind pcie-to-pci bridge.
|
||||
256 <= addr < 4K has no effects. */
|
||||
return;
|
||||
}
|
||||
pci_host_config_write_common(pci_dev, addr, limit, val, len);
|
||||
}
|
||||
|
||||
static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t addr, int len)
|
||||
static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t mmcfg_addr, int len)
|
||||
{
|
||||
PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, addr);
|
||||
PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
|
||||
uint32_t addr;
|
||||
uint32_t limit;
|
||||
|
||||
assert(len == 1 || len == 2 || len == 4);
|
||||
if (!pci_dev) {
|
||||
return ~0x0;
|
||||
}
|
||||
return pci_dev->config_read(pci_dev, PCIE_MMCFG_CONFOFFSET(addr), len);
|
||||
addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr);
|
||||
limit = pci_config_size(pci_dev);
|
||||
if (limit <= addr) {
|
||||
/* conventional pci device can be behind pcie-to-pci bridge.
|
||||
256 <= addr < 4K has no effects. */
|
||||
return ~0x0;
|
||||
}
|
||||
return pci_host_config_read_common(pci_dev, addr, limit, len);
|
||||
}
|
||||
|
||||
static void pcie_mmcfg_data_writeb(void *opaque,
|
||||
|
@ -120,7 +120,6 @@ static void vhost_dev_unassign_memory(struct vhost_dev *dev,
|
||||
if (start_addr <= reg->guest_phys_addr && memlast >= reglast) {
|
||||
--dev->mem->nregions;
|
||||
--to;
|
||||
assert(to >= 0);
|
||||
++overlap_middle;
|
||||
continue;
|
||||
}
|
||||
|
@ -594,4 +594,5 @@ void virtio_blk_exit(VirtIODevice *vdev)
|
||||
{
|
||||
VirtIOBlock *s = to_virtio_blk(vdev);
|
||||
unregister_savevm(s->qdev, "virtio-blk", s);
|
||||
virtio_cleanup(vdev);
|
||||
}
|
||||
|
@ -1073,6 +1073,6 @@ void virtio_net_exit(VirtIODevice *vdev)
|
||||
qemu_bh_delete(n->tx_bh);
|
||||
}
|
||||
|
||||
virtio_cleanup(&n->vdev);
|
||||
qemu_del_vlan_client(&n->nic->nc);
|
||||
virtio_cleanup(&n->vdev);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "kvm.h"
|
||||
#include "blockdev.h"
|
||||
#include "virtio-pci.h"
|
||||
#include "range.h"
|
||||
|
||||
/* from Linux's linux/virtio_pci.h */
|
||||
|
||||
@ -516,17 +517,16 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
|
||||
{
|
||||
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
|
||||
|
||||
if (PCI_COMMAND == address) {
|
||||
if (!(val & PCI_COMMAND_MASTER)) {
|
||||
if (!(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
|
||||
virtio_pci_stop_ioeventfd(proxy);
|
||||
virtio_set_status(proxy->vdev,
|
||||
proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
|
||||
}
|
||||
}
|
||||
pci_default_write_config(pci_dev, address, val, len);
|
||||
|
||||
if (range_covers_byte(address, len, PCI_COMMAND) &&
|
||||
!(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
|
||||
!(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
|
||||
virtio_pci_stop_ioeventfd(proxy);
|
||||
virtio_set_status(proxy->vdev,
|
||||
proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
|
||||
}
|
||||
|
||||
pci_default_write_config(pci_dev, address, val, len);
|
||||
msix_write_config(pci_dev, address, val, len);
|
||||
}
|
||||
|
||||
|
@ -834,6 +834,7 @@ void virtio_cleanup(VirtIODevice *vdev)
|
||||
if (vdev->config)
|
||||
qemu_free(vdev->config);
|
||||
qemu_free(vdev->vq);
|
||||
qemu_free(vdev);
|
||||
}
|
||||
|
||||
static void virtio_vmstate_change(void *opaque, int running, int reason)
|
||||
|
19
net.c
19
net.c
@ -150,12 +150,11 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr)
|
||||
static char *assign_name(VLANClientState *vc1, const char *model)
|
||||
{
|
||||
VLANState *vlan;
|
||||
VLANClientState *vc;
|
||||
char buf[256];
|
||||
int id = 0;
|
||||
|
||||
QTAILQ_FOREACH(vlan, &vlans, next) {
|
||||
VLANClientState *vc;
|
||||
|
||||
QTAILQ_FOREACH(vc, &vlan->clients, next) {
|
||||
if (vc != vc1 && strcmp(vc->model, model) == 0) {
|
||||
id++;
|
||||
@ -163,6 +162,12 @@ static char *assign_name(VLANClientState *vc1, const char *model)
|
||||
}
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
|
||||
if (vc != vc1 && strcmp(vc->model, model) == 0) {
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s.%d", model, id);
|
||||
|
||||
return qemu_strdup(buf);
|
||||
@ -653,6 +658,8 @@ VLANClientState *qemu_find_netdev(const char *id)
|
||||
VLANClientState *vc;
|
||||
|
||||
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
|
||||
if (vc->info->type == NET_CLIENT_TYPE_NIC)
|
||||
continue;
|
||||
if (!strcmp(vc->name, id)) {
|
||||
return vc;
|
||||
}
|
||||
@ -1212,7 +1219,7 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
VLANClientState *vc;
|
||||
|
||||
vc = qemu_find_netdev(id);
|
||||
if (!vc || vc->info->type == NET_CLIENT_TYPE_NIC) {
|
||||
if (!vc) {
|
||||
qerror_report(QERR_DEVICE_NOT_FOUND, id);
|
||||
return -1;
|
||||
}
|
||||
@ -1270,7 +1277,11 @@ int do_set_link(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
}
|
||||
}
|
||||
}
|
||||
vc = qemu_find_netdev(name);
|
||||
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
|
||||
if (!strcmp(vc->name, name)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
||||
if (!vc) {
|
||||
|
Loading…
Reference in New Issue
Block a user