intel_iommu.c (cc2a08480e19007c05be8fe5b6893e20448954dc) intel_iommu.c (642ba89672279fbdd14016a90da239c85e845d18)
1/*
2 * QEMU emulation of an Intel IOMMU (VT-d)
3 * (DMA Remapping device)
4 *
5 * Copyright (C) 2013 Knut Omang, Oracle <knut.omang@oracle.com>
6 * Copyright (C) 2014 Le Tan, <tamlokveer@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 3314 unchanged lines hidden (view full) ---

3323 addr = iommu->intr_root + index * sizeof(*entry);
3324 if (dma_memory_read(&address_space_memory, addr,
3325 entry, sizeof(*entry), MEMTXATTRS_UNSPECIFIED)) {
3326 error_report_once("%s: read failed: ind=0x%x addr=0x%" PRIx64,
3327 __func__, index, addr);
3328 return -VTD_FR_IR_ROOT_INVAL;
3329 }
3330
1/*
2 * QEMU emulation of an Intel IOMMU (VT-d)
3 * (DMA Remapping device)
4 *
5 * Copyright (C) 2013 Knut Omang, Oracle <knut.omang@oracle.com>
6 * Copyright (C) 2014 Le Tan, <tamlokveer@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 3314 unchanged lines hidden (view full) ---

3323 addr = iommu->intr_root + index * sizeof(*entry);
3324 if (dma_memory_read(&address_space_memory, addr,
3325 entry, sizeof(*entry), MEMTXATTRS_UNSPECIFIED)) {
3326 error_report_once("%s: read failed: ind=0x%x addr=0x%" PRIx64,
3327 __func__, index, addr);
3328 return -VTD_FR_IR_ROOT_INVAL;
3329 }
3330
3331 trace_vtd_ir_irte_get(index, le64_to_cpu(entry->data[1]),
3332 le64_to_cpu(entry->data[0]));
3331 entry->data[0] = le64_to_cpu(entry->data[0]);
3332 entry->data[1] = le64_to_cpu(entry->data[1]);
3333
3333
3334 trace_vtd_ir_irte_get(index, entry->data[1], entry->data[0]);
3335
3334 if (!entry->irte.present) {
3335 error_report_once("%s: detected non-present IRTE "
3336 "(index=%u, high=0x%" PRIx64 ", low=0x%" PRIx64 ")",
3336 if (!entry->irte.present) {
3337 error_report_once("%s: detected non-present IRTE "
3338 "(index=%u, high=0x%" PRIx64 ", low=0x%" PRIx64 ")",
3337 __func__, index, le64_to_cpu(entry->data[1]),
3338 le64_to_cpu(entry->data[0]));
3339 __func__, index, entry->data[1], entry->data[0]);
3339 return -VTD_FR_IR_ENTRY_P;
3340 }
3341
3342 if (entry->irte.__reserved_0 || entry->irte.__reserved_1 ||
3343 entry->irte.__reserved_2) {
3344 error_report_once("%s: detected non-zero reserved IRTE "
3345 "(index=%u, high=0x%" PRIx64 ", low=0x%" PRIx64 ")",
3340 return -VTD_FR_IR_ENTRY_P;
3341 }
3342
3343 if (entry->irte.__reserved_0 || entry->irte.__reserved_1 ||
3344 entry->irte.__reserved_2) {
3345 error_report_once("%s: detected non-zero reserved IRTE "
3346 "(index=%u, high=0x%" PRIx64 ", low=0x%" PRIx64 ")",
3346 __func__, index, le64_to_cpu(entry->data[1]),
3347 le64_to_cpu(entry->data[0]));
3347 __func__, index, entry->data[1], entry->data[0]);
3348 return -VTD_FR_IR_IRTE_RSVD;
3349 }
3350
3351 if (sid != X86_IOMMU_SID_INVALID) {
3352 /* Validate IRTE SID */
3348 return -VTD_FR_IR_IRTE_RSVD;
3349 }
3350
3351 if (sid != X86_IOMMU_SID_INVALID) {
3352 /* Validate IRTE SID */
3353 source_id = le32_to_cpu(entry->irte.source_id);
3353 source_id = entry->irte.source_id;
3354 switch (entry->irte.sid_vtype) {
3355 case VTD_SVT_NONE:
3356 break;
3357
3358 case VTD_SVT_ALL:
3359 mask = vtd_svt_mask[entry->irte.sid_q];
3360 if ((source_id & mask) != (sid & mask)) {
3361 error_report_once("%s: invalid IRTE SID "

--- 37 unchanged lines hidden (view full) ---

3399 ret = vtd_irte_get(iommu, index, &irte, sid);
3400 if (ret) {
3401 return ret;
3402 }
3403
3404 irq->trigger_mode = irte.irte.trigger_mode;
3405 irq->vector = irte.irte.vector;
3406 irq->delivery_mode = irte.irte.delivery_mode;
3354 switch (entry->irte.sid_vtype) {
3355 case VTD_SVT_NONE:
3356 break;
3357
3358 case VTD_SVT_ALL:
3359 mask = vtd_svt_mask[entry->irte.sid_q];
3360 if ((source_id & mask) != (sid & mask)) {
3361 error_report_once("%s: invalid IRTE SID "

--- 37 unchanged lines hidden (view full) ---

3399 ret = vtd_irte_get(iommu, index, &irte, sid);
3400 if (ret) {
3401 return ret;
3402 }
3403
3404 irq->trigger_mode = irte.irte.trigger_mode;
3405 irq->vector = irte.irte.vector;
3406 irq->delivery_mode = irte.irte.delivery_mode;
3407 irq->dest = le32_to_cpu(irte.irte.dest_id);
3407 irq->dest = irte.irte.dest_id;
3408 if (!iommu->intr_eime) {
3409#define VTD_IR_APIC_DEST_MASK (0xff00ULL)
3410#define VTD_IR_APIC_DEST_SHIFT (8)
3411 irq->dest = (irq->dest & VTD_IR_APIC_DEST_MASK) >>
3412 VTD_IR_APIC_DEST_SHIFT;
3413 }
3414 irq->dest_mode = irte.irte.dest_mode;
3415 irq->redir_hint = irte.irte.redir_hint;

--- 797 unchanged lines hidden ---
3408 if (!iommu->intr_eime) {
3409#define VTD_IR_APIC_DEST_MASK (0xff00ULL)
3410#define VTD_IR_APIC_DEST_SHIFT (8)
3411 irq->dest = (irq->dest & VTD_IR_APIC_DEST_MASK) >>
3412 VTD_IR_APIC_DEST_SHIFT;
3413 }
3414 irq->dest_mode = irte.irte.dest_mode;
3415 irq->redir_hint = irte.irte.redir_hint;

--- 797 unchanged lines hidden ---