RE: [PATCH 2/2] Intel-IOMMU, intr-remap: source-id checking

2009-05-19 Thread Han, Weidong
Ingo Molnar wrote:
 * Han, Weidong weidong@intel.com wrote:
 
 Ingo Molnar wrote:
 * Han, Weidong weidong@intel.com wrote:
 
 Siddha, Suresh B wrote:
 On Wed, 2009-05-06 at 23:16 -0700, Han, Weidong wrote:
 @@ -634,6 +694,44 @@ static int ir_parse_ioapic_scope(struct
 acpi_dmar_header *header,  0x%Lx\n,
 scope-enumeration_id, drhd-address);
 
 +bus = pci_find_bus(drhd-segment, scope-bus);
 +path = (struct acpi_dmar_pci_path *)(scope + 
 1); +  count =
 (scope-length - +sizeof(struct 
 acpi_dmar_device_scope))
 +/ sizeof(struct acpi_dmar_pci_path);
 +
 +while (count) {
 +if (pdev)
 +pci_dev_put(pdev);
 +
 +if (!bus)
 +break;
 +
 +pdev = pci_get_slot(bus,
 +PCI_DEVFN(path-dev, path-fn));
 +if (!pdev)
 +break;
 
 ir_parse_ioapic_scope() happens very early in the boot. So, I
 don't think we can do the pci related discovery here.
 
 
 Thanks for your pointing it out. It should enable the source-id
 checking for io-apic's after the pci subsystem is up. I will
 change it.
 
 Note, there's ways to do early PCI quirks too, check
 arch/x86/kernel/early-quirks.c. It's done by reading the PCI
 configuration space directly via a careful early-capable subset of
 the PCI config space APIs. 
 
 But it's a method of last resort.
 
 
 Thanks for your reminder. It can use direct PCI access here as
 follows. It's easy and clean. I think it's better than adding the
 source-id checking for io-apic's after the pci subsystem is up. I
 will send out updated patches after some tests.   
 
 @@ -634,6 +695,24 @@ static int ir_parse_ioapic_scope(struct
acpi_dmar_header *header,  0x%Lx\n,
scope-enumeration_id, drhd-address);
 
 +   bus = scope-bus;
 +   path = (struct acpi_dmar_pci_path *)(scope +
 1); +   count = (scope-length -
 +sizeof(struct
 acpi_dmar_device_scope)) +   /
 sizeof(struct acpi_dmar_pci_path); + +   while
 (--count  0) { +   /* Access PCI
 directly due to the PCI +* subsystem
 isn't initialized yet. +*/
 +   bus = read_pci_config_byte(bus,
 path-dev, +   path-fn,
 PCI_SECONDARY_BUS); +   path++;
 +   }
 +
 +   ir_ioapic[ir_ioapic_num].bus = bus;
 +   ir_ioapic[ir_ioapic_num].devfn =
 +   PCI_DEVFN(path-dev,
 path-fn); 
 
 looks good IMO, beyond the obligatory comment-style nitpick [*] :-)
 Also, the function above seems to be way too large - please split it
 into a couple of natural helper functions.
 
 Thanks,
 
   Ingo
 
 [*]
 
 Please use the customary comment style:
 
   /*
* Comment .
* .. goes here:
*/
 
 specified in Documentation/CodingStyle.

I have sent out the updated patches. Thanks!

Regards,
Weidong--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 2/2] Intel-IOMMU, intr-remap: source-id checking

2009-05-18 Thread Han, Weidong
Ingo Molnar wrote:
 * Han, Weidong weidong@intel.com wrote:
 
 Siddha, Suresh B wrote:
 On Wed, 2009-05-06 at 23:16 -0700, Han, Weidong wrote:
 @@ -634,6 +694,44 @@ static int ir_parse_ioapic_scope(struct
   acpi_dmar_header *header,  0x%Lx\n,
   scope-enumeration_id, drhd-address);
 
 +  bus = pci_find_bus(drhd-segment, scope-bus);
 +  path = (struct acpi_dmar_pci_path *)(scope + 1); +  
 count =
 (scope-length - +  sizeof(struct 
 acpi_dmar_device_scope))
 +  / sizeof(struct acpi_dmar_pci_path);
 +
 +  while (count) {
 +  if (pdev)
 +  pci_dev_put(pdev);
 +
 +  if (!bus)
 +  break;
 +
 +  pdev = pci_get_slot(bus,
 +  PCI_DEVFN(path-dev, path-fn));
 +  if (!pdev)
 +  break;
 
 ir_parse_ioapic_scope() happens very early in the boot. So, I
 don't think we can do the pci related discovery here.
 
 
 Thanks for your pointing it out. It should enable the source-id
 checking for io-apic's after the pci subsystem is up. I will
 change it.
 
 Note, there's ways to do early PCI quirks too, check
 arch/x86/kernel/early-quirks.c. It's done by reading the PCI
 configuration space directly via a careful early-capable subset of
 the PCI config space APIs.
 
 But it's a method of last resort.
 

Thanks for your reminder. It can use direct PCI access here as follows. It's 
easy and clean. I think it's better than adding the source-id checking for 
io-apic's after the pci subsystem is up. I will send out updated patches after 
some tests.
 
@@ -634,6 +695,24 @@ static int ir_parse_ioapic_scope(struct acpi_dmar_header 
*header,
0x%Lx\n, scope-enumeration_id,
   drhd-address);

+   bus = scope-bus;
+   path = (struct acpi_dmar_pci_path *)(scope + 1);
+   count = (scope-length -
+sizeof(struct acpi_dmar_device_scope))
+   / sizeof(struct acpi_dmar_pci_path);
+
+   while (--count  0) {
+   /* Access PCI directly due to the PCI
+* subsystem isn't initialized yet.
+*/
+   bus = read_pci_config_byte(bus, path-dev,
+   path-fn, PCI_SECONDARY_BUS);
+   path++;
+   }
+
+   ir_ioapic[ir_ioapic_num].bus = bus;
+   ir_ioapic[ir_ioapic_num].devfn =
+   PCI_DEVFN(path-dev, path-fn);
ir_ioapic[ir_ioapic_num].iommu = iommu;
ir_ioapic[ir_ioapic_num].id = scope-enumeration_id;
ir_ioapic_num++;




--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 2/2] Intel-IOMMU, intr-remap: source-id checking

2009-05-11 Thread Han, Weidong
Siddha, Suresh B wrote:
 On Wed, 2009-05-06 at 23:16 -0700, Han, Weidong wrote:
 @@ -634,6 +694,44 @@ static int ir_parse_ioapic_scope(struct
 acpi_dmar_header *header,  0x%Lx\n,
 scope-enumeration_id, drhd-address);
 
 +bus = pci_find_bus(drhd-segment, scope-bus);
 +path = (struct acpi_dmar_pci_path *)(scope + 1); +  
 count =
 (scope-length - +sizeof(struct 
 acpi_dmar_device_scope))
 +/ sizeof(struct acpi_dmar_pci_path);
 +
 +while (count) {
 +if (pdev)
 +pci_dev_put(pdev);
 +
 +if (!bus)
 +break;
 +
 +pdev = pci_get_slot(bus,
 +PCI_DEVFN(path-dev, path-fn));
 +if (!pdev)
 +break;
 
 ir_parse_ioapic_scope() happens very early in the boot. So, I don't
 think we can do the pci related discovery here.
 

Thanks for your pointing it out. It should enable the source-id checking for 
io-apic's after the pci subsystem is up. I will change it.

Regards,
Weidong--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] Intel-IOMMU, intr-remap: source-id checking

2009-05-07 Thread Weidong Han
To support domain-isolation usages, the platform hardware must be
capable of uniquely identifying the requestor (source-id) for each
interrupt message. Without source-id checking for interrupt remapping
, a rouge guest/VM with assigned devices can launch interrupt attacks
to bring down anothe guest/VM or the VMM itself.

This patch adds source-id checking for interrupt remapping, and then
really isolates interrupts for guests/VMs with assigned devices.

Signed-off-by: Weidong Han weidong@intel.com
---
 arch/x86/kernel/apic/io_apic.c |6 +++
 drivers/pci/intr_remapping.c   |   98 
 drivers/pci/intr_remapping.h   |2 +
 include/linux/dmar.h   |   11 +
 4 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 30da617..3d10c68 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1559,6 +1559,9 @@ int setup_ioapic_entry(int apic_id, int irq,
irte.vector = vector;
irte.dest_id = IRTE_DEST(destination);
 
+   /* Set source-id of interrupt request */
+   set_ioapic_sid(irte, apic_id);
+
modify_irte(irq, irte);
 
ir_entry-index2 = (index  15)  0x1;
@@ -3329,6 +3332,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned 
int irq, struct msi_ms
irte.vector = cfg-vector;
irte.dest_id = IRTE_DEST(dest);
 
+   /* Set source-id of interrupt request */
+   set_msi_sid(irte, pdev);
+
modify_irte(irq, irte);
 
msg-address_hi = MSI_ADDR_BASE_HI;
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 946e170..825bca2 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -10,6 +10,7 @@
 #include linux/intel-iommu.h
 #include intr_remapping.h
 #include acpi/acpi.h
+#include pci.h
 
 static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
 static int ir_ioapic_num;
@@ -405,6 +406,61 @@ int free_irte(int irq)
return rc;
 }
 
+int set_ioapic_sid(struct irte *irte, int apic)
+{
+   int i;
+   u16 sid = 0;
+
+   if (!irte)
+   return -1;
+
+   for (i = 0; i  MAX_IO_APICS; i++)
+   if (ir_ioapic[i].id == apic) {
+   sid = (ir_ioapic[i].bus  8) | ir_ioapic[i].devfn;
+   break;
+   }
+
+   if (sid == 0) {
+   printk(KERN_WARNING Failed to set source-id of 
+  I/O APIC (%d), because it is not under 
+  any DRHD\n, apic);
+   return -1;
+   }
+
+   irte-svt = 1; /* requestor ID verification SID/SQ */
+   irte-sq = 0;  /* comparing all 16-bit of SID */
+   irte-sid = sid;
+
+   return 0;
+}
+
+int set_msi_sid(struct irte *irte, struct pci_dev *dev)
+{
+   struct pci_dev *tmp;
+
+   if (!irte || !dev)
+   return -1;
+
+   tmp = pci_find_upstream_pcie_bridge(dev);
+   if (!tmp) { /* PCIE device or integrated PCI device */
+   irte-svt = 1; /* verify requestor ID verification SID/SQ */
+   irte-sq = 0;  /* comparing all 16-bit of SID */
+   irte-sid = (dev-bus-number  8) | dev-devfn;
+   return 0;
+   }
+
+   if (tmp-is_pcie) { /* this is a PCIE-to-PCI bridge */
+   irte-svt = 2; /* verify request ID verification SID */
+   irte-sid = (tmp-bus-number  8) | dev-bus-number;
+   } else { /* this is a legacy PCI bridge */
+   irte-svt = 1; /* verify requestor ID verification SID/SQ */
+   irte-sq = 0;  /* comparing all 16-bit of SID */
+   irte-sid = (tmp-bus-number  8) | tmp-devfn;
+   }
+
+   return 0;
+}
+
 static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
 {
u64 addr;
@@ -616,6 +672,10 @@ static int ir_parse_ioapic_scope(struct acpi_dmar_header 
*header,
struct acpi_dmar_hardware_unit *drhd;
struct acpi_dmar_device_scope *scope;
void *start, *end;
+   struct acpi_dmar_pci_path *path;
+   struct pci_bus *bus;
+   struct pci_dev *pdev = NULL;
+   int count;
 
drhd = (struct acpi_dmar_hardware_unit *)header;
 
@@ -634,6 +694,44 @@ static int ir_parse_ioapic_scope(struct acpi_dmar_header 
*header,
0x%Lx\n, scope-enumeration_id,
   drhd-address);
 
+   bus = pci_find_bus(drhd-segment, scope-bus);
+   path = (struct acpi_dmar_pci_path *)(scope + 1);
+   count = (scope-length -
+sizeof(struct acpi_dmar_device_scope))
+   / sizeof(struct acpi_dmar_pci_path);
+
+   while (count) {
+   if (pdev)
+ 

Re: [PATCH 2/2] Intel-IOMMU, intr-remap: source-id checking

2009-05-07 Thread Suresh Siddha
On Wed, 2009-05-06 at 23:16 -0700, Han, Weidong wrote:
 @@ -634,6 +694,44 @@ static int ir_parse_ioapic_scope(struct acpi_dmar_header 
 *header,
   0x%Lx\n, scope-enumeration_id,
  drhd-address);
  
 + bus = pci_find_bus(drhd-segment, scope-bus);
 + path = (struct acpi_dmar_pci_path *)(scope + 1);
 + count = (scope-length -
 +  sizeof(struct acpi_dmar_device_scope))
 + / sizeof(struct acpi_dmar_pci_path);
 +
 + while (count) {
 + if (pdev)
 + pci_dev_put(pdev);
 +
 + if (!bus)
 + break;
 +
 + pdev = pci_get_slot(bus,
 + PCI_DEVFN(path-dev, path-fn));
 + if (!pdev)
 + break;

ir_parse_ioapic_scope() happens very early in the boot. So, I don't
think we can do the pci related discovery here.

thanks,
suresh

 +
 + path++;
 + count--;
 + bus = pdev-subordinate;
 + }
 +
 + if (pdev) { /* PCI discoverable IOAPIC*/
 + ir_ioapic[ir_ioapic_num].bus =
 + pdev-bus-number;
 + ir_ioapic[ir_ioapic_num].devfn = pdev-devfn;
 + } else { /* Not PCI discoverable IOAPIC */
 + if (!bus)
 + ir_ioapic[ir_ioapic_num].bus =
 + scope-bus;
 + else
 + ir_ioapic[ir_ioapic_num].bus =
 + bus-number;
 + ir_ioapic[ir_ioapic_num].devfn =
 + PCI_DEVFN(path-dev, path-fn);
 + }
 +
   ir_ioapic[ir_ioapic_num].iommu = iommu;
   ir_ioapic[ir_ioapic_num].id = scope-enumeration_id;
   ir_ioapic_num++;


--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html