Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Sep 2009 16:23:45 +0000 (09:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Sep 2009 16:23:45 +0000 (09:23 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
  lguest: don't force VIRTIO_F_NOTIFY_ON_EMPTY
  lguest: cleanup for map_switcher()
  lguest: use PGDIR_SHIFT for PAE code to allow different PAGE_OFFSET
  lguest: use set_pte/set_pmd uniformly for real page table entries
  lguest: move panic notifier registration to its expected place.
  virtio_blk: add support for cache flush
  virtio: add virtio IDs file
  virtio: get rid of redundant VIRTIO_ID_9P definition
  virtio: make add_buf return capacity remaining
  virtio_pci: minor MSI-X cleanups

1  2 
drivers/block/virtio_blk.c
drivers/lguest/page_tables.c

index aa89fe45237d516907cacffa238985e98fdb0fec,3d5fe97569c70f34c98af7761a10ebcfc1c690b1..43f19389647a99b4efb7e78ce556e94153189197
@@@ -3,6 -3,7 +3,7 @@@
  #include <linux/blkdev.h>
  #include <linux/hdreg.h>
  #include <linux/virtio.h>
+ #include <linux/virtio_ids.h>
  #include <linux/virtio_blk.h>
  #include <linux/scatterlist.h>
  
@@@ -91,15 -92,26 +92,26 @@@ static bool do_req(struct request_queu
                return false;
  
        vbr->req = req;
-       if (blk_fs_request(vbr->req)) {
+       switch (req->cmd_type) {
+       case REQ_TYPE_FS:
                vbr->out_hdr.type = 0;
                vbr->out_hdr.sector = blk_rq_pos(vbr->req);
                vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
-       } else if (blk_pc_request(vbr->req)) {
+               break;
+       case REQ_TYPE_BLOCK_PC:
                vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
                vbr->out_hdr.sector = 0;
                vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
-       } else {
+               break;
+       case REQ_TYPE_LINUX_BLOCK:
+               if (req->cmd[0] == REQ_LB_OP_FLUSH) {
+                       vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
+                       vbr->out_hdr.sector = 0;
+                       vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
+                       break;
+               }
+               /*FALLTHRU*/
+       default:
                /* We don't put anything else in the queue. */
                BUG();
        }
                }
        }
  
-       if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr)) {
+       if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) {
                mempool_free(vbr, vblk->pool);
                return false;
        }
@@@ -199,6 -211,12 +211,12 @@@ out
        return err;
  }
  
+ static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
+ {
+       req->cmd_type = REQ_TYPE_LINUX_BLOCK;
+       req->cmd[0] = REQ_LB_OP_FLUSH;
+ }
  static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
                         unsigned cmd, unsigned long data)
  {
@@@ -243,7 -261,7 +261,7 @@@ static int virtblk_getgeo(struct block_
        return 0;
  }
  
 -static struct block_device_operations virtblk_fops = {
 +static const struct block_device_operations virtblk_fops = {
        .locked_ioctl = virtblk_ioctl,
        .owner  = THIS_MODULE,
        .getgeo = virtblk_getgeo,
@@@ -337,7 -355,10 +355,10 @@@ static int __devinit virtblk_probe(stru
        index++;
  
        /* If barriers are supported, tell block layer that queue is ordered */
-       if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
+       if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))
+               blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_DRAIN_FLUSH,
+                                 virtblk_prepare_flush);
+       else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
                blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
  
        /* If disk is read-only in the host, the guest should obey */
@@@ -424,7 -445,7 +445,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_BLK_SIZE,
-       VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY
+       VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH
  };
  
  /*
index 8aaad65c3bb592b35af2eb259bea80d26cbfb742,bf37a31c0e05f13717f3967cf345bf270e7e27fa..cf94326f1b597f1b46ccc3ddc996b5aa0ef84f5f
@@@ -380,7 -380,7 +380,7 @@@ bool demand_page(struct lg_cpu *cpu, un
                 * And we copy the flags to the shadow PMD entry.  The page
                 * number in the shadow PMD is the page we just allocated.
                 */
-               native_set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd)));
+               set_pmd(spmd, __pmd(__pa(ptepage) | pmd_flags(gpmd)));
        }
  
        /*
                 * we will come back here when a write does actually occur, so
                 * we can update the Guest's _PAGE_DIRTY flag.
                 */
-               native_set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0));
+               set_pte(spte, gpte_to_spte(cpu, pte_wrprotect(gpte), 0));
  
        /*
         * Finally, we write the Guest PTE entry back: we've set the
@@@ -528,7 -528,7 +528,7 @@@ static void release_pmd(pmd_t *spmd
                /* Now we can free the page of PTEs */
                free_page((long)ptepage);
                /* And zero out the PMD entry so we never release it twice. */
-               native_set_pmd(spmd, __pmd(0));
+               set_pmd(spmd, __pmd(0));
        }
  }
  
@@@ -833,15 -833,15 +833,15 @@@ static void do_set_pte(struct lg_cpu *c
                         */
                        if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) {
                                check_gpte(cpu, gpte);
-                               native_set_pte(spte,
-                                               gpte_to_spte(cpu, gpte,
+                               set_pte(spte,
+                                       gpte_to_spte(cpu, gpte,
                                                pte_flags(gpte) & _PAGE_DIRTY));
                        } else {
                                /*
                                 * Otherwise kill it and we can demand_page()
                                 * it in later.
                                 */
-                               native_set_pte(spte, __pte(0));
+                               set_pte(spte, __pte(0));
                        }
  #ifdef CONFIG_X86_PAE
                }
@@@ -894,7 -894,7 +894,7 @@@ void guest_set_pte(struct lg_cpu *cpu
   * tells us they've changed.  When the Guest tries to use the new entry it will
   * fault and demand_page() will fix it up.
   *
 - * So with that in mind here's our code to to update a (top-level) PGD entry:
 + * So with that in mind here's our code to update a (top-level) PGD entry:
   */
  void guest_set_pgd(struct lguest *lg, unsigned long gpgdir, u32 idx)
  {
@@@ -983,25 -983,22 +983,22 @@@ static unsigned long setup_pagetables(s
         */
        for (i = j = 0; i < mapped_pages && j < PTRS_PER_PMD;
             i += PTRS_PER_PTE, j++) {
-               /* FIXME: native_set_pmd is overkill here. */
-               native_set_pmd(&pmd, __pmd(((unsigned long)(linear + i)
-               - mem_base) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER));
+               pmd = pfn_pmd(((unsigned long)&linear[i] - mem_base)/PAGE_SIZE,
+                             __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER));
  
                if (copy_to_user(&pmds[j], &pmd, sizeof(pmd)) != 0)
                        return -EFAULT;
        }
  
        /* One PGD entry, pointing to that PMD page. */
-       set_pgd(&pgd, __pgd(((u32)pmds - mem_base) | _PAGE_PRESENT));
+       pgd = __pgd(((unsigned long)pmds - mem_base) | _PAGE_PRESENT);
        /* Copy it in as the first PGD entry (ie. addresses 0-1G). */
        if (copy_to_user(&pgdir[0], &pgd, sizeof(pgd)) != 0)
                return -EFAULT;
        /*
-        * And the third PGD entry (ie. addresses 3G-4G).
-        *
-        * FIXME: This assumes that PAGE_OFFSET for the Guest is 0xC0000000.
+        * And the other PGD entry to make the linear mapping at PAGE_OFFSET
         */
-       if (copy_to_user(&pgdir[3], &pgd, sizeof(pgd)) != 0)
+       if (copy_to_user(&pgdir[KERNEL_PGD_BOUNDARY], &pgd, sizeof(pgd)))
                return -EFAULT;
  #else
        /*
@@@ -1141,15 -1138,13 +1138,13 @@@ void map_switcher_in_guest(struct lg_cp
  {
        pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
        pte_t regs_pte;
-       unsigned long pfn;
  
  #ifdef CONFIG_X86_PAE
        pmd_t switcher_pmd;
        pmd_t *pmd_table;
  
-       /* FIXME: native_set_pmd is overkill here. */
-       native_set_pmd(&switcher_pmd, pfn_pmd(__pa(switcher_pte_page) >>
-                      PAGE_SHIFT, PAGE_KERNEL_EXEC));
+       switcher_pmd = pfn_pmd(__pa(switcher_pte_page) >> PAGE_SHIFT,
+                              PAGE_KERNEL_EXEC);
  
        /* Figure out where the pmd page is, by reading the PGD, and converting
         * it to a virtual address. */
                        pgdirs[cpu->cpu_pgd].pgdir[SWITCHER_PGD_INDEX])
                                                                << PAGE_SHIFT);
        /* Now write it into the shadow page table. */
-       native_set_pmd(&pmd_table[SWITCHER_PMD_INDEX], switcher_pmd);
+       set_pmd(&pmd_table[SWITCHER_PMD_INDEX], switcher_pmd);
  #else
        pgd_t switcher_pgd;
  
         * page is already mapped there, we don't have to copy them out
         * again.
         */
-       pfn = __pa(cpu->regs_page) >> PAGE_SHIFT;
-       native_set_pte(&regs_pte, pfn_pte(pfn, PAGE_KERNEL));
-       native_set_pte(&switcher_pte_page[pte_index((unsigned long)pages)],
-                       regs_pte);
+       regs_pte = pfn_pte(__pa(cpu->regs_page) >> PAGE_SHIFT, PAGE_KERNEL);
+       set_pte(&switcher_pte_page[pte_index((unsigned long)pages)], regs_pte);
  }
  /*:*/
  
@@@ -1209,7 -1202,7 +1202,7 @@@ static __init void populate_switcher_pt
  
        /* The first entries are easy: they map the Switcher code. */
        for (i = 0; i < pages; i++) {
-               native_set_pte(&pte[i], mk_pte(switcher_page[i],
+               set_pte(&pte[i], mk_pte(switcher_page[i],
                                __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED)));
        }
  
        i = pages + cpu*2;
  
        /* First page (Guest registers) is writable from the Guest */
-       native_set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_page[i]),
+       set_pte(&pte[i], pfn_pte(page_to_pfn(switcher_page[i]),
                         __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW)));
  
        /*
         * The second page contains the "struct lguest_ro_state", and is
         * read-only.
         */
-       native_set_pte(&pte[i+1], pfn_pte(page_to_pfn(switcher_page[i+1]),
+       set_pte(&pte[i+1], pfn_pte(page_to_pfn(switcher_page[i+1]),
                           __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED)));
  }