__thread struct kvm_cpu *current_kvm_cpu;
static int kvm_run_wrapper;
-extern int active_console;
extern int debug_iodelay;
bool do_debug_print = false;
kvm->cfg.console = DEFAULT_CONSOLE;
if (!strncmp(kvm->cfg.console, "virtio", 6))
- active_console = CONSOLE_VIRTIO;
+ kvm->cfg.active_console = CONSOLE_VIRTIO;
else if (!strncmp(kvm->cfg.console, "serial", 6))
- active_console = CONSOLE_8250;
+ kvm->cfg.active_console = CONSOLE_8250;
else if (!strncmp(kvm->cfg.console, "hv", 2))
- active_console = CONSOLE_HV;
+ kvm->cfg.active_console = CONSOLE_HV;
else
pr_warning("No console!");
}
- if (active_console == CONSOLE_VIRTIO)
+ if (kvm->cfg.active_console == CONSOLE_VIRTIO)
virtio_console__init(kvm);
if (kvm->cfg.virtio_rng)
},
};
-static void serial8250_flush_tx(struct serial8250_device *dev)
+static void serial8250_flush_tx(struct kvm *kvm, struct serial8250_device *dev)
{
dev->lsr |= UART_LSR_TEMT | UART_LSR_THRE;
if (dev->txcnt) {
- term_putc(CONSOLE_8250, dev->txbuf, dev->txcnt, dev->id);
+ if (kvm->cfg.active_console == CONSOLE_8250)
+ term_putc(dev->txbuf, dev->txcnt, dev->id);
dev->txcnt = 0;
}
}
* here.
*/
if (!(dev->ier & UART_IER_THRI))
- serial8250_flush_tx(dev);
+ serial8250_flush_tx(kvm, dev);
}
#define SYSRQ_PENDING_NONE 0
* should give the kernel the desired pause. That also flushes
* the tx fifo to the terminal.
*/
- serial8250_flush_tx(dev);
+ serial8250_flush_tx(kvm, dev);
if (dev->mcr & UART_MCR_LOOP)
return;
return;
}
- while (term_readable(CONSOLE_8250, dev->id) &&
+ if (kvm->cfg.active_console != CONSOLE_8250)
+ return;
+
+ while (term_readable(dev->id) &&
dev->rxcnt < FIFO_LEN) {
- c = term_getc(CONSOLE_8250, dev->id);
+ c = term_getc(dev->id);
if (c < 0)
break;
u8 image_count;
u8 num_net_devices;
bool virtio_rng;
+ int active_console;
const char *kernel_cmdline;
const char *kernel_filename;
const char *vmlinux_filename;
#define CONSOLE_VIRTIO 2
#define CONSOLE_HV 3
-int term_putc_iov(int who, struct iovec *iov, int iovcnt, int term);
-int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term);
-int term_putc(int who, char *addr, int cnt, int term);
-int term_getc(int who, int term);
+int term_putc_iov(struct iovec *iov, int iovcnt, int term);
+int term_getc_iov(struct iovec *iov, int iovcnt, int term);
+int term_putc(char *addr, int cnt, int term);
+int term_getc(int term);
-bool term_readable(int who, int term);
+bool term_readable(int term);
void term_set_tty(int term);
void term_init(void);
do {
int ret;
- ret = term_putc_iov(CONSOLE_HV, &iov, 1, 0);
+ if (kvm->cfg.active_console == CONSOLE_HV)
+ ret = term_putc_iov(&iov, 1, 0);
+ else
+ ret = 0;
if (ret < 0) {
die("term_putc_iov error %d!\n", errno);
}
union hv_chario data;
struct iovec iov;
- if (term_readable(CONSOLE_HV, 0)) {
+ if (kvm->cfg.active_console != CONSOLE_HV)
+ return H_SUCCESS;
+
+ if (term_readable(0)) {
iov.iov_base = data.buf;
iov.iov_len = 16;
- *len = term_getc_iov(CONSOLE_HV, &iov, 1, 0);
+ *len = term_getc_iov(&iov, 1, 0);
*char0_7 = be64_to_cpu(data.a.char0_7);
*char8_15 = be64_to_cpu(data.a.char8_15);
} else {
void spapr_hvcons_poll(struct kvm *kvm)
{
- if (term_readable(CONSOLE_HV, 0)) {
+ if (term_readable(0)) {
/*
* We can inject an IRQ to guest here if we want. The guest
* will happily poll, though, so not required.
int term_escape_char = 0x01; /* ctrl-a is used for escape */
bool term_got_escape = false;
-int active_console;
-
int term_fds[4][2];
-int term_getc(int who, int term)
+int term_getc(int term)
{
unsigned char c;
- if (who != active_console)
- return -1;
if (read_in_full(term_fds[term][TERM_FD_IN], &c, 1) < 0)
return -1;
return c;
}
-int term_putc(int who, char *addr, int cnt, int term)
+int term_putc(char *addr, int cnt, int term)
{
int ret;
- if (who != active_console)
- return -1;
-
while (cnt--) {
ret = write(term_fds[term][TERM_FD_OUT], addr++, 1);
if (ret < 0)
return cnt;
}
-int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term)
+int term_getc_iov(struct iovec *iov, int iovcnt, int term)
{
int c;
- if (who != active_console)
- return 0;
-
- c = term_getc(who, term);
+ c = term_getc(term);
if (c < 0)
return 0;
return sizeof(char);
}
-int term_putc_iov(int who, struct iovec *iov, int iovcnt, int term)
+int term_putc_iov(struct iovec *iov, int iovcnt, int term)
{
- if (who != active_console)
- return 0;
-
return writev(term_fds[term][TERM_FD_OUT], iov, iovcnt);
}
-bool term_readable(int who, int term)
+bool term_readable(int term)
{
struct pollfd pollfd = (struct pollfd) {
.fd = term_fds[term][TERM_FD_IN],
.revents = 0,
};
- if (who != active_console)
- return false;
-
return poll(&pollfd, 1, 0) > 0;
}
u16 head;
int len;
+ if (kvm->cfg.active_console != CONSOLE_VIRTIO)
+ return;
+
mutex_lock(&cdev.mutex);
vq = param;
- if (term_readable(CONSOLE_VIRTIO, 0) && virt_queue__available(vq)) {
+ if (term_readable(0) && virt_queue__available(vq)) {
head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
- len = term_getc_iov(CONSOLE_VIRTIO, iov, in, 0);
+ len = term_getc_iov(iov, in, 0);
virt_queue__set_used_elem(vq, head, len);
cdev.vdev.ops->signal_vq(kvm, &cdev.vdev, vq - cdev.vqs);
}
while (virt_queue__available(vq)) {
head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
- len = term_putc_iov(CONSOLE_VIRTIO, iov, out, 0);
+ if (kvm->cfg.active_console == CONSOLE_VIRTIO)
+ len = term_putc_iov(iov, out, 0);
+ else
+ len = 0;
virt_queue__set_used_elem(vq, head, len);
}