int __devinit gnttab_init(void) { int i; unsigned int max_nr_glist_frames, nr_glist_frames; unsigned int nr_init_grefs; if (!is_running_on_xen()) return -ENODEV; nr_grant_frames = 1; boot_max_nr_grant_frames = __max_nr_grant_frames(); /* Determine the maximum number of frames required for the * grant reference free list on the current hypervisor. */ max_nr_glist_frames = nr_freelist_frames(boot_max_nr_grant_frames); gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *), GFP_KERNEL); if (gnttab_list == NULL) return -ENOMEM; nr_glist_frames = nr_freelist_frames(nr_grant_frames); for (i = 0; i < nr_glist_frames; i++) { gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); if (gnttab_list[i] == NULL) goto ini_nomem; } if (gnttab_resume() < 0) return -ENODEV; nr_init_grefs = nr_grant_frames * ENTRIES_PER_GRANT_FRAME; for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) gnttab_entry(i) = i + 1; gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END; gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES; gnttab_free_head = NR_RESERVED_ENTRIES; return 0; ini_nomem: for (i--; i >= 0; i--) free_page((unsigned long)gnttab_list[i]); kfree(gnttab_list); return -ENOMEM; }
int __devinit gnttab_init(void) { int i; unsigned int max_nr_glist_frames, nr_glist_frames; unsigned int nr_init_grefs; if (!is_running_on_xen()) return -ENODEV; #if defined(CONFIG_XEN) && defined(CONFIG_PM_SLEEP) if (!is_initial_xendomain()) { int err = sysdev_class_register(&gnttab_sysclass); if (!err) err = sysdev_register(&device_gnttab); if (err) return err; } #endif nr_grant_frames = 1; boot_max_nr_grant_frames = __max_nr_grant_frames(); /* Determine the maximum number of frames required for the * grant reference free list on the current hypervisor. */ max_nr_glist_frames = nr_freelist_frames(boot_max_nr_grant_frames); gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *), GFP_KERNEL); if (gnttab_list == NULL) return -ENOMEM; nr_glist_frames = nr_freelist_frames(nr_grant_frames); for (i = 0; i < nr_glist_frames; i++) { gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); if (gnttab_list[i] == NULL) goto ini_nomem; } if (gnttab_resume() < 0) return -ENODEV; nr_init_grefs = nr_grant_frames * ENTRIES_PER_GRANT_FRAME; for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) gnttab_entry(i) = i + 1; gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END; gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES; gnttab_free_head = NR_RESERVED_ENTRIES; #if defined(CONFIG_XEN) && defined(__HAVE_ARCH_PTE_SPECIAL) if (!xen_feature(XENFEAT_auto_translated_physmap) && xen_feature(XENFEAT_gnttab_map_avail_bits)) { #ifdef CONFIG_X86 GNTMAP_pte_special = (__pte_val(pte_mkspecial(__pte_ma(0))) >> _PAGE_BIT_UNUSED1) << _GNTMAP_guest_avail0; #else #error Architecture not yet supported. #endif }