Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-f…
Browse files Browse the repository at this point in the history
…or-linus

* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
  virtio: Add transport feature handling stub for virtio_ring.
  virtio: Rename set_features to finalize_features
  virtio: Formally reserve bits 28-31 to be 'transport' features.
  s390: use virtio_console for KVM on s390
  virtio: console as a config option
  virtio_console: use virtqueue notification for hvc_console
  hvc_console: rework setup to replace irq functions with callbacks
  virtio_blk: check for hardsector size from host
  virtio: Use bus_type probe and remove methods
  virtio: don't always force a notification when ring is full
  virtio: clarify that ABI is usable by any implementations
  virtio: Recycle unused recv buffer pages for large skbs in net driver
  virtio net: Allow receiving SG packets
  virtio net: Add ethtool ops for SG/GSO
  virtio: fix virtio_net xmit of freed skb bug
  • Loading branch information
Linus Torvalds committed Jul 25, 2008
2 parents ed9559d + e34f872 commit 832fe9c
Show file tree
Hide file tree
Showing 28 changed files with 385 additions and 124 deletions.
1 change: 1 addition & 0 deletions arch/s390/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ bool "s390 guest support (EXPERIMENTAL)"
depends on 64BIT && EXPERIMENTAL
select VIRTIO
select VIRTIO_RING
select VIRTIO_CONSOLE
help
Select this option if you want to run the kernel under s390 linux
endmenu
Expand Down
4 changes: 3 additions & 1 deletion arch/s390/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include <asm/sections.h>
#include <asm/ebcdic.h>
#include <asm/compat.h>
#include <asm/kvm_virtio.h>

long psw_kernel_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
Expand Down Expand Up @@ -766,7 +767,8 @@ setup_arch(char **cmdline_p)
printk("We are running under VM (64 bit mode)\n");
else if (MACHINE_IS_KVM) {
printk("We are running under KVM (64 bit mode)\n");
add_preferred_console("ttyS", 1, NULL);
add_preferred_console("hvc", 0, NULL);
s390_virtio_console_init();
} else
printk("We are running native (64 bit mode)\n");
#endif /* CONFIG_64BIT */
Expand Down
10 changes: 9 additions & 1 deletion drivers/block/virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static int virtblk_probe(struct virtio_device *vdev)
int err;
u64 cap;
u32 v;
u32 blk_size;

if (index_to_minor(index) >= 1 << MINORBITS)
return -ENOSPC;
Expand Down Expand Up @@ -290,6 +291,13 @@ static int virtblk_probe(struct virtio_device *vdev)
if (!err)
blk_queue_max_hw_segments(vblk->disk->queue, v);

/* Host can optionally specify the block size of the device */
err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE,
offsetof(struct virtio_blk_config, blk_size),
&blk_size);
if (!err)
blk_queue_hardsect_size(vblk->disk->queue, blk_size);

add_disk(vblk->disk);
return 0;

Expand Down Expand Up @@ -330,7 +338,7 @@ static struct virtio_device_id id_table[] = {

static unsigned int features[] = {
VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO,
VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
};

static struct virtio_driver virtio_blk = {
Expand Down
11 changes: 10 additions & 1 deletion drivers/char/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,14 @@ config HVC_DRIVER
It will automatically be selected if one of the back-end console drivers
is selected.

config HVC_IRQ
bool

config HVC_CONSOLE
bool "pSeries Hypervisor Virtual Console support"
depends on PPC_PSERIES
select HVC_DRIVER
select HVC_IRQ
help
pSeries machines when partitioned support a hypervisor virtual
console. This driver allows each pSeries partition to have a console
Expand All @@ -593,6 +596,7 @@ config HVC_ISERIES
depends on PPC_ISERIES
default y
select HVC_DRIVER
select HVC_IRQ
help
iSeries machines support a hypervisor virtual console.

Expand All @@ -614,13 +618,18 @@ config HVC_XEN
bool "Xen Hypervisor Console support"
depends on XEN
select HVC_DRIVER
select HVC_IRQ
default y
help
Xen virtual console device driver

config VIRTIO_CONSOLE
bool
tristate "Virtio console"
depends on VIRTIO
select HVC_DRIVER
help
Virtio console for use with lguest and other hypervisors.


config HVCS
tristate "IBM Hypervisor Virtual Console Server support"
Expand Down
1 change: 1 addition & 0 deletions drivers/char/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
obj-$(CONFIG_HVC_IRQ) += hvc_irq.o
obj-$(CONFIG_HVC_XEN) += hvc_xen.o
obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
Expand Down
85 changes: 22 additions & 63 deletions drivers/char/hvc_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <linux/init.h>
#include <linux/kbd_kern.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/module.h>
Expand Down Expand Up @@ -75,23 +74,6 @@ static int hvc_init(void);
static int sysrq_pressed;
#endif

struct hvc_struct {
spinlock_t lock;
int index;
struct tty_struct *tty;
unsigned int count;
int do_wakeup;
char *outbuf;
int outbuf_size;
int n_outbuf;
uint32_t vtermno;
struct hv_ops *ops;
int irq_requested;
int irq;
struct list_head next;
struct kref kref; /* ref count & hvc_struct lifetime */
};

/* dynamic list of hvc_struct instances */
static LIST_HEAD(hvc_structs);

Expand Down Expand Up @@ -298,27 +280,15 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)

return 0;
}
EXPORT_SYMBOL_GPL(hvc_instantiate);

/* Wake the sleeping khvcd */
static void hvc_kick(void)
void hvc_kick(void)
{
hvc_kicked = 1;
wake_up_process(hvc_task);
}

static int hvc_poll(struct hvc_struct *hp);

/*
* NOTE: This API isn't used if the console adapter doesn't support interrupts.
* In this case the console is poll driven.
*/
static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
{
/* if hvc_poll request a repoll, then kick the hvcd thread */
if (hvc_poll(dev_instance))
hvc_kick();
return IRQ_HANDLED;
}
EXPORT_SYMBOL_GPL(hvc_kick);

static void hvc_unthrottle(struct tty_struct *tty)
{
Expand All @@ -333,7 +303,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
{
struct hvc_struct *hp;
unsigned long flags;
int irq = 0;
int rc = 0;

/* Auto increments kref reference if found. */
Expand All @@ -352,26 +321,22 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */

hp->tty = tty;
/* Save for request_irq outside of spin_lock. */
irq = hp->irq;
if (irq)
hp->irq_requested = 1;

if (hp->ops->notifier_add)
rc = hp->ops->notifier_add(hp, hp->data);

spin_unlock_irqrestore(&hp->lock, flags);
/* check error, fallback to non-irq */
if (irq)
rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, "hvc_console", hp);


/*
* If the request_irq() fails and we return an error. The tty layer
* If the notifier fails we return an error. The tty layer
* will call hvc_close() after a failed open but we don't want to clean
* up there so we'll clean up here and clear out the previously set
* tty fields and return the kref reference.
*/
if (rc) {
spin_lock_irqsave(&hp->lock, flags);
hp->tty = NULL;
hp->irq_requested = 0;
spin_unlock_irqrestore(&hp->lock, flags);
tty->driver_data = NULL;
kref_put(&hp->kref, destroy_hvc_struct);
Expand All @@ -386,7 +351,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
static void hvc_close(struct tty_struct *tty, struct file * filp)
{
struct hvc_struct *hp;
int irq = 0;
unsigned long flags;

if (tty_hung_up_p(filp))
Expand All @@ -404,9 +368,8 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
spin_lock_irqsave(&hp->lock, flags);

if (--hp->count == 0) {
if (hp->irq_requested)
irq = hp->irq;
hp->irq_requested = 0;
if (hp->ops->notifier_del)
hp->ops->notifier_del(hp, hp->data);

/* We are done with the tty pointer now. */
hp->tty = NULL;
Expand All @@ -418,10 +381,6 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
* waking periodically to check chars_in_buffer().
*/
tty_wait_until_sent(tty, HVC_CLOSE_WAIT);

if (irq)
free_irq(irq, hp);

} else {
if (hp->count < 0)
printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
Expand All @@ -436,7 +395,6 @@ static void hvc_hangup(struct tty_struct *tty)
{
struct hvc_struct *hp = tty->driver_data;
unsigned long flags;
int irq = 0;
int temp_open_count;

if (!hp)
Expand All @@ -458,13 +416,12 @@ static void hvc_hangup(struct tty_struct *tty)
hp->count = 0;
hp->n_outbuf = 0;
hp->tty = NULL;
if (hp->irq_requested)
/* Saved for use outside of spin_lock. */
irq = hp->irq;
hp->irq_requested = 0;

if (hp->ops->notifier_del)
hp->ops->notifier_del(hp, hp->data);

spin_unlock_irqrestore(&hp->lock, flags);
if (irq)
free_irq(irq, hp);

while(temp_open_count) {
--temp_open_count;
kref_put(&hp->kref, destroy_hvc_struct);
Expand Down Expand Up @@ -575,7 +532,7 @@ static u32 timeout = MIN_TIMEOUT;
#define HVC_POLL_READ 0x00000001
#define HVC_POLL_WRITE 0x00000002

static int hvc_poll(struct hvc_struct *hp)
int hvc_poll(struct hvc_struct *hp)
{
struct tty_struct *tty;
int i, n, poll_mask = 0;
Expand All @@ -602,10 +559,10 @@ static int hvc_poll(struct hvc_struct *hp)
if (test_bit(TTY_THROTTLED, &tty->flags))
goto throttled;

/* If we aren't interrupt driven and aren't throttled, we always
/* If we aren't notifier driven and aren't throttled, we always
* request a reschedule
*/
if (hp->irq == 0)
if (!hp->irq_requested)
poll_mask |= HVC_POLL_READ;

/* Read data if any */
Expand Down Expand Up @@ -674,6 +631,7 @@ static int hvc_poll(struct hvc_struct *hp)

return poll_mask;
}
EXPORT_SYMBOL_GPL(hvc_poll);

/*
* This kthread is either polling or interrupt driven. This is determined by
Expand Down Expand Up @@ -733,7 +691,7 @@ static const struct tty_operations hvc_ops = {
.chars_in_buffer = hvc_chars_in_buffer,
};

struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
struct hv_ops *ops, int outbuf_size)
{
struct hvc_struct *hp;
Expand All @@ -754,7 +712,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
memset(hp, 0x00, sizeof(*hp));

hp->vtermno = vtermno;
hp->irq = irq;
hp->data = data;
hp->ops = ops;
hp->outbuf_size = outbuf_size;
hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
Expand Down Expand Up @@ -784,6 +742,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,

return hp;
}
EXPORT_SYMBOL_GPL(hvc_alloc);

int __devexit hvc_remove(struct hvc_struct *hp)
{
Expand Down
35 changes: 31 additions & 4 deletions drivers/char/hvc_console.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#ifndef HVC_CONSOLE_H
#define HVC_CONSOLE_H
#include <linux/kref.h>

/*
* This is the max number of console adapters that can/will be found as
Expand All @@ -42,24 +43,50 @@
*/
#define HVC_ALLOC_TTY_ADAPTERS 8

struct hvc_struct {
spinlock_t lock;
int index;
struct tty_struct *tty;
unsigned int count;
int do_wakeup;
char *outbuf;
int outbuf_size;
int n_outbuf;
uint32_t vtermno;
struct hv_ops *ops;
int irq_requested;
int data;
struct list_head next;
struct kref kref; /* ref count & hvc_struct lifetime */
};

/* implemented by a low level driver */
struct hv_ops {
int (*get_chars)(uint32_t vtermno, char *buf, int count);
int (*put_chars)(uint32_t vtermno, const char *buf, int count);
};

struct hvc_struct;
/* Callbacks for notification. Called in open and close */
int (*notifier_add)(struct hvc_struct *hp, int irq);
void (*notifier_del)(struct hvc_struct *hp, int irq);
};

/* Register a vterm and a slot index for use as a console (console_init) */
extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);

/* register a vterm for hvc tty operation (module_init or hotplug add) */
extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data,
struct hv_ops *ops, int outbuf_size);
/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
extern int __devexit hvc_remove(struct hvc_struct *hp);

/* data available */
int hvc_poll(struct hvc_struct *hp);
void hvc_kick(void);

/* default notifier for irq based notification */
extern int notifier_add_irq(struct hvc_struct *hp, int data);
extern void notifier_del_irq(struct hvc_struct *hp, int data);


#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
#include <asm/xmon.h>
Expand Down
Loading

0 comments on commit 832fe9c

Please sign in to comment.