mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc and misc cleanups and fixes, virtio optimizations Included here: Refactoring and bugfix patches in PC/ACPI. New commands for ipmi. Virtio optimizations. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Sat 06 Feb 2016 18:44:26 GMT using RSA key ID D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: (45 commits) net: set endianness on all backend devices fix MSI injection on Xen intel_iommu: large page support dimm: Correct type of MemoryHotplugState->base pc: set the OEM fields in the RSDT and the FADT from the SLIC acpi: add function to extract oem_id and oem_table_id from the user's SLIC acpi: expose oem_id and oem_table_id in build_rsdt() acpi: take oem_id in build_header(), optionally pc: Eliminate PcGuestInfo struct pc: Move APIC and NUMA data from PcGuestInfo to PCMachineState pc: Move PcGuestInfo.fw_cfg to PCMachineState pc: Remove PcGuestInfo.isapc_ram_fw field pc: Remove RAM size fields from PcGuestInfo pc: Remove compat fields from PcGuestInfo acpi: Don't save PcGuestInfo on AcpiBuildState acpi: Remove guest_info parameters from functions pc: Simplify xen_load_linux() signature pc: Simplify pc_memory_init() signature pc: Eliminate struct PcGuestInfoState pc: Move PcGuestInfo declaration to top of file ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+1
-1
@@ -1587,7 +1587,7 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
|
||||
int read_count;
|
||||
int64_t xattr_len;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = &v->elems[pdu->idx];
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
|
||||
xattr_len = fidp->fs.xattr.len;
|
||||
read_count = xattr_len - off;
|
||||
|
||||
@@ -26,10 +26,12 @@ void virtio_9p_push_and_notify(V9fsPDU *pdu)
|
||||
{
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = &v->elems[pdu->idx];
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
|
||||
/* push onto queue and notify */
|
||||
virtqueue_push(v->vq, elem, pdu->size);
|
||||
g_free(elem);
|
||||
v->elems[pdu->idx] = NULL;
|
||||
|
||||
/* FIXME: we should batch these completions */
|
||||
virtio_notify(VIRTIO_DEVICE(v), v->vq);
|
||||
@@ -48,10 +50,10 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
uint8_t id;
|
||||
uint16_t tag_le;
|
||||
} QEMU_PACKED out;
|
||||
VirtQueueElement *elem = &v->elems[pdu->idx];
|
||||
VirtQueueElement *elem;
|
||||
|
||||
len = virtqueue_pop(vq, elem);
|
||||
if (!len) {
|
||||
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
|
||||
if (!elem) {
|
||||
pdu_free(pdu);
|
||||
break;
|
||||
}
|
||||
@@ -59,6 +61,7 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
BUG_ON(elem->out_num == 0 || elem->in_num == 0);
|
||||
QEMU_BUILD_BUG_ON(sizeof out != 7);
|
||||
|
||||
v->elems[pdu->idx] = elem;
|
||||
len = iov_to_buf(elem->out_sg, elem->out_num, 0,
|
||||
&out, sizeof out);
|
||||
BUG_ON(len != sizeof out);
|
||||
@@ -141,7 +144,7 @@ ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,
|
||||
{
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = &v->elems[pdu->idx];
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
|
||||
return v9fs_iov_vmarshal(elem->in_sg, elem->in_num, offset, 1, fmt, ap);
|
||||
}
|
||||
@@ -151,7 +154,7 @@ ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset,
|
||||
{
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = &v->elems[pdu->idx];
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
|
||||
return v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fmt, ap);
|
||||
}
|
||||
@@ -161,7 +164,7 @@ void virtio_init_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
|
||||
{
|
||||
V9fsState *s = pdu->s;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = &v->elems[pdu->idx];
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
|
||||
if (is_write) {
|
||||
*piov = elem->out_sg;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ typedef struct V9fsVirtioState
|
||||
VirtQueue *vq;
|
||||
size_t config_size;
|
||||
V9fsPDU pdus[MAX_REQ];
|
||||
VirtQueueElement elems[MAX_REQ];
|
||||
VirtQueueElement *elems[MAX_REQ];
|
||||
V9fsState state;
|
||||
} V9fsVirtioState;
|
||||
|
||||
|
||||
+10
-4
@@ -1426,12 +1426,17 @@ Aml *aml_alias(const char *source_object, const char *alias_object)
|
||||
void
|
||||
build_header(GArray *linker, GArray *table_data,
|
||||
AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
|
||||
const char *oem_table_id)
|
||||
const char *oem_id, const char *oem_table_id)
|
||||
{
|
||||
memcpy(&h->signature, sig, 4);
|
||||
h->length = cpu_to_le32(len);
|
||||
h->revision = rev;
|
||||
memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
|
||||
|
||||
if (oem_id) {
|
||||
strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
|
||||
} else {
|
||||
memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
|
||||
}
|
||||
|
||||
if (oem_table_id) {
|
||||
strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
|
||||
@@ -1487,7 +1492,8 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
|
||||
|
||||
/* Build rsdt table */
|
||||
void
|
||||
build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
||||
build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
|
||||
const char *oem_id, const char *oem_table_id)
|
||||
{
|
||||
AcpiRsdtDescriptorRev1 *rsdt;
|
||||
size_t rsdt_len;
|
||||
@@ -1506,5 +1512,5 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
build_header(linker, table_data,
|
||||
(void *)rsdt, "RSDT", rsdt_len, 1, NULL);
|
||||
(void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
|
||||
}
|
||||
|
||||
@@ -350,6 +350,22 @@ uint8_t *acpi_table_next(uint8_t *current)
|
||||
}
|
||||
}
|
||||
|
||||
int acpi_get_slic_oem(AcpiSlicOem *oem)
|
||||
{
|
||||
uint8_t *u;
|
||||
|
||||
for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
|
||||
struct acpi_table_header *hdr = (void *)(u - sizeof(hdr->_length));
|
||||
|
||||
if (memcmp(hdr->sig, "SLIC", 4) == 0) {
|
||||
oem->id = hdr->oem_id;
|
||||
oem->table_id = hdr->oem_table_id;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void acpi_notify_wakeup(Notifier *notifier, void *data)
|
||||
{
|
||||
ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
|
||||
|
||||
+2
-2
@@ -366,7 +366,7 @@ static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
|
||||
|
||||
build_header(linker, table_data,
|
||||
(void *)(table_data->data + header), "NFIT",
|
||||
sizeof(NvdimmNfitHeader) + structures->len, 1, NULL);
|
||||
sizeof(NvdimmNfitHeader) + structures->len, 1, NULL, NULL);
|
||||
g_array_free(structures, true);
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
|
||||
g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);
|
||||
build_header(linker, table_data,
|
||||
(void *)(table_data->data + table_data->len - ssdt->buf->len),
|
||||
"SSDT", ssdt->buf->len, 1, "NVDIMM");
|
||||
"SSDT", ssdt->buf->len, 1, NULL, "NVDIMM");
|
||||
free_aml_allocator();
|
||||
}
|
||||
|
||||
|
||||
@@ -394,7 +394,7 @@ build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
|
||||
spcr->pci_vendor_id = 0xffff; /* PCI Vendor ID: not a PCI device */
|
||||
|
||||
build_header(linker, table_data, (void *)spcr, "SPCR", sizeof(*spcr), 2,
|
||||
NULL);
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -413,7 +413,7 @@ build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
|
||||
mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
|
||||
/ PCIE_MMCFG_SIZE_MIN) - 1;
|
||||
|
||||
build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL);
|
||||
build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
/* GTDT */
|
||||
@@ -439,7 +439,7 @@ build_gtdt(GArray *table_data, GArray *linker)
|
||||
|
||||
build_header(linker, table_data,
|
||||
(void *)(table_data->data + gtdt_start), "GTDT",
|
||||
table_data->len - gtdt_start, 2, NULL);
|
||||
table_data->len - gtdt_start, 2, NULL, NULL);
|
||||
}
|
||||
|
||||
/* MADT */
|
||||
@@ -498,7 +498,7 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
|
||||
|
||||
build_header(linker, table_data,
|
||||
(void *)(table_data->data + madt_start), "APIC",
|
||||
table_data->len - madt_start, 3, NULL);
|
||||
table_data->len - madt_start, 3, NULL, NULL);
|
||||
}
|
||||
|
||||
/* FADT */
|
||||
@@ -523,7 +523,7 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
|
||||
sizeof fadt->dsdt);
|
||||
|
||||
build_header(linker, table_data,
|
||||
(void *)fadt, "FACP", sizeof(*fadt), 5, NULL);
|
||||
(void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
|
||||
}
|
||||
|
||||
/* DSDT */
|
||||
@@ -562,7 +562,7 @@ build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
|
||||
g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
|
||||
build_header(linker, table_data,
|
||||
(void *)(table_data->data + table_data->len - dsdt->buf->len),
|
||||
"DSDT", dsdt->buf->len, 2, NULL);
|
||||
"DSDT", dsdt->buf->len, 2, NULL, NULL);
|
||||
free_aml_allocator();
|
||||
}
|
||||
|
||||
@@ -623,7 +623,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
|
||||
|
||||
/* RSDT is pointed to by RSDP */
|
||||
rsdt = tables_blob->len;
|
||||
build_rsdt(tables_blob, tables->linker, table_offsets);
|
||||
build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
|
||||
|
||||
/* RSDP is in FSEG memory, so allocate it separately */
|
||||
build_rsdp(tables->rsdp, tables->linker, rsdt);
|
||||
|
||||
@@ -100,20 +100,19 @@ static void handle_notify(EventNotifier *e)
|
||||
blk_io_plug(s->conf->conf.blk);
|
||||
for (;;) {
|
||||
MultiReqBuffer mrb = {};
|
||||
int ret;
|
||||
|
||||
/* Disable guest->host notifies to avoid unnecessary vmexits */
|
||||
vring_disable_notification(s->vdev, &s->vring);
|
||||
|
||||
for (;;) {
|
||||
VirtIOBlockReq *req = virtio_blk_alloc_request(vblk);
|
||||
VirtIOBlockReq *req = vring_pop(s->vdev, &s->vring,
|
||||
sizeof(VirtIOBlockReq));
|
||||
|
||||
ret = vring_pop(s->vdev, &s->vring, &req->elem);
|
||||
if (ret < 0) {
|
||||
virtio_blk_free_request(req);
|
||||
if (req == NULL) {
|
||||
break; /* no more requests */
|
||||
}
|
||||
|
||||
virtio_blk_init_request(vblk, req);
|
||||
trace_virtio_blk_data_plane_process_request(s, req->elem.out_num,
|
||||
req->elem.in_num,
|
||||
req->elem.index);
|
||||
@@ -125,7 +124,7 @@ static void handle_notify(EventNotifier *e)
|
||||
virtio_blk_submit_multireq(s->conf->conf.blk, &mrb);
|
||||
}
|
||||
|
||||
if (likely(ret == -EAGAIN)) { /* vring emptied */
|
||||
if (likely(!vring_more_avail(s->vdev, &s->vring))) { /* vring emptied */
|
||||
/* Re-enable guest->host notifies and stop processing the vring.
|
||||
* But if the guest has snuck in more descriptors, keep processing.
|
||||
*/
|
||||
|
||||
+8
-15
@@ -29,15 +29,13 @@
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "hw/virtio/virtio-access.h"
|
||||
|
||||
VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
|
||||
void virtio_blk_init_request(VirtIOBlock *s, VirtIOBlockReq *req)
|
||||
{
|
||||
VirtIOBlockReq *req = g_new(VirtIOBlockReq, 1);
|
||||
req->dev = s;
|
||||
req->qiov.size = 0;
|
||||
req->in_len = 0;
|
||||
req->next = NULL;
|
||||
req->mr_next = NULL;
|
||||
return req;
|
||||
}
|
||||
|
||||
void virtio_blk_free_request(VirtIOBlockReq *req)
|
||||
@@ -193,13 +191,11 @@ out:
|
||||
|
||||
static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
|
||||
{
|
||||
VirtIOBlockReq *req = virtio_blk_alloc_request(s);
|
||||
VirtIOBlockReq *req = virtqueue_pop(s->vq, sizeof(VirtIOBlockReq));
|
||||
|
||||
if (!virtqueue_pop(s->vq, &req->elem)) {
|
||||
virtio_blk_free_request(req);
|
||||
return NULL;
|
||||
if (req) {
|
||||
virtio_blk_init_request(s, req);
|
||||
}
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
@@ -812,8 +808,7 @@ static void virtio_blk_save_device(VirtIODevice *vdev, QEMUFile *f)
|
||||
|
||||
while (req) {
|
||||
qemu_put_sbyte(f, 1);
|
||||
qemu_put_buffer(f, (unsigned char *)&req->elem,
|
||||
sizeof(VirtQueueElement));
|
||||
qemu_put_virtqueue_element(f, &req->elem);
|
||||
req = req->next;
|
||||
}
|
||||
qemu_put_sbyte(f, 0);
|
||||
@@ -836,13 +831,11 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
|
||||
VirtIOBlock *s = VIRTIO_BLK(vdev);
|
||||
|
||||
while (qemu_get_sbyte(f)) {
|
||||
VirtIOBlockReq *req = virtio_blk_alloc_request(s);
|
||||
qemu_get_buffer(f, (unsigned char *)&req->elem,
|
||||
sizeof(VirtQueueElement));
|
||||
VirtIOBlockReq *req;
|
||||
req = qemu_get_virtqueue_element(f, sizeof(VirtIOBlockReq));
|
||||
virtio_blk_init_request(s, req);
|
||||
req->next = s->rq;
|
||||
s->rq = req;
|
||||
|
||||
virtqueue_map(&req->elem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+47
-31
@@ -83,7 +83,7 @@ static bool use_multiport(VirtIOSerial *vser)
|
||||
static size_t write_to_port(VirtIOSerialPort *port,
|
||||
const uint8_t *buf, size_t size)
|
||||
{
|
||||
VirtQueueElement elem;
|
||||
VirtQueueElement *elem;
|
||||
VirtQueue *vq;
|
||||
size_t offset;
|
||||
|
||||
@@ -96,15 +96,17 @@ static size_t write_to_port(VirtIOSerialPort *port,
|
||||
while (offset < size) {
|
||||
size_t len;
|
||||
|
||||
if (!virtqueue_pop(vq, &elem)) {
|
||||
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
|
||||
if (!elem) {
|
||||
break;
|
||||
}
|
||||
|
||||
len = iov_from_buf(elem.in_sg, elem.in_num, 0,
|
||||
len = iov_from_buf(elem->in_sg, elem->in_num, 0,
|
||||
buf + offset, size - offset);
|
||||
offset += len;
|
||||
|
||||
virtqueue_push(vq, &elem, len);
|
||||
virtqueue_push(vq, elem, len);
|
||||
g_free(elem);
|
||||
}
|
||||
|
||||
virtio_notify(VIRTIO_DEVICE(port->vser), vq);
|
||||
@@ -113,13 +115,18 @@ static size_t write_to_port(VirtIOSerialPort *port,
|
||||
|
||||
static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
|
||||
{
|
||||
VirtQueueElement elem;
|
||||
VirtQueueElement *elem;
|
||||
|
||||
if (!virtio_queue_ready(vq)) {
|
||||
return;
|
||||
}
|
||||
while (virtqueue_pop(vq, &elem)) {
|
||||
virtqueue_push(vq, &elem, 0);
|
||||
for (;;) {
|
||||
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
|
||||
if (!elem) {
|
||||
break;
|
||||
}
|
||||
virtqueue_push(vq, elem, 0);
|
||||
g_free(elem);
|
||||
}
|
||||
virtio_notify(vdev, vq);
|
||||
}
|
||||
@@ -138,21 +145,22 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
|
||||
unsigned int i;
|
||||
|
||||
/* Pop an elem only if we haven't left off a previous one mid-way */
|
||||
if (!port->elem.out_num) {
|
||||
if (!virtqueue_pop(vq, &port->elem)) {
|
||||
if (!port->elem) {
|
||||
port->elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
|
||||
if (!port->elem) {
|
||||
break;
|
||||
}
|
||||
port->iov_idx = 0;
|
||||
port->iov_offset = 0;
|
||||
}
|
||||
|
||||
for (i = port->iov_idx; i < port->elem.out_num; i++) {
|
||||
for (i = port->iov_idx; i < port->elem->out_num; i++) {
|
||||
size_t buf_size;
|
||||
ssize_t ret;
|
||||
|
||||
buf_size = port->elem.out_sg[i].iov_len - port->iov_offset;
|
||||
buf_size = port->elem->out_sg[i].iov_len - port->iov_offset;
|
||||
ret = vsc->have_data(port,
|
||||
port->elem.out_sg[i].iov_base
|
||||
port->elem->out_sg[i].iov_base
|
||||
+ port->iov_offset,
|
||||
buf_size);
|
||||
if (port->throttled) {
|
||||
@@ -167,8 +175,9 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
|
||||
if (port->throttled) {
|
||||
break;
|
||||
}
|
||||
virtqueue_push(vq, &port->elem, 0);
|
||||
port->elem.out_num = 0;
|
||||
virtqueue_push(vq, port->elem, 0);
|
||||
g_free(port->elem);
|
||||
port->elem = NULL;
|
||||
}
|
||||
virtio_notify(vdev, vq);
|
||||
}
|
||||
@@ -185,22 +194,26 @@ static void flush_queued_data(VirtIOSerialPort *port)
|
||||
|
||||
static size_t send_control_msg(VirtIOSerial *vser, void *buf, size_t len)
|
||||
{
|
||||
VirtQueueElement elem;
|
||||
VirtQueueElement *elem;
|
||||
VirtQueue *vq;
|
||||
|
||||
vq = vser->c_ivq;
|
||||
if (!virtio_queue_ready(vq)) {
|
||||
return 0;
|
||||
}
|
||||
if (!virtqueue_pop(vq, &elem)) {
|
||||
|
||||
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
|
||||
if (!elem) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: detect a buffer that's too short, set NEEDS_RESET */
|
||||
iov_from_buf(elem.in_sg, elem.in_num, 0, buf, len);
|
||||
iov_from_buf(elem->in_sg, elem->in_num, 0, buf, len);
|
||||
|
||||
virtqueue_push(vq, &elem, len);
|
||||
virtqueue_push(vq, elem, len);
|
||||
virtio_notify(VIRTIO_DEVICE(vser), vq);
|
||||
g_free(elem);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -414,7 +427,7 @@ static void control_in(VirtIODevice *vdev, VirtQueue *vq)
|
||||
|
||||
static void control_out(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
VirtQueueElement elem;
|
||||
VirtQueueElement *elem;
|
||||
VirtIOSerial *vser;
|
||||
uint8_t *buf;
|
||||
size_t len;
|
||||
@@ -423,10 +436,15 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
|
||||
|
||||
len = 0;
|
||||
buf = NULL;
|
||||
while (virtqueue_pop(vq, &elem)) {
|
||||
for (;;) {
|
||||
size_t cur_len;
|
||||
|
||||
cur_len = iov_size(elem.out_sg, elem.out_num);
|
||||
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
|
||||
if (!elem) {
|
||||
break;
|
||||
}
|
||||
|
||||
cur_len = iov_size(elem->out_sg, elem->out_num);
|
||||
/*
|
||||
* Allocate a new buf only if we didn't have one previously or
|
||||
* if the size of the buf differs
|
||||
@@ -437,10 +455,11 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
|
||||
buf = g_malloc(cur_len);
|
||||
len = cur_len;
|
||||
}
|
||||
iov_to_buf(elem.out_sg, elem.out_num, 0, buf, cur_len);
|
||||
iov_to_buf(elem->out_sg, elem->out_num, 0, buf, cur_len);
|
||||
|
||||
handle_control_message(vser, buf, cur_len);
|
||||
virtqueue_push(vq, &elem, 0);
|
||||
virtqueue_push(vq, elem, 0);
|
||||
g_free(elem);
|
||||
}
|
||||
g_free(buf);
|
||||
virtio_notify(vdev, vq);
|
||||
@@ -620,16 +639,14 @@ static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
|
||||
qemu_put_byte(f, port->host_connected);
|
||||
|
||||
elem_popped = 0;
|
||||
if (port->elem.out_num) {
|
||||
if (port->elem) {
|
||||
elem_popped = 1;
|
||||
}
|
||||
qemu_put_be32s(f, &elem_popped);
|
||||
if (elem_popped) {
|
||||
qemu_put_be32s(f, &port->iov_idx);
|
||||
qemu_put_be64s(f, &port->iov_offset);
|
||||
|
||||
qemu_put_buffer(f, (unsigned char *)&port->elem,
|
||||
sizeof(port->elem));
|
||||
qemu_put_virtqueue_element(f, port->elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -704,9 +721,8 @@ static int fetch_active_ports_list(QEMUFile *f, int version_id,
|
||||
qemu_get_be32s(f, &port->iov_idx);
|
||||
qemu_get_be64s(f, &port->iov_offset);
|
||||
|
||||
qemu_get_buffer(f, (unsigned char *)&port->elem,
|
||||
sizeof(port->elem));
|
||||
virtqueue_map(&port->elem);
|
||||
port->elem =
|
||||
qemu_get_virtqueue_element(f, sizeof(VirtQueueElement));
|
||||
|
||||
/*
|
||||
* Port was throttled on source machine. Let's
|
||||
@@ -928,7 +944,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
port->elem.out_num = 0;
|
||||
port->elem = NULL;
|
||||
}
|
||||
|
||||
static void virtser_port_device_plug(HotplugHandler *hotplug_dev,
|
||||
|
||||
+13
-8
@@ -804,16 +804,15 @@ static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
}
|
||||
#endif
|
||||
|
||||
cmd = g_new(struct virtio_gpu_ctrl_command, 1);
|
||||
while (virtqueue_pop(vq, &cmd->elem)) {
|
||||
cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
|
||||
while (cmd) {
|
||||
cmd->vq = vq;
|
||||
cmd->error = 0;
|
||||
cmd->finished = false;
|
||||
cmd->waiting = false;
|
||||
QTAILQ_INSERT_TAIL(&g->cmdq, cmd, next);
|
||||
cmd = g_new(struct virtio_gpu_ctrl_command, 1);
|
||||
cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
|
||||
}
|
||||
g_free(cmd);
|
||||
|
||||
virtio_gpu_process_cmdq(g);
|
||||
|
||||
@@ -833,15 +832,20 @@ static void virtio_gpu_ctrl_bh(void *opaque)
|
||||
static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)
|
||||
{
|
||||
VirtIOGPU *g = VIRTIO_GPU(vdev);
|
||||
VirtQueueElement elem;
|
||||
VirtQueueElement *elem;
|
||||
size_t s;
|
||||
struct virtio_gpu_update_cursor cursor_info;
|
||||
|
||||
if (!virtio_queue_ready(vq)) {
|
||||
return;
|
||||
}
|
||||
while (virtqueue_pop(vq, &elem)) {
|
||||
s = iov_to_buf(elem.out_sg, elem.out_num, 0,
|
||||
for (;;) {
|
||||
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
|
||||
if (!elem) {
|
||||
break;
|
||||
}
|
||||
|
||||
s = iov_to_buf(elem->out_sg, elem->out_num, 0,
|
||||
&cursor_info, sizeof(cursor_info));
|
||||
if (s != sizeof(cursor_info)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
@@ -850,8 +854,9 @@ static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)
|
||||
} else {
|
||||
update_cursor(g, &cursor_info);
|
||||
}
|
||||
virtqueue_push(vq, &elem, 0);
|
||||
virtqueue_push(vq, elem, 0);
|
||||
virtio_notify(vdev, vq);
|
||||
g_free(elem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+509
-527
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,6 @@
|
||||
|
||||
#include "qemu/typedefs.h"
|
||||
|
||||
void acpi_setup(PcGuestInfo *);
|
||||
void acpi_setup(void);
|
||||
|
||||
#endif
|
||||
|
||||
+53
-21
@@ -153,14 +153,27 @@ static gboolean vtd_hash_remove_by_domain(gpointer key, gpointer value,
|
||||
return entry->domain_id == domain_id;
|
||||
}
|
||||
|
||||
/* The shift of an addr for a certain level of paging structure */
|
||||
static inline uint32_t vtd_slpt_level_shift(uint32_t level)
|
||||
{
|
||||
return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_SL_LEVEL_BITS;
|
||||
}
|
||||
|
||||
static inline uint64_t vtd_slpt_level_page_mask(uint32_t level)
|
||||
{
|
||||
return ~((1ULL << vtd_slpt_level_shift(level)) - 1);
|
||||
}
|
||||
|
||||
static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
VTDIOTLBEntry *entry = (VTDIOTLBEntry *)value;
|
||||
VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data;
|
||||
uint64_t gfn = info->gfn & info->mask;
|
||||
uint64_t gfn = (info->addr >> VTD_PAGE_SHIFT_4K) & info->mask;
|
||||
uint64_t gfn_tlb = (info->addr & entry->mask) >> VTD_PAGE_SHIFT_4K;
|
||||
return (entry->domain_id == info->domain_id) &&
|
||||
((entry->gfn & info->mask) == gfn);
|
||||
(((entry->gfn & info->mask) == gfn) ||
|
||||
(entry->gfn == gfn_tlb));
|
||||
}
|
||||
|
||||
/* Reset all the gen of VTDAddressSpace to zero and set the gen of
|
||||
@@ -194,24 +207,46 @@ static void vtd_reset_iotlb(IntelIOMMUState *s)
|
||||
g_hash_table_remove_all(s->iotlb);
|
||||
}
|
||||
|
||||
static uint64_t vtd_get_iotlb_key(uint64_t gfn, uint8_t source_id,
|
||||
uint32_t level)
|
||||
{
|
||||
return gfn | ((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT) |
|
||||
((uint64_t)(level) << VTD_IOTLB_LVL_SHIFT);
|
||||
}
|
||||
|
||||
static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t level)
|
||||
{
|
||||
return (addr & vtd_slpt_level_page_mask(level)) >> VTD_PAGE_SHIFT_4K;
|
||||
}
|
||||
|
||||
static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
|
||||
hwaddr addr)
|
||||
{
|
||||
VTDIOTLBEntry *entry;
|
||||
uint64_t key;
|
||||
int level;
|
||||
|
||||
key = (addr >> VTD_PAGE_SHIFT_4K) |
|
||||
((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT);
|
||||
return g_hash_table_lookup(s->iotlb, &key);
|
||||
for (level = VTD_SL_PT_LEVEL; level < VTD_SL_PML4_LEVEL; level++) {
|
||||
key = vtd_get_iotlb_key(vtd_get_iotlb_gfn(addr, level),
|
||||
source_id, level);
|
||||
entry = g_hash_table_lookup(s->iotlb, &key);
|
||||
if (entry) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return entry;
|
||||
}
|
||||
|
||||
static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
|
||||
uint16_t domain_id, hwaddr addr, uint64_t slpte,
|
||||
bool read_flags, bool write_flags)
|
||||
bool read_flags, bool write_flags,
|
||||
uint32_t level)
|
||||
{
|
||||
VTDIOTLBEntry *entry = g_malloc(sizeof(*entry));
|
||||
uint64_t *key = g_malloc(sizeof(*key));
|
||||
uint64_t gfn = addr >> VTD_PAGE_SHIFT_4K;
|
||||
uint64_t gfn = vtd_get_iotlb_gfn(addr, level);
|
||||
|
||||
VTD_DPRINTF(CACHE, "update iotlb sid 0x%"PRIx16 " gpa 0x%"PRIx64
|
||||
" slpte 0x%"PRIx64 " did 0x%"PRIx16, source_id, addr, slpte,
|
||||
@@ -226,7 +261,8 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
|
||||
entry->slpte = slpte;
|
||||
entry->read_flags = read_flags;
|
||||
entry->write_flags = write_flags;
|
||||
*key = gfn | ((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT);
|
||||
entry->mask = vtd_slpt_level_page_mask(level);
|
||||
*key = vtd_get_iotlb_key(gfn, source_id, level);
|
||||
g_hash_table_replace(s->iotlb, key, entry);
|
||||
}
|
||||
|
||||
@@ -501,12 +537,6 @@ static inline dma_addr_t vtd_get_slpt_base_from_context(VTDContextEntry *ce)
|
||||
return ce->lo & VTD_CONTEXT_ENTRY_SLPTPTR;
|
||||
}
|
||||
|
||||
/* The shift of an addr for a certain level of paging structure */
|
||||
static inline uint32_t vtd_slpt_level_shift(uint32_t level)
|
||||
{
|
||||
return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_SL_LEVEL_BITS;
|
||||
}
|
||||
|
||||
static inline uint64_t vtd_get_slpte_addr(uint64_t slpte)
|
||||
{
|
||||
return slpte & VTD_SL_PT_BASE_ADDR_MASK;
|
||||
@@ -762,7 +792,7 @@ static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
|
||||
VTDContextEntry ce;
|
||||
uint8_t bus_num = pci_bus_num(bus);
|
||||
VTDContextCacheEntry *cc_entry = &vtd_as->context_cache_entry;
|
||||
uint64_t slpte;
|
||||
uint64_t slpte, page_mask;
|
||||
uint32_t level;
|
||||
uint16_t source_id = vtd_make_source_id(bus_num, devfn);
|
||||
int ret_fr;
|
||||
@@ -802,6 +832,7 @@ static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
|
||||
slpte = iotlb_entry->slpte;
|
||||
reads = iotlb_entry->read_flags;
|
||||
writes = iotlb_entry->write_flags;
|
||||
page_mask = iotlb_entry->mask;
|
||||
goto out;
|
||||
}
|
||||
/* Try to fetch context-entry from cache first */
|
||||
@@ -848,12 +879,13 @@ static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
|
||||
return;
|
||||
}
|
||||
|
||||
page_mask = vtd_slpt_level_page_mask(level);
|
||||
vtd_update_iotlb(s, source_id, VTD_CONTEXT_ENTRY_DID(ce.hi), addr, slpte,
|
||||
reads, writes);
|
||||
reads, writes, level);
|
||||
out:
|
||||
entry->iova = addr & VTD_PAGE_MASK_4K;
|
||||
entry->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K;
|
||||
entry->addr_mask = ~VTD_PAGE_MASK_4K;
|
||||
entry->iova = addr & page_mask;
|
||||
entry->translated_addr = vtd_get_slpte_addr(slpte) & page_mask;
|
||||
entry->addr_mask = ~page_mask;
|
||||
entry->perm = (writes ? 2 : 0) + (reads ? 1 : 0);
|
||||
}
|
||||
|
||||
@@ -991,7 +1023,7 @@ static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
|
||||
|
||||
assert(am <= VTD_MAMV);
|
||||
info.domain_id = domain_id;
|
||||
info.gfn = addr >> VTD_PAGE_SHIFT_4K;
|
||||
info.addr = addr;
|
||||
info.mask = ~((1 << am) - 1);
|
||||
g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, &info);
|
||||
}
|
||||
@@ -1917,7 +1949,7 @@ static void vtd_init(IntelIOMMUState *s)
|
||||
s->iq_last_desc_type = VTD_INV_DESC_NONE;
|
||||
s->next_frcd_reg = 0;
|
||||
s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MGAW |
|
||||
VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI;
|
||||
VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS;
|
||||
s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;
|
||||
|
||||
vtd_reset_context_cache(s);
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
|
||||
/* The shift of source_id in the key of IOTLB hash table */
|
||||
#define VTD_IOTLB_SID_SHIFT 36
|
||||
#define VTD_IOTLB_LVL_SHIFT 44
|
||||
#define VTD_IOTLB_MAX_SIZE 1024 /* Max size of the hash table */
|
||||
|
||||
/* IOTLB_REG */
|
||||
@@ -185,9 +186,10 @@
|
||||
#define VTD_CAP_ND (((VTD_DOMAIN_ID_SHIFT - 4) / 2) & 7ULL)
|
||||
#define VTD_MGAW 39 /* Maximum Guest Address Width */
|
||||
#define VTD_CAP_MGAW (((VTD_MGAW - 1) & 0x3fULL) << 16)
|
||||
#define VTD_MAMV 9ULL
|
||||
#define VTD_MAMV 18ULL
|
||||
#define VTD_CAP_MAMV (VTD_MAMV << 48)
|
||||
#define VTD_CAP_PSI (1ULL << 39)
|
||||
#define VTD_CAP_SLLPS ((1ULL << 34) | (1ULL << 35))
|
||||
|
||||
/* Supported Adjusted Guest Address Widths */
|
||||
#define VTD_CAP_SAGAW_SHIFT 8
|
||||
@@ -320,7 +322,7 @@ typedef struct VTDInvDesc VTDInvDesc;
|
||||
/* Information about page-selective IOTLB invalidate */
|
||||
struct VTDIOTLBPageInvInfo {
|
||||
uint16_t domain_id;
|
||||
uint64_t gfn;
|
||||
uint64_t addr;
|
||||
uint8_t mask;
|
||||
};
|
||||
typedef struct VTDIOTLBPageInvInfo VTDIOTLBPageInvInfo;
|
||||
|
||||
+31
-46
@@ -1156,18 +1156,12 @@ typedef struct PcRomPciInfo {
|
||||
uint64_t w64_max;
|
||||
} PcRomPciInfo;
|
||||
|
||||
typedef struct PcGuestInfoState {
|
||||
PcGuestInfo info;
|
||||
Notifier machine_done;
|
||||
} PcGuestInfoState;
|
||||
|
||||
static
|
||||
void pc_guest_info_machine_done(Notifier *notifier, void *data)
|
||||
void pc_machine_done(Notifier *notifier, void *data)
|
||||
{
|
||||
PcGuestInfoState *guest_info_state = container_of(notifier,
|
||||
PcGuestInfoState,
|
||||
machine_done);
|
||||
PCIBus *bus = PC_MACHINE(qdev_get_machine())->bus;
|
||||
PCMachineState *pcms = container_of(notifier,
|
||||
PCMachineState, machine_done);
|
||||
PCIBus *bus = pcms->bus;
|
||||
|
||||
if (bus) {
|
||||
int extra_hosts = 0;
|
||||
@@ -1178,51 +1172,46 @@ void pc_guest_info_machine_done(Notifier *notifier, void *data)
|
||||
extra_hosts++;
|
||||
}
|
||||
}
|
||||
if (extra_hosts && guest_info_state->info.fw_cfg) {
|
||||
if (extra_hosts && pcms->fw_cfg) {
|
||||
uint64_t *val = g_malloc(sizeof(*val));
|
||||
*val = cpu_to_le64(extra_hosts);
|
||||
fw_cfg_add_file(guest_info_state->info.fw_cfg,
|
||||
fw_cfg_add_file(pcms->fw_cfg,
|
||||
"etc/extra-pci-roots", val, sizeof(*val));
|
||||
}
|
||||
}
|
||||
|
||||
acpi_setup(&guest_info_state->info);
|
||||
acpi_setup();
|
||||
}
|
||||
|
||||
PcGuestInfo *pc_guest_info_init(PCMachineState *pcms)
|
||||
void pc_guest_info_init(PCMachineState *pcms)
|
||||
{
|
||||
PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
|
||||
PcGuestInfo *guest_info = &guest_info_state->info;
|
||||
int i, j;
|
||||
|
||||
guest_info->ram_size_below_4g = pcms->below_4g_mem_size;
|
||||
guest_info->ram_size = pcms->below_4g_mem_size + pcms->above_4g_mem_size;
|
||||
guest_info->apic_id_limit = pc_apic_id_limit(max_cpus);
|
||||
guest_info->apic_xrupt_override = kvm_allows_irq0_override();
|
||||
guest_info->numa_nodes = nb_numa_nodes;
|
||||
guest_info->node_mem = g_malloc0(guest_info->numa_nodes *
|
||||
sizeof *guest_info->node_mem);
|
||||
pcms->apic_id_limit = pc_apic_id_limit(max_cpus);
|
||||
pcms->apic_xrupt_override = kvm_allows_irq0_override();
|
||||
pcms->numa_nodes = nb_numa_nodes;
|
||||
pcms->node_mem = g_malloc0(pcms->numa_nodes *
|
||||
sizeof *pcms->node_mem);
|
||||
for (i = 0; i < nb_numa_nodes; i++) {
|
||||
guest_info->node_mem[i] = numa_info[i].node_mem;
|
||||
pcms->node_mem[i] = numa_info[i].node_mem;
|
||||
}
|
||||
|
||||
guest_info->node_cpu = g_malloc0(guest_info->apic_id_limit *
|
||||
sizeof *guest_info->node_cpu);
|
||||
pcms->node_cpu = g_malloc0(pcms->apic_id_limit *
|
||||
sizeof *pcms->node_cpu);
|
||||
|
||||
for (i = 0; i < max_cpus; i++) {
|
||||
unsigned int apic_id = x86_cpu_apic_id_from_index(i);
|
||||
assert(apic_id < guest_info->apic_id_limit);
|
||||
assert(apic_id < pcms->apic_id_limit);
|
||||
for (j = 0; j < nb_numa_nodes; j++) {
|
||||
if (test_bit(i, numa_info[j].node_cpu)) {
|
||||
guest_info->node_cpu[apic_id] = j;
|
||||
pcms->node_cpu[apic_id] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
guest_info_state->machine_done.notify = pc_guest_info_machine_done;
|
||||
qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
|
||||
return guest_info;
|
||||
pcms->machine_done.notify = pc_machine_done;
|
||||
qemu_add_machine_init_done_notifier(&pcms->machine_done);
|
||||
}
|
||||
|
||||
/* setup pci memory address space mapping into system address space */
|
||||
@@ -1262,8 +1251,7 @@ void pc_acpi_init(const char *default_dsdt)
|
||||
}
|
||||
}
|
||||
|
||||
FWCfgState *xen_load_linux(PCMachineState *pcms,
|
||||
PcGuestInfo *guest_info)
|
||||
void xen_load_linux(PCMachineState *pcms)
|
||||
{
|
||||
int i;
|
||||
FWCfgState *fw_cfg;
|
||||
@@ -1279,15 +1267,13 @@ FWCfgState *xen_load_linux(PCMachineState *pcms,
|
||||
!strcmp(option_rom[i].name, "multiboot.bin"));
|
||||
rom_add_option(option_rom[i].name, option_rom[i].bootindex);
|
||||
}
|
||||
guest_info->fw_cfg = fw_cfg;
|
||||
return fw_cfg;
|
||||
pcms->fw_cfg = fw_cfg;
|
||||
}
|
||||
|
||||
FWCfgState *pc_memory_init(PCMachineState *pcms,
|
||||
MemoryRegion *system_memory,
|
||||
MemoryRegion *rom_memory,
|
||||
MemoryRegion **ram_memory,
|
||||
PcGuestInfo *guest_info)
|
||||
void pc_memory_init(PCMachineState *pcms,
|
||||
MemoryRegion *system_memory,
|
||||
MemoryRegion *rom_memory,
|
||||
MemoryRegion **ram_memory)
|
||||
{
|
||||
int linux_boot, i;
|
||||
MemoryRegion *ram, *option_rom_mr;
|
||||
@@ -1324,7 +1310,7 @@ FWCfgState *pc_memory_init(PCMachineState *pcms,
|
||||
e820_add_entry(0x100000000ULL, pcms->above_4g_mem_size, E820_RAM);
|
||||
}
|
||||
|
||||
if (!guest_info->has_reserved_memory &&
|
||||
if (!pcmc->has_reserved_memory &&
|
||||
(machine->ram_slots ||
|
||||
(machine->maxram_size > machine->ram_size))) {
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
@@ -1335,7 +1321,7 @@ FWCfgState *pc_memory_init(PCMachineState *pcms,
|
||||
}
|
||||
|
||||
/* initialize hotplug memory address space */
|
||||
if (guest_info->has_reserved_memory &&
|
||||
if (pcmc->has_reserved_memory &&
|
||||
(machine->ram_size < machine->maxram_size)) {
|
||||
ram_addr_t hotplug_mem_size =
|
||||
machine->maxram_size - machine->ram_size;
|
||||
@@ -1375,7 +1361,7 @@ FWCfgState *pc_memory_init(PCMachineState *pcms,
|
||||
}
|
||||
|
||||
/* Initialize PC system firmware */
|
||||
pc_system_firmware_init(rom_memory, guest_info->isapc_ram_fw);
|
||||
pc_system_firmware_init(rom_memory, !pcmc->pci_enabled);
|
||||
|
||||
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
|
||||
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
|
||||
@@ -1390,7 +1376,7 @@ FWCfgState *pc_memory_init(PCMachineState *pcms,
|
||||
|
||||
rom_set_fw(fw_cfg);
|
||||
|
||||
if (guest_info->has_reserved_memory && pcms->hotplug_memory.base) {
|
||||
if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) {
|
||||
uint64_t *val = g_malloc(sizeof(*val));
|
||||
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
|
||||
uint64_t res_mem_end = pcms->hotplug_memory.base;
|
||||
@@ -1409,8 +1395,7 @@ FWCfgState *pc_memory_init(PCMachineState *pcms,
|
||||
for (i = 0; i < nb_option_roms; i++) {
|
||||
rom_add_option(option_rom[i].name, option_rom[i].bootindex);
|
||||
}
|
||||
guest_info->fw_cfg = fw_cfg;
|
||||
return fw_cfg;
|
||||
pcms->fw_cfg = fw_cfg;
|
||||
}
|
||||
|
||||
qemu_irq pc_allocate_cpu_irq(void)
|
||||
|
||||
+3
-11
@@ -85,7 +85,6 @@ static void pc_init1(MachineState *machine,
|
||||
MemoryRegion *ram_memory;
|
||||
MemoryRegion *pci_memory;
|
||||
MemoryRegion *rom_memory;
|
||||
PcGuestInfo *guest_info;
|
||||
ram_addr_t lowmem;
|
||||
|
||||
/* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory).
|
||||
@@ -141,14 +140,7 @@ static void pc_init1(MachineState *machine,
|
||||
rom_memory = system_memory;
|
||||
}
|
||||
|
||||
guest_info = pc_guest_info_init(pcms);
|
||||
|
||||
guest_info->has_acpi_build = pcmc->has_acpi_build;
|
||||
guest_info->legacy_acpi_table_size = pcmc->legacy_acpi_table_size;
|
||||
|
||||
guest_info->isapc_ram_fw = !pcmc->pci_enabled;
|
||||
guest_info->has_reserved_memory = pcmc->has_reserved_memory;
|
||||
guest_info->rsdp_in_ram = pcmc->rsdp_in_ram;
|
||||
pc_guest_info_init(pcms);
|
||||
|
||||
if (pcmc->smbios_defaults) {
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
@@ -162,10 +154,10 @@ static void pc_init1(MachineState *machine,
|
||||
/* allocate ram and load rom/bios */
|
||||
if (!xen_enabled()) {
|
||||
pc_memory_init(pcms, system_memory,
|
||||
rom_memory, &ram_memory, guest_info);
|
||||
rom_memory, &ram_memory);
|
||||
} else if (machine->kernel_filename != NULL) {
|
||||
/* For xen HVM direct kernel boot, load linux here */
|
||||
xen_load_linux(pcms, guest_info);
|
||||
xen_load_linux(pcms);
|
||||
}
|
||||
|
||||
gsi_state = g_malloc0(sizeof(*gsi_state));
|
||||
|
||||
+2
-12
@@ -71,7 +71,6 @@ static void pc_q35_init(MachineState *machine)
|
||||
int i;
|
||||
ICH9LPCState *ich9_lpc;
|
||||
PCIDevice *ahci;
|
||||
PcGuestInfo *guest_info;
|
||||
ram_addr_t lowmem;
|
||||
DriveInfo *hd[MAX_SATA_PORTS];
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
@@ -134,16 +133,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
rom_memory = get_system_memory();
|
||||
}
|
||||
|
||||
guest_info = pc_guest_info_init(pcms);
|
||||
guest_info->isapc_ram_fw = false;
|
||||
guest_info->has_acpi_build = pcmc->has_acpi_build;
|
||||
guest_info->has_reserved_memory = pcmc->has_reserved_memory;
|
||||
guest_info->rsdp_in_ram = pcmc->rsdp_in_ram;
|
||||
|
||||
/* Migration was not supported in 2.0 for Q35, so do not bother
|
||||
* with this hack (see hw/i386/acpi-build.c).
|
||||
*/
|
||||
guest_info->legacy_acpi_table_size = 0;
|
||||
pc_guest_info_init(pcms);
|
||||
|
||||
if (pcmc->smbios_defaults) {
|
||||
/* These values are guest ABI, do not change */
|
||||
@@ -156,7 +146,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
/* allocate ram and load rom/bios */
|
||||
if (!xen_enabled()) {
|
||||
pc_memory_init(pcms, get_system_memory(),
|
||||
rom_memory, &ram_memory, guest_info);
|
||||
rom_memory, &ram_memory);
|
||||
}
|
||||
|
||||
/* irq lines */
|
||||
|
||||
+16
-8
@@ -17,7 +17,7 @@
|
||||
|
||||
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
|
||||
{
|
||||
VirtQueueElement elem;
|
||||
VirtQueueElement *elem;
|
||||
unsigned have, need;
|
||||
int i, len;
|
||||
|
||||
@@ -50,14 +50,16 @@ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
|
||||
|
||||
/* ... and finally pass them to the guest */
|
||||
for (i = 0; i < vinput->qindex; i++) {
|
||||
if (!virtqueue_pop(vinput->evt, &elem)) {
|
||||
elem = virtqueue_pop(vinput->evt, sizeof(VirtQueueElement));
|
||||
if (!elem) {
|
||||
/* should not happen, we've checked for space beforehand */
|
||||
fprintf(stderr, "%s: Huh? No vq elem available ...\n", __func__);
|
||||
return;
|
||||
}
|
||||
len = iov_from_buf(elem.in_sg, elem.in_num,
|
||||
len = iov_from_buf(elem->in_sg, elem->in_num,
|
||||
0, vinput->queue+i, sizeof(virtio_input_event));
|
||||
virtqueue_push(vinput->evt, &elem, len);
|
||||
virtqueue_push(vinput->evt, elem, len);
|
||||
g_free(elem);
|
||||
}
|
||||
virtio_notify(VIRTIO_DEVICE(vinput), vinput->evt);
|
||||
vinput->qindex = 0;
|
||||
@@ -73,17 +75,23 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq)
|
||||
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);
|
||||
VirtIOInput *vinput = VIRTIO_INPUT(vdev);
|
||||
virtio_input_event event;
|
||||
VirtQueueElement elem;
|
||||
VirtQueueElement *elem;
|
||||
int len;
|
||||
|
||||
while (virtqueue_pop(vinput->sts, &elem)) {
|
||||
for (;;) {
|
||||
elem = virtqueue_pop(vinput->sts, sizeof(VirtQueueElement));
|
||||
if (!elem) {
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
len = iov_to_buf(elem.out_sg, elem.out_num,
|
||||
len = iov_to_buf(elem->out_sg, elem->out_num,
|
||||
0, &event, sizeof(event));
|
||||
if (vic->handle_status) {
|
||||
vic->handle_status(vinput, &event);
|
||||
}
|
||||
virtqueue_push(vinput->sts, &elem, len);
|
||||
virtqueue_push(vinput->sts, elem, len);
|
||||
g_free(elem);
|
||||
}
|
||||
virtio_notify(vdev, vinput->sts);
|
||||
}
|
||||
|
||||
+205
-146
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user