diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-30 20:37:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-30 20:37:25 -0500 |
commit | ab70537c32a3245325b48774664da588904e47f2 (patch) | |
tree | fdb4447e520bd34dd8696fdd3b976075414d8555 /drivers | |
parent | 14a3c4ab0e58d143c7928c9eb2f2610205e13bf2 (diff) | |
parent | bda53cd510b6777ced652ba279020bb7b414b744 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
lguest: struct device - replace bus_id with dev_name()
lguest: move the initial guest page table creation code to the host
kvm-s390: implement config_changed for virtio on s390
virtio_console: support console resizing
virtio: add PCI device release() function
virtio_blk: fix type warning
virtio: block: dynamic maximum segments
virtio: set max_segment_size and max_sectors to infinite.
virtio: avoid implicit use of Linux page size in balloon interface
virtio: hand virtio ring alignment as argument to vring_new_virtqueue
virtio: use KVM_S390_VIRTIO_RING_ALIGN instead of relying on pagesize
virtio: use LGUEST_VRING_ALIGN instead of relying on pagesize
virtio: Don't use PAGE_SIZE for vring alignment in virtio_pci.
virtio: rename 'pagesize' arg to vring_init/vring_size
virtio: Don't use PAGE_SIZE in virtio_pci.c
virtio: struct device - replace bus_id with dev_name(), dev_set_name()
virtio-pci queue allocation not page-aligned
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/virtio_blk.c | 41 | ||||
-rw-r--r-- | drivers/char/hvc_console.c | 1 | ||||
-rw-r--r-- | drivers/char/virtio_console.c | 30 | ||||
-rw-r--r-- | drivers/lguest/lg.h | 2 | ||||
-rw-r--r-- | drivers/lguest/lguest_device.c | 8 | ||||
-rw-r--r-- | drivers/lguest/lguest_user.c | 13 | ||||
-rw-r--r-- | drivers/lguest/page_tables.c | 72 | ||||
-rw-r--r-- | drivers/s390/kvm/kvm_virtio.c | 34 | ||||
-rw-r--r-- | drivers/virtio/virtio.c | 2 | ||||
-rw-r--r-- | drivers/virtio/virtio_balloon.c | 13 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci.c | 43 | ||||
-rw-r--r-- | drivers/virtio/virtio_ring.c | 3 |
12 files changed, 206 insertions, 56 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index f151592ecf73..5d34764c8a87 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/virtio_blk.h> | 6 | #include <linux/virtio_blk.h> |
7 | #include <linux/scatterlist.h> | 7 | #include <linux/scatterlist.h> |
8 | 8 | ||
9 | #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) | ||
10 | #define PART_BITS 4 | 9 | #define PART_BITS 4 |
11 | 10 | ||
12 | static int major, index; | 11 | static int major, index; |
@@ -26,8 +25,11 @@ struct virtio_blk | |||
26 | 25 | ||
27 | mempool_t *pool; | 26 | mempool_t *pool; |
28 | 27 | ||
28 | /* What host tells us, plus 2 for header & tailer. */ | ||
29 | unsigned int sg_elems; | ||
30 | |||
29 | /* Scatterlist: can be too big for stack. */ | 31 | /* Scatterlist: can be too big for stack. */ |
30 | struct scatterlist sg[VIRTIO_MAX_SG]; | 32 | struct scatterlist sg[/*sg_elems*/]; |
31 | }; | 33 | }; |
32 | 34 | ||
33 | struct virtblk_req | 35 | struct virtblk_req |
@@ -97,8 +99,6 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | |||
97 | if (blk_barrier_rq(vbr->req)) | 99 | if (blk_barrier_rq(vbr->req)) |
98 | vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER; | 100 | vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER; |
99 | 101 | ||
100 | /* This init could be done at vblk creation time */ | ||
101 | sg_init_table(vblk->sg, VIRTIO_MAX_SG); | ||
102 | sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr)); | 102 | sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr)); |
103 | num = blk_rq_map_sg(q, vbr->req, vblk->sg+1); | 103 | num = blk_rq_map_sg(q, vbr->req, vblk->sg+1); |
104 | sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status)); | 104 | sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status)); |
@@ -130,7 +130,7 @@ static void do_virtblk_request(struct request_queue *q) | |||
130 | 130 | ||
131 | while ((req = elv_next_request(q)) != NULL) { | 131 | while ((req = elv_next_request(q)) != NULL) { |
132 | vblk = req->rq_disk->private_data; | 132 | vblk = req->rq_disk->private_data; |
133 | BUG_ON(req->nr_phys_segments > ARRAY_SIZE(vblk->sg)); | 133 | BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); |
134 | 134 | ||
135 | /* If this request fails, stop queue and wait for something to | 135 | /* If this request fails, stop queue and wait for something to |
136 | finish to restart it. */ | 136 | finish to restart it. */ |
@@ -196,12 +196,22 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
196 | int err; | 196 | int err; |
197 | u64 cap; | 197 | u64 cap; |
198 | u32 v; | 198 | u32 v; |
199 | u32 blk_size; | 199 | u32 blk_size, sg_elems; |
200 | 200 | ||
201 | if (index_to_minor(index) >= 1 << MINORBITS) | 201 | if (index_to_minor(index) >= 1 << MINORBITS) |
202 | return -ENOSPC; | 202 | return -ENOSPC; |
203 | 203 | ||
204 | vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); | 204 | /* We need to know how many segments before we allocate. */ |
205 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, | ||
206 | offsetof(struct virtio_blk_config, seg_max), | ||
207 | &sg_elems); | ||
208 | if (err) | ||
209 | sg_elems = 1; | ||
210 | |||
211 | /* We need an extra sg elements at head and tail. */ | ||
212 | sg_elems += 2; | ||
213 | vdev->priv = vblk = kmalloc(sizeof(*vblk) + | ||
214 | sizeof(vblk->sg[0]) * sg_elems, GFP_KERNEL); | ||
205 | if (!vblk) { | 215 | if (!vblk) { |
206 | err = -ENOMEM; | 216 | err = -ENOMEM; |
207 | goto out; | 217 | goto out; |
@@ -210,6 +220,8 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
210 | INIT_LIST_HEAD(&vblk->reqs); | 220 | INIT_LIST_HEAD(&vblk->reqs); |
211 | spin_lock_init(&vblk->lock); | 221 | spin_lock_init(&vblk->lock); |
212 | vblk->vdev = vdev; | 222 | vblk->vdev = vdev; |
223 | vblk->sg_elems = sg_elems; | ||
224 | sg_init_table(vblk->sg, vblk->sg_elems); | ||
213 | 225 | ||
214 | /* We expect one virtqueue, for output. */ | 226 | /* We expect one virtqueue, for output. */ |
215 | vblk->vq = vdev->config->find_vq(vdev, 0, blk_done); | 227 | vblk->vq = vdev->config->find_vq(vdev, 0, blk_done); |
@@ -279,6 +291,13 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
279 | } | 291 | } |
280 | set_capacity(vblk->disk, cap); | 292 | set_capacity(vblk->disk, cap); |
281 | 293 | ||
294 | /* We can handle whatever the host told us to handle. */ | ||
295 | blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2); | ||
296 | blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2); | ||
297 | |||
298 | /* No real sector limit. */ | ||
299 | blk_queue_max_sectors(vblk->disk->queue, -1U); | ||
300 | |||
282 | /* Host can optionally specify maximum segment size and number of | 301 | /* Host can optionally specify maximum segment size and number of |
283 | * segments. */ | 302 | * segments. */ |
284 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, | 303 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, |
@@ -286,12 +305,8 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
286 | &v); | 305 | &v); |
287 | if (!err) | 306 | if (!err) |
288 | blk_queue_max_segment_size(vblk->disk->queue, v); | 307 | blk_queue_max_segment_size(vblk->disk->queue, v); |
289 | 308 | else | |
290 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, | 309 | blk_queue_max_segment_size(vblk->disk->queue, -1U); |
291 | offsetof(struct virtio_blk_config, seg_max), | ||
292 | &v); | ||
293 | if (!err) | ||
294 | blk_queue_max_hw_segments(vblk->disk->queue, v); | ||
295 | 310 | ||
296 | /* Host can optionally specify the block size of the device */ | 311 | /* Host can optionally specify the block size of the device */ |
297 | err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, | 312 | err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index fb57f67bb427..0587b66d6fc7 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -695,6 +695,7 @@ void hvc_resize(struct hvc_struct *hp, struct winsize ws) | |||
695 | hp->ws = ws; | 695 | hp->ws = ws; |
696 | schedule_work(&hp->tty_resize); | 696 | schedule_work(&hp->tty_resize); |
697 | } | 697 | } |
698 | EXPORT_SYMBOL_GPL(hvc_resize); | ||
698 | 699 | ||
699 | /* | 700 | /* |
700 | * This kthread is either polling or interrupt driven. This is determined by | 701 | * This kthread is either polling or interrupt driven. This is determined by |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 3fb0d2c88ba5..ff6f5a4b58fb 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -138,12 +138,33 @@ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int)) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * virtio console configuration. This supports: | ||
142 | * - console resize | ||
143 | */ | ||
144 | static void virtcons_apply_config(struct virtio_device *dev) | ||
145 | { | ||
146 | struct winsize ws; | ||
147 | |||
148 | if (virtio_has_feature(dev, VIRTIO_CONSOLE_F_SIZE)) { | ||
149 | dev->config->get(dev, | ||
150 | offsetof(struct virtio_console_config, cols), | ||
151 | &ws.ws_col, sizeof(u16)); | ||
152 | dev->config->get(dev, | ||
153 | offsetof(struct virtio_console_config, rows), | ||
154 | &ws.ws_row, sizeof(u16)); | ||
155 | hvc_resize(hvc, ws); | ||
156 | } | ||
157 | } | ||
158 | |||
159 | /* | ||
141 | * we support only one console, the hvc struct is a global var | 160 | * we support only one console, the hvc struct is a global var |
142 | * There is no need to do anything | 161 | * We set the configuration at this point, since we now have a tty |
143 | */ | 162 | */ |
144 | static int notifier_add_vio(struct hvc_struct *hp, int data) | 163 | static int notifier_add_vio(struct hvc_struct *hp, int data) |
145 | { | 164 | { |
146 | hp->irq_requested = 1; | 165 | hp->irq_requested = 1; |
166 | virtcons_apply_config(vdev); | ||
167 | |||
147 | return 0; | 168 | return 0; |
148 | } | 169 | } |
149 | 170 | ||
@@ -234,11 +255,18 @@ static struct virtio_device_id id_table[] = { | |||
234 | { 0 }, | 255 | { 0 }, |
235 | }; | 256 | }; |
236 | 257 | ||
258 | static unsigned int features[] = { | ||
259 | VIRTIO_CONSOLE_F_SIZE, | ||
260 | }; | ||
261 | |||
237 | static struct virtio_driver virtio_console = { | 262 | static struct virtio_driver virtio_console = { |
263 | .feature_table = features, | ||
264 | .feature_table_size = ARRAY_SIZE(features), | ||
238 | .driver.name = KBUILD_MODNAME, | 265 | .driver.name = KBUILD_MODNAME, |
239 | .driver.owner = THIS_MODULE, | 266 | .driver.owner = THIS_MODULE, |
240 | .id_table = id_table, | 267 | .id_table = id_table, |
241 | .probe = virtcons_probe, | 268 | .probe = virtcons_probe, |
269 | .config_changed = virtcons_apply_config, | ||
242 | }; | 270 | }; |
243 | 271 | ||
244 | static int __init init(void) | 272 | static int __init init(void) |
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index 5faefeaf6790..f2c641e0bdde 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h | |||
@@ -164,7 +164,7 @@ void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt); | |||
164 | void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt); | 164 | void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt); |
165 | 165 | ||
166 | /* page_tables.c: */ | 166 | /* page_tables.c: */ |
167 | int init_guest_pagetable(struct lguest *lg, unsigned long pgtable); | 167 | int init_guest_pagetable(struct lguest *lg); |
168 | void free_guest_pagetable(struct lguest *lg); | 168 | void free_guest_pagetable(struct lguest *lg); |
169 | void guest_new_pagetable(struct lg_cpu *cpu, unsigned long pgtable); | 169 | void guest_new_pagetable(struct lg_cpu *cpu, unsigned long pgtable); |
170 | void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i); | 170 | void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i); |
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index a661bbdae3d6..915da6b8c924 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
@@ -250,7 +250,7 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev, | |||
250 | /* Figure out how many pages the ring will take, and map that memory */ | 250 | /* Figure out how many pages the ring will take, and map that memory */ |
251 | lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT, | 251 | lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT, |
252 | DIV_ROUND_UP(vring_size(lvq->config.num, | 252 | DIV_ROUND_UP(vring_size(lvq->config.num, |
253 | PAGE_SIZE), | 253 | LGUEST_VRING_ALIGN), |
254 | PAGE_SIZE)); | 254 | PAGE_SIZE)); |
255 | if (!lvq->pages) { | 255 | if (!lvq->pages) { |
256 | err = -ENOMEM; | 256 | err = -ENOMEM; |
@@ -259,8 +259,8 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev, | |||
259 | 259 | ||
260 | /* OK, tell virtio_ring.c to set up a virtqueue now we know its size | 260 | /* OK, tell virtio_ring.c to set up a virtqueue now we know its size |
261 | * and we've got a pointer to its pages. */ | 261 | * and we've got a pointer to its pages. */ |
262 | vq = vring_new_virtqueue(lvq->config.num, vdev, lvq->pages, | 262 | vq = vring_new_virtqueue(lvq->config.num, LGUEST_VRING_ALIGN, |
263 | lg_notify, callback); | 263 | vdev, lvq->pages, lg_notify, callback); |
264 | if (!vq) { | 264 | if (!vq) { |
265 | err = -ENOMEM; | 265 | err = -ENOMEM; |
266 | goto unmap; | 266 | goto unmap; |
@@ -272,7 +272,7 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev, | |||
272 | * the interrupt as a source of randomness: it'd be nice to have that | 272 | * the interrupt as a source of randomness: it'd be nice to have that |
273 | * back.. */ | 273 | * back.. */ |
274 | err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED, | 274 | err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED, |
275 | vdev->dev.bus_id, vq); | 275 | dev_name(&vdev->dev), vq); |
276 | if (err) | 276 | if (err) |
277 | goto destroy_vring; | 277 | goto destroy_vring; |
278 | 278 | ||
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index e73a000473cc..34bc017b8b3c 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c | |||
@@ -146,7 +146,7 @@ static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) | |||
146 | return 0; | 146 | return 0; |
147 | } | 147 | } |
148 | 148 | ||
149 | /*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit) | 149 | /*L:020 The initialization write supplies 3 pointer sized (32 or 64 bit) |
150 | * values (in addition to the LHREQ_INITIALIZE value). These are: | 150 | * values (in addition to the LHREQ_INITIALIZE value). These are: |
151 | * | 151 | * |
152 | * base: The start of the Guest-physical memory inside the Launcher memory. | 152 | * base: The start of the Guest-physical memory inside the Launcher memory. |
@@ -155,9 +155,6 @@ static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) | |||
155 | * allowed to access. The Guest memory lives inside the Launcher, so it sets | 155 | * allowed to access. The Guest memory lives inside the Launcher, so it sets |
156 | * this to ensure the Guest can only reach its own memory. | 156 | * this to ensure the Guest can only reach its own memory. |
157 | * | 157 | * |
158 | * pgdir: The (Guest-physical) address of the top of the initial Guest | ||
159 | * pagetables (which are set up by the Launcher). | ||
160 | * | ||
161 | * start: The first instruction to execute ("eip" in x86-speak). | 158 | * start: The first instruction to execute ("eip" in x86-speak). |
162 | */ | 159 | */ |
163 | static int initialize(struct file *file, const unsigned long __user *input) | 160 | static int initialize(struct file *file, const unsigned long __user *input) |
@@ -166,7 +163,7 @@ static int initialize(struct file *file, const unsigned long __user *input) | |||
166 | * Guest. */ | 163 | * Guest. */ |
167 | struct lguest *lg; | 164 | struct lguest *lg; |
168 | int err; | 165 | int err; |
169 | unsigned long args[4]; | 166 | unsigned long args[3]; |
170 | 167 | ||
171 | /* We grab the Big Lguest lock, which protects against multiple | 168 | /* We grab the Big Lguest lock, which protects against multiple |
172 | * simultaneous initializations. */ | 169 | * simultaneous initializations. */ |
@@ -192,14 +189,14 @@ static int initialize(struct file *file, const unsigned long __user *input) | |||
192 | lg->mem_base = (void __user *)args[0]; | 189 | lg->mem_base = (void __user *)args[0]; |
193 | lg->pfn_limit = args[1]; | 190 | lg->pfn_limit = args[1]; |
194 | 191 | ||
195 | /* This is the first cpu (cpu 0) and it will start booting at args[3] */ | 192 | /* This is the first cpu (cpu 0) and it will start booting at args[2] */ |
196 | err = lg_cpu_start(&lg->cpus[0], 0, args[3]); | 193 | err = lg_cpu_start(&lg->cpus[0], 0, args[2]); |
197 | if (err) | 194 | if (err) |
198 | goto release_guest; | 195 | goto release_guest; |
199 | 196 | ||
200 | /* Initialize the Guest's shadow page tables, using the toplevel | 197 | /* Initialize the Guest's shadow page tables, using the toplevel |
201 | * address the Launcher gave us. This allocates memory, so can fail. */ | 198 | * address the Launcher gave us. This allocates memory, so can fail. */ |
202 | err = init_guest_pagetable(lg, args[2]); | 199 | err = init_guest_pagetable(lg); |
203 | if (err) | 200 | if (err) |
204 | goto free_regs; | 201 | goto free_regs; |
205 | 202 | ||
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index 81d0c6053447..576a8318221c 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/percpu.h> | 14 | #include <linux/percpu.h> |
15 | #include <asm/tlbflush.h> | 15 | #include <asm/tlbflush.h> |
16 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
17 | #include <asm/bootparam.h> | ||
17 | #include "lg.h" | 18 | #include "lg.h" |
18 | 19 | ||
19 | /*M:008 We hold reference to pages, which prevents them from being swapped. | 20 | /*M:008 We hold reference to pages, which prevents them from being swapped. |
@@ -581,15 +582,82 @@ void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 idx) | |||
581 | release_pgd(lg, lg->pgdirs[pgdir].pgdir + idx); | 582 | release_pgd(lg, lg->pgdirs[pgdir].pgdir + idx); |
582 | } | 583 | } |
583 | 584 | ||
585 | /* Once we know how much memory we have we can construct simple identity | ||
586 | * (which set virtual == physical) and linear mappings | ||
587 | * which will get the Guest far enough into the boot to create its own. | ||
588 | * | ||
589 | * We lay them out of the way, just below the initrd (which is why we need to | ||
590 | * know its size here). */ | ||
591 | static unsigned long setup_pagetables(struct lguest *lg, | ||
592 | unsigned long mem, | ||
593 | unsigned long initrd_size) | ||
594 | { | ||
595 | pgd_t __user *pgdir; | ||
596 | pte_t __user *linear; | ||
597 | unsigned int mapped_pages, i, linear_pages, phys_linear; | ||
598 | unsigned long mem_base = (unsigned long)lg->mem_base; | ||
599 | |||
600 | /* We have mapped_pages frames to map, so we need | ||
601 | * linear_pages page tables to map them. */ | ||
602 | mapped_pages = mem / PAGE_SIZE; | ||
603 | linear_pages = (mapped_pages + PTRS_PER_PTE - 1) / PTRS_PER_PTE; | ||
604 | |||
605 | /* We put the toplevel page directory page at the top of memory. */ | ||
606 | pgdir = (pgd_t *)(mem + mem_base - initrd_size - PAGE_SIZE); | ||
607 | |||
608 | /* Now we use the next linear_pages pages as pte pages */ | ||
609 | linear = (void *)pgdir - linear_pages * PAGE_SIZE; | ||
610 | |||
611 | /* Linear mapping is easy: put every page's address into the | ||
612 | * mapping in order. */ | ||
613 | for (i = 0; i < mapped_pages; i++) { | ||
614 | pte_t pte; | ||
615 | pte = pfn_pte(i, __pgprot(_PAGE_PRESENT|_PAGE_RW|_PAGE_USER)); | ||
616 | if (copy_to_user(&linear[i], &pte, sizeof(pte)) != 0) | ||
617 | return -EFAULT; | ||
618 | } | ||
619 | |||
620 | /* The top level points to the linear page table pages above. | ||
621 | * We setup the identity and linear mappings here. */ | ||
622 | phys_linear = (unsigned long)linear - mem_base; | ||
623 | for (i = 0; i < mapped_pages; i += PTRS_PER_PTE) { | ||
624 | pgd_t pgd; | ||
625 | pgd = __pgd((phys_linear + i * sizeof(pte_t)) | | ||
626 | (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER)); | ||
627 | |||
628 | if (copy_to_user(&pgdir[i / PTRS_PER_PTE], &pgd, sizeof(pgd)) | ||
629 | || copy_to_user(&pgdir[pgd_index(PAGE_OFFSET) | ||
630 | + i / PTRS_PER_PTE], | ||
631 | &pgd, sizeof(pgd))) | ||
632 | return -EFAULT; | ||
633 | } | ||
634 | |||
635 | /* We return the top level (guest-physical) address: remember where | ||
636 | * this is. */ | ||
637 | return (unsigned long)pgdir - mem_base; | ||
638 | } | ||
639 | |||
584 | /*H:500 (vii) Setting up the page tables initially. | 640 | /*H:500 (vii) Setting up the page tables initially. |
585 | * | 641 | * |
586 | * When a Guest is first created, the Launcher tells us where the toplevel of | 642 | * When a Guest is first created, the Launcher tells us where the toplevel of |
587 | * its first page table is. We set some things up here: */ | 643 | * its first page table is. We set some things up here: */ |
588 | int init_guest_pagetable(struct lguest *lg, unsigned long pgtable) | 644 | int init_guest_pagetable(struct lguest *lg) |
589 | { | 645 | { |
646 | u64 mem; | ||
647 | u32 initrd_size; | ||
648 | struct boot_params __user *boot = (struct boot_params *)lg->mem_base; | ||
649 | |||
650 | /* Get the Guest memory size and the ramdisk size from the boot header | ||
651 | * located at lg->mem_base (Guest address 0). */ | ||
652 | if (copy_from_user(&mem, &boot->e820_map[0].size, sizeof(mem)) | ||
653 | || get_user(initrd_size, &boot->hdr.ramdisk_size)) | ||
654 | return -EFAULT; | ||
655 | |||
590 | /* We start on the first shadow page table, and give it a blank PGD | 656 | /* We start on the first shadow page table, and give it a blank PGD |
591 | * page. */ | 657 | * page. */ |
592 | lg->pgdirs[0].gpgdir = pgtable; | 658 | lg->pgdirs[0].gpgdir = setup_pagetables(lg, mem, initrd_size); |
659 | if (IS_ERR_VALUE(lg->pgdirs[0].gpgdir)) | ||
660 | return lg->pgdirs[0].gpgdir; | ||
593 | lg->pgdirs[0].pgdir = (pgd_t *)get_zeroed_page(GFP_KERNEL); | 661 | lg->pgdirs[0].pgdir = (pgd_t *)get_zeroed_page(GFP_KERNEL); |
594 | if (!lg->pgdirs[0].pgdir) | 662 | if (!lg->pgdirs[0].pgdir) |
595 | return -ENOMEM; | 663 | return -ENOMEM; |
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 3d442444c618..28c90b89f2b4 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
@@ -188,11 +188,13 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev, | |||
188 | config = kvm_vq_config(kdev->desc)+index; | 188 | config = kvm_vq_config(kdev->desc)+index; |
189 | 189 | ||
190 | err = vmem_add_mapping(config->address, | 190 | err = vmem_add_mapping(config->address, |
191 | vring_size(config->num, PAGE_SIZE)); | 191 | vring_size(config->num, |
192 | KVM_S390_VIRTIO_RING_ALIGN)); | ||
192 | if (err) | 193 | if (err) |
193 | goto out; | 194 | goto out; |
194 | 195 | ||
195 | vq = vring_new_virtqueue(config->num, vdev, (void *) config->address, | 196 | vq = vring_new_virtqueue(config->num, KVM_S390_VIRTIO_RING_ALIGN, |
197 | vdev, (void *) config->address, | ||
196 | kvm_notify, callback); | 198 | kvm_notify, callback); |
197 | if (!vq) { | 199 | if (!vq) { |
198 | err = -ENOMEM; | 200 | err = -ENOMEM; |
@@ -209,7 +211,8 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev, | |||
209 | return vq; | 211 | return vq; |
210 | unmap: | 212 | unmap: |
211 | vmem_remove_mapping(config->address, | 213 | vmem_remove_mapping(config->address, |
212 | vring_size(config->num, PAGE_SIZE)); | 214 | vring_size(config->num, |
215 | KVM_S390_VIRTIO_RING_ALIGN)); | ||
213 | out: | 216 | out: |
214 | return ERR_PTR(err); | 217 | return ERR_PTR(err); |
215 | } | 218 | } |
@@ -220,7 +223,8 @@ static void kvm_del_vq(struct virtqueue *vq) | |||
220 | 223 | ||
221 | vring_del_virtqueue(vq); | 224 | vring_del_virtqueue(vq); |
222 | vmem_remove_mapping(config->address, | 225 | vmem_remove_mapping(config->address, |
223 | vring_size(config->num, PAGE_SIZE)); | 226 | vring_size(config->num, |
227 | KVM_S390_VIRTIO_RING_ALIGN)); | ||
224 | } | 228 | } |
225 | 229 | ||
226 | /* | 230 | /* |
@@ -295,13 +299,29 @@ static void scan_devices(void) | |||
295 | */ | 299 | */ |
296 | static void kvm_extint_handler(u16 code) | 300 | static void kvm_extint_handler(u16 code) |
297 | { | 301 | { |
298 | void *data = (void *) *(long *) __LC_PFAULT_INTPARM; | 302 | struct virtqueue *vq; |
299 | u16 subcode = S390_lowcore.cpu_addr; | 303 | u16 subcode; |
304 | int config_changed; | ||
300 | 305 | ||
306 | subcode = S390_lowcore.cpu_addr; | ||
301 | if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) | 307 | if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) |
302 | return; | 308 | return; |
303 | 309 | ||
304 | vring_interrupt(0, data); | 310 | /* The LSB might be overloaded, we have to mask it */ |
311 | vq = (struct virtqueue *) ((*(long *) __LC_PFAULT_INTPARM) & ~1UL); | ||
312 | |||
313 | /* We use the LSB of extparam, to decide, if this interrupt is a config | ||
314 | * change or a "standard" interrupt */ | ||
315 | config_changed = (*(int *) __LC_EXT_PARAMS & 1); | ||
316 | |||
317 | if (config_changed) { | ||
318 | struct virtio_driver *drv; | ||
319 | drv = container_of(vq->vdev->dev.driver, | ||
320 | struct virtio_driver, driver); | ||
321 | if (drv->config_changed) | ||
322 | drv->config_changed(vq->vdev); | ||
323 | } else | ||
324 | vring_interrupt(0, vq); | ||
305 | } | 325 | } |
306 | 326 | ||
307 | /* | 327 | /* |
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 5b78fd0aff0a..018c070a357f 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
@@ -176,7 +176,7 @@ int register_virtio_device(struct virtio_device *dev) | |||
176 | 176 | ||
177 | /* Assign a unique device index and hence name. */ | 177 | /* Assign a unique device index and hence name. */ |
178 | dev->index = dev_index++; | 178 | dev->index = dev_index++; |
179 | sprintf(dev->dev.bus_id, "virtio%u", dev->index); | 179 | dev_set_name(&dev->dev, "virtio%u", dev->index); |
180 | 180 | ||
181 | /* We always start by resetting the device, in case a previous | 181 | /* We always start by resetting the device, in case a previous |
182 | * driver messed it up. This also tests that code path a little. */ | 182 | * driver messed it up. This also tests that code path a little. */ |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 62eab43152d2..59268266b79a 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -56,6 +56,15 @@ static struct virtio_device_id id_table[] = { | |||
56 | { 0 }, | 56 | { 0 }, |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static u32 page_to_balloon_pfn(struct page *page) | ||
60 | { | ||
61 | unsigned long pfn = page_to_pfn(page); | ||
62 | |||
63 | BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT); | ||
64 | /* Convert pfn from Linux page size to balloon page size. */ | ||
65 | return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT); | ||
66 | } | ||
67 | |||
59 | static void balloon_ack(struct virtqueue *vq) | 68 | static void balloon_ack(struct virtqueue *vq) |
60 | { | 69 | { |
61 | struct virtio_balloon *vb; | 70 | struct virtio_balloon *vb; |
@@ -99,7 +108,7 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num) | |||
99 | msleep(200); | 108 | msleep(200); |
100 | break; | 109 | break; |
101 | } | 110 | } |
102 | vb->pfns[vb->num_pfns] = page_to_pfn(page); | 111 | vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); |
103 | totalram_pages--; | 112 | totalram_pages--; |
104 | vb->num_pages++; | 113 | vb->num_pages++; |
105 | list_add(&page->lru, &vb->pages); | 114 | list_add(&page->lru, &vb->pages); |
@@ -132,7 +141,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) | |||
132 | for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { | 141 | for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { |
133 | page = list_first_entry(&vb->pages, struct page, lru); | 142 | page = list_first_entry(&vb->pages, struct page, lru); |
134 | list_del(&page->lru); | 143 | list_del(&page->lru); |
135 | vb->pfns[vb->num_pfns] = page_to_pfn(page); | 144 | vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); |
136 | vb->num_pages--; | 145 | vb->num_pages--; |
137 | } | 146 | } |
138 | 147 | ||
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index c7dc37c7cce9..265fdf2d1276 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -75,7 +75,7 @@ MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); | |||
75 | * would make more sense for virtio to not insist on having it's own device. */ | 75 | * would make more sense for virtio to not insist on having it's own device. */ |
76 | static struct device virtio_pci_root = { | 76 | static struct device virtio_pci_root = { |
77 | .parent = NULL, | 77 | .parent = NULL, |
78 | .bus_id = "virtio-pci", | 78 | .init_name = "virtio-pci", |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /* Convert a generic virtio device to our structure */ | 81 | /* Convert a generic virtio device to our structure */ |
@@ -216,7 +216,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, | |||
216 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 216 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
217 | struct virtio_pci_vq_info *info; | 217 | struct virtio_pci_vq_info *info; |
218 | struct virtqueue *vq; | 218 | struct virtqueue *vq; |
219 | unsigned long flags; | 219 | unsigned long flags, size; |
220 | u16 num; | 220 | u16 num; |
221 | int err; | 221 | int err; |
222 | 222 | ||
@@ -237,19 +237,20 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, | |||
237 | info->queue_index = index; | 237 | info->queue_index = index; |
238 | info->num = num; | 238 | info->num = num; |
239 | 239 | ||
240 | info->queue = kzalloc(PAGE_ALIGN(vring_size(num,PAGE_SIZE)), GFP_KERNEL); | 240 | size = PAGE_ALIGN(vring_size(num, VIRTIO_PCI_VRING_ALIGN)); |
241 | info->queue = alloc_pages_exact(size, GFP_KERNEL|__GFP_ZERO); | ||
241 | if (info->queue == NULL) { | 242 | if (info->queue == NULL) { |
242 | err = -ENOMEM; | 243 | err = -ENOMEM; |
243 | goto out_info; | 244 | goto out_info; |
244 | } | 245 | } |
245 | 246 | ||
246 | /* activate the queue */ | 247 | /* activate the queue */ |
247 | iowrite32(virt_to_phys(info->queue) >> PAGE_SHIFT, | 248 | iowrite32(virt_to_phys(info->queue) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT, |
248 | vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); | 249 | vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); |
249 | 250 | ||
250 | /* create the vring */ | 251 | /* create the vring */ |
251 | vq = vring_new_virtqueue(info->num, vdev, info->queue, | 252 | vq = vring_new_virtqueue(info->num, VIRTIO_PCI_VRING_ALIGN, |
252 | vp_notify, callback); | 253 | vdev, info->queue, vp_notify, callback); |
253 | if (!vq) { | 254 | if (!vq) { |
254 | err = -ENOMEM; | 255 | err = -ENOMEM; |
255 | goto out_activate_queue; | 256 | goto out_activate_queue; |
@@ -266,7 +267,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, | |||
266 | 267 | ||
267 | out_activate_queue: | 268 | out_activate_queue: |
268 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); | 269 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); |
269 | kfree(info->queue); | 270 | free_pages_exact(info->queue, size); |
270 | out_info: | 271 | out_info: |
271 | kfree(info); | 272 | kfree(info); |
272 | return ERR_PTR(err); | 273 | return ERR_PTR(err); |
@@ -277,7 +278,7 @@ static void vp_del_vq(struct virtqueue *vq) | |||
277 | { | 278 | { |
278 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); | 279 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); |
279 | struct virtio_pci_vq_info *info = vq->priv; | 280 | struct virtio_pci_vq_info *info = vq->priv; |
280 | unsigned long flags; | 281 | unsigned long flags, size; |
281 | 282 | ||
282 | spin_lock_irqsave(&vp_dev->lock, flags); | 283 | spin_lock_irqsave(&vp_dev->lock, flags); |
283 | list_del(&info->node); | 284 | list_del(&info->node); |
@@ -289,7 +290,8 @@ static void vp_del_vq(struct virtqueue *vq) | |||
289 | iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); | 290 | iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); |
290 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); | 291 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); |
291 | 292 | ||
292 | kfree(info->queue); | 293 | size = PAGE_ALIGN(vring_size(info->num, VIRTIO_PCI_VRING_ALIGN)); |
294 | free_pages_exact(info->queue, size); | ||
293 | kfree(info); | 295 | kfree(info); |
294 | } | 296 | } |
295 | 297 | ||
@@ -305,6 +307,20 @@ static struct virtio_config_ops virtio_pci_config_ops = { | |||
305 | .finalize_features = vp_finalize_features, | 307 | .finalize_features = vp_finalize_features, |
306 | }; | 308 | }; |
307 | 309 | ||
310 | static void virtio_pci_release_dev(struct device *_d) | ||
311 | { | ||
312 | struct virtio_device *dev = container_of(_d, struct virtio_device, dev); | ||
313 | struct virtio_pci_device *vp_dev = to_vp_device(dev); | ||
314 | struct pci_dev *pci_dev = vp_dev->pci_dev; | ||
315 | |||
316 | free_irq(pci_dev->irq, vp_dev); | ||
317 | pci_set_drvdata(pci_dev, NULL); | ||
318 | pci_iounmap(pci_dev, vp_dev->ioaddr); | ||
319 | pci_release_regions(pci_dev); | ||
320 | pci_disable_device(pci_dev); | ||
321 | kfree(vp_dev); | ||
322 | } | ||
323 | |||
308 | /* the PCI probing function */ | 324 | /* the PCI probing function */ |
309 | static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, | 325 | static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, |
310 | const struct pci_device_id *id) | 326 | const struct pci_device_id *id) |
@@ -328,6 +344,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, | |||
328 | return -ENOMEM; | 344 | return -ENOMEM; |
329 | 345 | ||
330 | vp_dev->vdev.dev.parent = &virtio_pci_root; | 346 | vp_dev->vdev.dev.parent = &virtio_pci_root; |
347 | vp_dev->vdev.dev.release = virtio_pci_release_dev; | ||
331 | vp_dev->vdev.config = &virtio_pci_config_ops; | 348 | vp_dev->vdev.config = &virtio_pci_config_ops; |
332 | vp_dev->pci_dev = pci_dev; | 349 | vp_dev->pci_dev = pci_dev; |
333 | INIT_LIST_HEAD(&vp_dev->virtqueues); | 350 | INIT_LIST_HEAD(&vp_dev->virtqueues); |
@@ -357,7 +374,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, | |||
357 | 374 | ||
358 | /* register a handler for the queue with the PCI device's interrupt */ | 375 | /* register a handler for the queue with the PCI device's interrupt */ |
359 | err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, IRQF_SHARED, | 376 | err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, IRQF_SHARED, |
360 | vp_dev->vdev.dev.bus_id, vp_dev); | 377 | dev_name(&vp_dev->vdev.dev), vp_dev); |
361 | if (err) | 378 | if (err) |
362 | goto out_set_drvdata; | 379 | goto out_set_drvdata; |
363 | 380 | ||
@@ -387,12 +404,6 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev) | |||
387 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); | 404 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); |
388 | 405 | ||
389 | unregister_virtio_device(&vp_dev->vdev); | 406 | unregister_virtio_device(&vp_dev->vdev); |
390 | free_irq(pci_dev->irq, vp_dev); | ||
391 | pci_set_drvdata(pci_dev, NULL); | ||
392 | pci_iounmap(pci_dev, vp_dev->ioaddr); | ||
393 | pci_release_regions(pci_dev); | ||
394 | pci_disable_device(pci_dev); | ||
395 | kfree(vp_dev); | ||
396 | } | 407 | } |
397 | 408 | ||
398 | #ifdef CONFIG_PM | 409 | #ifdef CONFIG_PM |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 6eb5303fed11..5777196bf6c9 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -274,6 +274,7 @@ static struct virtqueue_ops vring_vq_ops = { | |||
274 | }; | 274 | }; |
275 | 275 | ||
276 | struct virtqueue *vring_new_virtqueue(unsigned int num, | 276 | struct virtqueue *vring_new_virtqueue(unsigned int num, |
277 | unsigned int vring_align, | ||
277 | struct virtio_device *vdev, | 278 | struct virtio_device *vdev, |
278 | void *pages, | 279 | void *pages, |
279 | void (*notify)(struct virtqueue *), | 280 | void (*notify)(struct virtqueue *), |
@@ -292,7 +293,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, | |||
292 | if (!vq) | 293 | if (!vq) |
293 | return NULL; | 294 | return NULL; |
294 | 295 | ||
295 | vring_init(&vq->vring, num, pages, PAGE_SIZE); | 296 | vring_init(&vq->vring, num, pages, vring_align); |
296 | vq->vq.callback = callback; | 297 | vq->vq.callback = callback; |
297 | vq->vq.vdev = vdev; | 298 | vq->vq.vdev = vdev; |
298 | vq->vq.vq_ops = &vring_vq_ops; | 299 | vq->vq.vq_ops = &vring_vq_ops; |