Commit 2932c9eb authored by Pekka Enberg's avatar Pekka Enberg Committed by Will Deacon
Browse files

kvm tools: Make 8250 code thread-safe



In preparation for threaded execution, make 8250 code thread safe by
introducing a per-device mutex.

Cc: Asias He <asias.hejun@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: default avatarPekka Enberg <penberg@kernel.org>
parent 5c3d55fa
......@@ -8,8 +8,11 @@
#include <linux/serial_reg.h>
#include <pthread.h>
struct serial8250_device {
pthread_mutex_t mutex;
uint16_t iobase;
uint8_t irq;
......@@ -29,6 +32,8 @@ struct serial8250_device {
static struct serial8250_device devices[] = {
/* ttyS0 */
[0] = {
.mutex = PTHREAD_MUTEX_INITIALIZER,
.iobase = 0x3f8,
.irq = 4,
......@@ -39,6 +44,8 @@ static struct serial8250_device devices[] = {
},
/* ttyS1 */
[1] = {
.mutex = PTHREAD_MUTEX_INITIALIZER,
.iobase = 0x2f8,
.irq = 3,
......@@ -46,6 +53,8 @@ static struct serial8250_device devices[] = {
},
/* ttyS2 */
[2] = {
.mutex = PTHREAD_MUTEX_INITIALIZER,
.iobase = 0x3e8,
.irq = 4,
......@@ -107,6 +116,9 @@ void serial8250__inject_interrupt(struct kvm *self)
{
struct serial8250_device *dev = &devices[0];
if (pthread_mutex_lock(&dev->mutex) < 0)
die("pthread_mutex_lock");
serial8250__receive(self, dev);
if (dev->ier & UART_IER_RDI && dev->lsr & UART_LSR_DR)
......@@ -120,6 +132,9 @@ void serial8250__inject_interrupt(struct kvm *self)
kvm__irq_line(self, dev->irq, 0);
kvm__irq_line(self, dev->irq, 1);
}
if (pthread_mutex_unlock(&dev->mutex) < 0)
die("pthread_mutex_unlock");
}
void serial8250__inject_sysrq(struct kvm *self)
......@@ -144,11 +159,15 @@ static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size
{
struct serial8250_device *dev;
uint16_t offset;
bool ret = true;
dev = find_device(port);
if (!dev)
return false;
if (pthread_mutex_lock(&dev->mutex) < 0)
die("pthread_mutex_lock");
offset = port - dev->iobase;
if (dev->lcr & UART_LCR_DLAB) {
......@@ -178,7 +197,8 @@ static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size
dev->scr = ioport__read8(data);
break;
default:
return false;
ret = false;
goto out_unlock;
}
} else {
switch (offset) {
......@@ -213,31 +233,43 @@ static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size
dev->scr = ioport__read8(data);
break;
default:
return false;
ret = false;
goto out_unlock;
}
}
return true;
out_unlock:
if (pthread_mutex_unlock(&dev->mutex) < 0)
die("pthread_mutex_unlock");
return ret;
}
static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
{
struct serial8250_device *dev;
uint16_t offset;
bool ret = true;
dev = find_device(port);
if (!dev)
return false;
if (pthread_mutex_lock(&dev->mutex) < 0)
die("pthread_mutex_lock");
offset = port - dev->iobase;
if (dev->lcr & UART_LCR_DLAB) {
switch (offset) {
case UART_DLL:
ioport__write8(data, dev->dll);
return true;
goto out_unlock;
case UART_DLM:
ioport__write8(data, dev->dlm);
return true;
goto out_unlock;
default:
break;
}
......@@ -247,10 +279,12 @@ static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size,
ioport__write8(data, dev->rbr);
dev->lsr &= ~UART_LSR_DR;
dev->iir = UART_IIR_NO_INT;
return true;
goto out_unlock;
case UART_IER:
ioport__write8(data, dev->ier);
return true;
goto out_unlock;
default:
break;
}
......@@ -283,9 +317,14 @@ static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size,
ioport__write8(data, dev->scr);
break;
default:
return false;
ret = false;
goto out_unlock;
}
return true;
out_unlock:
if (pthread_mutex_unlock(&dev->mutex) < 0)
die("pthread_mutex_unlock");
return ret;
}
static struct ioport_operations serial8250_ops = {
......
......@@ -41,6 +41,7 @@ OBJS += bios.o
OBJS += bios/bios.o
LIBS += -lrt
LIBS += -lpthread
# Additional ARCH settings for x86
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment