Merge remote-tracking branch 'qemu-kvm/memory/urgent' into staging
* qemu-kvm/memory/urgent: memory: abort if a memory region is destroyed during a transaction i440fx: avoid destroying memory regions within a transaction memory: Make eventfd adhere to device endianness
This commit is contained in:
commit
50d2b4d93f
@ -69,8 +69,8 @@ typedef struct PIIX3State {
|
|||||||
} PIIX3State;
|
} PIIX3State;
|
||||||
|
|
||||||
typedef struct PAMMemoryRegion {
|
typedef struct PAMMemoryRegion {
|
||||||
MemoryRegion mem;
|
MemoryRegion alias[4]; /* index = PAM value */
|
||||||
bool initialized;
|
unsigned current;
|
||||||
} PAMMemoryRegion;
|
} PAMMemoryRegion;
|
||||||
|
|
||||||
struct PCII440FXState {
|
struct PCII440FXState {
|
||||||
@ -105,37 +105,35 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
|
|||||||
return (pci_intx + slot_addend) & 3;
|
return (pci_intx + slot_addend) & 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r,
|
static void init_pam(PCII440FXState *d, PAMMemoryRegion *mem,
|
||||||
PAMMemoryRegion *mem)
|
uint32_t start, uint32_t size)
|
||||||
{
|
{
|
||||||
if (mem->initialized) {
|
int i;
|
||||||
memory_region_del_subregion(d->system_memory, &mem->mem);
|
|
||||||
memory_region_destroy(&mem->mem);
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("ISA mapping %08x-0x%08x: %d\n", start, end, r);
|
/* RAM */
|
||||||
switch(r) {
|
memory_region_init_alias(&mem->alias[3], "pam-ram", d->ram_memory, start, size);
|
||||||
case 3:
|
/* ROM (XXX: not quite correct) */
|
||||||
/* RAM */
|
memory_region_init_alias(&mem->alias[1], "pam-rom", d->ram_memory, start, size);
|
||||||
memory_region_init_alias(&mem->mem, "pam-ram", d->ram_memory,
|
memory_region_set_readonly(&mem->alias[1], true);
|
||||||
start, end - start);
|
|
||||||
break;
|
/* XXX: should distinguish read/write cases */
|
||||||
case 1:
|
memory_region_init_alias(&mem->alias[0], "pam-pci", d->pci_address_space,
|
||||||
/* ROM (XXX: not quite correct) */
|
start, size);
|
||||||
memory_region_init_alias(&mem->mem, "pam-rom", d->ram_memory,
|
memory_region_init_alias(&mem->alias[2], "pam-pci", d->pci_address_space,
|
||||||
start, end - start);
|
start, size);
|
||||||
memory_region_set_readonly(&mem->mem, true);
|
|
||||||
break;
|
for (i = 0; i < 4; ++i) {
|
||||||
case 2:
|
memory_region_set_enabled(&mem->alias[i], false);
|
||||||
case 0:
|
memory_region_add_subregion_overlap(d->system_memory, start, &mem->alias[i], 1);
|
||||||
/* XXX: should distinguish read/write cases */
|
|
||||||
memory_region_init_alias(&mem->mem, "pam-pci", d->pci_address_space,
|
|
||||||
start, end - start);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
memory_region_add_subregion_overlap(d->system_memory,
|
mem->current = 0;
|
||||||
start, &mem->mem, 1);
|
}
|
||||||
mem->initialized = true;
|
|
||||||
|
static void update_pam(PAMMemoryRegion *pam, unsigned r)
|
||||||
|
{
|
||||||
|
memory_region_set_enabled(&pam->alias[pam->current], false);
|
||||||
|
pam->current = r;
|
||||||
|
memory_region_set_enabled(&pam->alias[pam->current], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i440fx_update_memory_mappings(PCII440FXState *d)
|
static void i440fx_update_memory_mappings(PCII440FXState *d)
|
||||||
@ -145,12 +143,10 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
|
|||||||
bool smram_enabled;
|
bool smram_enabled;
|
||||||
|
|
||||||
memory_region_transaction_begin();
|
memory_region_transaction_begin();
|
||||||
update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
|
update_pam(&d->pam_regions[0], (d->dev.config[I440FX_PAM] >> 4) & 3);
|
||||||
&d->pam_regions[0]);
|
|
||||||
for(i = 0; i < 12; i++) {
|
for(i = 0; i < 12; i++) {
|
||||||
r = (d->dev.config[(i >> 1) + (I440FX_PAM + 1)] >> ((i & 1) * 4)) & 3;
|
r = (d->dev.config[(i >> 1) + (I440FX_PAM + 1)] >> ((i & 1) * 4)) & 3;
|
||||||
update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r,
|
update_pam(&d->pam_regions[i+1], r);
|
||||||
&d->pam_regions[i+1]);
|
|
||||||
}
|
}
|
||||||
smram = d->dev.config[I440FX_SMRAM];
|
smram = d->dev.config[I440FX_SMRAM];
|
||||||
smram_enabled = (d->smm_enabled && (smram & 0x08)) || (smram & 0x40);
|
smram_enabled = (d->smm_enabled && (smram & 0x08)) || (smram & 0x40);
|
||||||
@ -272,6 +268,7 @@ static PCIBus *i440fx_common_init(const char *device_name,
|
|||||||
PCIHostState *s;
|
PCIHostState *s;
|
||||||
PIIX3State *piix3;
|
PIIX3State *piix3;
|
||||||
PCII440FXState *f;
|
PCII440FXState *f;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
dev = qdev_create(NULL, "i440FX-pcihost");
|
dev = qdev_create(NULL, "i440FX-pcihost");
|
||||||
s = PCI_HOST_BRIDGE(dev);
|
s = PCI_HOST_BRIDGE(dev);
|
||||||
@ -303,6 +300,10 @@ static PCIBus *i440fx_common_init(const char *device_name,
|
|||||||
memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
|
memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
|
||||||
&f->smram_region, 1);
|
&f->smram_region, 1);
|
||||||
memory_region_set_enabled(&f->smram_region, false);
|
memory_region_set_enabled(&f->smram_region, false);
|
||||||
|
init_pam(f, &f->pam_regions[0], 0xf0000, 0x10000);
|
||||||
|
for (i = 0; i < 12; ++i) {
|
||||||
|
init_pam(f, &f->pam_regions[i+1], 0xc0000 + i * 0x4000, 0x4000);
|
||||||
|
}
|
||||||
|
|
||||||
/* Xen supports additional interrupt routes from the PCI devices to
|
/* Xen supports additional interrupt routes from the PCI devices to
|
||||||
* the IOAPIC: the four pins of each PCI device on the bus are also
|
* the IOAPIC: the four pins of each PCI device on the bus are also
|
||||||
|
3
memory.c
3
memory.c
@ -1019,6 +1019,7 @@ void memory_region_init_reservation(MemoryRegion *mr,
|
|||||||
void memory_region_destroy(MemoryRegion *mr)
|
void memory_region_destroy(MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
assert(QTAILQ_EMPTY(&mr->subregions));
|
assert(QTAILQ_EMPTY(&mr->subregions));
|
||||||
|
assert(memory_region_transaction_depth == 0);
|
||||||
mr->destructor(mr);
|
mr->destructor(mr);
|
||||||
memory_region_clear_coalescing(mr);
|
memory_region_clear_coalescing(mr);
|
||||||
g_free((char *)mr->name);
|
g_free((char *)mr->name);
|
||||||
@ -1234,6 +1235,7 @@ void memory_region_add_eventfd(MemoryRegion *mr,
|
|||||||
};
|
};
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
adjust_endianness(mr, &mrfd.data, size);
|
||||||
memory_region_transaction_begin();
|
memory_region_transaction_begin();
|
||||||
for (i = 0; i < mr->ioeventfd_nb; ++i) {
|
for (i = 0; i < mr->ioeventfd_nb; ++i) {
|
||||||
if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
|
if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
|
||||||
@ -1265,6 +1267,7 @@ void memory_region_del_eventfd(MemoryRegion *mr,
|
|||||||
};
|
};
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
adjust_endianness(mr, &mrfd.data, size);
|
||||||
memory_region_transaction_begin();
|
memory_region_transaction_begin();
|
||||||
for (i = 0; i < mr->ioeventfd_nb; ++i) {
|
for (i = 0; i < mr->ioeventfd_nb; ++i) {
|
||||||
if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
|
if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
|
||||||
|
Loading…
Reference in New Issue
Block a user