[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] Ping#2: [PATCH] AMD-Vi: allocate root table on demand



Suravee? Or alternatively, Sherry, is Suravee unavailable for an
extended period of time?

Jan

>>> On 10.03.17 at 17:19, <JBeulich@xxxxxxxx> wrote:
>>>> On 03.03.17 at 15:29, <JBeulich@xxxxxxxx> wrote:
>> This was my originally intended fix for the AMD side of XSA-207:
>> There's no need to unconditionally allocate the root table, and with
>> that there's then also no way to leak it when a guest has no devices
>> assigned.
>> 
>> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
>> 
>> --- a/xen/drivers/passthrough/amd/iommu_map.c
>> +++ b/xen/drivers/passthrough/amd/iommu_map.c
>> @@ -636,11 +636,10 @@ int amd_iommu_map_page(struct domain *d,
>>  {
>>      bool_t need_flush = 0;
>>      struct domain_iommu *hd = dom_iommu(d);
>> +    int rc;
>>      unsigned long pt_mfn[7];
>>      unsigned int merge_level;
>>  
>> -    BUG_ON( !hd->arch.root_table );
>> -
>>      if ( iommu_use_hap_pt(d) )
>>          return 0;
>>  
>> @@ -648,6 +647,13 @@ int amd_iommu_map_page(struct domain *d,
>>  
>>      spin_lock(&hd->arch.mapping_lock);
>>  
>> +    rc = amd_iommu_alloc_root(hd);
>> +    if ( rc )
>> +    {
>> +        spin_unlock(&hd->arch.mapping_lock);
>> +        return rc;
>> +    }
>> +
>>      /* Since HVM domain is initialized with 2 level IO page table,
>>       * we might need a deeper page table for lager gfn now */
>>      if ( is_hvm_domain(d) )
>> @@ -717,8 +723,6 @@ int amd_iommu_unmap_page(struct domain *
>>      unsigned long pt_mfn[7];
>>      struct domain_iommu *hd = dom_iommu(d);
>>  
>> -    BUG_ON( !hd->arch.root_table );
>> -
>>      if ( iommu_use_hap_pt(d) )
>>          return 0;
>>  
>> @@ -726,6 +730,12 @@ int amd_iommu_unmap_page(struct domain *
>>  
>>      spin_lock(&hd->arch.mapping_lock);
>>  
>> +    if ( !hd->arch.root_table )
>> +    {
>> +        spin_unlock(&hd->arch.mapping_lock);
>> +        return 0;
>> +    }
>> +
>>      /* Since HVM domain is initialized with 2 level IO page table,
>>       * we might need a deeper page table for lager gfn now */
>>      if ( is_hvm_domain(d) )
>> --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
>> +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
>> @@ -222,23 +222,29 @@ int __init amd_iov_detect(void)
>>      return scan_pci_devices();
>>  }
>>  
>> -static int allocate_domain_resources(struct domain_iommu *hd)
>> +int amd_iommu_alloc_root(struct domain_iommu *hd)
>>  {
>> -    /* allocate root table */
>> -    spin_lock(&hd->arch.mapping_lock);
>> -    if ( !hd->arch.root_table )
>> +    if ( unlikely(!hd->arch.root_table) )
>>      {
>>          hd->arch.root_table = alloc_amd_iommu_pgtable();
>>          if ( !hd->arch.root_table )
>> -        {
>> -            spin_unlock(&hd->arch.mapping_lock);
>>              return -ENOMEM;
>> -        }
>>      }
>> -    spin_unlock(&hd->arch.mapping_lock);
>> +
>>      return 0;
>>  }
>>  
>> +static int __must_check allocate_domain_resources(struct domain_iommu *hd)
>> +{
>> +    int rc;
>> +
>> +    spin_lock(&hd->arch.mapping_lock);
>> +    rc = amd_iommu_alloc_root(hd);
>> +    spin_unlock(&hd->arch.mapping_lock);
>> +
>> +    return rc;
>> +}
>> +
>>  static int get_paging_mode(unsigned long entries)
>>  {
>>      int level = 1;
>> @@ -259,14 +265,6 @@ static int amd_iommu_domain_init(struct
>>  {
>>      struct domain_iommu *hd = dom_iommu(d);
>>  
>> -    /* allocate page directroy */
>> -    if ( allocate_domain_resources(hd) != 0 )
>> -    {
>> -        if ( hd->arch.root_table )
>> -            free_domheap_page(hd->arch.root_table);
>> -        return -ENOMEM;
>> -    }
>> -
>>      /* For pv and dom0, stick with get_paging_mode(max_page)
>>       * For HVM dom0, use 2 level page table at first */
>>      hd->arch.paging_mode = is_hvm_domain(d) ?
>> @@ -280,6 +278,9 @@ static void __hwdom_init amd_iommu_hwdom
>>      unsigned long i; 
>>      const struct amd_iommu *iommu;
>>  
>> +    if ( allocate_domain_resources(dom_iommu(d)) )
>> +        BUG();
>> +
>>      if ( !iommu_passthrough && !need_iommu(d) )
>>      {
>>          int rc = 0;
>> @@ -363,7 +364,7 @@ static int reassign_device(struct domain
>>                             u8 devfn, struct pci_dev *pdev)
>>  {
>>      struct amd_iommu *iommu;
>> -    int bdf;
>> +    int bdf, rc;
>>      struct domain_iommu *t = dom_iommu(target);
>>  
>>      bdf = PCI_BDF2(pdev->bus, pdev->devfn);
>> @@ -385,10 +386,9 @@ static int reassign_device(struct domain
>>          pdev->domain = target;
>>      }
>>  
>> -    /* IO page tables might be destroyed after pci-detach the last device
>> -     * In this case, we have to re-allocate root table for next 
> pci-attach.*/
>> -    if ( t->arch.root_table == NULL )
>> -        allocate_domain_resources(t);
>> +    rc = allocate_domain_resources(t);
>> +    if ( rc )
>> +        return rc;
>>  
>>      amd_iommu_setup_domain_device(target, iommu, devfn, pdev);
>>      AMD_IOMMU_DEBUG("Re-assign %04x:%02x:%02x.%u from dom%d to dom%d\n",
>> --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
>> +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
>> @@ -56,6 +56,7 @@ int __must_check amd_iommu_map_page(stru
>>                                      unsigned long mfn, unsigned int flags);
>>  int __must_check amd_iommu_unmap_page(struct domain *d, unsigned long gfn);
>>  u64 amd_iommu_get_next_table_from_pte(u32 *entry);
>> +int __must_check amd_iommu_alloc_root(struct domain_iommu *hd);
>>  int amd_iommu_reserve_domain_unity_map(struct domain *domain,
>>                                         u64 phys_addr, unsigned long size,
>>                                         int iw, int ir);
> 
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx 
> https://lists.xen.org/xen-devel 



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.