Compare commits
20 Commits
pull-ui-20
...
pull-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6575ccddf4 | ||
|
|
01df51432e | ||
|
|
f22d0af076 | ||
|
|
b98d26e333 | ||
|
|
f2c1d54c18 | ||
|
|
071608b519 | ||
|
|
1da90c34c9 | ||
|
|
3ff430aa91 | ||
|
|
35227e6a09 | ||
|
|
e8ce12d9ea | ||
|
|
beded0ff7f | ||
|
|
a005b3ef50 | ||
|
|
902c053d83 | ||
|
|
09b5e30da5 | ||
|
|
2d7d06d847 | ||
|
|
cba0e7796b | ||
|
|
ce266b75fe | ||
|
|
d4a63ac8b1 | ||
|
|
3d0db3e74d | ||
|
|
e6915b5f3a |
@@ -857,6 +857,10 @@ M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
S: Maintained
|
||||
F: hw/usb/*
|
||||
F: tests/usb-*-test.c
|
||||
F: docs/usb2.txt
|
||||
F: docs/usb-storage.txt
|
||||
F: include/hw/usb.h
|
||||
F: include/hw/usb/
|
||||
|
||||
USB (serial adapter)
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
|
||||
@@ -312,6 +312,21 @@ static bool machine_get_suppress_vmdesc(Object *obj, Error **errp)
|
||||
return ms->suppress_vmdesc;
|
||||
}
|
||||
|
||||
static void machine_set_enforce_config_section(Object *obj, bool value,
|
||||
Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
ms->enforce_config_section = value;
|
||||
}
|
||||
|
||||
static bool machine_get_enforce_config_section(Object *obj, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
return ms->enforce_config_section;
|
||||
}
|
||||
|
||||
static int error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
error_report("Option '-device %s' cannot be handled by this machine",
|
||||
@@ -467,6 +482,12 @@ static void machine_initfn(Object *obj)
|
||||
object_property_set_description(obj, "suppress-vmdesc",
|
||||
"Set on to disable self-describing migration",
|
||||
NULL);
|
||||
object_property_add_bool(obj, "enforce-config-section",
|
||||
machine_get_enforce_config_section,
|
||||
machine_set_enforce_config_section, NULL);
|
||||
object_property_set_description(obj, "enforce-config-section",
|
||||
"Set on to enforce configuration section migration",
|
||||
NULL);
|
||||
|
||||
/* Register notifier when init is done for sysbus sanity checks */
|
||||
ms->sysbus_notifier.notify = machine_init_notify;
|
||||
|
||||
@@ -140,9 +140,9 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
|
||||
case INPUT_EVENT_KIND_BTN:
|
||||
if (evt->u.btn->down) {
|
||||
e->buttons_state |= bmap[evt->u.btn->button];
|
||||
if (evt->u.btn->button == INPUT_BUTTON_WHEELUP) {
|
||||
if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
|
||||
e->dz--;
|
||||
} else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) {
|
||||
} else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
|
||||
e->dz++;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -406,9 +406,9 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
|
||||
case INPUT_EVENT_KIND_BTN:
|
||||
if (evt->u.btn->down) {
|
||||
s->mouse_buttons |= bmap[evt->u.btn->button];
|
||||
if (evt->u.btn->button == INPUT_BUTTON_WHEELUP) {
|
||||
if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
|
||||
s->mouse_dz--;
|
||||
} else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) {
|
||||
} else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
|
||||
s->mouse_dz++;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -143,8 +143,8 @@ static const unsigned int keymap_button[INPUT_BUTTON__MAX] = {
|
||||
[INPUT_BUTTON_LEFT] = BTN_LEFT,
|
||||
[INPUT_BUTTON_RIGHT] = BTN_RIGHT,
|
||||
[INPUT_BUTTON_MIDDLE] = BTN_MIDDLE,
|
||||
[INPUT_BUTTON_WHEELUP] = BTN_GEAR_UP,
|
||||
[INPUT_BUTTON_WHEELDOWN] = BTN_GEAR_DOWN,
|
||||
[INPUT_BUTTON_WHEEL_UP] = BTN_GEAR_UP,
|
||||
[INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN,
|
||||
};
|
||||
|
||||
static const unsigned int axismap_rel[INPUT_AXIS__MAX] = {
|
||||
|
||||
@@ -712,7 +712,7 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi)
|
||||
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp)
|
||||
{
|
||||
ICSState *ics = &icp->ics[src];
|
||||
int irq;
|
||||
@@ -720,14 +720,14 @@ int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi)
|
||||
if (irq_hint) {
|
||||
assert(src == xics_find_source(icp, irq_hint));
|
||||
if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
|
||||
trace_xics_alloc_failed_hint(src, irq_hint);
|
||||
error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
|
||||
return -1;
|
||||
}
|
||||
irq = irq_hint;
|
||||
} else {
|
||||
irq = ics_find_free_block(ics, 1, 1);
|
||||
if (irq < 0) {
|
||||
trace_xics_alloc_failed_no_left(src);
|
||||
error_setg(errp, "can't allocate IRQ: no IRQ left");
|
||||
return -1;
|
||||
}
|
||||
irq += ics->offset;
|
||||
@@ -743,7 +743,8 @@ int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi)
|
||||
* Allocate block of consecutive IRQs, and return the number of the first IRQ in the block.
|
||||
* If align==true, aligns the first IRQ number to num.
|
||||
*/
|
||||
int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align)
|
||||
int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align,
|
||||
Error **errp)
|
||||
{
|
||||
int i, first = -1;
|
||||
ICSState *ics = &icp->ics[src];
|
||||
@@ -763,6 +764,10 @@ int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align)
|
||||
} else {
|
||||
first = ics_find_free_block(ics, num, 1);
|
||||
}
|
||||
if (first < 0) {
|
||||
error_setg(errp, "can't find a free %d-IRQ block", num);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (first >= 0) {
|
||||
for (i = first; i < first + num; ++i) {
|
||||
|
||||
@@ -557,11 +557,13 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
|
||||
|
||||
DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan);
|
||||
|
||||
assert(rw);
|
||||
assert(flush);
|
||||
|
||||
ch->irq = irq;
|
||||
ch->rw = rw;
|
||||
ch->flush = flush;
|
||||
ch->io.opaque = opaque;
|
||||
ch->io.channel = ch;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -775,6 +777,20 @@ static void dbdma_reset(void *opaque)
|
||||
memset(s->channels[i].regs, 0, DBDMA_SIZE);
|
||||
}
|
||||
|
||||
static void dbdma_unassigned_rw(DBDMA_io *io)
|
||||
{
|
||||
DBDMA_channel *ch = io->channel;
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
|
||||
__func__, ch->channel);
|
||||
}
|
||||
|
||||
static void dbdma_unassigned_flush(DBDMA_io *io)
|
||||
{
|
||||
DBDMA_channel *ch = io->channel;
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
|
||||
__func__, ch->channel);
|
||||
}
|
||||
|
||||
void* DBDMA_init (MemoryRegion **dbdma_mem)
|
||||
{
|
||||
DBDMAState *s;
|
||||
@@ -784,8 +800,13 @@ void* DBDMA_init (MemoryRegion **dbdma_mem)
|
||||
|
||||
for (i = 0; i < DBDMA_CHANNELS; i++) {
|
||||
DBDMA_io *io = &s->channels[i].io;
|
||||
DBDMA_channel *ch = &s->channels[i];
|
||||
qemu_iovec_init(&io->iov, 1);
|
||||
s->channels[i].channel = i;
|
||||
|
||||
ch->rw = dbdma_unassigned_rw;
|
||||
ch->flush = dbdma_unassigned_flush;
|
||||
ch->channel = i;
|
||||
ch->io.channel = ch;
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->mem, NULL, &dbdma_ops, s, "dbdma", 0x1000);
|
||||
|
||||
@@ -778,17 +778,19 @@ FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
|
||||
DeviceState *dev;
|
||||
FWCfgState *s;
|
||||
uint32_t version = FW_CFG_VERSION;
|
||||
bool dma_enabled = dma_iobase && dma_as;
|
||||
bool dma_requested = dma_iobase && dma_as;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_FW_CFG_IO);
|
||||
qdev_prop_set_uint32(dev, "iobase", iobase);
|
||||
qdev_prop_set_uint32(dev, "dma_iobase", dma_iobase);
|
||||
qdev_prop_set_bit(dev, "dma_enabled", dma_enabled);
|
||||
if (!dma_requested) {
|
||||
qdev_prop_set_bit(dev, "dma_enabled", false);
|
||||
}
|
||||
|
||||
fw_cfg_init1(dev);
|
||||
s = FW_CFG(dev);
|
||||
|
||||
if (dma_enabled) {
|
||||
if (s->dma_enabled) {
|
||||
/* 64 bits for the address field */
|
||||
s->dma_as = dma_as;
|
||||
s->dma_addr = 0;
|
||||
@@ -814,11 +816,13 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
|
||||
SysBusDevice *sbd;
|
||||
FWCfgState *s;
|
||||
uint32_t version = FW_CFG_VERSION;
|
||||
bool dma_enabled = dma_addr && dma_as;
|
||||
bool dma_requested = dma_addr && dma_as;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
|
||||
qdev_prop_set_uint32(dev, "data_width", data_width);
|
||||
qdev_prop_set_bit(dev, "dma_enabled", dma_enabled);
|
||||
if (!dma_requested) {
|
||||
qdev_prop_set_bit(dev, "dma_enabled", false);
|
||||
}
|
||||
|
||||
fw_cfg_init1(dev);
|
||||
|
||||
@@ -828,7 +832,7 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
|
||||
|
||||
s = FW_CFG(dev);
|
||||
|
||||
if (dma_enabled) {
|
||||
if (s->dma_enabled) {
|
||||
s->dma_as = dma_as;
|
||||
s->dma_addr = 0;
|
||||
sysbus_mmio_map(sbd, 2, dma_addr);
|
||||
@@ -873,7 +877,7 @@ static Property fw_cfg_io_properties[] = {
|
||||
DEFINE_PROP_UINT32("iobase", FWCfgIoState, iobase, -1),
|
||||
DEFINE_PROP_UINT32("dma_iobase", FWCfgIoState, dma_iobase, -1),
|
||||
DEFINE_PROP_BOOL("dma_enabled", FWCfgIoState, parent_obj.dma_enabled,
|
||||
false),
|
||||
true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -913,7 +917,7 @@ static const TypeInfo fw_cfg_io_info = {
|
||||
static Property fw_cfg_mem_properties[] = {
|
||||
DEFINE_PROP_UINT32("data_width", FWCfgMemState, data_width, -1),
|
||||
DEFINE_PROP_BOOL("dma_enabled", FWCfgMemState, parent_obj.dma_enabled,
|
||||
false),
|
||||
true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
||||
@@ -2427,6 +2427,7 @@ static void spapr_machine_2_3_instance_options(MachineState *machine)
|
||||
spapr_machine_2_4_instance_options(machine);
|
||||
savevm_skip_section_footers();
|
||||
global_state_set_optional();
|
||||
savevm_skip_configuration();
|
||||
}
|
||||
|
||||
static void spapr_machine_2_3_class_options(MachineClass *mc)
|
||||
@@ -2452,6 +2453,7 @@ DEFINE_SPAPR_MACHINE(2_3, "2.3", false);
|
||||
static void spapr_machine_2_2_instance_options(MachineState *machine)
|
||||
{
|
||||
spapr_machine_2_3_instance_options(machine);
|
||||
machine->suppress_vmdesc = true;
|
||||
}
|
||||
|
||||
static void spapr_machine_2_2_class_options(MachineClass *mc)
|
||||
|
||||
@@ -588,7 +588,8 @@ out_no_events:
|
||||
void spapr_events_init(sPAPRMachineState *spapr)
|
||||
{
|
||||
QTAILQ_INIT(&spapr->pending_events);
|
||||
spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false);
|
||||
spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false,
|
||||
&error_fatal);
|
||||
spapr->epow_notifier.notify = spapr_powerdown_req;
|
||||
qemu_register_powerdown_notifier(&spapr->epow_notifier);
|
||||
spapr_rtas_register(RTAS_CHECK_EXCEPTION, "check-exception",
|
||||
|
||||
@@ -275,11 +275,12 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
unsigned int req_num = rtas_ld(args, 4); /* 0 == remove all */
|
||||
unsigned int seq_num = rtas_ld(args, 5);
|
||||
unsigned int ret_intr_type;
|
||||
unsigned int irq, max_irqs = 0, num = 0;
|
||||
unsigned int irq, max_irqs = 0;
|
||||
sPAPRPHBState *phb = NULL;
|
||||
PCIDevice *pdev = NULL;
|
||||
spapr_pci_msi *msi;
|
||||
int *config_addr_key;
|
||||
Error *err = NULL;
|
||||
|
||||
switch (func) {
|
||||
case RTAS_CHANGE_MSI_FN:
|
||||
@@ -305,9 +306,10 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return;
|
||||
}
|
||||
|
||||
msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr);
|
||||
|
||||
/* Releasing MSIs */
|
||||
if (!req_num) {
|
||||
msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr);
|
||||
if (!msi) {
|
||||
trace_spapr_pci_msi("Releasing wrong config", config_addr);
|
||||
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
|
||||
@@ -316,10 +318,10 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
|
||||
xics_free(spapr->icp, msi->first_irq, msi->num);
|
||||
if (msi_present(pdev)) {
|
||||
spapr_msi_setmsg(pdev, 0, false, 0, num);
|
||||
spapr_msi_setmsg(pdev, 0, false, 0, 0);
|
||||
}
|
||||
if (msix_present(pdev)) {
|
||||
spapr_msi_setmsg(pdev, 0, true, 0, num);
|
||||
spapr_msi_setmsg(pdev, 0, true, 0, 0);
|
||||
}
|
||||
g_hash_table_remove(phb->msi, &config_addr);
|
||||
|
||||
@@ -353,13 +355,20 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
|
||||
/* Allocate MSIs */
|
||||
irq = xics_alloc_block(spapr->icp, 0, req_num, false,
|
||||
ret_intr_type == RTAS_TYPE_MSI);
|
||||
if (!irq) {
|
||||
error_report("Cannot allocate MSIs for device %x", config_addr);
|
||||
ret_intr_type == RTAS_TYPE_MSI, &err);
|
||||
if (err) {
|
||||
error_reportf_err(err, "Can't allocate MSIs for device %x: ",
|
||||
config_addr);
|
||||
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Release previous MSIs */
|
||||
if (msi) {
|
||||
xics_free(spapr->icp, msi->first_irq, msi->num);
|
||||
g_hash_table_remove(phb->msi, &config_addr);
|
||||
}
|
||||
|
||||
/* Setup MSI/MSIX vectors in the device (via cfgspace or MSIX BAR) */
|
||||
spapr_msi_setmsg(pdev, SPAPR_PCI_MSI_WINDOW, ret_intr_type == RTAS_TYPE_MSIX,
|
||||
irq, req_num);
|
||||
@@ -1360,10 +1369,12 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
|
||||
/* Initialize the LSI table */
|
||||
for (i = 0; i < PCI_NUM_PINS; i++) {
|
||||
uint32_t irq;
|
||||
Error *local_err = NULL;
|
||||
|
||||
irq = xics_alloc_block(spapr->icp, 0, 1, true, false);
|
||||
if (!irq) {
|
||||
error_setg(errp, "spapr_allocate_lsi failed");
|
||||
irq = xics_alloc_block(spapr->icp, 0, 1, true, false, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
error_prepend(errp, "can't allocate LSIs: ");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ static void spapr_rng_class_init(ObjectClass *oc, void *data)
|
||||
dc->realize = spapr_rng_realize;
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
dc->props = spapr_rng_properties;
|
||||
dc->hotpluggable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo spapr_rng_info = {
|
||||
|
||||
@@ -431,6 +431,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
|
||||
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
|
||||
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
char *id;
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (dev->reg != -1) {
|
||||
/*
|
||||
@@ -463,9 +464,9 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
|
||||
dev->qdev.id = id;
|
||||
}
|
||||
|
||||
dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false);
|
||||
if (!dev->irq) {
|
||||
error_setg(errp, "can't allocate IRQ");
|
||||
dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -447,7 +447,7 @@ static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
|
||||
return p;
|
||||
}
|
||||
|
||||
static void bufp_alloc(USBRedirDevice *dev, uint8_t *data, uint16_t len,
|
||||
static int bufp_alloc(USBRedirDevice *dev, uint8_t *data, uint16_t len,
|
||||
uint8_t status, uint8_t ep, void *free_on_destroy)
|
||||
{
|
||||
struct buf_packet *bufp;
|
||||
@@ -464,7 +464,7 @@ static void bufp_alloc(USBRedirDevice *dev, uint8_t *data, uint16_t len,
|
||||
if (dev->endpoint[EP2I(ep)].bufpq_size >
|
||||
dev->endpoint[EP2I(ep)].bufpq_target_size) {
|
||||
free(data);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
|
||||
}
|
||||
@@ -477,6 +477,7 @@ static void bufp_alloc(USBRedirDevice *dev, uint8_t *data, uint16_t len,
|
||||
bufp->free_on_destroy = free_on_destroy;
|
||||
QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
|
||||
dev->endpoint[EP2I(ep)].bufpq_size++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
|
||||
@@ -2082,13 +2083,17 @@ static void usbredir_buffered_bulk_packet(void *priv, uint64_t id,
|
||||
status = usb_redir_success;
|
||||
free_on_destroy = NULL;
|
||||
for (i = 0; i < data_len; i += len) {
|
||||
int r;
|
||||
if (len >= (data_len - i)) {
|
||||
len = data_len - i;
|
||||
status = buffered_bulk_packet->status;
|
||||
free_on_destroy = data;
|
||||
}
|
||||
/* bufp_alloc also adds the packet to the ep queue */
|
||||
bufp_alloc(dev, data + i, len, status, ep, free_on_destroy);
|
||||
r = bufp_alloc(dev, data + i, len, status, ep, free_on_destroy);
|
||||
if (r) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->endpoint[EP2I(ep)].pending_async_packet) {
|
||||
|
||||
@@ -127,6 +127,7 @@ struct MachineState {
|
||||
char *firmware;
|
||||
bool iommu;
|
||||
bool suppress_vmdesc;
|
||||
bool enforce_config_section;
|
||||
|
||||
ram_addr_t ram_size;
|
||||
ram_addr_t maxram_size;
|
||||
|
||||
@@ -42,6 +42,14 @@
|
||||
.driver = "virtio-pci",\
|
||||
.property = "migrate-extra",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "fw_cfg_mem",\
|
||||
.property = "dma_enabled",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
.driver = "fw_cfg_io",\
|
||||
.property = "dma_enabled",\
|
||||
.value = "off",\
|
||||
},
|
||||
|
||||
#define HW_COMPAT_2_3 \
|
||||
|
||||
@@ -161,8 +161,9 @@ struct ICSIRQState {
|
||||
|
||||
qemu_irq xics_get_qirq(XICSState *icp, int irq);
|
||||
void xics_set_irq_type(XICSState *icp, int irq, bool lsi);
|
||||
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi);
|
||||
int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align);
|
||||
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp);
|
||||
int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align,
|
||||
Error **errp);
|
||||
void xics_free(XICSState *icp, int irq, int num);
|
||||
|
||||
void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
|
||||
|
||||
@@ -378,6 +378,8 @@ void graphic_hw_gl_block(QemuConsole *con, bool block);
|
||||
|
||||
QemuConsole *qemu_console_lookup_by_index(unsigned int index);
|
||||
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);
|
||||
QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
|
||||
uint32_t head, Error **errp);
|
||||
bool qemu_console_is_visible(QemuConsole *con);
|
||||
bool qemu_console_is_graphic(QemuConsole *con);
|
||||
bool qemu_console_is_fixedsize(QemuConsole *con);
|
||||
|
||||
@@ -878,13 +878,19 @@ bool qemu_savevm_state_blocked(Error **errp)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool enforce_config_section(void)
|
||||
{
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
return machine->enforce_config_section;
|
||||
}
|
||||
|
||||
void qemu_savevm_state_header(QEMUFile *f)
|
||||
{
|
||||
trace_savevm_state_header();
|
||||
qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
|
||||
qemu_put_be32(f, QEMU_VM_FILE_VERSION);
|
||||
|
||||
if (!savevm_state.skip_configuration) {
|
||||
if (!savevm_state.skip_configuration || enforce_config_section()) {
|
||||
qemu_put_byte(f, QEMU_VM_CONFIGURATION);
|
||||
vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);
|
||||
}
|
||||
@@ -1883,7 +1889,7 @@ int qemu_loadvm_state(QEMUFile *f)
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!savevm_state.skip_configuration) {
|
||||
if (!savevm_state.skip_configuration || enforce_config_section()) {
|
||||
if (qemu_get_byte(f) != QEMU_VM_CONFIGURATION) {
|
||||
error_report("Configuration section missing");
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1375,7 +1375,7 @@ static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
|
||||
if (dz_str) {
|
||||
dz = strtol(dz_str, NULL, 0);
|
||||
if (dz != 0) {
|
||||
button = (dz > 0) ? INPUT_BUTTON_WHEELUP : INPUT_BUTTON_WHEELDOWN;
|
||||
button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
|
||||
qemu_input_queue_btn(NULL, button, true);
|
||||
qemu_input_event_sync();
|
||||
qemu_input_queue_btn(NULL, button, false);
|
||||
|
||||
@@ -3743,12 +3743,9 @@
|
||||
# Button of a pointer input device (mouse, tablet).
|
||||
#
|
||||
# Since: 2.0
|
||||
#
|
||||
# Note that the spelling of these values may change when the
|
||||
# x-input-send-event is promoted out of experimental status.
|
||||
##
|
||||
{ 'enum' : 'InputButton',
|
||||
'data' : [ 'Left', 'Middle', 'Right', 'WheelUp', 'WheelDown' ] }
|
||||
'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down' ] }
|
||||
|
||||
##
|
||||
# @InputAxis
|
||||
@@ -3756,12 +3753,9 @@
|
||||
# Position axis of a pointer input device (mouse, tablet).
|
||||
#
|
||||
# Since: 2.0
|
||||
#
|
||||
# Note that the spelling of these values may change when the
|
||||
# x-input-send-event is promoted out of experimental status.
|
||||
##
|
||||
{ 'enum' : 'InputAxis',
|
||||
'data' : [ 'X', 'Y' ] }
|
||||
'data' : [ 'x', 'y' ] }
|
||||
|
||||
##
|
||||
# @InputKeyEvent
|
||||
@@ -3825,38 +3819,34 @@
|
||||
'abs' : 'InputMoveEvent' } }
|
||||
|
||||
##
|
||||
# @x-input-send-event
|
||||
# @input-send-event
|
||||
#
|
||||
# Send input event(s) to guest.
|
||||
#
|
||||
# @console: #optional console to send event(s) to.
|
||||
# This parameter can be used to send the input event to
|
||||
# specific input devices in case (a) multiple input devices
|
||||
# of the same kind are added to the virtual machine and (b)
|
||||
# you have configured input routing (see docs/multiseat.txt)
|
||||
# for those input devices. If input routing is not
|
||||
# configured this parameter has no effect.
|
||||
# If @console is missing, only devices that aren't associated
|
||||
# with a console are admissible.
|
||||
# If @console is specified, it must exist, and both devices
|
||||
# associated with that console and devices not associated with a
|
||||
# console are admissible, but the former take precedence.
|
||||
|
||||
#
|
||||
# @device: #optional display device to send event(s) to.
|
||||
# @head: #optional head to send event(s) to, in case the
|
||||
# display device supports multiple scanouts.
|
||||
# @events: List of InputEvent union.
|
||||
#
|
||||
# Returns: Nothing on success.
|
||||
#
|
||||
# Since: 2.2
|
||||
#
|
||||
# Note: this command is experimental, and not a stable API. Things that
|
||||
# might change before it becomes stable include the spelling of enum
|
||||
# values for InputButton and InputAxis, and the notion of how to designate
|
||||
# which console will receive the event.
|
||||
# The @display and @head parameters can be used to send the input
|
||||
# event to specific input devices in case (a) multiple input devices
|
||||
# of the same kind are added to the virtual machine and (b) you have
|
||||
# configured input routing (see docs/multiseat.txt) for those input
|
||||
# devices. The parameters work exactly like the device and head
|
||||
# properties of input devices. If @device is missing, only devices
|
||||
# that have no input routing config are admissible. If @device is
|
||||
# specified, both input devices with and without input routing config
|
||||
# are admissible, but devices with input routing config take
|
||||
# precedence.
|
||||
#
|
||||
# Since: 2.6
|
||||
##
|
||||
{ 'command': 'x-input-send-event',
|
||||
'data': { '*console':'int', 'events': [ 'InputEvent' ] } }
|
||||
{ 'command': 'input-send-event',
|
||||
'data': { '*device': 'str',
|
||||
'*head' : 'int',
|
||||
'events' : [ 'InputEvent' ] } }
|
||||
|
||||
##
|
||||
# @NumaOptions
|
||||
|
||||
@@ -43,7 +43,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
|
||||
" aes-key-wrap=on|off controls support for AES key wrapping (default=on)\n"
|
||||
" dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n"
|
||||
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
|
||||
" nvdimm=on|off controls NVDIMM support (default=off)\n",
|
||||
" nvdimm=on|off controls NVDIMM support (default=off)\n"
|
||||
" enforce-config-section=on|off enforce configuration section migration (default=off)\n",
|
||||
QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
|
||||
|
||||
@@ -4658,21 +4658,22 @@ Example:
|
||||
EQMP
|
||||
|
||||
{
|
||||
.name = "x-input-send-event",
|
||||
.name = "input-send-event",
|
||||
.args_type = "console:i?,events:q",
|
||||
.mhandler.cmd_new = qmp_marshal_x_input_send_event,
|
||||
.mhandler.cmd_new = qmp_marshal_input_send_event,
|
||||
},
|
||||
|
||||
SQMP
|
||||
@x-input-send-event
|
||||
@input-send-event
|
||||
-----------------
|
||||
|
||||
Send input event to guest.
|
||||
|
||||
Arguments:
|
||||
|
||||
- "console": console index. (json-int, optional)
|
||||
- "events": list of input events.
|
||||
- "device": display device (json-string, optional)
|
||||
- "head": display head (json-int, optional)
|
||||
- "events": list of input events
|
||||
|
||||
The consoles are visible in the qom tree, under
|
||||
/backend/console[$index]. They have a device link and head property, so
|
||||
@@ -4684,24 +4685,24 @@ Example (1):
|
||||
|
||||
Press left mouse button.
|
||||
|
||||
-> { "execute": "x-input-send-event",
|
||||
"arguments": { "console": 0,
|
||||
-> { "execute": "input-send-event",
|
||||
"arguments": { "device": "video0",
|
||||
"events": [ { "type": "btn",
|
||||
"data" : { "down": true, "button": "Left" } } ] } }
|
||||
"data" : { "down": true, "button": "left" } } ] } }
|
||||
<- { "return": {} }
|
||||
|
||||
-> { "execute": "x-input-send-event",
|
||||
"arguments": { "console": 0,
|
||||
-> { "execute": "input-send-event",
|
||||
"arguments": { "device": "video0",
|
||||
"events": [ { "type": "btn",
|
||||
"data" : { "down": false, "button": "Left" } } ] } }
|
||||
"data" : { "down": false, "button": "left" } } ] } }
|
||||
<- { "return": {} }
|
||||
|
||||
Example (2):
|
||||
|
||||
Press ctrl-alt-del.
|
||||
|
||||
-> { "execute": "x-input-send-event",
|
||||
"arguments": { "console": 0, "events": [
|
||||
-> { "execute": "input-send-event",
|
||||
"arguments": { "events": [
|
||||
{ "type": "key", "data" : { "down": true,
|
||||
"key": {"type": "qcode", "data": "ctrl" } } },
|
||||
{ "type": "key", "data" : { "down": true,
|
||||
@@ -4714,10 +4715,10 @@ Example (3):
|
||||
|
||||
Move mouse pointer to absolute coordinates (20000, 400).
|
||||
|
||||
-> { "execute": "x-input-send-event" ,
|
||||
"arguments": { "console": 0, "events": [
|
||||
{ "type": "abs", "data" : { "axis": "X", "value" : 20000 } },
|
||||
{ "type": "abs", "data" : { "axis": "Y", "value" : 400 } } ] } }
|
||||
-> { "execute": "input-send-event" ,
|
||||
"arguments": { "events": [
|
||||
{ "type": "abs", "data" : { "axis": "x", "value" : 20000 } },
|
||||
{ "type": "abs", "data" : { "axis": "y", "value" : 400 } } ] } }
|
||||
<- { "return": {} }
|
||||
|
||||
EQMP
|
||||
|
||||
@@ -66,8 +66,6 @@ case_whitelist = [
|
||||
'CpuInfoBase', # CPU, visible through query-cpu
|
||||
'CpuInfoMIPS', # PC, visible through query-cpu
|
||||
'CpuInfoTricore', # PC, visible through query-cpu
|
||||
'InputAxis', # TODO: drop when x-input-send-event is fixed
|
||||
'InputButton', # TODO: drop when x-input-send-event is fixed
|
||||
'QapiErrorClass', # all members, visible through errors
|
||||
'UuidInfo', # UUID, visible through query-uuid
|
||||
'X86CPURegister32', # all members, visible indirectly through qom-get
|
||||
|
||||
@@ -1409,8 +1409,6 @@ xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_
|
||||
xics_ics_reject(int nr, int srcno) "reject irq %#x [src %d]"
|
||||
xics_ics_eoi(int nr) "ics_eoi: irq %#x"
|
||||
xics_alloc(int src, int irq) "source#%d, irq %d"
|
||||
xics_alloc_failed_hint(int src, int irq) "source#%d, irq %d is already in use"
|
||||
xics_alloc_failed_no_left(int src) "source#%d, no irq left"
|
||||
xics_alloc_block(int src, int first, int num, bool lsi, int align) "source#%d, first irq %d, %d irqs, lsi=%d, alignnum %d"
|
||||
xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
|
||||
xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free"
|
||||
|
||||
@@ -739,8 +739,8 @@ QemuCocoaView *cocoaView;
|
||||
[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
|
||||
[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
|
||||
[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
|
||||
[INPUT_BUTTON_WHEELUP] = MOUSE_EVENT_WHEELUP,
|
||||
[INPUT_BUTTON_WHEELDOWN] = MOUSE_EVENT_WHEELDN,
|
||||
[INPUT_BUTTON_WHEEL_UP] = MOUSE_EVENT_WHEELUP,
|
||||
[INPUT_BUTTON_WHEEL_DOWN] = MOUSE_EVENT_WHEELDN,
|
||||
};
|
||||
qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons);
|
||||
last_buttons = buttons;
|
||||
|
||||
23
ui/console.c
23
ui/console.c
@@ -1790,6 +1790,29 @@ QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
|
||||
uint32_t head, Error **errp)
|
||||
{
|
||||
DeviceState *dev;
|
||||
QemuConsole *con;
|
||||
|
||||
dev = qdev_find_recursive(sysbus_get_default(), device_id);
|
||||
if (dev == NULL) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
con = qemu_console_lookup_by_device(dev, head);
|
||||
if (con == NULL) {
|
||||
error_setg(errp, "Device %s (head %d) is not bound to a QemuConsole",
|
||||
device_id, head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return con;
|
||||
}
|
||||
|
||||
bool qemu_console_is_visible(QemuConsole *con)
|
||||
{
|
||||
return (con == active_console) || (con->dcls > 0);
|
||||
|
||||
4
ui/gtk.c
4
ui/gtk.c
@@ -966,9 +966,9 @@ static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll,
|
||||
InputButton btn;
|
||||
|
||||
if (scroll->direction == GDK_SCROLL_UP) {
|
||||
btn = INPUT_BUTTON_WHEELUP;
|
||||
btn = INPUT_BUTTON_WHEEL_UP;
|
||||
} else if (scroll->direction == GDK_SCROLL_DOWN) {
|
||||
btn = INPUT_BUTTON_WHEELDOWN;
|
||||
btn = INPUT_BUTTON_WHEEL_DOWN;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
|
||||
} else {
|
||||
s->buttons &= ~bmap[evt->u.btn->button];
|
||||
}
|
||||
if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEELUP) {
|
||||
if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
|
||||
s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
|
||||
s->axis[INPUT_AXIS_X],
|
||||
s->axis[INPUT_AXIS_Y],
|
||||
@@ -166,7 +166,7 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
|
||||
s->buttons);
|
||||
}
|
||||
if (evt->u.btn->down &&
|
||||
evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) {
|
||||
evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
|
||||
s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
|
||||
s->axis[INPUT_AXIS_X],
|
||||
s->axis[INPUT_AXIS_Y],
|
||||
|
||||
32
ui/input.c
32
ui/input.c
@@ -82,19 +82,12 @@ void qemu_input_handler_bind(QemuInputHandlerState *s,
|
||||
const char *device_id, int head,
|
||||
Error **errp)
|
||||
{
|
||||
DeviceState *dev;
|
||||
QemuConsole *con;
|
||||
Error *err = NULL;
|
||||
|
||||
dev = qdev_find_recursive(sysbus_get_default(), device_id);
|
||||
if (dev == NULL) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device_id);
|
||||
return;
|
||||
}
|
||||
|
||||
con = qemu_console_lookup_by_device(dev, head);
|
||||
if (con == NULL) {
|
||||
error_setg(errp, "Device %s is not bound to a QemuConsole", device_id);
|
||||
con = qemu_console_lookup_by_device_name(device_id, head, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -126,17 +119,22 @@ qemu_input_find_handler(uint32_t mask, QemuConsole *con)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void qmp_x_input_send_event(bool has_console, int64_t console,
|
||||
InputEventList *events, Error **errp)
|
||||
void qmp_input_send_event(bool has_device, const char *device,
|
||||
bool has_head, int64_t head,
|
||||
InputEventList *events, Error **errp)
|
||||
{
|
||||
InputEventList *e;
|
||||
QemuConsole *con;
|
||||
Error *err = NULL;
|
||||
|
||||
con = NULL;
|
||||
if (has_console) {
|
||||
con = qemu_console_lookup_by_index(console);
|
||||
if (!con) {
|
||||
error_setg(errp, "console %" PRId64 " not found", console);
|
||||
if (has_device) {
|
||||
if (!has_head) {
|
||||
head = 0;
|
||||
}
|
||||
con = qemu_console_lookup_by_device_name(device, head, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
4
ui/sdl.c
4
ui/sdl.c
@@ -475,8 +475,8 @@ static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)
|
||||
[INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT),
|
||||
[INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE),
|
||||
[INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT),
|
||||
[INPUT_BUTTON_WHEELUP] = SDL_BUTTON(SDL_BUTTON_WHEELUP),
|
||||
[INPUT_BUTTON_WHEELDOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),
|
||||
[INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP),
|
||||
[INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),
|
||||
};
|
||||
static uint32_t prev_state;
|
||||
|
||||
|
||||
@@ -509,9 +509,9 @@ static void handle_mousewheel(SDL_Event *ev)
|
||||
InputButton btn;
|
||||
|
||||
if (wev->y > 0) {
|
||||
btn = INPUT_BUTTON_WHEELUP;
|
||||
btn = INPUT_BUTTON_WHEEL_UP;
|
||||
} else if (wev->y < 0) {
|
||||
btn = INPUT_BUTTON_WHEELDOWN;
|
||||
btn = INPUT_BUTTON_WHEEL_DOWN;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,8 +108,8 @@ static void spice_update_buttons(QemuSpicePointer *pointer,
|
||||
[INPUT_BUTTON_LEFT] = 0x01,
|
||||
[INPUT_BUTTON_MIDDLE] = 0x04,
|
||||
[INPUT_BUTTON_RIGHT] = 0x02,
|
||||
[INPUT_BUTTON_WHEELUP] = 0x10,
|
||||
[INPUT_BUTTON_WHEELDOWN] = 0x20,
|
||||
[INPUT_BUTTON_WHEEL_UP] = 0x10,
|
||||
[INPUT_BUTTON_WHEEL_DOWN] = 0x20,
|
||||
};
|
||||
|
||||
if (wheel < 0) {
|
||||
|
||||
19
ui/vnc.c
19
ui/vnc.c
@@ -1593,8 +1593,8 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y)
|
||||
[INPUT_BUTTON_LEFT] = 0x01,
|
||||
[INPUT_BUTTON_MIDDLE] = 0x02,
|
||||
[INPUT_BUTTON_RIGHT] = 0x04,
|
||||
[INPUT_BUTTON_WHEELUP] = 0x08,
|
||||
[INPUT_BUTTON_WHEELDOWN] = 0x10,
|
||||
[INPUT_BUTTON_WHEEL_UP] = 0x08,
|
||||
[INPUT_BUTTON_WHEEL_DOWN] = 0x10,
|
||||
};
|
||||
QemuConsole *con = vs->vd->dcl.con;
|
||||
int width = pixman_image_get_width(vs->vd->server);
|
||||
@@ -3732,19 +3732,12 @@ void vnc_display_open(const char *id, Error **errp)
|
||||
|
||||
device_id = qemu_opt_get(opts, "display");
|
||||
if (device_id) {
|
||||
DeviceState *dev;
|
||||
int head = qemu_opt_get_number(opts, "head", 0);
|
||||
Error *err = NULL;
|
||||
|
||||
dev = qdev_find_recursive(sysbus_get_default(), device_id);
|
||||
if (dev == NULL) {
|
||||
error_setg(errp, "Device '%s' not found", device_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
con = qemu_console_lookup_by_device(dev, head);
|
||||
if (con == NULL) {
|
||||
error_setg(errp, "Device %s is not bound to a QemuConsole",
|
||||
device_id);
|
||||
con = qemu_console_lookup_by_device_name(device_id, head, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user