* char: rename CharBackend->CharFrontend

* esp: fix esp_cdb_ready() FIFO wraparound limit calculation
 * isapc: warn rather than reject modern x86 CPU models
 * mshv: fix Coverity issues
 * qdev: Change PropertyInfo method print() to return malloc'ed string
 * qobject: make refcount atomic
 * rcu: make synchronize_rcu() more efficient
 * rust: cleanup glib_sys bindings
 * rust: Convert bit value to u8 within #[property]
 * rust: only leave leaf crates as workspace members
 * scripts: clean up meson-buildoptions.py
 * scsi: make refcount atomic
 * target/i386: Init SMM cpu address space for hotplugged CPUs
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmkB3UUUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroMrRAgAidqHD3mBOEPhcz3Xh5xuJGd+fFnr
 wD5/zi5DPy2ZmPKY/buMv/92R6GKKQwZVJrKKdj2+yXFayp0LZNs+ZXNhOl8+EWT
 uZayJJt1Wx5E8BB31NKDBLSnvIjVnP+0QDN3pn7ihoIYtdy7ziUd2sS955z+42Vx
 ewLwZMfIodSykYfeUsjA7A4GgXtHZWv1bGOZ4qVX/Bgr06efKui3WUaVAkN6i6T+
 WJBn4Wb3fBiHLhmFzdIxB91hZjyP9athOQb5kiTL1g+2uYsuQPSfWRhqfgy3EWGf
 K72bpnxnMSzhjz0YXKz5S5kjpe/3g7OCiPJm0Jf5Aq7KqGyIkUSSdgo59Q==
 =KCqH
 -----END PGP SIGNATURE-----

Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging

* char: rename CharBackend->CharFrontend
* esp: fix esp_cdb_ready() FIFO wraparound limit calculation
* isapc: warn rather than reject modern x86 CPU models
* mshv: fix Coverity issues
* qdev: Change PropertyInfo method print() to return malloc'ed string
* qobject: make refcount atomic
* rcu: make synchronize_rcu() more efficient
* rust: cleanup glib_sys bindings
* rust: Convert bit value to u8 within #[property]
* rust: only leave leaf crates as workspace members
* scripts: clean up meson-buildoptions.py
* scsi: make refcount atomic
* target/i386: Init SMM cpu address space for hotplugged CPUs

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmkB3UUUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroMrRAgAidqHD3mBOEPhcz3Xh5xuJGd+fFnr
# wD5/zi5DPy2ZmPKY/buMv/92R6GKKQwZVJrKKdj2+yXFayp0LZNs+ZXNhOl8+EWT
# uZayJJt1Wx5E8BB31NKDBLSnvIjVnP+0QDN3pn7ihoIYtdy7ziUd2sS955z+42Vx
# ewLwZMfIodSykYfeUsjA7A4GgXtHZWv1bGOZ4qVX/Bgr06efKui3WUaVAkN6i6T+
# WJBn4Wb3fBiHLhmFzdIxB91hZjyP9athOQb5kiTL1g+2uYsuQPSfWRhqfgy3EWGf
# K72bpnxnMSzhjz0YXKz5S5kjpe/3g7OCiPJm0Jf5Aq7KqGyIkUSSdgo59Q==
# =KCqH
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 29 Oct 2025 10:24:21 AM CET
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [unknown]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# 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

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
  rust: migration: allow passing ParentField<> to vmstate_of!
  target/i386: clear CPU_INTERRUPT_SIPI for all accelerators
  docs/about/deprecated.rst: document isapc deprecation for modern x86 CPU models
  hw/i386/isapc.c: warn rather than reject modern x86 CPU models
  qdev: Change PropertyInfo method print() to return malloc'ed string
  scsi: make SCSIRequest refcount atomic
  rust/qemu-macros: Convert bit value to u8 within #[property]
  qtest/am53c974-test: add additional test for cmdfifo overflow
  esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation
  accel/mshv: use return value of handle_pio_str_read
  accel/mshv: initialize thread name
  char: rename CharBackend->CharFrontend
  qobject: make refcount atomic
  rust: only leave leaf crates as workspace members
  rust: remove useless glib_sys bindings
  rcu: Unify force quiescent state
  i386/kvm/cpu: Init SMM cpu address space for hotplugged CPUs
  scripts: clean up meson-buildoptions.py

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-10-29 10:43:56 +01:00
commit 5d7a40b5b2
121 changed files with 678 additions and 572 deletions

View file

@ -596,6 +596,9 @@ static void mshv_start_vcpu_thread(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/MSHV",
cpu->cpu_index);
cpu->thread = g_malloc0(sizeof(QemuThread));
cpu->halt_cond = g_malloc0(sizeof(QemuCond));

View file

@ -46,7 +46,7 @@ struct CryptoDevBackendVhostUser {
CryptoDevBackend parent_obj;
VhostUserState vhost_user;
CharBackend chr;
CharFrontend chr;
char *chr_name;
bool opened;
CryptoDevBackendVhost *vhost_crypto[MAX_CRYPTO_QUEUE_NUM];

View file

@ -24,7 +24,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(RngEgd, RNG_EGD)
struct RngEgd {
RngBackend parent;
CharBackend chr;
CharFrontend chr;
char *chr_name;
};

View file

@ -69,7 +69,7 @@ struct TPMEmulator {
TPMBackend parent;
TPMEmulatorOptions *options;
CharBackend ctrl_chr;
CharFrontend ctrl_chr;
QIOChannel *data_ioc;
TPMVersion tpm_version;
uint32_t caps; /* capabilities of the TPM */
@ -126,7 +126,7 @@ static int tpm_emulator_ctrlcmd(TPMEmulator *tpm, unsigned long cmd, void *msg,
size_t msg_len_in, size_t msg_len_out_err,
size_t msg_len_out_total)
{
CharBackend *dev = &tpm->ctrl_chr;
CharFrontend *dev = &tpm->ctrl_chr;
uint32_t cmd_no = cpu_to_be32(cmd);
ssize_t n = sizeof(uint32_t) + msg_len_in;
ptm_res res;

View file

@ -30,9 +30,9 @@
#include "chardev/char-io.h"
#include "chardev-internal.h"
int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len)
int qemu_chr_fe_write(CharFrontend *c, const uint8_t *buf, int len)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return 0;
@ -41,9 +41,9 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len)
return qemu_chr_write(s, buf, len, false);
}
int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
int qemu_chr_fe_write_all(CharFrontend *c, const uint8_t *buf, int len)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return 0;
@ -52,9 +52,9 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
return qemu_chr_write(s, buf, len, true);
}
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
int qemu_chr_fe_read_all(CharFrontend *c, uint8_t *buf, int len)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
int offset = 0;
int res;
@ -95,9 +95,9 @@ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
return offset;
}
int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg)
int qemu_chr_fe_ioctl(CharFrontend *c, int cmd, void *arg)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
int res;
if (!s || !CHARDEV_GET_CLASS(s)->chr_ioctl || qemu_chr_replay(s)) {
@ -109,11 +109,11 @@ int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg)
return res;
}
int qemu_chr_fe_get_msgfd(CharBackend *be)
int qemu_chr_fe_get_msgfd(CharFrontend *c)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
int fd;
int res = (qemu_chr_fe_get_msgfds(be, &fd, 1) == 1) ? fd : -1;
int res = (qemu_chr_fe_get_msgfds(c, &fd, 1) == 1) ? fd : -1;
if (s && qemu_chr_replay(s)) {
error_report("Replay: get msgfd is not supported "
"for serial devices yet");
@ -122,9 +122,9 @@ int qemu_chr_fe_get_msgfd(CharBackend *be)
return res;
}
int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len)
int qemu_chr_fe_get_msgfds(CharFrontend *c, int *fds, int len)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return -1;
@ -134,9 +134,9 @@ int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int len)
CHARDEV_GET_CLASS(s)->get_msgfds(s, fds, len) : -1;
}
int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num)
int qemu_chr_fe_set_msgfds(CharFrontend *c, int *fds, int num)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return -1;
@ -146,9 +146,9 @@ int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num)
CHARDEV_GET_CLASS(s)->set_msgfds(s, fds, num) : -1;
}
void qemu_chr_fe_accept_input(CharBackend *be)
void qemu_chr_fe_accept_input(CharFrontend *c)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
if (!s) {
return;
@ -160,7 +160,7 @@ void qemu_chr_fe_accept_input(CharBackend *be)
qemu_notify_event();
}
void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
void qemu_chr_fe_printf(CharFrontend *c, const char *fmt, ...)
{
char buf[CHR_READ_BUF_LEN];
va_list ap;
@ -168,28 +168,28 @@ void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
vsnprintf(buf, sizeof(buf), fmt, ap);
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
qemu_chr_fe_write_all(be, (uint8_t *)buf, strlen(buf));
qemu_chr_fe_write_all(c, (uint8_t *)buf, strlen(buf));
va_end(ap);
}
Chardev *qemu_chr_fe_get_driver(CharBackend *be)
Chardev *qemu_chr_fe_get_driver(CharFrontend *c)
{
/* this is unsafe for the users that support chardev hotswap */
assert(be->chr_be_change == NULL);
return be->chr;
assert(c->chr_be_change == NULL);
return c->chr;
}
bool qemu_chr_fe_backend_connected(CharBackend *be)
bool qemu_chr_fe_backend_connected(CharFrontend *c)
{
return !!be->chr;
return !!c->chr;
}
bool qemu_chr_fe_backend_open(CharBackend *be)
bool qemu_chr_fe_backend_open(CharFrontend *c)
{
return be->chr && be->chr->be_open;
return c->chr && c->chr->be_open;
}
bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
bool qemu_chr_fe_init(CharFrontend *c, Chardev *s, Error **errp)
{
unsigned int tag = 0;
@ -197,49 +197,49 @@ bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp)
if (CHARDEV_IS_MUX(s)) {
MuxChardev *d = MUX_CHARDEV(s);
if (!mux_chr_attach_frontend(d, b, &tag, errp)) {
if (!mux_chr_attach_frontend(d, c, &tag, errp)) {
return false;
}
} else if (s->be) {
} else if (s->fe) {
error_setg(errp, "chardev '%s' is already in use", s->label);
return false;
} else {
s->be = b;
s->fe = c;
}
}
b->fe_is_open = false;
b->tag = tag;
b->chr = s;
c->fe_is_open = false;
c->tag = tag;
c->chr = s;
return true;
}
void qemu_chr_fe_deinit(CharBackend *b, bool del)
void qemu_chr_fe_deinit(CharFrontend *c, bool del)
{
assert(b);
assert(c);
if (b->chr) {
qemu_chr_fe_set_handlers(b, NULL, NULL, NULL, NULL, NULL, NULL, true);
if (b->chr->be == b) {
b->chr->be = NULL;
if (c->chr) {
qemu_chr_fe_set_handlers(c, NULL, NULL, NULL, NULL, NULL, NULL, true);
if (c->chr->fe == c) {
c->chr->fe = NULL;
}
if (CHARDEV_IS_MUX(b->chr)) {
MuxChardev *d = MUX_CHARDEV(b->chr);
mux_chr_detach_frontend(d, b->tag);
if (CHARDEV_IS_MUX(c->chr)) {
MuxChardev *d = MUX_CHARDEV(c->chr);
mux_chr_detach_frontend(d, c->tag);
}
if (del) {
Object *obj = OBJECT(b->chr);
Object *obj = OBJECT(c->chr);
if (obj->parent) {
object_unparent(obj);
} else {
object_unref(obj);
}
}
b->chr = NULL;
c->chr = NULL;
}
}
void qemu_chr_fe_set_handlers_full(CharBackend *b,
void qemu_chr_fe_set_handlers_full(CharFrontend *c,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
@ -252,7 +252,7 @@ void qemu_chr_fe_set_handlers_full(CharBackend *b,
Chardev *s;
bool fe_open;
s = b->chr;
s = c->chr;
if (!s) {
return;
}
@ -263,20 +263,20 @@ void qemu_chr_fe_set_handlers_full(CharBackend *b,
} else {
fe_open = true;
}
b->chr_can_read = fd_can_read;
b->chr_read = fd_read;
b->chr_event = fd_event;
b->chr_be_change = be_change;
b->opaque = opaque;
c->chr_can_read = fd_can_read;
c->chr_read = fd_read;
c->chr_event = fd_event;
c->chr_be_change = be_change;
c->opaque = opaque;
qemu_chr_be_update_read_handlers(s, context);
if (set_open) {
qemu_chr_fe_set_open(b, fe_open);
qemu_chr_fe_set_open(c, fe_open);
}
if (fe_open) {
qemu_chr_fe_take_focus(b);
qemu_chr_fe_take_focus(c);
/* We're connecting to an already opened device, so let's make sure we
also get the open event */
if (sync_state && s->be_open) {
@ -285,7 +285,7 @@ void qemu_chr_fe_set_handlers_full(CharBackend *b,
}
}
void qemu_chr_fe_set_handlers(CharBackend *b,
void qemu_chr_fe_set_handlers(CharFrontend *c,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
@ -294,62 +294,62 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
GMainContext *context,
bool set_open)
{
qemu_chr_fe_set_handlers_full(b, fd_can_read, fd_read, fd_event, be_change,
qemu_chr_fe_set_handlers_full(c, fd_can_read, fd_read, fd_event, be_change,
opaque, context, set_open,
true);
}
void qemu_chr_fe_take_focus(CharBackend *b)
void qemu_chr_fe_take_focus(CharFrontend *c)
{
if (!b->chr) {
if (!c->chr) {
return;
}
if (CHARDEV_IS_MUX(b->chr)) {
mux_set_focus(b->chr, b->tag);
if (CHARDEV_IS_MUX(c->chr)) {
mux_set_focus(c->chr, c->tag);
}
}
int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp)
int qemu_chr_fe_wait_connected(CharFrontend *c, Error **errp)
{
if (!be->chr) {
if (!c->chr) {
error_setg(errp, "missing associated backend");
return -1;
}
return qemu_chr_wait_connected(be->chr, errp);
return qemu_chr_wait_connected(c->chr, errp);
}
void qemu_chr_fe_set_echo(CharBackend *be, bool echo)
void qemu_chr_fe_set_echo(CharFrontend *c, bool echo)
{
Chardev *chr = be->chr;
Chardev *chr = c->chr;
if (chr && CHARDEV_GET_CLASS(chr)->chr_set_echo) {
CHARDEV_GET_CLASS(chr)->chr_set_echo(chr, echo);
}
}
void qemu_chr_fe_set_open(CharBackend *be, bool is_open)
void qemu_chr_fe_set_open(CharFrontend *c, bool is_open)
{
Chardev *chr = be->chr;
Chardev *chr = c->chr;
if (!chr) {
return;
}
if (be->fe_is_open == is_open) {
if (c->fe_is_open == is_open) {
return;
}
be->fe_is_open = is_open;
c->fe_is_open = is_open;
if (CHARDEV_GET_CLASS(chr)->chr_set_fe_open) {
CHARDEV_GET_CLASS(chr)->chr_set_fe_open(chr, is_open);
}
}
guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
guint qemu_chr_fe_add_watch(CharFrontend *c, GIOCondition cond,
FEWatchFunc func, void *user_data)
{
Chardev *s = be->chr;
Chardev *s = c->chr;
GSource *src;
guint tag;
@ -369,9 +369,9 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
return tag;
}
void qemu_chr_fe_disconnect(CharBackend *be)
void qemu_chr_fe_disconnect(CharFrontend *c)
{
Chardev *chr = be->chr;
Chardev *chr = c->chr;
if (chr && CHARDEV_GET_CLASS(chr)->chr_disconnect) {
CHARDEV_GET_CLASS(chr)->chr_disconnect(chr);

View file

@ -54,7 +54,7 @@ static int hub_chr_write(Chardev *chr, const uint8_t *buf, int len)
d->be_eagain_ind = -1;
for (i = 0; i < d->be_cnt; i++) {
if (!d->backends[i].be.chr->be_open) {
if (!d->backends[i].fe.chr->be_open) {
/* Skip closed backend */
continue;
}
@ -64,7 +64,7 @@ static int hub_chr_write(Chardev *chr, const uint8_t *buf, int len)
ret = MIN(written, ret);
continue;
}
r = qemu_chr_fe_write(&d->backends[i].be, buf, len);
r = qemu_chr_fe_write(&d->backends[i].fe, buf, len);
if (r < 0) {
if (errno == EAGAIN) {
/* Set index and expect to be called soon on watch wake up */
@ -84,7 +84,7 @@ static int hub_chr_write(Chardev *chr, const uint8_t *buf, int len)
static int hub_chr_can_read(void *opaque)
{
HubCharBackend *backend = opaque;
CharBackend *fe = backend->hub->parent.be;
CharFrontend *fe = backend->hub->parent.fe;
if (fe && fe->chr_can_read) {
return fe->chr_can_read(fe->opaque);
@ -96,7 +96,7 @@ static int hub_chr_can_read(void *opaque)
static void hub_chr_read(void *opaque, const uint8_t *buf, int size)
{
HubCharBackend *backend = opaque;
CharBackend *fe = backend->hub->parent.be;
CharFrontend *fe = backend->hub->parent.fe;
if (fe && fe->chr_read) {
fe->chr_read(fe->opaque, buf, size);
@ -107,7 +107,7 @@ static void hub_chr_event(void *opaque, QEMUChrEvent event)
{
HubCharBackend *backend = opaque;
HubChardev *d = backend->hub;
CharBackend *fe = d->parent.be;
CharFrontend *fe = d->parent.fe;
if (event == CHR_EVENT_OPENED) {
/*
@ -147,7 +147,7 @@ static GSource *hub_chr_add_watch(Chardev *s, GIOCondition cond)
}
assert(d->be_eagain_ind < d->be_cnt);
chr = qemu_chr_fe_get_driver(&d->backends[d->be_eagain_ind].be);
chr = qemu_chr_fe_get_driver(&d->backends[d->be_eagain_ind].fe);
cc = CHARDEV_GET_CLASS(chr);
if (!cc->chr_add_watch) {
return NULL;
@ -167,7 +167,7 @@ static bool hub_chr_attach_chardev(HubChardev *d, Chardev *chr,
d->parent.label);
return false;
}
ret = qemu_chr_fe_init(&d->backends[d->be_cnt].be, chr, errp);
ret = qemu_chr_fe_init(&d->backends[d->be_cnt].fe, chr, errp);
if (ret) {
d->backends[d->be_cnt].hub = d;
d->backends[d->be_cnt].be_ind = d->be_cnt;
@ -183,7 +183,7 @@ static void char_hub_finalize(Object *obj)
int i;
for (i = 0; i < d->be_cnt; i++) {
qemu_chr_fe_deinit(&d->backends[i].be, false);
qemu_chr_fe_deinit(&d->backends[i].fe, false);
}
}
@ -193,7 +193,7 @@ static void hub_chr_update_read_handlers(Chardev *chr)
int i;
for (i = 0; i < d->be_cnt; i++) {
qemu_chr_fe_set_handlers_full(&d->backends[i].be,
qemu_chr_fe_set_handlers_full(&d->backends[i].fe,
hub_chr_can_read,
hub_chr_read,
hub_chr_event,

View file

@ -128,10 +128,10 @@ static void mux_print_help(Chardev *chr)
static void mux_chr_send_event(MuxChardev *d, unsigned int mux_nr,
QEMUChrEvent event)
{
CharBackend *be = d->backends[mux_nr];
CharFrontend *fe = d->frontends[mux_nr];
if (be && be->chr_event) {
be->chr_event(be->opaque, event);
if (fe && fe->chr_event) {
fe->chr_event(fe->opaque, event);
}
}
@ -200,11 +200,11 @@ static void mux_chr_accept_input(Chardev *chr)
{
MuxChardev *d = MUX_CHARDEV(chr);
int m = d->focus;
CharBackend *be = d->backends[m];
CharFrontend *fe = d->frontends[m];
while (be && d->prod[m] != d->cons[m] &&
be->chr_can_read && be->chr_can_read(be->opaque)) {
be->chr_read(be->opaque,
while (fe && d->prod[m] != d->cons[m] &&
fe->chr_can_read && fe->chr_can_read(fe->opaque)) {
fe->chr_read(fe->opaque,
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
}
}
@ -213,14 +213,14 @@ static int mux_chr_can_read(void *opaque)
{
MuxChardev *d = MUX_CHARDEV(opaque);
int m = d->focus;
CharBackend *be = d->backends[m];
CharFrontend *fe = d->frontends[m];
if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) {
return 1;
}
if (be && be->chr_can_read) {
return be->chr_can_read(be->opaque);
if (fe && fe->chr_can_read) {
return fe->chr_can_read(fe->opaque);
}
return 0;
@ -231,7 +231,7 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
Chardev *chr = CHARDEV(opaque);
MuxChardev *d = MUX_CHARDEV(opaque);
int m = d->focus;
CharBackend *be = d->backends[m];
CharFrontend *fe = d->frontends[m];
int i;
mux_chr_accept_input(opaque);
@ -239,9 +239,9 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
for (i = 0; i < size; i++)
if (mux_proc_byte(chr, d, buf[i])) {
if (d->prod[m] == d->cons[m] &&
be && be->chr_can_read &&
be->chr_can_read(be->opaque)) {
be->chr_read(be->opaque, &buf[i], 1);
fe && fe->chr_can_read &&
fe->chr_can_read(fe->opaque)) {
fe->chr_read(fe->opaque, &buf[i], 1);
} else {
d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
}
@ -289,9 +289,9 @@ static void char_mux_finalize(Object *obj)
bit = -1;
while ((bit = find_next_bit(&d->mux_bitset, MAX_MUX, bit + 1)) < MAX_MUX) {
CharBackend *be = d->backends[bit];
CharFrontend *be = d->frontends[bit];
be->chr = NULL;
d->backends[bit] = NULL;
d->frontends[bit] = NULL;
}
d->mux_bitset = 0;
qemu_chr_fe_deinit(&d->chr, false);
@ -311,7 +311,7 @@ static void mux_chr_update_read_handlers(Chardev *chr)
chr->gcontext, true, false);
}
bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b,
bool mux_chr_attach_frontend(MuxChardev *d, CharFrontend *c,
unsigned int *tag, Error **errp)
{
unsigned int bit;
@ -328,7 +328,7 @@ bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b,
}
d->mux_bitset |= (1ul << bit);
d->backends[bit] = b;
d->frontends[bit] = c;
*tag = bit;
return true;
@ -341,7 +341,7 @@ bool mux_chr_detach_frontend(MuxChardev *d, unsigned int tag)
}
d->mux_bitset &= ~(1ul << tag);
d->backends[tag] = NULL;
d->frontends[tag] = NULL;
return true;
}
@ -357,7 +357,7 @@ void mux_set_focus(Chardev *chr, unsigned int focus)
}
d->focus = focus;
chr->be = d->backends[focus];
chr->fe = d->frontends[focus];
mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
}

View file

@ -53,13 +53,13 @@ Object *get_chardevs_root(void)
static void chr_be_event(Chardev *s, QEMUChrEvent event)
{
CharBackend *be = s->be;
CharFrontend *fe = s->fe;
if (!be || !be->chr_event) {
if (!fe || !fe->chr_event) {
return;
}
be->chr_event(be->opaque, event);
fe->chr_event(fe->opaque, event);
}
void qemu_chr_be_event(Chardev *s, QEMUChrEvent event)
@ -197,21 +197,21 @@ int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all)
int qemu_chr_be_can_write(Chardev *s)
{
CharBackend *be = s->be;
CharFrontend *fe = s->fe;
if (!be || !be->chr_can_read) {
if (!fe || !fe->chr_can_read) {
return 0;
}
return be->chr_can_read(be->opaque);
return fe->chr_can_read(fe->opaque);
}
void qemu_chr_be_write_impl(Chardev *s, const uint8_t *buf, int len)
{
CharBackend *be = s->be;
CharFrontend *fe = s->fe;
if (be && be->chr_read) {
be->chr_read(be->opaque, buf, len);
if (fe && fe->chr_read) {
fe->chr_read(fe->opaque, buf, len);
}
}
@ -307,8 +307,8 @@ static void char_finalize(Object *obj)
{
Chardev *chr = CHARDEV(obj);
if (chr->be) {
chr->be->chr = NULL;
if (chr->fe) {
chr->fe->chr = NULL;
}
g_free(chr->filename);
g_free(chr->label);
@ -335,7 +335,7 @@ static bool qemu_chr_is_busy(Chardev *s)
MuxChardev *d = MUX_CHARDEV(s);
return d->mux_bitset != 0;
} else {
return s->be != NULL;
return s->fe != NULL;
}
}
@ -798,7 +798,7 @@ static int qmp_query_chardev_foreach(Object *obj, void *data)
value->label = g_strdup(chr->label);
value->filename = g_strdup(chr->filename);
value->frontend_open = chr->be && chr->be->fe_is_open;
value->frontend_open = chr->fe && chr->fe->fe_is_open;
QAPI_LIST_PREPEND(*list, value);
@ -1112,7 +1112,7 @@ err:
ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
Error **errp)
{
CharBackend *be;
CharFrontend *fe;
const ChardevClass *cc, *cc_new;
Chardev *chr, *chr_new;
bool closed_sent = false;
@ -1136,14 +1136,14 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
return NULL;
}
be = chr->be;
if (!be) {
fe = chr->fe;
if (!fe) {
/* easy case */
object_unparent(OBJECT(chr));
return qmp_chardev_add(id, backend, errp);
}
if (!be->chr_be_change) {
if (!fe->chr_be_change) {
error_setg(errp, "Chardev user does not support chardev hotswap");
return NULL;
}
@ -1171,13 +1171,13 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend,
closed_sent = true;
}
chr->be = NULL;
qemu_chr_fe_init(be, chr_new, &error_abort);
chr->fe = NULL;
qemu_chr_fe_init(fe, chr_new, &error_abort);
if (be->chr_be_change(be->opaque) < 0) {
if (fe->chr_be_change(fe->opaque) < 0) {
error_setg(errp, "Chardev '%s' change failed", chr_new->label);
chr_new->be = NULL;
qemu_chr_fe_init(be, chr, &error_abort);
chr_new->fe = NULL;
qemu_chr_fe_init(fe, chr, &error_abort);
if (closed_sent) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}

View file

@ -37,9 +37,9 @@
struct MuxChardev {
Chardev parent;
/* Linked frontends */
CharBackend *backends[MAX_MUX];
/* Linked backend */
CharBackend chr;
CharFrontend *frontends[MAX_MUX];
/* frontend of the underlying muxed chardev */
CharFrontend chr;
unsigned long mux_bitset;
int focus;
bool term_got_escape;
@ -65,7 +65,7 @@ typedef struct HubCharBackend HubCharBackend;
*/
struct HubCharBackend {
HubChardev *hub;
CharBackend be;
CharFrontend fe;
unsigned int be_ind;
};
@ -108,7 +108,7 @@ DECLARE_INSTANCE_CHECKER(HubChardev, HUB_CHARDEV,
#define CHARDEV_IS_HUB(chr) \
object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_HUB)
bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b,
bool mux_chr_attach_frontend(MuxChardev *d, CharFrontend *c,
unsigned int *tag, Error **errp);
bool mux_chr_detach_frontend(MuxChardev *d, unsigned int tag);
void mux_set_focus(Chardev *chr, unsigned int focus);

View file

@ -544,6 +544,20 @@ available firmwares that are using the current (wrong) name. The
property is kept as is in 9.1, together with "riscv,delegation", to
give more time for firmware developers to change their code.
x86 "isapc" board use of modern x86 CPUs (since 10.2)
'''''''''''''''''''''''''''''''''''''''''''''''''''''
The "isapc" board represents a historical x86 ISA PC and is intended for
older 32-bit x86 CPU models, defaulting to a 486 CPU model. Previously it
was possible (but non-sensical) to specify a more modern x86 CPU, including
``-cpu host`` or ``-cpu max`` even if the features were incompatible with many
of the intended guest OSs.
If the user requests a modern x86 CPU model (i.e. not one of ``486``,
``athlon``, ``kvm32``, ``pentium``, ``pentium2``, ``pentium3``or ``qemu32``)
a warning will be displayed until a future QEMU version when such CPUs will
be rejected.
Migration
---------

View file

@ -34,7 +34,7 @@
/* System emulation specific state */
typedef struct {
CharBackend chr;
CharFrontend chr;
Chardev *mon_chr;
} GDBSystemState;

View file

@ -927,7 +927,7 @@ struct StrongARMUARTState {
SysBusDevice parent_obj;
MemoryRegion iomem;
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
uint8_t utcr0;

View file

@ -40,7 +40,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(ISADebugconState, ISA_DEBUGCON_DEVICE)
typedef struct DebugconState {
MemoryRegion io;
CharBackend chr;
CharFrontend chr;
uint32_t readback;
} DebugconState;

View file

@ -154,7 +154,7 @@ struct Exynos4210UartState {
QEMUTimer *fifo_timeout_timer;
uint64_t wordtime; /* word time in ns */
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
qemu_irq dmairq;

View file

@ -84,7 +84,7 @@ struct UART {
MemoryRegion iomem;
qemu_irq irq;
CharBackend chr;
CharFrontend chr;
/* registers */
uint32_t status;

View file

@ -102,7 +102,7 @@ typedef struct SCC2698Block SCC2698Block;
struct SCC2698Channel {
IPOctalState *ipoctal;
CharBackend dev;
CharFrontend dev;
bool rx_enabled;
uint8_t mr[2];
uint8_t mr_idx;

View file

@ -36,7 +36,7 @@ struct mcf_uart_state {
int tx_enabled;
int rx_enabled;
qemu_irq irq;
CharBackend chr;
CharFrontend chr;
};
#define TYPE_MCF_UART "mcf-uart"

View file

@ -41,7 +41,7 @@ typedef struct OprtnsCommand {
struct SCLPConsoleLM {
SCLPEvent event;
CharBackend chr;
CharFrontend chr;
bool echo; /* immediate echo of input if true */
uint32_t write_errors; /* errors writing to char layer */
uint32_t length; /* length of byte stream in buffer */

View file

@ -35,7 +35,7 @@ typedef struct ASCIIConsoleData {
struct SCLPConsole {
SCLPEvent event;
CharBackend chr;
CharFrontend chr;
uint8_t iov[SIZE_BUFFER_VT220];
uint32_t iov_sclp; /* offset in buf for SCLP read operation */
uint32_t iov_bs; /* offset in buf for char layer read operation */

View file

@ -67,7 +67,7 @@ struct SHSerialState {
int flags;
int rtrg;
CharBackend chr;
CharFrontend chr;
QEMUTimer fifo_timeout_timer;
uint64_t etu; /* Elementary Time Unit (ns) */

View file

@ -14,7 +14,7 @@
struct SpaprVioVty {
SpaprVioDevice sdev;
CharBackend chardev;
CharFrontend chardev;
uint32_t in, out;
uint8_t buf[VTERM_BUFSIZE];
};

View file

@ -30,7 +30,7 @@
struct Terminal3270 {
EmulatedCcw3270Device cdev;
CharBackend chr;
CharFrontend chr;
uint8_t inv[INPUT_BUFFER_SIZE];
uint8_t outv[OUTPUT_BUFFER_SIZE];
int in_len;

View file

@ -30,7 +30,7 @@ DECLARE_INSTANCE_CHECKER(VirtConsole, VIRTIO_CONSOLE,
struct VirtConsole {
VirtIOSerialPort parent_obj;
CharBackend chr;
CharFrontend chr;
guint watch;
};

View file

@ -53,7 +53,7 @@ struct XenConsole {
char *fe_path;
unsigned int ring_ref;
void *sring;
CharBackend chr;
CharFrontend chr;
int backlog;
};

View file

@ -60,7 +60,7 @@ struct XilinxUARTLite {
EndianMode model_endianness;
MemoryRegion mmio;
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
uint8_t rx_fifo[8];

View file

@ -258,10 +258,10 @@ const PropertyInfo qdev_prop_drive_iothread = {
static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
CharBackend *be = object_field_prop_ptr(obj, opaque);
CharFrontend *fe = object_field_prop_ptr(obj, opaque);
char *p;
p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
p = g_strdup(fe->chr && fe->chr->label ? fe->chr->label : "");
visit_type_str(v, name, &p, errp);
g_free(p);
}
@ -271,7 +271,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
{
ERRP_GUARD();
const Property *prop = opaque;
CharBackend *be = object_field_prop_ptr(obj, prop);
CharFrontend *fe = object_field_prop_ptr(obj, prop);
Chardev *s;
char *str;
@ -283,13 +283,13 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
* TODO Should this really be an error? If no, the old value
* needs to be released before we store the new one.
*/
if (!check_prop_still_unset(obj, name, be->chr, str, false, errp)) {
if (!check_prop_still_unset(obj, name, fe->chr, str, false, errp)) {
return;
}
if (!*str) {
g_free(str);
be->chr = NULL;
fe->chr = NULL;
return;
}
@ -297,7 +297,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
if (s == NULL) {
error_setg(errp, "Property '%s.%s' can't find value '%s'",
object_get_typename(obj), name, str);
} else if (!qemu_chr_fe_init(be, s, errp)) {
} else if (!qemu_chr_fe_init(fe, s, errp)) {
error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
object_get_typename(obj), name, str);
}
@ -307,9 +307,9 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
static void release_chr(Object *obj, const char *name, void *opaque)
{
const Property *prop = opaque;
CharBackend *be = object_field_prop_ptr(obj, prop);
CharFrontend *fe = object_field_prop_ptr(obj, prop);
qemu_chr_fe_deinit(be, false);
qemu_chr_fe_deinit(fe, false);
}
const PropertyInfo qdev_prop_chr = {
@ -865,15 +865,14 @@ out:
visit_end_alternate(v, (void **) &alt);
}
static int print_pci_devfn(Object *obj, const Property *prop, char *dest,
size_t len)
static char *print_pci_devfn(Object *obj, const Property *prop)
{
int32_t *ptr = object_field_prop_ptr(obj, prop);
if (*ptr == -1) {
return snprintf(dest, len, "<unset>");
return g_strdup("<unset>");
} else {
return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
return g_strdup_printf("%02x.%x", *ptr >> 3, *ptr & 7);
}
}

View file

@ -1117,12 +1117,11 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v,
Error **errp)
{
const Property *prop = opaque;
char *s;
char buffer[1024];
char *ptr = buffer;
prop->info->print(obj, prop, buffer, sizeof(buffer));
visit_type_str(v, name, &ptr, errp);
s = prop->info->print(obj, prop);
visit_type_str(v, name, &s, errp);
g_free(s);
}
/**

View file

@ -151,7 +151,7 @@ static void io_cpu_write(void *opaque, hwaddr addr,
ch = val;
debugout = serial_hd(0);
if (debugout) {
qemu_chr_fe_write_all(debugout->be, &ch, 1);
qemu_chr_fe_write_all(debugout->fe, &ch, 1);
} else {
fprintf(stderr, "%c", ch);
}

View file

@ -41,29 +41,31 @@ static void pc_init_isa(MachineState *machine)
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
int i;
/*
* There is a small chance that someone unintentionally passes "-cpu max"
* for the isapc machine, which will provide a much more modern 32-bit
* CPU than would be expected for an ISA-era PC. If the "max" cpu type has
* been specified, choose the "best" 32-bit cpu possible which we consider
* be the pentium3 (deliberately choosing an Intel CPU given that the
* default 486 CPU for the isapc machine is also an Intel CPU).
*/
if (!strcmp(machine->cpu_type, X86_CPU_TYPE_NAME("max"))) {
machine->cpu_type = X86_CPU_TYPE_NAME("pentium3");
warn_report("-cpu max is invalid for isapc machine, using pentium3");
}
bool valid_cpu_type = false;
static const char * const valid_cpu_types[] = {
X86_CPU_TYPE_NAME("486"),
X86_CPU_TYPE_NAME("athlon"),
X86_CPU_TYPE_NAME("kvm32"),
X86_CPU_TYPE_NAME("pentium"),
X86_CPU_TYPE_NAME("pentium2"),
X86_CPU_TYPE_NAME("pentium3"),
X86_CPU_TYPE_NAME("qemu32"),
};
/*
* Similarly if someone unintentionally passes "-cpu host" for the isapc
* machine then display a warning and also switch to the "best" 32-bit
* cpu possible which we consider to be the pentium3. This is because any
* host CPU will already be modern than this, but it also ensures any
* newer CPU flags/features are filtered out for older guests.
* The isapc machine is supposed to represent a legacy ISA-only PC with a
* 32-bit processor. For historical reasons the machine can still accept
* almost any valid processor, but this is now deprecated in 10.2. Emit
* a warning if anyone tries to use a deprecated CPU.
*/
if (!strcmp(machine->cpu_type, X86_CPU_TYPE_NAME("host"))) {
machine->cpu_type = X86_CPU_TYPE_NAME("pentium3");
warn_report("-cpu host is invalid for isapc machine, using pentium3");
for (i = 0; i < ARRAY_SIZE(valid_cpu_types); i++) {
if (!strcmp(machine->cpu_type, valid_cpu_types[i])) {
valid_cpu_type = true;
}
}
if (!valid_cpu_type) {
warn_report("cpu type %s is deprecated for isapc machine", machine->cpu_type);
}
if (machine->ram_size > 3.5 * GiB) {
@ -154,18 +156,6 @@ static void pc_init_isa(MachineState *machine)
static void isapc_machine_options(MachineClass *m)
{
static const char * const valid_cpu_types[] = {
X86_CPU_TYPE_NAME("486"),
X86_CPU_TYPE_NAME("athlon"),
X86_CPU_TYPE_NAME("kvm32"),
X86_CPU_TYPE_NAME("pentium"),
X86_CPU_TYPE_NAME("pentium2"),
X86_CPU_TYPE_NAME("pentium3"),
X86_CPU_TYPE_NAME("qemu32"),
X86_CPU_TYPE_NAME("max"),
X86_CPU_TYPE_NAME("host"),
NULL
};
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
m->desc = "ISA-only PC";
@ -180,7 +170,6 @@ static void isapc_machine_options(MachineClass *m)
pcmc->has_reserved_memory = false;
m->default_nic = "ne2k_isa";
m->default_cpu_type = X86_CPU_TYPE_NAME("486");
m->valid_cpu_types = valid_cpu_types;
m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC);
m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
}

View file

@ -183,6 +183,17 @@ void x86_cpu_plug(HotplugHandler *hotplug_dev,
fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
}
/*
* Non-hotplugged CPUs get their SMM cpu address space initialized in
* machine init done notifier: register_smram_listener().
*
* We need initialize the SMM cpu address space for the hotplugged CPU
* specifically.
*/
if (kvm_enabled() && dev->hotplugged && x86_machine_is_smm_enabled(x86ms)) {
kvm_smm_cpu_address_space_init(cpu);
}
found_cpu = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, NULL);
found_cpu->cpu = CPU(dev);
out:

View file

@ -67,7 +67,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(IPMIBmcExtern, IPMI_BMC_EXTERN)
struct IPMIBmcExtern {
IPMIBmc parent;
CharBackend chr;
CharFrontend chr;
bool connected;

View file

@ -68,7 +68,7 @@ struct BostonState {
SerialMM *uart;
Clock *cpuclk;
CharBackend lcd_display;
CharFrontend lcd_display;
char lcd_content[8];
bool lcd_inited;

View file

@ -89,7 +89,7 @@ typedef struct {
uint32_t i2coe;
uint32_t i2cout;
uint32_t i2csel;
CharBackend display;
CharFrontend display;
char display_text[9];
SerialMM *uart;
bool display_inited;

View file

@ -94,7 +94,7 @@ struct IVShmemState {
/* exactly one of these two may be set */
HostMemoryBackend *hostmem; /* with interrupts */
CharBackend server_chr; /* without interrupts */
CharFrontend server_chr; /* without interrupts */
/* registers */
uint32_t intrmask;

View file

@ -623,7 +623,7 @@ static uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
return H_PARAMETER;
}
static bool spapr_qtest_callback(CharBackend *chr, gchar **words)
static bool spapr_qtest_callback(CharFrontend *chr, gchar **words)
{
if (strcmp(words[0], "rtas") == 0) {
uint64_t res, args, ret;

View file

@ -78,7 +78,7 @@ static void csr_call(char *cmd, uint64_t cpu_num, int csrno, uint64_t *val)
g_assert(ret == RISCV_EXCP_NONE);
}
static bool csr_qtest_callback(CharBackend *chr, gchar **words)
static bool csr_qtest_callback(CharFrontend *chr, gchar **words)
{
if (strcmp(words[0], "csr") == 0) {

View file

@ -447,7 +447,9 @@ static void write_response(ESPState *s)
static bool esp_cdb_ready(ESPState *s)
{
int len = fifo8_num_used(&s->cmdfifo) - s->cmdfifo_cdb_offset;
/* scsi_cdb_length() only reads the first byte */
int limit = s->cmdfifo_cdb_offset + 1;
int len = fifo8_num_used(&s->cmdfifo);
const uint8_t *pbuf;
uint32_t n;
int cdblen;
@ -457,7 +459,7 @@ static bool esp_cdb_ready(ESPState *s)
}
pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n);
if (n < len) {
if (n < limit) {
/*
* In normal use the cmdfifo should never wrap, but include this check
* to prevent a malicious guest from reading past the end of the

View file

@ -823,7 +823,6 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
{
SCSIRequest *req;
SCSIBus *bus = scsi_bus_from_device(d);
BusState *qbus = BUS(bus);
const int memset_off = offsetof(SCSIRequest, sense)
+ sizeof(req->sense);
@ -838,8 +837,6 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
req->status = -1;
req->host_status = -1;
req->ops = reqops;
object_ref(OBJECT(d));
object_ref(OBJECT(qbus->parent));
notifier_list_init(&req->cancel_notifiers);
if (reqops->init_req) {
@ -1496,15 +1493,15 @@ void scsi_device_report_change(SCSIDevice *dev, SCSISense sense)
SCSIRequest *scsi_req_ref(SCSIRequest *req)
{
assert(req->refcount > 0);
req->refcount++;
assert(qatomic_read(&req->refcount) > 0);
qatomic_inc(&req->refcount);
return req;
}
void scsi_req_unref(SCSIRequest *req)
{
assert(req->refcount > 0);
if (--req->refcount == 0) {
assert(qatomic_read(&req->refcount) > 0);
if (qatomic_fetch_dec(&req->refcount) == 1) {
BusState *qbus = req->dev->qdev.parent_bus;
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, qbus);
@ -1514,8 +1511,6 @@ void scsi_req_unref(SCSIRequest *req)
if (req->ops->free_req) {
req->ops->free_req(req);
}
object_unref(OBJECT(req->dev));
object_unref(OBJECT(qbus->parent));
g_free(req);
}
}

View file

@ -56,7 +56,7 @@ typedef struct PassthruState PassthruState;
struct PassthruState {
CCIDCardState base;
CharBackend cs;
CharFrontend cs;
uint8_t vscard_in_data[VSCARD_IN_SIZE];
uint32_t vscard_in_pos;
uint32_t vscard_in_hdr;

View file

@ -105,7 +105,7 @@ struct USBSerialState {
uint8_t xoff;
QEMUSerialSetParams params;
int latency; /* ms */
CharBackend cs;
CharFrontend cs;
};
#define TYPE_USB_SERIAL "usb-serial-dev"

View file

@ -113,7 +113,7 @@ struct PacketIdQueue {
struct USBRedirDevice {
USBDevice dev;
/* Properties */
CharBackend cs;
CharFrontend cs;
bool enable_streams;
bool suppress_remote_wake;
bool in_write;

View file

@ -12,7 +12,7 @@ unsigned int vhost_get_free_memslots(void)
return UINT_MAX;
}
bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp)
bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp)
{
return false;
}

View file

@ -275,7 +275,7 @@ struct scrub_regions {
static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg)
{
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
CharFrontend *chr = u->user->chr;
uint8_t *p = (uint8_t *) msg;
int r, size = VHOST_USER_HDR_SIZE;
@ -303,7 +303,7 @@ static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg)
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
{
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
CharFrontend *chr = u->user->chr;
uint8_t *p = (uint8_t *) msg;
int r, size;
@ -383,7 +383,7 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
int *fds, int fd_num)
{
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
CharFrontend *chr = u->user->chr;
int ret, size = VHOST_USER_HDR_SIZE + msg->hdr.size;
/*
@ -1680,7 +1680,7 @@ int vhost_user_get_shared_object(struct vhost_dev *dev, unsigned char *uuid,
int *dmabuf_fd)
{
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
CharFrontend *chr = u->user->chr;
int ret;
VhostUserMsg msg = {
.hdr.request = VHOST_USER_GET_SHARED_OBJECT,
@ -1721,7 +1721,7 @@ vhost_user_backend_handle_shared_object_lookup(struct vhost_user *u,
VhostUserPayload *payload)
{
QemuUUID uuid;
CharBackend *chr = u->user->chr;
CharFrontend *chr = u->user->chr;
Error *local_err = NULL;
int dmabuf_fd = -1;
int fd_num = 0;
@ -2004,7 +2004,7 @@ static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp)
{
#ifdef CONFIG_LINUX
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
CharFrontend *chr = u->user->chr;
int ufd;
int ret;
VhostUserMsg msg = {
@ -2670,7 +2670,7 @@ static int vhost_user_get_inflight_fd(struct vhost_dev *dev,
int fd;
int ret;
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
CharFrontend *chr = u->user->chr;
VhostUserMsg msg = {
.hdr.request = VHOST_USER_GET_INFLIGHT_FD,
.hdr.flags = VHOST_USER_VERSION,
@ -2761,7 +2761,7 @@ static void vhost_user_state_destroy(gpointer data)
vhost_user_host_notifier_remove(n, NULL, true);
}
bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp)
bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp)
{
if (user->chr) {
error_setg(errp, "Cannot initialize vhost-user state");
@ -2787,7 +2787,7 @@ void vhost_user_cleanup(VhostUserState *user)
typedef struct {
vu_async_close_fn cb;
DeviceState *dev;
CharBackend *cd;
CharFrontend *cd;
struct vhost_dev *vhost;
} VhostAsyncCallback;
@ -2806,7 +2806,7 @@ static void vhost_user_async_close_bh(void *opaque)
* purposes.
*/
void vhost_user_async_close(DeviceState *d,
CharBackend *chardev, struct vhost_dev *vhost,
CharFrontend *chardev, struct vhost_dev *vhost,
vu_async_close_fn cb)
{
if (!runstate_check(RUN_STATE_SHUTDOWN)) {

View file

@ -8,12 +8,12 @@ typedef void IOEventHandler(void *opaque, QEMUChrEvent event);
typedef int BackendChangeHandler(void *opaque);
/**
* struct CharBackend - back end as seen by front end
* struct CharFrontend - Chardev as seen by front end
* @fe_is_open: the front end is ready for IO
*
* The actual backend is Chardev
*/
struct CharBackend {
struct CharFrontend {
Chardev *chr;
IOEventHandler *chr_event;
IOCanReadHandler *chr_can_read;
@ -27,53 +27,52 @@ struct CharBackend {
/**
* qemu_chr_fe_init:
*
* Initializes a front end for the given CharBackend and
* Chardev. Call qemu_chr_fe_deinit() to remove the association and
* release the driver.
* Initializes the frontend @c for the given Chardev backend @s. Call
* qemu_chr_fe_deinit() to remove the association and release the backend.
*
* Returns: false on error.
*/
bool qemu_chr_fe_init(CharBackend *b, Chardev *s, Error **errp);
bool qemu_chr_fe_init(CharFrontend *c, Chardev *be, Error **errp);
/**
* qemu_chr_fe_deinit:
* @b: a CharBackend
* @c: a CharFrontend
* @del: if true, delete the chardev backend
*
* Dissociate the CharBackend from the Chardev.
* Dissociate the CharFrontend from the Chardev.
*
* Safe to call without associated Chardev.
*/
void qemu_chr_fe_deinit(CharBackend *b, bool del);
void qemu_chr_fe_deinit(CharFrontend *c, bool del);
/**
* qemu_chr_fe_get_driver:
*
* Returns: the driver associated with a CharBackend or NULL if no
* Returns: the driver associated with a CharFrontend or NULL if no
* associated Chardev.
* Note: avoid this function as the driver should never be accessed directly,
* especially by the frontends that support chardevice hotswap.
* Consider qemu_chr_fe_backend_connected() to check for driver existence
*/
Chardev *qemu_chr_fe_get_driver(CharBackend *be);
Chardev *qemu_chr_fe_get_driver(CharFrontend *c);
/**
* qemu_chr_fe_backend_connected:
*
* Returns: true if there is a chardevice associated with @be.
* Returns: true if there is a backend associated with @c.
*/
bool qemu_chr_fe_backend_connected(CharBackend *be);
bool qemu_chr_fe_backend_connected(CharFrontend *c);
/**
* qemu_chr_fe_backend_open:
*
* Returns: true if chardevice associated with @be is open.
* Returns: true if the backend associated with @c is open.
*/
bool qemu_chr_fe_backend_open(CharBackend *be);
bool qemu_chr_fe_backend_open(CharFrontend *c);
/**
* qemu_chr_fe_set_handlers_full:
* @b: a CharBackend
* @c: a CharFrontend
* @fd_can_read: callback to get the amount of data the frontend may
* receive
* @fd_read: callback to receive data from char
@ -91,7 +90,7 @@ bool qemu_chr_fe_backend_open(CharBackend *be);
*
* Without associated Chardev, nothing is changed.
*/
void qemu_chr_fe_set_handlers_full(CharBackend *b,
void qemu_chr_fe_set_handlers_full(CharFrontend *c,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
@ -106,7 +105,7 @@ void qemu_chr_fe_set_handlers_full(CharBackend *b,
*
* Version of qemu_chr_fe_set_handlers_full() with sync_state = true.
*/
void qemu_chr_fe_set_handlers(CharBackend *b,
void qemu_chr_fe_set_handlers(CharFrontend *c,
IOCanReadHandler *fd_can_read,
IOReadHandler *fd_read,
IOEventHandler *fd_event,
@ -122,14 +121,14 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
*
* Without associated Chardev, nothing is changed.
*/
void qemu_chr_fe_take_focus(CharBackend *b);
void qemu_chr_fe_take_focus(CharFrontend *c);
/**
* qemu_chr_fe_accept_input:
*
* Notify that the frontend is ready to receive data
*/
void qemu_chr_fe_accept_input(CharBackend *be);
void qemu_chr_fe_accept_input(CharFrontend *c);
/**
* qemu_chr_fe_disconnect:
@ -137,7 +136,7 @@ void qemu_chr_fe_accept_input(CharBackend *be);
* Close a fd accepted by character backend.
* Without associated Chardev, do nothing.
*/
void qemu_chr_fe_disconnect(CharBackend *be);
void qemu_chr_fe_disconnect(CharFrontend *c);
/**
* qemu_chr_fe_wait_connected:
@ -145,7 +144,7 @@ void qemu_chr_fe_disconnect(CharBackend *be);
* Wait for character backend to be connected, return < 0 on error or
* if no associated Chardev.
*/
int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp);
int qemu_chr_fe_wait_connected(CharFrontend *c, Error **errp);
/**
* qemu_chr_fe_set_echo:
@ -156,17 +155,17 @@ int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp);
* can see what you type if you try to type QMP commands.
* Without associated Chardev, do nothing.
*/
void qemu_chr_fe_set_echo(CharBackend *be, bool echo);
void qemu_chr_fe_set_echo(CharFrontend *c, bool echo);
/**
* qemu_chr_fe_set_open:
* @be: a CharBackend
* @c: a CharFrontend
* @is_open: the front end open status
*
* This is an indication that the front end is ready (or not) to begin
* doing I/O. Without associated Chardev, do nothing.
*/
void qemu_chr_fe_set_open(CharBackend *be, bool is_open);
void qemu_chr_fe_set_open(CharFrontend *c, bool is_open);
/**
* qemu_chr_fe_printf:
@ -176,7 +175,7 @@ void qemu_chr_fe_set_open(CharBackend *be, bool is_open);
* function is thread-safe. It does nothing without associated
* Chardev.
*/
void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
void qemu_chr_fe_printf(CharFrontend *c, const char *fmt, ...)
G_GNUC_PRINTF(2, 3);
@ -215,7 +214,7 @@ typedef gboolean (*FEWatchFunc)(void *do_not_use, GIOCondition condition, void *
*
* Returns: the source tag
*/
guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
guint qemu_chr_fe_add_watch(CharFrontend *c, GIOCondition cond,
FEWatchFunc func, void *user_data);
/**
@ -230,7 +229,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
* Returns: the number of bytes consumed (0 if no associated Chardev)
* or -1 on error.
*/
int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
int qemu_chr_fe_write(CharFrontend *c, const uint8_t *buf, int len);
/**
* qemu_chr_fe_write_all:
@ -245,7 +244,7 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
* Returns: the number of bytes consumed (0 if no associated Chardev)
* or -1 on error.
*/
int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
int qemu_chr_fe_write_all(CharFrontend *c, const uint8_t *buf, int len);
/**
* qemu_chr_fe_read_all:
@ -257,7 +256,7 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
* Returns: the number of bytes read (0 if no associated Chardev)
* or -1 on error.
*/
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
int qemu_chr_fe_read_all(CharFrontend *c, uint8_t *buf, int len);
/**
* qemu_chr_fe_ioctl:
@ -270,7 +269,7 @@ int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
* associated Chardev, -ENOTSUP, otherwise the return
* value depends on the semantics of @cmd
*/
int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg);
int qemu_chr_fe_ioctl(CharFrontend *c, int cmd, void *arg);
/**
* qemu_chr_fe_get_msgfd:
@ -283,7 +282,7 @@ int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg);
* this function will return -1 until a client sends a new file
* descriptor.
*/
int qemu_chr_fe_get_msgfd(CharBackend *be);
int qemu_chr_fe_get_msgfd(CharFrontend *c);
/**
* qemu_chr_fe_get_msgfds:
@ -296,7 +295,7 @@ int qemu_chr_fe_get_msgfd(CharBackend *be);
* this function will return -1 until a client sends a new set of file
* descriptors.
*/
int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num);
int qemu_chr_fe_get_msgfds(CharFrontend *c, int *fds, int num);
/**
* qemu_chr_fe_set_msgfds:
@ -309,6 +308,6 @@ int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num);
*
* Returns: -1 if fd passing isn't supported or no associated Chardev.
*/
int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num);
int qemu_chr_fe_set_msgfds(CharFrontend *c, int *fds, int num);
#endif /* QEMU_CHAR_FE_H */

View file

@ -15,7 +15,7 @@
#define IAC 255
/* character device */
typedef struct CharBackend CharBackend;
typedef struct CharFrontend CharFrontend;
typedef enum {
CHR_EVENT_BREAK, /* serial break char */
@ -60,7 +60,7 @@ struct Chardev {
Object parent_obj;
QemuMutex chr_write_lock;
CharBackend *be;
CharFrontend *fe;
char *label;
char *filename;
int logfd;

View file

@ -66,7 +66,7 @@ struct AVRUsartState {
/* <public> */
MemoryRegion mmio;
CharBackend chr;
CharFrontend chr;
bool enabled;

View file

@ -24,7 +24,7 @@ struct BCM2835AuxState {
/*< public >*/
MemoryRegion iomem;
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN];

View file

@ -47,7 +47,7 @@ struct CadenceUARTState {
uint32_t rx_count;
uint32_t tx_count;
uint64_t char_tx_time;
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
QEMUTimer *fifo_trigger_handle;
Clock *refclk;

View file

@ -25,7 +25,7 @@ struct CMSDKAPBUART {
/*< public >*/
MemoryRegion iomem;
CharBackend chr;
CharFrontend chr;
qemu_irq txint;
qemu_irq rxint;
qemu_irq txovrint;

View file

@ -38,7 +38,7 @@ struct DigicUartState {
/*< public >*/
MemoryRegion regs_region;
CharBackend chr;
CharFrontend chr;
uint32_t reg_rx;
uint32_t reg_st;

View file

@ -36,7 +36,7 @@ typedef struct ESCCChannelState {
uint32_t reg;
uint8_t wregs[ESCC_SERIAL_REGS], rregs[ESCC_SERIAL_REGS];
ESCCSERIOQueue queue;
CharBackend chr;
CharFrontend chr;
int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
int disabled;
int clock;

View file

@ -24,7 +24,7 @@ struct GoldfishTTYState {
MemoryRegion iomem;
qemu_irq irq;
CharBackend chr;
CharFrontend chr;
uint32_t data_len;
uint64_t data_ptr;

View file

@ -64,7 +64,7 @@ struct IbexUartState {
Clock *f_clk;
CharBackend chr;
CharFrontend chr;
qemu_irq tx_watermark;
qemu_irq rx_watermark;
qemu_irq tx_empty;

View file

@ -122,7 +122,7 @@ struct IMXSerialState {
uint32_t ucr4;
qemu_irq irq;
CharBackend chr;
CharFrontend chr;
};
#endif

View file

@ -72,7 +72,7 @@ struct Max78000UartState {
Fifo8 rx_fifo;
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
};
#endif /* HW_STM32F2XX_USART_H */

View file

@ -59,7 +59,7 @@ struct NRF51UARTState {
SysBusDevice parent_obj;
MemoryRegion iomem;
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
guint watch_tag;

View file

@ -15,7 +15,7 @@ typedef struct ParallelState {
uint8_t control;
qemu_irq irq;
int irq_pending;
CharBackend chr;
CharFrontend chr;
int hw_driver;
int epp_timeout;
uint32_t last_read_offset; /* For debugging */

View file

@ -47,7 +47,7 @@ struct PL011State {
int read_pos;
int read_count;
int read_trigger;
CharBackend chr;
CharFrontend chr;
qemu_irq irq[6];
Clock *clk;
bool migrate_clk;

View file

@ -33,7 +33,7 @@ struct RSCIState {
MemoryRegion memory;
QEMUTimer timer;
CharBackend chr;
CharFrontend chr;
qemu_irq irq[SCI_NR_IRQ];
uint8_t smr;

View file

@ -36,7 +36,7 @@ typedef struct HTIFState {
hwaddr fromhost_offset;
MemoryRegion mmio;
CharBackend chr;
CharFrontend chr;
uint64_t pending_read;
} HTIFState;

View file

@ -54,7 +54,7 @@ struct SerialState {
it can be reset while reading iir */
int thr_ipending;
qemu_irq irq;
CharBackend chr;
CharFrontend chr;
int last_break_enable;
uint32_t baudbase;
uint32_t tsr_retry;

View file

@ -68,7 +68,7 @@ typedef struct {
uint32_t uart_iq_cycles;
uint32_t uart_rx_threshold;
CharBackend chr;
CharFrontend chr;
} ShaktiUartState;
#endif /* HW_SHAKTI_UART_H */

View file

@ -67,7 +67,7 @@ struct SiFiveUARTState {
/*< public >*/
qemu_irq irq;
MemoryRegion mmio;
CharBackend chr;
CharFrontend chr;
uint32_t txfifo;
uint32_t ie;

View file

@ -73,7 +73,7 @@ struct STM32F2XXUsartState {
uint32_t usart_cr3;
uint32_t usart_gtpr;
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
};
#endif /* HW_STM32F2XX_USART_H */

View file

@ -53,7 +53,7 @@ struct Stm32l4x5UsartBaseState {
uint32_t tdr;
Clock *clk;
CharBackend chr;
CharFrontend chr;
qemu_irq irq;
guint watch_tag;
};

View file

@ -65,7 +65,7 @@ struct IvshmemFTState {
QTAILQ_HEAD(, IvshmemPeer) peer;
IvshmemPeer own;
CharBackend server_chr;
CharFrontend server_chr;
/* IRQ */
qemu_irq irq;

View file

@ -38,7 +38,7 @@ extern const PropertyInfo qdev_prop_virtio_gpu_output_list;
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
#define DEFINE_PROP_CHR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend)
DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharFrontend)
#define DEFINE_PROP_NETDEV(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NICPeers)
#define DEFINE_PROP_DRIVE(_n, _s, _f) \

View file

@ -34,7 +34,7 @@ struct PropertyInfo {
const char *description;
const QEnumLookup *enum_table;
bool realized_set_allowed; /* allow setting property on realized device */
int (*print)(Object *obj, const Property *prop, char *dest, size_t len);
char *(*print)(Object *obj, const Property *prop);
void (*set_default_value)(ObjectProperty *op, const Property *prop);
ObjectProperty *(*create)(ObjectClass *oc, const char *name,
const Property *prop);

View file

@ -20,7 +20,7 @@ struct VHostUserBase {
VirtIODevice parent_obj;
/* Properties */
CharBackend chardev;
CharFrontend chardev;
uint16_t virtio_id;
uint32_t num_vqs;
uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */

View file

@ -29,7 +29,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserBlk, VHOST_USER_BLK)
struct VHostUserBlk {
VirtIODevice parent_obj;
CharBackend chardev;
CharFrontend chardev;
int32_t bootindex;
struct virtio_blk_config blkcfg;
uint16_t num_queues;

View file

@ -24,7 +24,7 @@
OBJECT_DECLARE_SIMPLE_TYPE(VHostUserFS, VHOST_USER_FS)
typedef struct {
CharBackend chardev;
CharFrontend chardev;
char *tag;
uint16_t num_request_queues;
uint16_t queue_size;

View file

@ -18,7 +18,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSCMI, VHOST_USER_SCMI);
struct VHostUserSCMI {
VirtIODevice parent;
CharBackend chardev;
CharFrontend chardev;
struct vhost_virtqueue *vhost_vqs;
struct vhost_dev vhost_dev;
VhostUserState vhost_user;

View file

@ -20,7 +20,7 @@
OBJECT_DECLARE_SIMPLE_TYPE(VHostUserVSock, VHOST_USER_VSOCK)
typedef struct {
CharBackend chardev;
CharFrontend chardev;
} VHostUserVSockConf;
struct VHostUserVSock {

View file

@ -64,7 +64,7 @@ typedef struct VhostUserHostNotifier {
* @memory_slots:
*/
typedef struct VhostUserState {
CharBackend *chr;
CharFrontend *chr;
GPtrArray *notifiers;
int memory_slots;
bool supports_config;
@ -82,7 +82,7 @@ typedef struct VhostUserState {
*
* Return: true on success, false on error while setting errp.
*/
bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp);
bool vhost_user_init(VhostUserState *user, CharFrontend *chr, Error **errp);
/**
* vhost_user_cleanup() - cleanup state
@ -96,7 +96,7 @@ void vhost_user_cleanup(VhostUserState *user);
/**
* vhost_user_async_close() - cleanup vhost-user post connection drop
* @d: DeviceState for the associated device (passed to callback)
* @chardev: the CharBackend associated with the connection
* @chardev: the CharFrontend associated with the connection
* @vhost: the common vhost device
* @cb: the user callback function to complete the clean-up
*
@ -108,7 +108,7 @@ void vhost_user_cleanup(VhostUserState *user);
typedef void (*vu_async_close_fn)(DeviceState *cb);
void vhost_user_async_close(DeviceState *d,
CharBackend *chardev, struct vhost_dev *vhost,
CharFrontend *chardev, struct vhost_dev *vhost,
vu_async_close_fn cb);
#endif

View file

@ -257,7 +257,7 @@ struct VhostUserGPU {
VhostUserBackend *vhost;
int vhost_gpu_fd; /* closed by the chardev */
CharBackend vhost_chr;
CharFrontend vhost_chr;
QemuDmaBuf *dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
bool backend_blocked;
};

View file

@ -58,7 +58,7 @@ struct VirtIOSCSIConf {
uint32_t cmd_per_lun;
char *vhostfd;
char *wwpn;
CharBackend chardev;
CharFrontend chardev;
uint32_t boot_tpgt;
IOThread *iothread;
IOThreadVirtQueueMappingList *iothread_vq_mapping_list;

View file

@ -32,6 +32,7 @@
#ifndef QOBJECT_H
#define QOBJECT_H
#include "qemu/atomic.h"
#include "qapi/qapi-builtin-types.h"
/* Not for use outside include/qobject/ */
@ -73,7 +74,7 @@ QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7,
static inline void qobject_ref_impl(QObject *obj)
{
if (obj) {
obj->base.refcnt++;
qatomic_inc(&obj->base.refcnt);
}
}
@ -95,7 +96,7 @@ void qobject_destroy(QObject *obj);
static inline void qobject_unref_impl(QObject *obj)
{
assert(!obj || obj->base.refcnt);
if (obj && --obj->base.refcnt == 0) {
if (obj && qatomic_fetch_dec(&obj->base.refcnt) == 1) {
qobject_destroy(obj);
}
}

View file

@ -23,8 +23,8 @@ static inline bool qtest_enabled(void)
return qtest_allowed;
}
void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr, const char *fmt, ...);
void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words));
void G_GNUC_PRINTF(2, 3) qtest_sendf(CharFrontend *chr, const char *fmt, ...);
void qtest_set_command_cb(bool (*pc_cb)(CharFrontend *chr, gchar **words));
bool qtest_driver(void);
void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);

View file

@ -32,7 +32,7 @@ struct VhostUserBackend {
Object parent;
char *chr_name;
CharBackend chr;
CharFrontend chr;
VhostUserState vhost_user;
struct vhost_dev dev;
VirtIODevice *vdev;

View file

@ -4251,6 +4251,7 @@ if have_rust
'--allowlist-file', meson.project_source_root() + '/include/.*',
'--allowlist-file', meson.project_build_root() + '/.*',
'--blocklist-file', glib_pc.get_variable('includedir') + '/glib-2.0/.*',
'--blocklist-type', '.*_([a-z]*autoptr)$',
]
if not rustfmt.found()
if bindgen.version().version_compare('<0.65.0')

View file

@ -93,7 +93,7 @@ typedef struct HMPCommand {
} HMPCommand;
struct Monitor {
CharBackend chr;
CharFrontend chr;
int suspend_cnt; /* Needs to be accessed atomically */
bool is_qmp;
bool skip_flush;

View file

@ -88,7 +88,7 @@ static uint32_t max_queue_size;
typedef struct SendCo {
Coroutine *co;
struct CompareState *s;
CharBackend *chr;
CharFrontend *chr;
GQueue send_list;
bool notify_remote_frame;
bool done;
@ -108,10 +108,10 @@ struct CompareState {
char *sec_indev;
char *outdev;
char *notify_dev;
CharBackend chr_pri_in;
CharBackend chr_sec_in;
CharBackend chr_out;
CharBackend chr_notify_dev;
CharFrontend chr_pri_in;
CharFrontend chr_sec_in;
CharFrontend chr_out;
CharFrontend chr_notify_dev;
SocketReadState pri_rs;
SocketReadState sec_rs;
SocketReadState notify_rs;

View file

@ -37,8 +37,8 @@ struct MirrorState {
NetFilterState parent_obj;
char *indev;
char *outdev;
CharBackend chr_in;
CharBackend chr_out;
CharFrontend chr_in;
CharFrontend chr_out;
SocketReadState rs;
bool vnet_hdr;
};

View file

@ -71,7 +71,7 @@ typedef struct NetPasstState {
/* vhost user */
VhostUserState *vhost_user;
VHostNetState *vhost_net;
CharBackend vhost_chr;
CharFrontend vhost_chr;
guint vhost_watch;
uint64_t acked_features;
bool started;

View file

@ -80,7 +80,7 @@ struct slirp_config_str {
};
struct GuestFwd {
CharBackend hd;
CharFrontend hd;
struct in_addr server;
int port;
Slirp *slirp;

View file

@ -65,7 +65,7 @@ static const int user_feature_bits[] = {
typedef struct NetVhostUserState {
NetClientState nc;
CharBackend chr; /* only queue index 0 */
CharFrontend chr; /* only queue index 0 */
VhostUserState *vhost_user;
VHostNetState *vhost_net;
guint watch;

View file

@ -1,18 +1,8 @@
[workspace]
resolver = "2"
members = [
"bits",
"bql",
"common",
"migration",
"qemu-macros",
"qom",
"system",
"hw/core",
"hw/char/pl011",
"hw/timer/hpet",
"trace",
"util",
"tests",
]

View file

@ -28,8 +28,8 @@ include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
// BQL is taken, either directly or via `BqlCell` and `BqlRefCell`.
// When bindings for character devices are introduced, this can be
// moved to the Opaque<> wrapper in src/chardev.rs.
unsafe impl Send for CharBackend {}
unsafe impl Sync for CharBackend {}
unsafe impl Send for CharFrontend {}
unsafe impl Sync for CharFrontend {}
// SAFETY: this is a pure data struct
unsafe impl Send for CoalescedMemoryRange {}

View file

@ -18,9 +18,7 @@
clippy::too_many_arguments
)]
use glib_sys::{
guint, GArray, GHashTable, GHashTableIter, GList, GPollFD, GPtrArray, GQueue, GSList, GSource,
};
use glib_sys::{guint, GArray, GHashTable, GHashTableIter, GPollFD, GPtrArray, GSList, GSource};
#[cfg(MESON)]
include!("bindings.inc.rs");

View file

@ -20,8 +20,8 @@
use common::Zeroable;
use glib_sys::{
gboolean, guint, GArray, GHashTable, GHashTableIter, GIOCondition, GList, GMainContext,
GPollFD, GPtrArray, GQueue, GSList, GSource, GSourceFunc,
gboolean, guint, GArray, GHashTable, GHashTableIter, GIOCondition, GMainContext, GPollFD,
GPtrArray, GSList, GSource, GSourceFunc,
};
#[cfg(MESON)]
@ -34,7 +34,7 @@ include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
// BQL is taken, either directly or via `BqlCell` and `BqlRefCell`.
// When bindings for character devices are introduced, this can be
// moved to the Opaque<> wrapper in src/chardev.rs.
unsafe impl Send for CharBackend {}
unsafe impl Sync for CharBackend {}
unsafe impl Send for CharFrontend {}
unsafe impl Sync for CharFrontend {}
unsafe impl Zeroable for CharBackend {}
unsafe impl Zeroable for CharFrontend {}

View file

@ -6,7 +6,7 @@
//!
//! Character devices in QEMU can run under the big QEMU lock or in a separate
//! `GMainContext`. Here we only support the former, because the bindings
//! enforce that the BQL is taken whenever the functions in [`CharBackend`] are
//! enforce that the BQL is taken whenever the functions in [`CharFrontend`] are
//! called.
use std::{
@ -32,25 +32,25 @@ pub struct Chardev(Opaque<bindings::Chardev>);
pub type ChardevClass = bindings::ChardevClass;
pub type Event = bindings::QEMUChrEvent;
/// A safe wrapper around [`bindings::CharBackend`], denoting the character
/// A safe wrapper around [`bindings::CharFrontend`], denoting the character
/// back-end that is used for example by a device. Compared to the
/// underlying C struct it adds BQL protection, and is marked as pinned
/// because the QOM object ([`bindings::Chardev`]) contains a pointer to
/// the `CharBackend`.
pub struct CharBackend {
inner: BqlRefCell<bindings::CharBackend>,
/// the `CharFrontend`.
pub struct CharFrontend {
inner: BqlRefCell<bindings::CharFrontend>,
_pin: PhantomPinned,
}
pub struct CharBackendMut<'a>(BqlRefMut<'a, bindings::CharBackend>);
pub struct CharFrontendMut<'a>(BqlRefMut<'a, bindings::CharFrontend>);
impl Write for CharBackendMut<'_> {
impl Write for CharFrontendMut<'_> {
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let chr: &mut bindings::CharBackend = &mut self.0;
let chr: &mut bindings::CharFrontend = &mut self.0;
let len = buf.len().try_into().unwrap();
let r = unsafe { bindings::qemu_chr_fe_write(addr_of_mut!(*chr), buf.as_ptr(), len) };
@ -58,7 +58,7 @@ impl Write for CharBackendMut<'_> {
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
let chr: &mut bindings::CharBackend = &mut self.0;
let chr: &mut bindings::CharFrontend = &mut self.0;
let len = buf.len().try_into().unwrap();
let r = unsafe { bindings::qemu_chr_fe_write_all(addr_of_mut!(*chr), buf.as_ptr(), len) };
@ -72,7 +72,7 @@ impl Write for CharBackendMut<'_> {
}
}
impl Debug for CharBackend {
impl Debug for CharFrontend {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// SAFETY: accessed just to print the values
let chr = self.inner.as_ptr();
@ -81,13 +81,13 @@ impl Debug for CharBackend {
}
// FIXME: use something like PinnedDrop from the pinned_init crate
impl Drop for CharBackend {
impl Drop for CharFrontend {
fn drop(&mut self) {
self.disable_handlers();
}
}
impl CharBackend {
impl CharFrontend {
/// Enable the front-end's character device handlers, if there is an
/// associated `Chardev`.
pub fn enable_handlers<
@ -198,7 +198,7 @@ impl CharBackend {
/// the big QEMU lock while the character device is borrowed, as
/// that might cause C code to write to the character device.
pub fn borrow_mut(&self) -> impl Write + '_ {
CharBackendMut(self.inner.borrow_mut())
CharFrontendMut(self.inner.borrow_mut())
}
/// Send a continuous stream of zero bits on the line if `enabled` is

View file

@ -22,7 +22,7 @@
use glib_sys::{
gboolean, guint, GArray, GByteArray, GHashTable, GHashTableIter, GIOCondition, GList,
GMainContext, GPollFD, GPtrArray, GQueue, GSList, GSource, GSourceFunc, GString,
GMainContext, GPollFD, GPtrArray, GSList, GSource, GSourceFunc, GString,
};
#[cfg(MESON)]

View file

@ -5,7 +5,7 @@
use std::{ffi::CStr, mem::size_of};
use bql::BqlRefCell;
use chardev::{CharBackend, Chardev, Event};
use chardev::{CharFrontend, Chardev, Event};
use common::{static_assert, uninit_field_mut};
use hwcore::{
Clock, ClockEvent, DeviceImpl, DeviceMethods, DeviceState, IRQState, InterruptSource,
@ -106,7 +106,7 @@ pub struct PL011State {
pub iomem: MemoryRegion,
#[doc(alias = "chr")]
#[property(rename = "chardev")]
pub char_backend: CharBackend,
pub char_frontend: CharFrontend,
pub regs: BqlRefCell<PL011Registers>,
/// QEMU interrupts
///
@ -240,7 +240,7 @@ impl PL011Registers {
}
let update = (self.line_control.send_break() != new_val.send_break()) && {
let break_enable = new_val.send_break();
let _ = device.char_backend.send_break(break_enable);
let _ = device.char_frontend.send_break(break_enable);
self.loopback_break(break_enable)
};
self.line_control = new_val;
@ -561,7 +561,7 @@ impl PL011State {
trace::trace_pl011_read(offset, result, c"");
if update_irq {
self.update();
self.char_backend.accept_input();
self.char_frontend.accept_input();
}
result.into()
}
@ -579,7 +579,7 @@ impl PL011State {
let ch: [u8; 1] = [value as u8];
// XXX this blocks entire thread. Rewrite to use
// qemu_chr_fe_write and background I/O callbacks
let _ = self.char_backend.write_all(&ch);
let _ = self.char_frontend.write_all(&ch);
}
update_irq = self.regs.borrow_mut().write(field, value as u32, self);
@ -645,7 +645,7 @@ impl PL011State {
}
fn realize(&self) -> util::Result<()> {
self.char_backend
self.char_frontend
.enable_handlers(self, Self::can_receive, Self::receive, Self::event);
Ok(())
}

View file

@ -20,9 +20,7 @@
use chardev::bindings::Chardev;
use common::Zeroable;
use glib_sys::{
GArray, GByteArray, GHashTable, GHashTableIter, GList, GPtrArray, GQueue, GSList, GString,
};
use glib_sys::{GArray, GByteArray, GHashTable, GHashTableIter, GList, GPtrArray, GSList, GString};
use migration::bindings::VMStateDescription;
use qom::bindings::ObjectClass;
use system::bindings::MemoryRegion;

View file

@ -156,7 +156,7 @@ impl_qdev_prop!(u64, qdev_prop_uint64, qdev_prop_bit64);
impl_qdev_prop!(usize, qdev_prop_usize);
impl_qdev_prop!(i32, qdev_prop_int32);
impl_qdev_prop!(i64, qdev_prop_int64);
impl_qdev_prop!(chardev::CharBackend, qdev_prop_chr);
impl_qdev_prop!(chardev::CharFrontend, qdev_prop_chr);
/// Trait to define device properties.
///

View file

@ -539,7 +539,7 @@ pub struct HPETState {
// Internal state
/// Capabilities that QEMU HPET supports.
/// bit 0: MSI (or FSB) support.
#[property(rename = "msi", bit = HPET_FLAG_MSI_SUPPORT_SHIFT as u8, default = false)]
#[property(rename = "msi", bit = HPET_FLAG_MSI_SUPPORT_SHIFT, default = false)]
flags: u32,
/// Offset of main counter relative to qemu clock.

View file

@ -19,7 +19,7 @@
)]
use common::Zeroable;
use glib_sys::{GHashTable, GHashTableIter, GList, GPtrArray, GQueue, GSList};
use glib_sys::{GHashTable, GHashTableIter, GPtrArray, GSList};
#[cfg(MESON)]
include!("bindings.inc.rs");

View file

@ -268,7 +268,7 @@ macro_rules! impl_vmstate_transparent {
($type:ty where $base:tt: VMState $($where:tt)*) => {
unsafe impl<$base> $crate::vmstate::VMState for $type where $base: $crate::vmstate::VMState $($where)* {
const BASE: $crate::vmstate::VMStateField = $crate::vmstate::VMStateField {
size: mem::size_of::<$type>(),
size: ::core::mem::size_of::<$type>(),
..<$base as $crate::vmstate::VMState>::BASE
};
const VARRAY_FLAG: $crate::bindings::VMStateFlags = <$base as $crate::vmstate::VMState>::VARRAY_FLAG;
@ -282,6 +282,7 @@ impl_vmstate_transparent!(std::cell::Cell<T> where T: VMState);
impl_vmstate_transparent!(std::cell::UnsafeCell<T> where T: VMState);
impl_vmstate_transparent!(std::pin::Pin<T> where T: VMState);
impl_vmstate_transparent!(common::Opaque<T> where T: VMState);
impl_vmstate_transparent!(std::mem::ManuallyDrop<T> where T: VMState);
#[macro_export]
macro_rules! impl_vmstate_bitsized {

View file

@ -262,12 +262,25 @@ fn derive_device_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream
},
)?;
let field_ty = field.ty.clone();
let qdev_prop = if bitnr.is_none() {
quote! { <#field_ty as ::hwcore::QDevProp>::BASE_INFO }
let (qdev_prop, bitval) = if let Some(bitval) = bitnr {
(
quote! { <#field_ty as ::hwcore::QDevProp>::BIT_INFO },
quote! {
{
const {
assert!(#bitval >= 0 && #bitval < #field_ty::BITS as _,
"bit number exceeds type bits range");
}
#bitval as u8
}
},
)
} else {
quote! { <#field_ty as ::hwcore::QDevProp>::BIT_INFO }
(
quote! { <#field_ty as ::hwcore::QDevProp>::BASE_INFO },
quote! { 0 },
)
};
let bitnr = bitnr.unwrap_or(syn::Expr::Verbatim(quote! { 0 }));
let set_default = defval.is_some();
let defval = defval.unwrap_or(syn::Expr::Verbatim(quote! { 0 }));
properties_expanded.push(quote! {
@ -275,7 +288,7 @@ fn derive_device_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream
name: ::std::ffi::CStr::as_ptr(#prop_name),
info: #qdev_prop,
offset: ::core::mem::offset_of!(#name, #field_name) as isize,
bitnr: #bitnr,
bitnr: #bitval,
set_default: #set_default,
defval: ::hwcore::bindings::Property__bindgen_ty_1 { u: #defval as u64 },
..::common::Zeroable::ZERO

View file

@ -179,7 +179,10 @@ fn test_derive_device() {
name: ::std::ffi::CStr::as_ptr(c"flags"),
info: <u32 as ::hwcore::QDevProp>::BIT_INFO,
offset: ::core::mem::offset_of!(DummyState, flags) as isize,
bitnr: 3,
bitnr : {
const { assert!(3 >= 0 && 3 < u32::BITS as _ , "bit number exceeds type bits range"); }
3 as u8
},
set_default: false,
defval: ::hwcore::bindings::Property__bindgen_ty_1 { u: 0 as u64 },
..::common::Zeroable::ZERO
@ -207,7 +210,10 @@ fn test_derive_device() {
name: ::std::ffi::CStr::as_ptr(c"flags"),
info: <u32 as ::hwcore::QDevProp>::BIT_INFO,
offset: ::core::mem::offset_of!(DummyState, flags) as isize,
bitnr: 3,
bitnr : {
const { assert!(3 >= 0 && 3 < u32::BITS as _ , "bit number exceeds type bits range"); }
3 as u8
},
set_default: true,
defval: ::hwcore::bindings::Property__bindgen_ty_1 { u: true as u64 },
..::common::Zeroable::ZERO
@ -235,7 +241,10 @@ fn test_derive_device() {
name: ::std::ffi::CStr::as_ptr(c"msi"),
info: <u64 as ::hwcore::QDevProp>::BIT_INFO,
offset: ::core::mem::offset_of!(DummyState, flags) as isize,
bitnr: 3,
bitnr : {
const { assert!(3 >= 0 && 3 < u64::BITS as _ , "bit number exceeds type bits range"); }
3 as u8
},
set_default: true,
defval: ::hwcore::bindings::Property__bindgen_ty_1 { u: false as u64 },
..::common::Zeroable::ZERO

Some files were not shown because too many files have changed in this diff Show more