~ressu/+junk/xen-ubuntu

« back to all changes in this revision

Viewing changes to xen/drivers/passthrough/amd/pci_amd_iommu.c

  • Committer: sami at haahtinen
  • Date: 2011-05-23 19:11:45 UTC
  • mfrom: (3.1.3 xen)
  • Revision ID: sami@haahtinen.name-20110523191145-55rhsn3endndbbge
* Upload new version to ppa, base off the 4.1.0 package in debian
* Re-enable hvmloader:
  - Use packaged ipxe.
* Workaround incompatibility with xenstored of Xen 4.0.
* New upstream release.
* New upstream release candidate.
* Build documentation using pdflatex.
* Use python 2.6. (closes: #596545)
* Fix lintian override.
* Install new tools: xl, xenpaging.
* Enable blktap2.
  - Use own md5 implementation.
  - Fix includes.
  - Fix linking of blktap2 binaries.
  - Remove optimization setting.
* Temporarily disable hvmloader, wants to download ipxe.
* Remove xenstored pid check from xl.

Show diffs side-by-side

added added

removed removed

Lines of Context:
109
109
        invalidate_dev_table_entry(iommu, req_id);
110
110
        flush_command_buffer(iommu);
111
111
 
112
 
        AMD_IOMMU_DEBUG("Setup I/O page table at DTE:0x%x, root_table:%"PRIx64","
113
 
        "domain_id:%d, paging_mode:%d\n", req_id,
114
 
        page_to_maddr(hd->root_table), hd->domain_id, hd->paging_mode);
 
112
        AMD_IOMMU_DEBUG("Setup I/O page table: device id = 0x%04x, "
 
113
                        "root table = 0x%"PRIx64", "
 
114
                        "domain = %d, paging mode = %d\n", req_id,
 
115
                        page_to_maddr(hd->root_table),
 
116
                        hd->domain_id, hd->paging_mode);
115
117
    }
116
118
 
117
119
    spin_unlock_irqrestore(&iommu->lock, flags);
118
120
}
119
121
 
120
 
static void amd_iommu_setup_dom0_devices(struct domain *d)
 
122
static void __init amd_iommu_setup_dom0_devices(struct domain *d)
121
123
{
122
124
    struct amd_iommu *iommu;
123
125
    struct pci_dev *pdev;
124
 
    int bus, dev, func;
125
 
    u32 l;
126
 
    int bdf;
 
126
    int bus, devfn, bdf;
127
127
 
128
128
    spin_lock(&pcidevs_lock);
129
129
    for ( bus = 0; bus < 256; bus++ )
130
130
    {
131
 
        for ( dev = 0; dev < 32; dev++ )
 
131
        for ( devfn = 0; devfn < 256; devfn++ )
132
132
        {
133
 
            for ( func = 0; func < 8; func++ )
134
 
            {
135
 
                l = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID);
136
 
                /* some broken boards return 0 or ~0 if a slot is empty: */
137
 
                if ( (l == 0xffffffff) || (l == 0x00000000) ||
138
 
                     (l == 0x0000ffff) || (l == 0xffff0000) )
139
 
                    continue;
140
 
 
141
 
                pdev = alloc_pdev(bus, PCI_DEVFN(dev, func));
142
 
                pdev->domain = d;
143
 
                list_add(&pdev->domain_list, &d->arch.pdev_list);
144
 
 
145
 
                bdf = (bus << 8) | pdev->devfn;
146
 
                iommu = find_iommu_for_device(bdf);
147
 
 
148
 
                if ( !iommu )
149
 
                {
150
 
                    AMD_IOMMU_DEBUG("Fail to find iommu for device"
151
 
                        "%02x:%02x.%x\n", bus, dev, func);
152
 
                    continue;
153
 
                }
 
133
            pdev = pci_get_pdev(bus, devfn);
 
134
            if ( !pdev )
 
135
                continue;
 
136
 
 
137
            pdev->domain = d;
 
138
            list_add(&pdev->domain_list, &d->arch.pdev_list);
 
139
 
 
140
            bdf = (bus << 8) | devfn;
 
141
            iommu = find_iommu_for_device(bdf);
 
142
 
 
143
            if ( likely(iommu != NULL) )
154
144
                amd_iommu_setup_domain_device(d, iommu, bdf);
155
 
            }
 
145
            else
 
146
                AMD_IOMMU_DEBUG("No iommu for device %02x:%02x.%x\n",
 
147
                                bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
156
148
        }
157
149
    }
158
150
    spin_unlock(&pcidevs_lock);
159
151
}
160
152
 
161
 
int amd_iov_detect(void)
 
153
int __init amd_iov_detect(void)
162
154
{
163
155
    INIT_LIST_HEAD(&amd_iommu_head);
164
156
 
170
162
 
171
163
    if ( amd_iommu_init() != 0 )
172
164
    {
173
 
        printk("Error initialization\n");
 
165
        printk("AMD-Vi: Error initialization\n");
174
166
        return -ENODEV;
175
167
    }
176
 
    return 0;
 
168
 
 
169
    return scan_pci_devices();
177
170
}
178
171
 
179
172
static int allocate_domain_resources(struct hvm_iommu *hd)
197
190
{
198
191
    int level = 1;
199
192
 
200
 
    BUG_ON(!max_page);
201
 
 
202
 
    if ( entries > max_page )
203
 
        entries = max_page;
 
193
    BUG_ON( !entries );
204
194
 
205
195
    while ( entries > PTE_PER_TABLE_SIZE )
206
196
    {
224
214
        return -ENOMEM;
225
215
    }
226
216
 
 
217
    /* For pv and dom0, stick with get_paging_mode(max_page)
 
218
     * For HVM dom0, use 2 level page table at first */
227
219
    hd->paging_mode = is_hvm_domain(d) ?
228
 
        IOMMU_PAGE_TABLE_LEVEL_4 : get_paging_mode(max_page);
 
220
                      IOMMU_PAGING_MODE_LEVEL_2 :
 
221
                      get_paging_mode(max_page);
229
222
 
230
223
    hd->domain_id = d->domain_id;
231
224
 
232
225
    return 0;
233
226
}
234
227
 
235
 
static void amd_iommu_dom0_init(struct domain *d)
 
228
static void __init amd_iommu_dom0_init(struct domain *d)
236
229
{
237
230
    unsigned long i; 
238
231
 
239
232
    if ( !iommu_passthrough && !need_iommu(d) )
240
233
    {
241
234
        /* Set up 1:1 page table for dom0 */
242
 
        for ( i = 0; i < max_page; i++ )
243
 
            amd_iommu_map_page(d, i, i, IOMMUF_readable|IOMMUF_writable);
 
235
        for ( i = 0; i < max_pdx; i++ )
 
236
        {
 
237
            unsigned long pfn = pdx_to_pfn(i);
 
238
 
 
239
            /*
 
240
             * XXX Should we really map all non-RAM (above 4G)? Minimally
 
241
             * a pfn_valid() check would seem desirable here.
 
242
             */
 
243
            amd_iommu_map_page(d, pfn, pfn, IOMMUF_readable|IOMMUF_writable);
 
244
        }
244
245
    }
245
246
 
246
247
    amd_iommu_setup_dom0_devices(d);
263
264
        disable_translation((u32 *)dte);
264
265
        invalidate_dev_table_entry(iommu, req_id);
265
266
        flush_command_buffer(iommu);
266
 
        AMD_IOMMU_DEBUG("Disable DTE:0x%x,"
267
 
                " domain_id:%d, paging_mode:%d\n",
268
 
                req_id,  domain_hvm_iommu(domain)->domain_id,
269
 
                domain_hvm_iommu(domain)->paging_mode);
 
267
        AMD_IOMMU_DEBUG("Disable: device id = 0x%04x, "
 
268
                        "domain = %d, paging mode = %d\n",
 
269
                        req_id,  domain_hvm_iommu(domain)->domain_id,
 
270
                        domain_hvm_iommu(domain)->paging_mode);
270
271
    }
271
272
    spin_unlock_irqrestore(&iommu->lock, flags);
272
273
}
277
278
    struct pci_dev *pdev;
278
279
    struct amd_iommu *iommu;
279
280
    int bdf;
 
281
    struct hvm_iommu *t = domain_hvm_iommu(target);
280
282
 
281
283
    ASSERT(spin_is_locked(&pcidevs_lock));
282
284
    pdev = pci_get_pdev_by_domain(source, bus, devfn);
288
290
    if ( !iommu )
289
291
    {
290
292
        AMD_IOMMU_DEBUG("Fail to find iommu."
291
 
            " %x:%x.%x cannot be assigned to domain %d\n", 
292
 
            bus, PCI_SLOT(devfn), PCI_FUNC(devfn), target->domain_id);
 
293
                        " %02x:%x02.%x cannot be assigned to domain %d\n", 
 
294
                        bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
 
295
                        target->domain_id);
293
296
        return -ENODEV;
294
297
    }
295
298
 
298
301
    list_move(&pdev->domain_list, &target->arch.pdev_list);
299
302
    pdev->domain = target;
300
303
 
 
304
    /* IO page tables might be destroyed after pci-detach the last device
 
305
     * In this case, we have to re-allocate root table for next pci-attach.*/
 
306
    if ( t->root_table == NULL )
 
307
        allocate_domain_resources(t);
 
308
 
301
309
    amd_iommu_setup_domain_device(target, iommu, bdf);
302
 
    AMD_IOMMU_DEBUG("reassign %x:%x.%x domain %d -> domain %d\n",
303
 
                 bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
304
 
                 source->domain_id, target->domain_id);
 
310
    AMD_IOMMU_DEBUG("Re-assign %02x:%02x.%x from domain %d to domain %d\n",
 
311
                    bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
 
312
                    source->domain_id, target->domain_id);
305
313
 
306
314
    return 0;
307
315
}
388
396
    if ( !iommu )
389
397
    {
390
398
        AMD_IOMMU_DEBUG("Fail to find iommu."
391
 
            " %x:%x.%x cannot be assigned to domain %d\n", 
392
 
            pdev->bus, PCI_SLOT(pdev->devfn),
393
 
            PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
 
399
                        " %02x:%02x.%x cannot be assigned to domain %d\n", 
 
400
                        pdev->bus, PCI_SLOT(pdev->devfn),
 
401
                        PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
394
402
        return -ENODEV;
395
403
    }
396
404
 
410
418
    if ( !iommu )
411
419
    {
412
420
        AMD_IOMMU_DEBUG("Fail to find iommu."
413
 
            " %x:%x.%x cannot be removed from domain %d\n", 
414
 
            pdev->bus, PCI_SLOT(pdev->devfn),
415
 
            PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
 
421
                        " %02x:%02x.%x cannot be removed from domain %d\n", 
 
422
                        pdev->bus, PCI_SLOT(pdev->devfn),
 
423
                        PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
416
424
        return -ENODEV;
417
425
    }
418
426