static __user void *mpx_get_bounds_dir(void) { const struct bndcsr *bndcsr; if (!cpu_feature_enabled(X86_FEATURE_MPX)) return MPX_INVALID_BOUNDS_DIR; /* * The bounds directory pointer is stored in a register * only accessible if we first do an xsave. */ bndcsr = get_xsave_field_ptr(XSTATE_BNDCSR); if (!bndcsr) return MPX_INVALID_BOUNDS_DIR; /* * Make sure the register looks valid by checking the * enable bit. */ if (!(bndcsr->bndcfgu & MPX_BNDCFG_ENABLE_FLAG)) return MPX_INVALID_BOUNDS_DIR; /* * Lastly, mask off the low bits used for configuration * flags, and return the address of the bounds table. */ return (void __user *)(unsigned long) (bndcsr->bndcfgu & MPX_BNDCFG_ADDR_MASK); }
int mpx_disable_management(void) { struct mm_struct *mm = current->mm; if (!cpu_feature_enabled(X86_FEATURE_MPX)) return -ENXIO; down_write(&mm->mmap_sem); mm->bd_addr = MPX_INVALID_BOUNDS_DIR; up_write(&mm->mmap_sem); return 0; }
int intel_svm_init(struct intel_iommu *iommu) { struct page *pages; int order; if (cpu_feature_enabled(X86_FEATURE_GBPAGES) && !cap_fl1gp_support(iommu->cap)) return -EINVAL; if (cpu_feature_enabled(X86_FEATURE_LA57) && !cap_5lp_support(iommu->cap)) return -EINVAL; /* Start at 2 because it's defined as 2^(1+PSS) */ iommu->pasid_max = 2 << ecap_pss(iommu->ecap); /* Eventually I'm promised we will get a multi-level PASID table * and it won't have to be physically contiguous. Until then, * limit the size because 8MiB contiguous allocations can be hard * to come by. The limit of 0x20000, which is 1MiB for each of * the PASID and PASID-state tables, is somewhat arbitrary. */ if (iommu->pasid_max > 0x20000) iommu->pasid_max = 0x20000; order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); if (ecap_dis(iommu->ecap)) { /* Just making it explicit... */ BUILD_BUG_ON(sizeof(struct pasid_entry) != sizeof(struct pasid_state_entry)); pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); if (pages) iommu->pasid_state_table = page_address(pages); else pr_warn("IOMMU: %s: Failed to allocate PASID state table\n", iommu->name); } return 0; }