Memory hot addition
Static void pc_dimm_class_init (ObjectClass oc, void data)
{
DeviceClass dc = DEVICE_CLASS (oc)
PCDIMMDeviceClass ddc = PC_DIMM_CLASS (oc)
Dc- > realize = pc_dimm_realize;dc- > unrealize = pc_dimm_unrealize;dc- > props = pc_dimm_properties;dc- > desc = "DIMM memory module"; ddc- > get_memory_region = pc_dimm_get_memory_region;ddc- > get_vmstate_memory_region = pc_dimm_get_vmstate_memory_region
}
Static void piix4_pm_class_init (ObjectClass klass, void data)
{
DeviceClass dc = DEVICE_CLASS (klass)
PCIDeviceClass k = PCI_DEVICE_CLASS (klass)
HotplugHandlerClass hc = HOTPLUG_HANDLER_CLASS (klass)
AcpiDeviceIfClass adevc = ACPI_DEVICE_IF_CLASS (klass)
K-> realize = piix4_pm_realize;k- > config_write = pm_write_config;k- > vendor_id = PCI_VENDOR_ID_INTEL;k- > device_id = PCI_DEVICE_ID_INTEL_82371AB_3;k- > revision = 0x03 political k-> class_id = PCI_CLASS_BRIDGE_OTHER;dc- > desc = "PM"; dc- > vmsd = & vmstate_acpi;dc- > props = piix4_pm_properties / * * Reason: part of PIIX4 southbridge, needs to be wired up, * e.g. By mips_malta_init () * / dc- > user_creatable = false;dc- > hotpluggable = false;hc- > plug = piix4_device_plug_cb;hc- > unplug_request = piix4_device_unplug_request_cb;hc- > unplug = piix4_device_unplug_cb;adevc- > ospm_status = piix4_ospm_status;adevc- > send_event = piix4_send_gpe;adevc- > madt_cpu = pc_madt_cpu_entry
}
Pc_init1
{
Set interrupt callback function
If (kvm_ioapic_in_kernel ()) {
Kvm_pc_setup_irq_routing (pcmc- > pci_enabled)
Pcms- > gsi = qemu_allocate_irqs (kvm_pc_gsi_handler, gsi_state
GSI_NUM_PINS)
} else {
Pcms- > gsi = qemu_allocate_irqs (gsi_handler, gsi_state, GSI_NUM_PINS)
}
Initialization interrupt if (kvm_pic_in_kernel ()) {i8259 = kvm_i8259_init (isa_bus);} else if (xen_enabled ()) {i8259 = xen_interrupt_controller_init ();} else {i8259 = i8259_init (isa_bus, pc_allocate_cpu_irq ());}
}
Qemu_irq kvm_i8259_init (ISABus bus)
{
I8259_init_chip (TYPE_KVM_I8259, bus, true); initialize the main interrupt
I8259_init_chip (TYPE_KVM_I8259, bus, false); initialize from interrupt
Return qemu_allocate_irqs (kvm_pic_set_irq, NULL, ISA_NUM_IRQS)
}
# 2 0x00007f117a950f34 in qemuMonitorSend (mon=0x7f1160035880, msg=0x7f117605b6f0) at. / src/qemu/qemu_monitor.c:1087
# 3 0x00007f117a96749e in qemuMonitorJSONCommandWithFd (mon=0x7f1160035880, cmd=0x7f113c01ac40, scm_fd=-1, reply=0x7f117605b798) at. / src/qemu/qemu_monitor_json.c:303
# 4 0x00007f117a9675d7 in qemuMonitorJSONCommand (mon=0x7f1160035880, cmd=0x7f113c01ac40, reply=0x7f117605b798) at. / src/qemu/qemu_monitor_json.c:333
# 5 0x00007f117a9709c5 in qemuMonitorJSONAddDeviceArgs (mon=0x7f1160035880, args=0x0) at. / src/qemu/qemu_monitor_json.c:3808
# 6 0x00007f117a970a78 in qemuMonitorJSONAddDevice (mon=0x7f1160035880, devicestr=0x7f113c001af0 "pc-dimm,node=0,memdev=ram0,id=dimm0,slot=0") at. / src/qemu/qemu_monitor_json.c:3832
# 7 0x00007f117a9597cc in qemuMonitorAddDeviceWithFd (mon=0x7f1160035880, devicestr=0x7f113c001af0 "pc-dimm,node=0,memdev=ram0,id=dimm0,slot=0", fd=-1, fdname=0x0) at. / src/qemu/qemu_monitor.c:3195
# 8 0x00007f117a959877 in qemuMonitorAddDevice (mon=0x7f1160035880, devicestr=0x7f113c001af0 "pc-dimm,node=0,memdev=ram0,id=dimm0,slot=0") at. / src/qemu/qemu_monitor.c:3212
# 9 0x00007f117a9163b5 in qemuDomainAttachMemory (driver=0x7f1170002b10, vm=0x7f11700dd610, mem=0x7f113c002370) at. / src/qemu/qemu_hotplug.c:2210
# 10 0x00007f117a98f8a0 in qemuDomainAttachDeviceLive (vm=0x7f11700dd610, dev=0x7f113c000a90, conn=0x7f116c0164d0, driver=0x7f1170002b10) at. / src/qemu/qemu_driver.c:7734
# 11 0x00007f117a992994 in qemuDomainAttachDeviceLiveAndConfig (conn=0x7f116c0164d0, vm=0x7f11700dd610, driver=0x7f1170002b10
Xml=0x7f113c001590 "20971520", flags=3)
At.. / src/qemu/qemu_driver.c:8796
# 12 0x00007f117a992cc1 in qemuDomainAttachDeviceFlags (dom=0x7f113c001360
Xml=0x7f113c001590 "20971520", flags=3)
At.. / src/qemu/qemu_driver.c:8880
# 13 0x00007f118a0cdd80 in virDomainAttachDeviceFlags (domain=0x7f113c001360
Xml=0x7f113c001590 "20971520", flags=3)
At.. / src/libvirt-domain.c:8156
Pc_dimm_plug-- > piix4_device_plug_cb-> acpi_memory_plug_cb-- > acpi_send_event-- > piix4_send_gpe-- > acpi_send_gpe_event-- > acpi_update_sci-- > qemu_set_irq
-- > kvm_pc_gsi_handler-- > qemu_set_irq-- > kvm_pic_set_irq-- > kvm_set_irq
# 0 pc_dimm_memory_plug (dev=dev@entry=0x5564b9dcaf60, hpms=hpms@entry=0x5564b8f03af0, mr=0x5564b9d57ce0, align=2097152, errp=errp@entry=0x7ffcd7286750)
At / vms/disk2/v-e0522/v-e0522/daemon/qemu/qemu-2.12/hw/mem/pc-dimm.c:40
# 1 0x00005564b75a17db in pc_dimm_plug (errp=0x7ffcd72867b0, dev=0x5564b9dcaf60, hotplug_dev=) qemu-2.12/hw/i386/pc.c:1714
# 2 pc_machine_device_plug_cb (hotplug_dev=, dev=0x5564b9dcaf60, errp=0x7ffcd72867b0) qemu-2.12/hw/i386/pc.c:2024
# 3 0x00005564b76a5f6e in device_set_realized (obj=, value=, errp=0x7ffcd72868d8) qemu-2.12/hw/core/qdev.c:862
# 4 0x00005564b7809227 in property_set_bool (obj=0x5564b9dcaf60, Venture, name=, opaque=0x5564ba43ee50, errp=0x7ffcd72868d8) v-e0522/daemon/qemu/qemu-2.12/qom/object.c:1923
# 5 0x00005564b780d46f in object_property_set_qobject (obj=obj@entry=0x5564b9dcaf60, value=value@entry=0x5564b9ab1570, name=name@entry=0x5564b79ca95f "realized", errp=errp@entry=0x7ffcd72868d8)
At / vms/disk2/v-e0522/v-e0522/daemon/qemu/qemu-2.12/qom/qom-qobject.c:27
# 6 0x00005564b780b090 in object_property_set_bool (obj=0x5564b9dcaf60, value=, name=0x5564b79ca95f "realized", errp=0x7ffcd72868d8) at / vms/disk2/v-e0522/v-e0522/daemon/qemu/qemu-2.12/qom/object.c:1188
# 7 0x00005564b762b68a in qdev_device_add (opts=opts@entry=0x5564b9dcbc80, errp=errp@entry=0x7ffcd72869b0) qemu-2.12/qdev-monitor.c:627
# 8 0x00005564b762bcb3 in qmp_device_add (qdict=, ret_data=, errp=0x7ffcd72869e8) qemu-2.12/qdev-monitor.c:807
Pc_dimm_plug-- > pc_dimm_memory_plug-- > memory_region_add_subregion-- > memory_region_add_subregion_common-- > memory_region_update_container_subregions
-- > memory_region_transaction_commit |-- > flatviews_reset-- > generate_memory_topology-- > render_memory_region
| |-- > address_space_set_flatview-- > address_space_update_topology_pass-- > kvm_region_add-- > kvm_set_phys_mem |
Map MemoryRegion to linear address space FlatView, get several MemoryRegionSection, call kvm_region_add, register MemoryRegionSection in KVM
Memory_region_add_subregion_common joins subregions linked list
Memory_region_transaction_begin
-- > qemu_flush_coalesced_mmio_buffer |-- > kvm_flush_coalesced_mmio_buffer
|-- > + + memory_region_transaction_depth
Batch optimizations have been made to some MMIO in KVM: when KVM encounters MMIO and VMEXIT, the MMIO operation is recorded in the kvm_coalesced_mmio structure and then stuffed into kvm_coalesced_mmio_ring without exiting to QEMU. Until the moment when you go back to QEMU and update the memory space, take the kvm_coalesced_mmio out of kvm_coalesced_mmio_ring and do it again to ensure memory consistency. That's what kvm_flush_coalesced_mmio_buffer did.
Qemu_allocate_irq allocates interrupt number
Pic_stat_update_irq counts the number of interruptions
Mr = ddc- > get_memory_region = pc_dimm_get_memory_region
Hhc- > plug = piix4_device_plug_cb
Adevc- > send_event = piix4_send_gpe