~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/xen/grant-table.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include <linux/module.h>
35
35
#include <linux/sched.h>
36
36
#include <linux/mm.h>
 
37
#include <linux/slab.h>
37
38
#include <linux/vmalloc.h>
38
39
#include <linux/uaccess.h>
 
40
#include <linux/io.h>
39
41
 
 
42
#include <xen/xen.h>
40
43
#include <xen/interface/xen.h>
41
44
#include <xen/page.h>
42
45
#include <xen/grant_table.h>
 
46
#include <xen/interface/memory.h>
43
47
#include <asm/xen/hypercall.h>
44
48
 
45
49
#include <asm/pgtable.h>
57
61
static int gnttab_free_count;
58
62
static grant_ref_t gnttab_free_head;
59
63
static DEFINE_SPINLOCK(gnttab_list_lock);
 
64
unsigned long xen_hvm_resume_frames;
 
65
EXPORT_SYMBOL_GPL(xen_hvm_resume_frames);
60
66
 
61
67
static struct grant_entry *shared;
62
68
 
431
437
        return query.max_nr_frames;
432
438
}
433
439
 
434
 
static inline unsigned int max_nr_grant_frames(void)
 
440
unsigned int gnttab_max_grant_frames(void)
435
441
{
436
442
        unsigned int xen_max = __max_nr_grant_frames();
437
443
 
439
445
                return boot_max_nr_grant_frames;
440
446
        return xen_max;
441
447
}
 
448
EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
 
449
 
 
450
int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
 
451
                    struct page **pages, unsigned int count)
 
452
{
 
453
        int i, ret;
 
454
        pte_t *pte;
 
455
        unsigned long mfn;
 
456
 
 
457
        ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count);
 
458
        if (ret)
 
459
                return ret;
 
460
 
 
461
        for (i = 0; i < count; i++) {
 
462
                /* m2p override only supported for GNTMAP_contains_pte mappings */
 
463
                if (!(map_ops[i].flags & GNTMAP_contains_pte))
 
464
                        continue;
 
465
                pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
 
466
                                (map_ops[i].host_addr & ~PAGE_MASK));
 
467
                mfn = pte_mfn(*pte);
 
468
                ret = m2p_add_override(mfn, pages[i]);
 
469
                if (ret)
 
470
                        return ret;
 
471
        }
 
472
 
 
473
        return ret;
 
474
}
 
475
EXPORT_SYMBOL_GPL(gnttab_map_refs);
 
476
 
 
477
int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
 
478
                struct page **pages, unsigned int count)
 
479
{
 
480
        int i, ret;
 
481
 
 
482
        ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count);
 
483
        if (ret)
 
484
                return ret;
 
485
 
 
486
        for (i = 0; i < count; i++) {
 
487
                ret = m2p_remove_override(pages[i]);
 
488
                if (ret)
 
489
                        return ret;
 
490
        }
 
491
 
 
492
        return ret;
 
493
}
 
494
EXPORT_SYMBOL_GPL(gnttab_unmap_refs);
442
495
 
443
496
static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
444
497
{
447
500
        unsigned int nr_gframes = end_idx + 1;
448
501
        int rc;
449
502
 
 
503
        if (xen_hvm_domain()) {
 
504
                struct xen_add_to_physmap xatp;
 
505
                unsigned int i = end_idx;
 
506
                rc = 0;
 
507
                /*
 
508
                 * Loop backwards, so that the first hypercall has the largest
 
509
                 * index, ensuring that the table will grow only once.
 
510
                 */
 
511
                do {
 
512
                        xatp.domid = DOMID_SELF;
 
513
                        xatp.idx = i;
 
514
                        xatp.space = XENMAPSPACE_grant_table;
 
515
                        xatp.gpfn = (xen_hvm_resume_frames >> PAGE_SHIFT) + i;
 
516
                        rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
 
517
                        if (rc != 0) {
 
518
                                printk(KERN_WARNING
 
519
                                                "grant table add_to_physmap failed, err=%d\n", rc);
 
520
                                break;
 
521
                        }
 
522
                } while (i-- > start_idx);
 
523
 
 
524
                return rc;
 
525
        }
 
526
 
450
527
        frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC);
451
528
        if (!frames)
452
529
                return -ENOMEM;
463
540
 
464
541
        BUG_ON(rc || setup.status);
465
542
 
466
 
        rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(),
 
543
        rc = arch_gnttab_map_shared(frames, nr_gframes, gnttab_max_grant_frames(),
467
544
                                    &shared);
468
545
        BUG_ON(rc);
469
546
 
474
551
 
475
552
int gnttab_resume(void)
476
553
{
477
 
        if (max_nr_grant_frames() < nr_grant_frames)
 
554
        unsigned int max_nr_gframes;
 
555
 
 
556
        max_nr_gframes = gnttab_max_grant_frames();
 
557
        if (max_nr_gframes < nr_grant_frames)
478
558
                return -ENOSYS;
479
 
        return gnttab_map(0, nr_grant_frames - 1);
 
559
 
 
560
        if (xen_pv_domain())
 
561
                return gnttab_map(0, nr_grant_frames - 1);
 
562
 
 
563
        if (!shared) {
 
564
                shared = ioremap(xen_hvm_resume_frames, PAGE_SIZE * max_nr_gframes);
 
565
                if (shared == NULL) {
 
566
                        printk(KERN_WARNING
 
567
                                        "Failed to ioremap gnttab share frames!");
 
568
                        return -ENOMEM;
 
569
                }
 
570
        }
 
571
 
 
572
        gnttab_map(0, nr_grant_frames - 1);
 
573
 
 
574
        return 0;
480
575
}
481
576
 
482
577
int gnttab_suspend(void)
493
588
        cur = nr_grant_frames;
494
589
        extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
495
590
                 GREFS_PER_GRANT_FRAME);
496
 
        if (cur + extra > max_nr_grant_frames())
 
591
        if (cur + extra > gnttab_max_grant_frames())
497
592
                return -ENOSPC;
498
593
 
499
594
        rc = gnttab_map(cur, cur + extra - 1);
503
598
        return rc;
504
599
}
505
600
 
506
 
static int __devinit gnttab_init(void)
 
601
int gnttab_init(void)
507
602
{
508
603
        int i;
509
604
        unsigned int max_nr_glist_frames, nr_glist_frames;
510
605
        unsigned int nr_init_grefs;
511
606
 
512
 
        if (!xen_domain())
513
 
                return -ENODEV;
514
 
 
515
607
        nr_grant_frames = 1;
516
608
        boot_max_nr_grant_frames = __max_nr_grant_frames();
517
609
 
554
646
        kfree(gnttab_list);
555
647
        return -ENOMEM;
556
648
}
557
 
 
558
 
core_initcall(gnttab_init);
 
649
EXPORT_SYMBOL_GPL(gnttab_init);
 
650
 
 
651
static int __devinit __gnttab_init(void)
 
652
{
 
653
        /* Delay grant-table initialization in the PV on HVM case */
 
654
        if (xen_hvm_domain())
 
655
                return 0;
 
656
 
 
657
        if (!xen_pv_domain())
 
658
                return -ENODEV;
 
659
 
 
660
        return gnttab_init();
 
661
}
 
662
 
 
663
core_initcall(__gnttab_init);