mirror of https://github.com/xqemu/xqemu.git
* xsetbv fix (x86 targets TCG)
* remove unused functions * qht segfault and memory leak fixes * NBD fixes * Fix for non-power-of-2 discard granularity * Memory hotplug fixes * Migration regressions * IOAPIC fixes and (disabled by default) EOI register support * Various other small fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQExBAABCAAbBQJXoiNRFBxwYm9uemluaUByZWRoYXQuY29tAAoJEL/70l94x66D ZwMH/1HmEYIAyyd9T8z2sNjdN7vKCNsphS7OXALDnwTp+VX4icUbf41NC6Eeg/e+ 6OKA90KSBTquG3wxsXrUK5Nwy7EKMoCXVQrdYw5T04OidQLtJosKgPx4MrvPSx8h caFUXo9WynT/aGRNc14gnZZiooQxsy/JoNhuml/WL0nupEmoUb/Ns3Yo++HRHntR rFmJvvD9SrQsWzd9+aJ8zm+Qi09gXsbj1grr6LHCLVmwDWAJooFev6MqBvplkL50 OLqCJfAXJ2srUoEboVdg3V+sFtB8Eru+iMdpZyLwo07V4BBK7heEsXx6JJkTObMC 90MSnMo6BauUO/R/bMvvLlNWykU= =XqbI -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging * xsetbv fix (x86 targets TCG) * remove unused functions * qht segfault and memory leak fixes * NBD fixes * Fix for non-power-of-2 discard granularity * Memory hotplug fixes * Migration regressions * IOAPIC fixes and (disabled by default) EOI register support * Various other small fixes # gpg: Signature made Wed 03 Aug 2016 18:01:05 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (25 commits) util: Fix assertion in iov_copy() upon zero 'bytes' and non-zero 'offset' qdev: Fix use after free in qdev_init_nofail error path Reorganize help output of '-display' option x86: ioapic: add support for explicit EOI x86: ioapic: ignore level irq during processing apic: fix broken migration for kvm-apic fw_cfg: Make base type "fw_cfg" abstract block: Cater to iscsi with non-power-of-2 discard osdep: Document differences in rounding macros nbd: Limit nbdflags to 16 bits nbd: Fix bad flag detection on server i2c: fix migration regression introduced by broadcast support mptsas: really fix migration compatibility qdist: return "(empty)" instead of NULL when printing an empty dist qdist: use g_renew and g_new instead of g_realloc and g_malloc. qdist: fix memory leak during binning target-i386: fix typo in xsetbv implementation qht: do not segfault when gathering stats from an uninitialized qht util: Drop inet_listen() util: drop unix_nonblocking_connect() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
09704e6ded
|
@ -203,6 +203,7 @@ static bool host_memory_backend_get_prealloc(Object *obj, Error **errp)
|
|||
static void host_memory_backend_set_prealloc(Object *obj, bool value,
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
|
||||
|
||||
if (backend->force_prealloc) {
|
||||
|
@ -223,7 +224,11 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value,
|
|||
void *ptr = memory_region_get_ram_ptr(&backend->mr);
|
||||
uint64_t sz = memory_region_size(&backend->mr);
|
||||
|
||||
os_mem_prealloc(fd, ptr, sz);
|
||||
os_mem_prealloc(fd, ptr, sz, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
backend->prealloc = true;
|
||||
}
|
||||
}
|
||||
|
@ -286,8 +291,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
|
|||
if (bc->alloc) {
|
||||
bc->alloc(backend, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ptr = memory_region_get_ram_ptr(&backend->mr);
|
||||
|
@ -343,9 +347,15 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
|
|||
* specified NUMA policy in place.
|
||||
*/
|
||||
if (backend->prealloc) {
|
||||
os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz);
|
||||
os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
15
block/io.c
15
block/io.c
|
@ -1180,10 +1180,11 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
|
|||
int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
|
||||
bs->bl.request_alignment);
|
||||
|
||||
assert(is_power_of_2(alignment));
|
||||
head = offset & (alignment - 1);
|
||||
tail = (offset + count) & (alignment - 1);
|
||||
max_write_zeroes &= ~(alignment - 1);
|
||||
assert(alignment % bs->bl.request_alignment == 0);
|
||||
head = offset % alignment;
|
||||
tail = (offset + count) % alignment;
|
||||
max_write_zeroes = QEMU_ALIGN_DOWN(max_write_zeroes, alignment);
|
||||
assert(max_write_zeroes >= bs->bl.request_alignment);
|
||||
|
||||
while (count > 0 && !ret) {
|
||||
int num = count;
|
||||
|
@ -2429,9 +2430,10 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
|
|||
|
||||
/* Discard is advisory, so ignore any unaligned head or tail */
|
||||
align = MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment);
|
||||
assert(is_power_of_2(align));
|
||||
head = MIN(count, -offset & (align - 1));
|
||||
assert(align % bs->bl.request_alignment == 0);
|
||||
head = offset % align;
|
||||
if (head) {
|
||||
head = MIN(count, align - head);
|
||||
count -= head;
|
||||
offset += head;
|
||||
}
|
||||
|
@ -2449,6 +2451,7 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
|
|||
|
||||
max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard, INT_MAX),
|
||||
align);
|
||||
assert(max_pdiscard);
|
||||
|
||||
while (count > 0) {
|
||||
int ret;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
typedef struct NbdClientSession {
|
||||
QIOChannelSocket *sioc; /* The master data channel */
|
||||
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
|
||||
uint32_t nbdflags;
|
||||
uint16_t nbdflags;
|
||||
off_t size;
|
||||
|
||||
CoMutex send_mutex;
|
||||
|
|
10
exec.c
10
exec.c
|
@ -1226,7 +1226,7 @@ static void *file_ram_alloc(RAMBlock *block,
|
|||
char *filename;
|
||||
char *sanitized_name;
|
||||
char *c;
|
||||
void *area;
|
||||
void *area = MAP_FAILED;
|
||||
int fd = -1;
|
||||
int64_t page_size;
|
||||
|
||||
|
@ -1314,13 +1314,19 @@ static void *file_ram_alloc(RAMBlock *block,
|
|||
}
|
||||
|
||||
if (mem_prealloc) {
|
||||
os_mem_prealloc(fd, area, memory);
|
||||
os_mem_prealloc(fd, area, memory, errp);
|
||||
if (errp && *errp) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
block->fd = fd;
|
||||
return area;
|
||||
|
||||
error:
|
||||
if (area != MAP_FAILED) {
|
||||
qemu_ram_munmap(area, memory);
|
||||
}
|
||||
if (unlink_on_error) {
|
||||
unlink(path);
|
||||
}
|
||||
|
|
|
@ -354,12 +354,14 @@ void qdev_init_nofail(DeviceState *dev)
|
|||
|
||||
assert(!dev->realized);
|
||||
|
||||
object_ref(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), true, "realized", &err);
|
||||
if (err) {
|
||||
error_reportf_err(err, "Initialization of device %s failed: ",
|
||||
object_get_typename(OBJECT(dev)));
|
||||
exit(1);
|
||||
}
|
||||
object_unref(OBJECT(dev));
|
||||
}
|
||||
|
||||
void qdev_machine_creation_done(void)
|
||||
|
|
|
@ -17,6 +17,8 @@ struct I2CNode {
|
|||
QLIST_ENTRY(I2CNode) next;
|
||||
};
|
||||
|
||||
#define I2C_BROADCAST 0x00
|
||||
|
||||
struct I2CBus
|
||||
{
|
||||
BusState qbus;
|
||||
|
@ -47,6 +49,8 @@ static void i2c_bus_pre_save(void *opaque)
|
|||
if (!QLIST_EMPTY(&bus->current_devs)) {
|
||||
if (!bus->broadcast) {
|
||||
bus->saved_address = QLIST_FIRST(&bus->current_devs)->elt->address;
|
||||
} else {
|
||||
bus->saved_address = I2C_BROADCAST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +62,6 @@ static const VMStateDescription vmstate_i2c_bus = {
|
|||
.pre_save = i2c_bus_pre_save,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT8(saved_address, I2CBus),
|
||||
VMSTATE_BOOL(broadcast, I2CBus),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
@ -93,7 +96,7 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
|
|||
I2CSlaveClass *sc;
|
||||
I2CNode *node;
|
||||
|
||||
if (address == 0x00) {
|
||||
if (address == I2C_BROADCAST) {
|
||||
/*
|
||||
* This is a broadcast, the current_devs will be all the devices of the
|
||||
* bus.
|
||||
|
@ -221,7 +224,8 @@ static int i2c_slave_post_load(void *opaque, int version_id)
|
|||
I2CNode *node;
|
||||
|
||||
bus = I2C_BUS(qdev_get_parent_bus(DEVICE(dev)));
|
||||
if ((bus->saved_address == dev->address) || (bus->broadcast)) {
|
||||
if ((bus->saved_address == dev->address) ||
|
||||
(bus->saved_address == I2C_BROADCAST)) {
|
||||
node = g_malloc(sizeof(struct I2CNode));
|
||||
node->elt = dev;
|
||||
QLIST_INSERT_HEAD(&bus->current_devs, node, next);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/i386/pc.h"
|
||||
|
@ -117,21 +118,25 @@ static void ioapic_service(IOAPICCommonState *s)
|
|||
s->ioredtbl[i] |= IOAPIC_LVT_REMOTE_IRR;
|
||||
}
|
||||
|
||||
if (coalesce) {
|
||||
/* We are level triggered interrupts, and the
|
||||
* guest should be still working on previous one,
|
||||
* so skip it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
if (kvm_irqchip_is_split()) {
|
||||
if (info.trig_mode == IOAPIC_TRIGGER_EDGE) {
|
||||
kvm_set_irq(kvm_state, i, 1);
|
||||
kvm_set_irq(kvm_state, i, 0);
|
||||
} else {
|
||||
if (!coalesce) {
|
||||
kvm_set_irq(kvm_state, i, 1);
|
||||
}
|
||||
kvm_set_irq(kvm_state, i, 1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
(void)coalesce;
|
||||
#endif
|
||||
|
||||
/* No matter whether IR is enabled, we translate
|
||||
* the IOAPIC message into a MSI one, and its
|
||||
* address space will decide whether we need a
|
||||
|
@ -265,7 +270,7 @@ ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
|
|||
val = s->id << IOAPIC_ID_SHIFT;
|
||||
break;
|
||||
case IOAPIC_REG_VER:
|
||||
val = IOAPIC_VERSION |
|
||||
val = s->version |
|
||||
((IOAPIC_NUM_PINS - 1) << IOAPIC_VER_ENTRIES_SHIFT);
|
||||
break;
|
||||
default:
|
||||
|
@ -354,6 +359,13 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case IOAPIC_EOI:
|
||||
/* Explicit EOI is only supported for IOAPIC version 0x20 */
|
||||
if (size != 4 || s->version != 0x20) {
|
||||
break;
|
||||
}
|
||||
ioapic_eoi_broadcast(val);
|
||||
break;
|
||||
}
|
||||
|
||||
ioapic_update_kvm_routes(s);
|
||||
|
@ -387,6 +399,12 @@ static void ioapic_realize(DeviceState *dev, Error **errp)
|
|||
{
|
||||
IOAPICCommonState *s = IOAPIC_COMMON(dev);
|
||||
|
||||
if (s->version != 0x11 && s->version != 0x20) {
|
||||
error_report("IOAPIC only supports version 0x11 or 0x20 "
|
||||
"(default: 0x11).");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s,
|
||||
"ioapic", 0x1000);
|
||||
|
||||
|
@ -397,6 +415,11 @@ static void ioapic_realize(DeviceState *dev, Error **errp)
|
|||
qemu_add_machine_init_done_notifier(&s->machine_done);
|
||||
}
|
||||
|
||||
static Property ioapic_properties[] = {
|
||||
DEFINE_PROP_UINT8("version", IOAPICCommonState, version, 0x11),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void ioapic_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
|
||||
|
@ -404,6 +427,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data)
|
|||
|
||||
k->realize = ioapic_realize;
|
||||
dc->reset = ioapic_reset_common;
|
||||
dc->props = ioapic_properties;
|
||||
}
|
||||
|
||||
static const TypeInfo ioapic_info = {
|
||||
|
|
|
@ -990,6 +990,7 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data)
|
|||
static const TypeInfo fw_cfg_info = {
|
||||
.name = TYPE_FW_CFG,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.abstract = true,
|
||||
.instance_size = sizeof(FWCfgState),
|
||||
.class_init = fw_cfg_class_init,
|
||||
};
|
||||
|
|
|
@ -1295,6 +1295,8 @@ static void mptsas_scsi_init(PCIDevice *dev, Error **errp)
|
|||
/* With msi=auto, we fall back to MSI off silently */
|
||||
error_free(err);
|
||||
|
||||
/* Only used for migration. */
|
||||
s->msi_in_use = (ret == 0);
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->mmio_io, OBJECT(s), &mptsas_mmio_ops, s,
|
||||
|
@ -1370,7 +1372,7 @@ static const VMStateDescription vmstate_mptsas = {
|
|||
.post_load = mptsas_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(dev, MPTSASState),
|
||||
VMSTATE_UNUSED(sizeof(bool)), /* Was msi_in_use */
|
||||
VMSTATE_BOOL(msi_in_use, MPTSASState),
|
||||
VMSTATE_UINT32(state, MPTSASState),
|
||||
VMSTATE_UINT8(who_init, MPTSASState),
|
||||
VMSTATE_UINT8(doorbell_state, MPTSASState),
|
||||
|
|
|
@ -31,6 +31,8 @@ struct MPTSASState {
|
|||
OnOffAuto msi;
|
||||
uint64_t sas_addr;
|
||||
|
||||
bool msi_in_use;
|
||||
|
||||
/* Doorbell register */
|
||||
uint32_t state;
|
||||
uint8_t who_init;
|
||||
|
|
|
@ -330,36 +330,39 @@ typedef struct BlockLimits {
|
|||
* otherwise. */
|
||||
uint32_t request_alignment;
|
||||
|
||||
/* maximum number of bytes that can be discarded at once (since it
|
||||
* is signed, it must be < 2G, if set), should be multiple of
|
||||
/* Maximum number of bytes that can be discarded at once (since it
|
||||
* is signed, it must be < 2G, if set). Must be multiple of
|
||||
* pdiscard_alignment, but need not be power of 2. May be 0 if no
|
||||
* inherent 32-bit limit */
|
||||
int32_t max_pdiscard;
|
||||
|
||||
/* optimal alignment for discard requests in bytes, must be power
|
||||
* of 2, less than max_pdiscard if that is set, and multiple of
|
||||
* bl.request_alignment. May be 0 if bl.request_alignment is good
|
||||
* enough */
|
||||
/* Optimal alignment for discard requests in bytes. A power of 2
|
||||
* is best but not mandatory. Must be a multiple of
|
||||
* bl.request_alignment, and must be less than max_pdiscard if
|
||||
* that is set. May be 0 if bl.request_alignment is good enough */
|
||||
uint32_t pdiscard_alignment;
|
||||
|
||||
/* maximum number of bytes that can zeroized at once (since it is
|
||||
* signed, it must be < 2G, if set), should be multiple of
|
||||
/* Maximum number of bytes that can zeroized at once (since it is
|
||||
* signed, it must be < 2G, if set). Must be multiple of
|
||||
* pwrite_zeroes_alignment. May be 0 if no inherent 32-bit limit */
|
||||
int32_t max_pwrite_zeroes;
|
||||
|
||||
/* optimal alignment for write zeroes requests in bytes, must be
|
||||
* power of 2, less than max_pwrite_zeroes if that is set, and
|
||||
* multiple of bl.request_alignment. May be 0 if
|
||||
* bl.request_alignment is good enough */
|
||||
/* Optimal alignment for write zeroes requests in bytes. A power
|
||||
* of 2 is best but not mandatory. Must be a multiple of
|
||||
* bl.request_alignment, and must be less than max_pwrite_zeroes
|
||||
* if that is set. May be 0 if bl.request_alignment is good
|
||||
* enough */
|
||||
uint32_t pwrite_zeroes_alignment;
|
||||
|
||||
/* optimal transfer length in bytes (must be power of 2, and
|
||||
* multiple of bl.request_alignment), or 0 if no preferred size */
|
||||
/* Optimal transfer length in bytes. A power of 2 is best but not
|
||||
* mandatory. Must be a multiple of bl.request_alignment, or 0 if
|
||||
* no preferred size */
|
||||
uint32_t opt_transfer;
|
||||
|
||||
/* maximal transfer length in bytes (need not be power of 2, but
|
||||
* should be multiple of opt_transfer), or 0 for no 32-bit limit.
|
||||
* For now, anything larger than INT_MAX is clamped down. */
|
||||
/* Maximal transfer length in bytes. Need not be power of 2, but
|
||||
* must be multiple of opt_transfer and bl.request_alignment, or 0
|
||||
* for no 32-bit limit. For now, anything larger than INT_MAX is
|
||||
* clamped down. */
|
||||
uint32_t max_transfer;
|
||||
|
||||
/* memory alignment, in bytes so that no bounce buffer is needed */
|
||||
|
|
|
@ -90,11 +90,11 @@ ssize_t nbd_wr_syncv(QIOChannel *ioc,
|
|||
size_t niov,
|
||||
size_t length,
|
||||
bool do_read);
|
||||
int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags,
|
||||
int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
|
||||
QCryptoTLSCreds *tlscreds, const char *hostname,
|
||||
QIOChannel **outioc,
|
||||
off_t *size, Error **errp);
|
||||
int nbd_init(int fd, QIOChannelSocket *sioc, uint32_t flags, off_t size);
|
||||
int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size);
|
||||
ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request);
|
||||
ssize_t nbd_receive_reply(QIOChannel *ioc, struct nbd_reply *reply);
|
||||
int nbd_client(int fd);
|
||||
|
@ -104,7 +104,7 @@ typedef struct NBDExport NBDExport;
|
|||
typedef struct NBDClient NBDClient;
|
||||
|
||||
NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
|
||||
uint32_t nbdflags, void (*close)(NBDExport *),
|
||||
uint16_t nbdflags, void (*close)(NBDExport *),
|
||||
Error **errp);
|
||||
void nbd_export_close(NBDExport *exp);
|
||||
void nbd_export_get(NBDExport *exp);
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
|
||||
#define MAX_IOAPICS 1
|
||||
|
||||
#define IOAPIC_VERSION 0x11
|
||||
|
||||
#define IOAPIC_LVT_DEST_SHIFT 56
|
||||
#define IOAPIC_LVT_DEST_IDX_SHIFT 48
|
||||
#define IOAPIC_LVT_MASKED_SHIFT 16
|
||||
|
@ -71,6 +69,7 @@
|
|||
|
||||
#define IOAPIC_IOREGSEL 0x00
|
||||
#define IOAPIC_IOWIN 0x10
|
||||
#define IOAPIC_EOI 0x40
|
||||
|
||||
#define IOAPIC_REG_ID 0x00
|
||||
#define IOAPIC_REG_VER 0x01
|
||||
|
@ -109,6 +108,7 @@ struct IOAPICCommonState {
|
|||
uint32_t irr;
|
||||
uint64_t ioredtbl[IOAPIC_NUM_PINS];
|
||||
Notifier machine_done;
|
||||
uint8_t version;
|
||||
};
|
||||
|
||||
void ioapic_reset_common(DeviceState *dev);
|
||||
|
|
|
@ -388,7 +388,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
|||
.value = "off",\
|
||||
},\
|
||||
{\
|
||||
.driver = "apic",\
|
||||
.driver = "apic-common",\
|
||||
.property = "legacy-instance-id",\
|
||||
.value = "on",\
|
||||
},
|
||||
|
|
|
@ -158,7 +158,8 @@ extern int daemon(int, int);
|
|||
/* Round number down to multiple */
|
||||
#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
|
||||
|
||||
/* Round number up to multiple */
|
||||
/* Round number up to multiple. Safe when m is not a power of 2 (see
|
||||
* ROUND_UP for a faster version when a power of 2 is guaranteed) */
|
||||
#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
|
||||
|
||||
/* Check if n is a multiple of m */
|
||||
|
@ -175,6 +176,9 @@ extern int daemon(int, int);
|
|||
/* Check if pointer p is n-bytes aligned */
|
||||
#define QEMU_PTR_IS_ALIGNED(p, n) QEMU_IS_ALIGNED((uintptr_t)(p), (n))
|
||||
|
||||
/* Round number up to multiple. Requires that d be a power of 2 (see
|
||||
* QEMU_ALIGN_UP for a safer but slower version on arbitrary
|
||||
* numbers) */
|
||||
#ifndef ROUND_UP
|
||||
#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d))
|
||||
#endif
|
||||
|
@ -379,7 +383,7 @@ unsigned long qemu_getauxval(unsigned long type);
|
|||
|
||||
void qemu_set_tty_echo(int fd, bool echo);
|
||||
|
||||
void os_mem_prealloc(int fd, char *area, size_t sz);
|
||||
void os_mem_prealloc(int fd, char *area, size_t sz, Error **errp);
|
||||
|
||||
int qemu_read_password(char *buf, int buf_size);
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ void qht_destroy(struct qht *ht);
|
|||
* Attempting to insert a NULL @p is a bug.
|
||||
* Inserting the same pointer @p with different @hash values is a bug.
|
||||
*
|
||||
* In case of successful operation, smp_wmb() is implied before the pointer is
|
||||
* inserted into the hash table.
|
||||
*
|
||||
* Returns true on sucess.
|
||||
* Returns false if the @p-@hash pair already exists in the hash table.
|
||||
*/
|
||||
|
@ -83,6 +86,8 @@ bool qht_insert(struct qht *ht, void *p, uint32_t hash);
|
|||
*
|
||||
* Needs to be called under an RCU read-critical section.
|
||||
*
|
||||
* smp_read_barrier_depends() is implied before the call to @func.
|
||||
*
|
||||
* The user-provided @func compares pointers in QHT against @userp.
|
||||
* If the function returns true, a match has been found.
|
||||
*
|
||||
|
|
|
@ -33,20 +33,12 @@ int socket_set_fast_reuse(int fd);
|
|||
typedef void NonBlockingConnectHandler(int fd, Error *err, void *opaque);
|
||||
|
||||
InetSocketAddress *inet_parse(const char *str, Error **errp);
|
||||
int inet_listen(const char *str, char *ostr, int olen,
|
||||
int socktype, int port_offset, Error **errp);
|
||||
int inet_connect(const char *str, Error **errp);
|
||||
int inet_nonblocking_connect(const char *str,
|
||||
NonBlockingConnectHandler *callback,
|
||||
void *opaque, Error **errp);
|
||||
|
||||
NetworkAddressFamily inet_netfamily(int family);
|
||||
|
||||
int unix_listen(const char *path, char *ostr, int olen, Error **errp);
|
||||
int unix_connect(const char *path, Error **errp);
|
||||
int unix_nonblocking_connect(const char *str,
|
||||
NonBlockingConnectHandler *callback,
|
||||
void *opaque, Error **errp);
|
||||
|
||||
SocketAddress *socket_parse(const char *str, Error **errp);
|
||||
int socket_connect(SocketAddress *addr, Error **errp,
|
||||
|
|
28
nbd/client.c
28
nbd/client.c
|
@ -408,7 +408,7 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
|
|||
}
|
||||
|
||||
|
||||
int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags,
|
||||
int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
|
||||
QCryptoTLSCreds *tlscreds, const char *hostname,
|
||||
QIOChannel **outioc,
|
||||
off_t *size, Error **errp)
|
||||
|
@ -468,7 +468,6 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags,
|
|||
uint32_t opt;
|
||||
uint32_t namesize;
|
||||
uint16_t globalflags;
|
||||
uint16_t exportflags;
|
||||
bool fixedNewStyle = false;
|
||||
|
||||
if (read_sync(ioc, &globalflags, sizeof(globalflags)) !=
|
||||
|
@ -477,7 +476,6 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags,
|
|||
goto fail;
|
||||
}
|
||||
globalflags = be16_to_cpu(globalflags);
|
||||
*flags = globalflags << 16;
|
||||
TRACE("Global flags are %" PRIx32, globalflags);
|
||||
if (globalflags & NBD_FLAG_FIXED_NEWSTYLE) {
|
||||
fixedNewStyle = true;
|
||||
|
@ -545,17 +543,15 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags,
|
|||
goto fail;
|
||||
}
|
||||
*size = be64_to_cpu(s);
|
||||
TRACE("Size is %" PRIu64, *size);
|
||||
|
||||
if (read_sync(ioc, &exportflags, sizeof(exportflags)) !=
|
||||
sizeof(exportflags)) {
|
||||
if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) {
|
||||
error_setg(errp, "Failed to read export flags");
|
||||
goto fail;
|
||||
}
|
||||
exportflags = be16_to_cpu(exportflags);
|
||||
*flags |= exportflags;
|
||||
TRACE("Export flags are %" PRIx16, exportflags);
|
||||
be16_to_cpus(flags);
|
||||
} else if (magic == NBD_CLIENT_MAGIC) {
|
||||
uint32_t oldflags;
|
||||
|
||||
if (name) {
|
||||
error_setg(errp, "Server does not support export names");
|
||||
goto fail;
|
||||
|
@ -572,16 +568,22 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags,
|
|||
*size = be64_to_cpu(s);
|
||||
TRACE("Size is %" PRIu64, *size);
|
||||
|
||||
if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) {
|
||||
if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) {
|
||||
error_setg(errp, "Failed to read export flags");
|
||||
goto fail;
|
||||
}
|
||||
*flags = be32_to_cpu(*flags);
|
||||
be32_to_cpus(&oldflags);
|
||||
if (oldflags & ~0xffff) {
|
||||
error_setg(errp, "Unexpected export flags %0x" PRIx32, oldflags);
|
||||
goto fail;
|
||||
}
|
||||
*flags = oldflags;
|
||||
} else {
|
||||
error_setg(errp, "Bad magic received");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags);
|
||||
if (read_sync(ioc, &buf, 124) != 124) {
|
||||
error_setg(errp, "Failed to read reserved block");
|
||||
goto fail;
|
||||
|
@ -593,7 +595,7 @@ fail:
|
|||
}
|
||||
|
||||
#ifdef __linux__
|
||||
int nbd_init(int fd, QIOChannelSocket *sioc, uint32_t flags, off_t size)
|
||||
int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size)
|
||||
{
|
||||
unsigned long sectors = size / BDRV_SECTOR_SIZE;
|
||||
if (size / BDRV_SECTOR_SIZE != sectors) {
|
||||
|
@ -689,7 +691,7 @@ int nbd_disconnect(int fd)
|
|||
}
|
||||
|
||||
#else
|
||||
int nbd_init(int fd, QIOChannelSocket *ioc, uint32_t flags, off_t size)
|
||||
int nbd_init(int fd, QIOChannelSocket *ioc, uint16_t flags, off_t size)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
|
13
nbd/server.c
13
nbd/server.c
|
@ -63,7 +63,7 @@ struct NBDExport {
|
|||
char *name;
|
||||
off_t dev_offset;
|
||||
off_t size;
|
||||
uint32_t nbdflags;
|
||||
uint16_t nbdflags;
|
||||
QTAILQ_HEAD(, NBDClient) clients;
|
||||
QTAILQ_ENTRY(NBDExport) next;
|
||||
|
||||
|
@ -544,8 +544,8 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
|
|||
NBDClient *client = data->client;
|
||||
char buf[8 + 8 + 8 + 128];
|
||||
int rc;
|
||||
const int myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
|
||||
NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
|
||||
const uint16_t myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
|
||||
NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
|
||||
bool oldStyle;
|
||||
|
||||
/* Old style negotiation header without options
|
||||
|
@ -575,7 +575,6 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
|
|||
|
||||
oldStyle = client->exp != NULL && !client->tlscreds;
|
||||
if (oldStyle) {
|
||||
assert ((client->exp->nbdflags & ~65535) == 0);
|
||||
TRACE("advertising size %" PRIu64 " and flags %x",
|
||||
client->exp->size, client->exp->nbdflags | myflags);
|
||||
stq_be_p(buf + 8, NBD_CLIENT_MAGIC);
|
||||
|
@ -606,7 +605,6 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
assert ((client->exp->nbdflags & ~65535) == 0);
|
||||
TRACE("advertising size %" PRIu64 " and flags %x",
|
||||
client->exp->size, client->exp->nbdflags | myflags);
|
||||
stq_be_p(buf + 18, client->exp->size);
|
||||
|
@ -810,7 +808,7 @@ static void nbd_eject_notifier(Notifier *n, void *data)
|
|||
}
|
||||
|
||||
NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
|
||||
uint32_t nbdflags, void (*close)(NBDExport *),
|
||||
uint16_t nbdflags, void (*close)(NBDExport *),
|
||||
Error **errp)
|
||||
{
|
||||
NBDExport *exp = g_malloc0(sizeof(NBDExport));
|
||||
|
@ -1057,7 +1055,8 @@ static ssize_t nbd_co_receive_request(NBDRequest *req,
|
|||
if (request->type & ~NBD_CMD_MASK_COMMAND & ~NBD_CMD_FLAG_FUA) {
|
||||
LOG("unsupported flags (got 0x%x)",
|
||||
request->type & ~NBD_CMD_MASK_COMMAND);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
|
1
numa.c
1
numa.c
|
@ -463,6 +463,7 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
|
|||
exit(1);
|
||||
}
|
||||
|
||||
host_memory_backend_set_mapped(backend, true);
|
||||
memory_region_add_subregion(mr, addr, seg);
|
||||
vmstate_register_ram_global(seg);
|
||||
addr += size;
|
||||
|
|
|
@ -251,7 +251,7 @@ static void *nbd_client_thread(void *arg)
|
|||
{
|
||||
char *device = arg;
|
||||
off_t size;
|
||||
uint32_t nbdflags;
|
||||
uint16_t nbdflags;
|
||||
QIOChannelSocket *sioc;
|
||||
int fd;
|
||||
int ret;
|
||||
|
@ -465,7 +465,7 @@ int main(int argc, char **argv)
|
|||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
off_t dev_offset = 0;
|
||||
uint32_t nbdflags = 0;
|
||||
uint16_t nbdflags = 0;
|
||||
bool disconnect = false;
|
||||
const char *bindto = "0.0.0.0";
|
||||
const char *port = NULL;
|
||||
|
|
|
@ -927,10 +927,25 @@ ETEXI
|
|||
|
||||
DEF("display", HAS_ARG, QEMU_OPTION_display,
|
||||
"-display sdl[,frame=on|off][,alt_grab=on|off][,ctrl_grab=on|off]\n"
|
||||
" [,window_close=on|off]|curses|none|\n"
|
||||
" gtk[,grab_on_hover=on|off]|\n"
|
||||
" vnc=<display>[,<optargs>]\n"
|
||||
" select display type\n", QEMU_ARCH_ALL)
|
||||
" [,window_close=on|off][,gl=on|off]|curses|none|\n"
|
||||
"-display gtk[,grab_on_hover=on|off][,gl=on|off]|\n"
|
||||
"-display vnc=<display>[,<optargs>]\n"
|
||||
"-display curses\n"
|
||||
"-display none"
|
||||
" select display type\n"
|
||||
"The default display is equivalent to\n"
|
||||
#if defined(CONFIG_GTK)
|
||||
"\t\"-display gtk\"\n"
|
||||
#elif defined(CONFIG_SDL)
|
||||
"\t\"-display sdl\"\n"
|
||||
#elif defined(CONFIG_COCOA)
|
||||
"\t\"-display cocoa\"\n"
|
||||
#elif defined(CONFIG_VNC)
|
||||
"\t\"-vnc localhost:0,to=99,id=default\"\n"
|
||||
#else
|
||||
"\t\"-display none\"\n"
|
||||
#endif
|
||||
, QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -display @var{type}
|
||||
@findex -display
|
||||
|
@ -977,7 +992,7 @@ the console and monitor.
|
|||
ETEXI
|
||||
|
||||
DEF("curses", 0, QEMU_OPTION_curses,
|
||||
"-curses use a curses/ncurses interface instead of SDL\n",
|
||||
"-curses shorthand for -display curses\n",
|
||||
QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -curses
|
||||
|
@ -1027,7 +1042,7 @@ Disable SDL window close capability.
|
|||
ETEXI
|
||||
|
||||
DEF("sdl", 0, QEMU_OPTION_sdl,
|
||||
"-sdl enable SDL\n", QEMU_ARCH_ALL)
|
||||
"-sdl shorthand for -display sdl\n", QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -sdl
|
||||
@findex -sdl
|
||||
|
@ -1224,7 +1239,7 @@ Set the initial graphical resolution and depth (PPC, SPARC only).
|
|||
ETEXI
|
||||
|
||||
DEF("vnc", HAS_ARG, QEMU_OPTION_vnc ,
|
||||
"-vnc display start a VNC server on display\n", QEMU_ARCH_ALL)
|
||||
"-vnc <display> shorthand for -display vnc=<display>\n", QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -vnc @var{display}[,@var{option}[,@var{option}[,...]]]
|
||||
@findex -vnc
|
||||
|
|
|
@ -2544,7 +2544,7 @@ sub process {
|
|||
}
|
||||
}
|
||||
|
||||
# check for non-portable ffs() calls that have portable alternatives in QEMU
|
||||
# check for non-portable libc calls that have portable alternatives in QEMU
|
||||
if ($line =~ /\bffs\(/) {
|
||||
ERROR("use ctz32() instead of ffs()\n" . $herecurr);
|
||||
}
|
||||
|
@ -2554,6 +2554,9 @@ sub process {
|
|||
if ($line =~ /\bffsll\(/) {
|
||||
ERROR("use ctz64() instead of ffsll()\n" . $herecurr);
|
||||
}
|
||||
if ($line =~ /\bbzero\(/) {
|
||||
ERROR("use memset() instead of bzero()\n" . $herecurr);
|
||||
}
|
||||
}
|
||||
|
||||
# If we have no input at all, then there is nothing to report on
|
||||
|
|
|
@ -7176,7 +7176,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
|||
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_ECX]);
|
||||
gen_helper_xsetbv(cpu_env, cpu_tmp2_i32, cpu_tmp1_i64);
|
||||
/* End TB because translation flags may change. */
|
||||
gen_jmp_im(s->pc - pc_start);
|
||||
gen_jmp_im(s->pc - s->cs_base);
|
||||
gen_eob(s);
|
||||
break;
|
||||
|
||||
|
|
|
@ -360,10 +360,16 @@ static void test_none(void)
|
|||
g_assert(isnan(qdist_xmax(&dist)));
|
||||
|
||||
pr = qdist_pr_plain(&dist, 0);
|
||||
g_assert(pr == NULL);
|
||||
g_assert_cmpstr(pr, ==, "(empty)");
|
||||
g_free(pr);
|
||||
|
||||
pr = qdist_pr_plain(&dist, 2);
|
||||
g_assert(pr == NULL);
|
||||
g_assert_cmpstr(pr, ==, "(empty)");
|
||||
g_free(pr);
|
||||
|
||||
pr = qdist_pr(&dist, 0, QDIST_PR_BORDER);
|
||||
g_assert_cmpstr(pr, ==, "(empty)");
|
||||
g_free(pr);
|
||||
|
||||
qdist_destroy(&dist);
|
||||
}
|
||||
|
|
|
@ -95,8 +95,12 @@ static void iter_check(unsigned int count)
|
|||
|
||||
static void qht_do_test(unsigned int mode, size_t init_entries)
|
||||
{
|
||||
/* under KVM we might fetch stats from an uninitialized qht */
|
||||
check_n(0);
|
||||
|
||||
qht_init(&ht, 0, mode);
|
||||
|
||||
check_n(0);
|
||||
insert(0, N);
|
||||
check(0, N, true);
|
||||
check_n(N);
|
||||
|
|
|
@ -1663,15 +1663,50 @@ void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr)
|
|||
TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
|
||||
}
|
||||
|
||||
static void print_qht_statistics(FILE *f, fprintf_function cpu_fprintf,
|
||||
struct qht_stats hst)
|
||||
{
|
||||
uint32_t hgram_opts;
|
||||
size_t hgram_bins;
|
||||
char *hgram;
|
||||
|
||||
if (!hst.head_buckets) {
|
||||
return;
|
||||
}
|
||||
cpu_fprintf(f, "TB hash buckets %zu/%zu (%0.2f%% head buckets used)\n",
|
||||
hst.used_head_buckets, hst.head_buckets,
|
||||
(double)hst.used_head_buckets / hst.head_buckets * 100);
|
||||
|
||||
hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS;
|
||||
hgram_opts |= QDIST_PR_100X | QDIST_PR_PERCENT;
|
||||
if (qdist_xmax(&hst.occupancy) - qdist_xmin(&hst.occupancy) == 1) {
|
||||
hgram_opts |= QDIST_PR_NODECIMAL;
|
||||
}
|
||||
hgram = qdist_pr(&hst.occupancy, 10, hgram_opts);
|
||||
cpu_fprintf(f, "TB hash occupancy %0.2f%% avg chain occ. Histogram: %s\n",
|
||||
qdist_avg(&hst.occupancy) * 100, hgram);
|
||||
g_free(hgram);
|
||||
|
||||
hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS;
|
||||
hgram_bins = qdist_xmax(&hst.chain) - qdist_xmin(&hst.chain);
|
||||
if (hgram_bins > 10) {
|
||||
hgram_bins = 10;
|
||||
} else {
|
||||
hgram_bins = 0;
|
||||
hgram_opts |= QDIST_PR_NODECIMAL | QDIST_PR_NOBINRANGE;
|
||||
}
|
||||
hgram = qdist_pr(&hst.chain, hgram_bins, hgram_opts);
|
||||
cpu_fprintf(f, "TB hash avg chain %0.3f buckets. Histogram: %s\n",
|
||||
qdist_avg(&hst.chain), hgram);
|
||||
g_free(hgram);
|
||||
}
|
||||
|
||||
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
|
||||
{
|
||||
int i, target_code_size, max_target_code_size;
|
||||
int direct_jmp_count, direct_jmp2_count, cross_page;
|
||||
TranslationBlock *tb;
|
||||
struct qht_stats hst;
|
||||
uint32_t hgram_opts;
|
||||
size_t hgram_bins;
|
||||
char *hgram;
|
||||
|
||||
target_code_size = 0;
|
||||
max_target_code_size = 0;
|
||||
|
@ -1724,34 +1759,7 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
|
|||
tcg_ctx.tb_ctx.nb_tbs : 0);
|
||||
|
||||
qht_statistics_init(&tcg_ctx.tb_ctx.htable, &hst);
|
||||
|
||||
cpu_fprintf(f, "TB hash buckets %zu/%zu (%0.2f%% head buckets used)\n",
|
||||
hst.used_head_buckets, hst.head_buckets,
|
||||
(double)hst.used_head_buckets / hst.head_buckets * 100);
|
||||
|
||||
hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS;
|
||||
hgram_opts |= QDIST_PR_100X | QDIST_PR_PERCENT;
|
||||
if (qdist_xmax(&hst.occupancy) - qdist_xmin(&hst.occupancy) == 1) {
|
||||
hgram_opts |= QDIST_PR_NODECIMAL;
|
||||
}
|
||||
hgram = qdist_pr(&hst.occupancy, 10, hgram_opts);
|
||||
cpu_fprintf(f, "TB hash occupancy %0.2f%% avg chain occ. Histogram: %s\n",
|
||||
qdist_avg(&hst.occupancy) * 100, hgram);
|
||||
g_free(hgram);
|
||||
|
||||
hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS;
|
||||
hgram_bins = qdist_xmax(&hst.chain) - qdist_xmin(&hst.chain);
|
||||
if (hgram_bins > 10) {
|
||||
hgram_bins = 10;
|
||||
} else {
|
||||
hgram_bins = 0;
|
||||
hgram_opts |= QDIST_PR_NODECIMAL | QDIST_PR_NOBINRANGE;
|
||||
}
|
||||
hgram = qdist_pr(&hst.chain, hgram_bins, hgram_opts);
|
||||
cpu_fprintf(f, "TB hash avg chain %0.3f buckets. Histogram: %s\n",
|
||||
qdist_avg(&hst.chain), hgram);
|
||||
g_free(hgram);
|
||||
|
||||
print_qht_statistics(f, cpu_fprintf, hst);
|
||||
qht_statistics_destroy(&hst);
|
||||
|
||||
cpu_fprintf(f, "\nStatistics:\n");
|
||||
|
|
|
@ -247,7 +247,8 @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
|
|||
{
|
||||
size_t len;
|
||||
unsigned int i, j;
|
||||
for (i = 0, j = 0; i < iov_cnt && j < dst_iov_cnt && bytes; i++) {
|
||||
for (i = 0, j = 0;
|
||||
i < iov_cnt && j < dst_iov_cnt && (offset || bytes); i++) {
|
||||
if (offset >= iov[i].iov_len) {
|
||||
offset -= iov[i].iov_len;
|
||||
continue;
|
||||
|
|
|
@ -318,7 +318,7 @@ static void sigbus_handler(int signal)
|
|||
siglongjmp(sigjump, 1);
|
||||
}
|
||||
|
||||
void os_mem_prealloc(int fd, char *area, size_t memory)
|
||||
void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
struct sigaction act, oldact;
|
||||
|
@ -330,8 +330,9 @@ void os_mem_prealloc(int fd, char *area, size_t memory)
|
|||
|
||||
ret = sigaction(SIGBUS, &act, &oldact);
|
||||
if (ret) {
|
||||
perror("os_mem_prealloc: failed to install signal handler");
|
||||
exit(1);
|
||||
error_setg_errno(errp, errno,
|
||||
"os_mem_prealloc: failed to install signal handler");
|
||||
return;
|
||||
}
|
||||
|
||||
/* unblock SIGBUS */
|
||||
|
@ -340,9 +341,8 @@ void os_mem_prealloc(int fd, char *area, size_t memory)
|
|||
pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
|
||||
|
||||
if (sigsetjmp(sigjump, 1)) {
|
||||
fprintf(stderr, "os_mem_prealloc: Insufficient free host memory "
|
||||
"pages available to allocate guest RAM\n");
|
||||
exit(1);
|
||||
error_setg(errp, "os_mem_prealloc: Insufficient free host memory "
|
||||
"pages available to allocate guest RAM\n");
|
||||
} else {
|
||||
int i;
|
||||
size_t hpagesize = qemu_fd_getpagesize(fd);
|
||||
|
@ -352,15 +352,15 @@ void os_mem_prealloc(int fd, char *area, size_t memory)
|
|||
for (i = 0; i < numpages; i++) {
|
||||
memset(area + (hpagesize * i), 0, 1);
|
||||
}
|
||||
|
||||
ret = sigaction(SIGBUS, &oldact, NULL);
|
||||
if (ret) {
|
||||
perror("os_mem_prealloc: failed to reinstall signal handler");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||
}
|
||||
|
||||
ret = sigaction(SIGBUS, &oldact, NULL);
|
||||
if (ret) {
|
||||
/* Terminate QEMU since it can't recover from error */
|
||||
perror("os_mem_prealloc: failed to reinstall signal handler");
|
||||
exit(1);
|
||||
}
|
||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -539,7 +539,7 @@ int getpagesize(void)
|
|||
return system_info.dwPageSize;
|
||||
}
|
||||
|
||||
void os_mem_prealloc(int fd, char *area, size_t memory)
|
||||
void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)
|
||||
{
|
||||
int i;
|
||||
size_t pagesize = getpagesize();
|
||||
|
|
13
util/qdist.c
13
util/qdist.c
|
@ -14,9 +14,11 @@
|
|||
#define NAN (0.0 / 0.0)
|
||||
#endif
|
||||
|
||||
#define QDIST_EMPTY_STR "(empty)"
|
||||
|
||||
void qdist_init(struct qdist *dist)
|
||||
{
|
||||
dist->entries = g_malloc(sizeof(*dist->entries));
|
||||
dist->entries = g_new(struct qdist_entry, 1);
|
||||
dist->size = 1;
|
||||
dist->n = 0;
|
||||
}
|
||||
|
@ -62,8 +64,7 @@ void qdist_add(struct qdist *dist, double x, long count)
|
|||
|
||||
if (unlikely(dist->n == dist->size)) {
|
||||
dist->size *= 2;
|
||||
dist->entries = g_realloc(dist->entries,
|
||||
sizeof(*dist->entries) * (dist->size));
|
||||
dist->entries = g_renew(struct qdist_entry, dist->entries, dist->size);
|
||||
}
|
||||
dist->n++;
|
||||
entry = &dist->entries[dist->n - 1];
|
||||
|
@ -188,7 +189,7 @@ void qdist_bin__internal(struct qdist *to, const struct qdist *from, size_t n)
|
|||
}
|
||||
}
|
||||
/* they're equally spaced, so copy the dist and bail out */
|
||||
to->entries = g_new(struct qdist_entry, from->n);
|
||||
to->entries = g_renew(struct qdist_entry, to->entries, n);
|
||||
to->n = from->n;
|
||||
memcpy(to->entries, from->entries, sizeof(*to->entries) * to->n);
|
||||
return;
|
||||
|
@ -234,7 +235,7 @@ char *qdist_pr_plain(const struct qdist *dist, size_t n)
|
|||
char *ret;
|
||||
|
||||
if (dist->n == 0) {
|
||||
return NULL;
|
||||
return g_strdup(QDIST_EMPTY_STR);
|
||||
}
|
||||
qdist_bin__internal(&binned, dist, n);
|
||||
ret = qdist_pr_internal(&binned);
|
||||
|
@ -309,7 +310,7 @@ char *qdist_pr(const struct qdist *dist, size_t n_bins, uint32_t opt)
|
|||
GString *s;
|
||||
|
||||
if (dist->n == 0) {
|
||||
return NULL;
|
||||
return g_strdup(QDIST_EMPTY_STR);
|
||||
}
|
||||
|
||||
s = g_string_new("");
|
||||
|
|
|
@ -624,34 +624,6 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int inet_listen(const char *str, char *ostr, int olen,
|
||||
int socktype, int port_offset, Error **errp)
|
||||
{
|
||||
char *optstr;
|
||||
int sock = -1;
|
||||
InetSocketAddress *addr;
|
||||
|
||||
addr = inet_parse(str, errp);
|
||||
if (addr != NULL) {
|
||||
sock = inet_listen_saddr(addr, port_offset, true, errp);
|
||||
if (sock != -1 && ostr) {
|
||||
optstr = strchr(str, ',');
|
||||
if (addr->ipv6) {
|
||||
snprintf(ostr, olen, "[%s]:%s%s",
|
||||
addr->host,
|
||||
addr->port,
|
||||
optstr ? optstr : "");
|
||||
} else {
|
||||
snprintf(ostr, olen, "%s:%s%s",
|
||||
addr->host,
|
||||
addr->port,
|
||||
optstr ? optstr : "");
|
||||
}
|
||||
}
|
||||
qapi_free_InetSocketAddress(addr);
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a blocking socket and connect it to an address.
|
||||
|
@ -674,36 +646,6 @@ int inet_connect(const char *str, Error **errp)
|
|||
return sock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a non-blocking socket and connect it to an address.
|
||||
* Calls the callback function with fd in case of success or -1 in case of
|
||||
* error.
|
||||
*
|
||||
* @str: address string
|
||||
* @callback: callback function that is called when connect completes,
|
||||
* cannot be NULL.
|
||||
* @opaque: opaque for callback function
|
||||
* @errp: set in case of an error
|
||||
*
|
||||
* Returns: -1 on immediate error, file descriptor on success.
|
||||
**/
|
||||
int inet_nonblocking_connect(const char *str,
|
||||
NonBlockingConnectHandler *callback,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
int sock = -1;
|
||||
InetSocketAddress *addr;
|
||||
|
||||
g_assert(callback != NULL);
|
||||
|
||||
addr = inet_parse(str, errp);
|
||||
if (addr != NULL) {
|
||||
sock = inet_connect_saddr(addr, errp, callback, opaque);
|
||||
qapi_free_InetSocketAddress(addr);
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
static int unix_listen_saddr(UnixSocketAddress *saddr,
|
||||
|
@ -893,22 +835,6 @@ int unix_connect(const char *path, Error **errp)
|
|||
}
|
||||
|
||||
|
||||
int unix_nonblocking_connect(const char *path,
|
||||
NonBlockingConnectHandler *callback,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
UnixSocketAddress *saddr;
|
||||
int sock = -1;
|
||||
|
||||
g_assert(callback != NULL);
|
||||
|
||||
saddr = g_new0(UnixSocketAddress, 1);
|
||||
saddr->path = g_strdup(path);
|
||||
sock = unix_connect_saddr(saddr, errp, callback, opaque);
|
||||
qapi_free_UnixSocketAddress(saddr);
|
||||
return sock;
|
||||
}
|
||||
|
||||
SocketAddress *socket_parse(const char *str, Error **errp)
|
||||
{
|
||||
SocketAddress *addr;
|
||||
|
|
14
util/qht.c
14
util/qht.c
|
@ -445,7 +445,11 @@ void *qht_do_lookup(struct qht_bucket *head, qht_lookup_func_t func,
|
|||
do {
|
||||
for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
|
||||
if (b->hashes[i] == hash) {
|
||||
void *p = atomic_read(&b->pointers[i]);
|
||||
/* The pointer is dereferenced before seqlock_read_retry,
|
||||
* so (unlike qht_insert__locked) we need to use
|
||||
* atomic_rcu_read here.
|
||||
*/
|
||||
void *p = atomic_rcu_read(&b->pointers[i]);
|
||||
|
||||
if (likely(p) && likely(func(p, userp))) {
|
||||
return p;
|
||||
|
@ -535,6 +539,7 @@ static bool qht_insert__locked(struct qht *ht, struct qht_map *map,
|
|||
atomic_rcu_set(&prev->next, b);
|
||||
}
|
||||
b->hashes[i] = hash;
|
||||
/* smp_wmb() implicit in seqlock_write_begin. */
|
||||
atomic_set(&b->pointers[i], p);
|
||||
seqlock_write_end(&head->sequence);
|
||||
return true;
|
||||
|
@ -784,11 +789,16 @@ void qht_statistics_init(struct qht *ht, struct qht_stats *stats)
|
|||
|
||||
map = atomic_rcu_read(&ht->map);
|
||||
|
||||
stats->head_buckets = map->n_buckets;
|
||||
stats->used_head_buckets = 0;
|
||||
stats->entries = 0;
|
||||
qdist_init(&stats->chain);
|
||||
qdist_init(&stats->occupancy);
|
||||
/* bail out if the qht has not yet been initialized */
|
||||
if (unlikely(map == NULL)) {
|
||||
stats->head_buckets = 0;
|
||||
return;
|
||||
}
|
||||
stats->head_buckets = map->n_buckets;
|
||||
|
||||
for (i = 0; i < map->n_buckets; i++) {
|
||||
struct qht_bucket *head = &map->buckets[i];
|
||||
|
|
Loading…
Reference in New Issue