Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-10-01 Thread Konrad Rzeszutek Wilk
>> I was thinking the other way around. You recover the old affinity. Should
>> you print out a warning mentioning to the system admin that you could not
>> set the new affinity but reverted to the old one? Or will that not serve
>> anything except spam the kernel logs?
>
> Well, I don't think it makes sense to print an additional error at this
> point. The error will be propagated upwards in the call-chain and in the
> end it is up to the initiator how to handle this situation (for example
> just return a failure to user-space).

OK. Thx for the explanation. I was not sure whether the error would
propagate properly up the chain.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-10-01 Thread Joerg Roedel
On Mon, Oct 01, 2012 at 09:47:53AM -0400, Konrad Rzeszutek Wilk wrote:
> On Mon, Oct 01, 2012 at 10:40:51AM +0200, Joerg Roedel wrote:

> > Don't understand this. What is not set?
> 
> the IRQ_DELAYED_DISABLE. But I could not even find that enum anymore?
> Has that been obsoleted?

You are right, its was removed. Ok, I will remove that line of the
comment too.

> I was thinking the other way around. You recover the old affinity. Should
> you print out a warning mentioning to the system admin that you could not
> set the new affinity but reverted to the old one? Or will that not serve
> anything except spam the kernel logs?

Well, I don't think it makes sense to print an additional error at this
point. The error will be propagated upwards in the call-chain and in the
end it is up to the initiator how to handle this situation (for example
just return a failure to user-space).


Joerg

-- 
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-10-01 Thread Konrad Rzeszutek Wilk
On Mon, Oct 01, 2012 at 10:40:51AM +0200, Joerg Roedel wrote:
> On Fri, Sep 28, 2012 at 10:45:15AM -0400, Konrad Rzeszutek Wilk wrote:
> > On Fri, Sep 28, 2012 at 02:23:59PM +0200, Joerg Roedel wrote:
> > > + /*
> > > +  * Mask level triggered irqs.
> > > +  * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
> > 
> > so how come it is not set?
> 
> Don't understand this. What is not set?

the IRQ_DELAYED_DISABLE. But I could not even find that enum anymore?
Has that been obsoleted?
> 
> > > + if (!config_enabled(CONFIG_SMP))
> > > + return -1;
> > 
> > -1? -ENOx something?
> 
> No, -1 for compatibiblity with the other implementation of this.

OK.
> 
> > > + err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, );
> > > + if (err) {
> > > + if (assign_irq_vector(irq, cfg, data->affinity))
> > > + pr_err("AMD-Vi: Failed to recover vector for irq %d\n", 
> > > irq);
> > 
> > If we do OK with the assignment of the vector, should we just continue
> > on instead of returning error?
> 
> The purpose of this is to recover to the old affinity if we failed at
> this point. Even in this case, setting the new affinity still failed and
> we need to inform the caller about this. Thus returning the error.
> Also note the pr_err message which also tells you about the
> recovery-case :)

I was thinking the other way around. You recover the old affinity. Should
you print out a warning mentioning to the system admin that you could not
set the new affinity but reverted to the old one? Or will that not serve
anything except spam the kernel logs?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-10-01 Thread Joerg Roedel
On Fri, Sep 28, 2012 at 10:45:15AM -0400, Konrad Rzeszutek Wilk wrote:
> On Fri, Sep 28, 2012 at 02:23:59PM +0200, Joerg Roedel wrote:
> > +   /*
> > +* Mask level triggered irqs.
> > +* Use IRQ_DELAYED_DISABLE for edge triggered irqs.
> 
> so how come it is not set?

Don't understand this. What is not set?

> > +   if (!config_enabled(CONFIG_SMP))
> > +   return -1;
> 
> -1? -ENOx something?

No, -1 for compatibiblity with the other implementation of this.

> > +   err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, );
> > +   if (err) {
> > +   if (assign_irq_vector(irq, cfg, data->affinity))
> > +   pr_err("AMD-Vi: Failed to recover vector for irq %d\n", 
> > irq);
> 
> If we do OK with the assignment of the vector, should we just continue
> on instead of returning error?

The purpose of this is to recover to the old affinity if we failed at
this point. Even in this case, setting the new affinity still failed and
we need to inform the caller about this. Thus returning the error.
Also note the pr_err message which also tells you about the
recovery-case :)


Joerg


-- 
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-10-01 Thread Joerg Roedel
On Fri, Sep 28, 2012 at 10:45:15AM -0400, Konrad Rzeszutek Wilk wrote:
 On Fri, Sep 28, 2012 at 02:23:59PM +0200, Joerg Roedel wrote:
  +   /*
  +* Mask level triggered irqs.
  +* Use IRQ_DELAYED_DISABLE for edge triggered irqs.
 
 so how come it is not set?

Don't understand this. What is not set?

  +   if (!config_enabled(CONFIG_SMP))
  +   return -1;
 
 -1? -ENOx something?

No, -1 for compatibiblity with the other implementation of this.

  +   err = apic-cpu_mask_to_apicid_and(cfg-domain, mask, dest);
  +   if (err) {
  +   if (assign_irq_vector(irq, cfg, data-affinity))
  +   pr_err(AMD-Vi: Failed to recover vector for irq %d\n, 
  irq);
 
 If we do OK with the assignment of the vector, should we just continue
 on instead of returning error?

The purpose of this is to recover to the old affinity if we failed at
this point. Even in this case, setting the new affinity still failed and
we need to inform the caller about this. Thus returning the error.
Also note the pr_err message which also tells you about the
recovery-case :)


Joerg


-- 
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-10-01 Thread Konrad Rzeszutek Wilk
On Mon, Oct 01, 2012 at 10:40:51AM +0200, Joerg Roedel wrote:
 On Fri, Sep 28, 2012 at 10:45:15AM -0400, Konrad Rzeszutek Wilk wrote:
  On Fri, Sep 28, 2012 at 02:23:59PM +0200, Joerg Roedel wrote:
   + /*
   +  * Mask level triggered irqs.
   +  * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
  
  so how come it is not set?
 
 Don't understand this. What is not set?

the IRQ_DELAYED_DISABLE. But I could not even find that enum anymore?
Has that been obsoleted?
 
   + if (!config_enabled(CONFIG_SMP))
   + return -1;
  
  -1? -ENOx something?
 
 No, -1 for compatibiblity with the other implementation of this.

OK.
 
   + err = apic-cpu_mask_to_apicid_and(cfg-domain, mask, dest);
   + if (err) {
   + if (assign_irq_vector(irq, cfg, data-affinity))
   + pr_err(AMD-Vi: Failed to recover vector for irq %d\n, 
   irq);
  
  If we do OK with the assignment of the vector, should we just continue
  on instead of returning error?
 
 The purpose of this is to recover to the old affinity if we failed at
 this point. Even in this case, setting the new affinity still failed and
 we need to inform the caller about this. Thus returning the error.
 Also note the pr_err message which also tells you about the
 recovery-case :)

I was thinking the other way around. You recover the old affinity. Should
you print out a warning mentioning to the system admin that you could not
set the new affinity but reverted to the old one? Or will that not serve
anything except spam the kernel logs?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-10-01 Thread Joerg Roedel
On Mon, Oct 01, 2012 at 09:47:53AM -0400, Konrad Rzeszutek Wilk wrote:
 On Mon, Oct 01, 2012 at 10:40:51AM +0200, Joerg Roedel wrote:

  Don't understand this. What is not set?
 
 the IRQ_DELAYED_DISABLE. But I could not even find that enum anymore?
 Has that been obsoleted?

You are right, its was removed. Ok, I will remove that line of the
comment too.

 I was thinking the other way around. You recover the old affinity. Should
 you print out a warning mentioning to the system admin that you could not
 set the new affinity but reverted to the old one? Or will that not serve
 anything except spam the kernel logs?

Well, I don't think it makes sense to print an additional error at this
point. The error will be propagated upwards in the call-chain and in the
end it is up to the initiator how to handle this situation (for example
just return a failure to user-space).


Joerg

-- 
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-10-01 Thread Konrad Rzeszutek Wilk
 I was thinking the other way around. You recover the old affinity. Should
 you print out a warning mentioning to the system admin that you could not
 set the new affinity but reverted to the old one? Or will that not serve
 anything except spam the kernel logs?

 Well, I don't think it makes sense to print an additional error at this
 point. The error will be propagated upwards in the call-chain and in the
 end it is up to the initiator how to handle this situation (for example
 just return a failure to user-space).

OK. Thx for the explanation. I was not sure whether the error would
propagate properly up the chain.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-09-28 Thread Konrad Rzeszutek Wilk
On Fri, Sep 28, 2012 at 02:23:59PM +0200, Joerg Roedel wrote:
> Add the routine to setup interrupt remapping for ioapic
> interrupts. Also add a routine to change the affinity of an
> irq and to free an irq allocation for interrupt remapping.
> The last two functions will also be used for MSI interrupts.
> 
> Signed-off-by: Joerg Roedel 
> ---
>  drivers/iommu/amd_iommu.c |  126 
> +
>  1 file changed, 126 insertions(+)
> 
> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> index bd277924..3df01b2 100644
> --- a/drivers/iommu/amd_iommu.c
> +++ b/drivers/iommu/amd_iommu.c
> @@ -4000,4 +4000,130 @@ static void free_irte(u16 devid, int index)
>   iommu_completion_wait(iommu);
>  }
>  
> +static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
> +   unsigned int destination, int vector,
> +   struct io_apic_irq_attr *attr)
> +{
> + struct irq_remap_table *table;
> + struct irq_2_iommu *irte_info;
> + struct irq_cfg *cfg;
> + union irte irte;
> + int ioapic_id;
> + int index;
> + int devid;
> + int ret;
> +
> + cfg = irq_get_chip_data(irq);
> + if (!cfg)
> + return -EINVAL;
> +
> + irte_info = >irq_2_iommu;
> + ioapic_id = mpc_ioapic_id(attr->ioapic);
> + devid = get_ioapic_devid(ioapic_id);
> +
> + if (devid < 0)
> + return devid;
> +
> + table = get_irq_table(devid, true);
> + if (table == NULL)
> + return -ENOMEM;
> +
> + index = attr->ioapic_pin;
> +
> + /* Setup IRQ remapping info */
> + irte_info->sub_handle = devid;
> + irte_info->irte_index = index;
> + irte_info->iommu  = (void *)cfg;
> +
> + /* Setup IRTE for IOMMU */
> + irte.val= 0;
> + irte.fields.vector  = vector;
> + irte.fields.int_type= apic->irq_delivery_mode;
> + irte.fields.destination = destination;
> + irte.fields.dm  = apic->irq_dest_mode;
> + irte.fields.valid   = 1;
> +
> + ret = modify_irte(devid, index, irte);
> + if (ret)
> + return ret;
> +
> + /* Setup IOAPIC entry */
> + memset(entry, 0, sizeof(*entry));
> +
> + entry->vector= index;
> + entry->mask  = 0;
> + entry->trigger   = attr->trigger;
> + entry->polarity  = attr->polarity;
> +
> + /*
> +  * Mask level triggered irqs.
> +  * Use IRQ_DELAYED_DISABLE for edge triggered irqs.

so how come it is not set?

> +  */
> + if (attr->trigger)
> + entry->mask = 1;
> +
> + return 0;
> +}
> +
> +static int set_affinity(struct irq_data *data, const struct cpumask *mask,
> + bool force)
> +{
> + struct irq_2_iommu *irte_info;
> + unsigned int dest, irq;
> + struct irq_cfg *cfg;
> + union irte irte;
> + int err;
> +
> + if (!config_enabled(CONFIG_SMP))
> + return -1;

-1? -ENOx something?
> +
> + cfg   = data->chip_data;
> + irq   = data->irq;
> + irte_info = >irq_2_iommu;
> +
> + if (!cpumask_intersects(mask, cpu_online_mask))
> + return -EINVAL;
> +
> + if (get_irte(irte_info->sub_handle, irte_info->irte_index, ))
> + return -EBUSY;
> +
> + if (assign_irq_vector(irq, cfg, mask))
> + return -EBUSY;
> +
> + err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, );
> + if (err) {
> + if (assign_irq_vector(irq, cfg, data->affinity))
> + pr_err("AMD-Vi: Failed to recover vector for irq %d\n", 
> irq);

If we do OK with the assignment of the vector, should we just continue
on instead of returning error?

> + return err;
> + }
> +
> + irte.fields.vector  = cfg->vector;
> + irte.fields.destination = dest;
> +
> + modify_irte(irte_info->sub_handle, irte_info->irte_index, irte);
> +
> + if (cfg->move_in_progress)
> + send_cleanup_vector(cfg);
> +
> + cpumask_copy(data->affinity, mask);
> +
> + return 0;
> +}
> +
> +static int free_irq(int irq)
> +{
> + struct irq_2_iommu *irte_info;
> + struct irq_cfg *cfg;
> +
> + cfg = irq_get_chip_data(irq);
> + if (!cfg)
> + return -EINVAL;
> +
> + irte_info = >irq_2_iommu;
> +
> + free_irte(irte_info->sub_handle, irte_info->irte_index);
> +
> + return 0;
> +}
> +
>  #endif
> -- 
> 1.7.9.5
> 
> 
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-09-28 Thread Joerg Roedel
Add the routine to setup interrupt remapping for ioapic
interrupts. Also add a routine to change the affinity of an
irq and to free an irq allocation for interrupt remapping.
The last two functions will also be used for MSI interrupts.

Signed-off-by: Joerg Roedel 
---
 drivers/iommu/amd_iommu.c |  126 +
 1 file changed, 126 insertions(+)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index bd277924..3df01b2 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -4000,4 +4000,130 @@ static void free_irte(u16 devid, int index)
iommu_completion_wait(iommu);
 }
 
+static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
+ unsigned int destination, int vector,
+ struct io_apic_irq_attr *attr)
+{
+   struct irq_remap_table *table;
+   struct irq_2_iommu *irte_info;
+   struct irq_cfg *cfg;
+   union irte irte;
+   int ioapic_id;
+   int index;
+   int devid;
+   int ret;
+
+   cfg = irq_get_chip_data(irq);
+   if (!cfg)
+   return -EINVAL;
+
+   irte_info = >irq_2_iommu;
+   ioapic_id = mpc_ioapic_id(attr->ioapic);
+   devid = get_ioapic_devid(ioapic_id);
+
+   if (devid < 0)
+   return devid;
+
+   table = get_irq_table(devid, true);
+   if (table == NULL)
+   return -ENOMEM;
+
+   index = attr->ioapic_pin;
+
+   /* Setup IRQ remapping info */
+   irte_info->sub_handle = devid;
+   irte_info->irte_index = index;
+   irte_info->iommu  = (void *)cfg;
+
+   /* Setup IRTE for IOMMU */
+   irte.val= 0;
+   irte.fields.vector  = vector;
+   irte.fields.int_type= apic->irq_delivery_mode;
+   irte.fields.destination = destination;
+   irte.fields.dm  = apic->irq_dest_mode;
+   irte.fields.valid   = 1;
+
+   ret = modify_irte(devid, index, irte);
+   if (ret)
+   return ret;
+
+   /* Setup IOAPIC entry */
+   memset(entry, 0, sizeof(*entry));
+
+   entry->vector= index;
+   entry->mask  = 0;
+   entry->trigger   = attr->trigger;
+   entry->polarity  = attr->polarity;
+
+   /*
+* Mask level triggered irqs.
+* Use IRQ_DELAYED_DISABLE for edge triggered irqs.
+*/
+   if (attr->trigger)
+   entry->mask = 1;
+
+   return 0;
+}
+
+static int set_affinity(struct irq_data *data, const struct cpumask *mask,
+   bool force)
+{
+   struct irq_2_iommu *irte_info;
+   unsigned int dest, irq;
+   struct irq_cfg *cfg;
+   union irte irte;
+   int err;
+
+   if (!config_enabled(CONFIG_SMP))
+   return -1;
+
+   cfg   = data->chip_data;
+   irq   = data->irq;
+   irte_info = >irq_2_iommu;
+
+   if (!cpumask_intersects(mask, cpu_online_mask))
+   return -EINVAL;
+
+   if (get_irte(irte_info->sub_handle, irte_info->irte_index, ))
+   return -EBUSY;
+
+   if (assign_irq_vector(irq, cfg, mask))
+   return -EBUSY;
+
+   err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, );
+   if (err) {
+   if (assign_irq_vector(irq, cfg, data->affinity))
+   pr_err("AMD-Vi: Failed to recover vector for irq %d\n", 
irq);
+   return err;
+   }
+
+   irte.fields.vector  = cfg->vector;
+   irte.fields.destination = dest;
+
+   modify_irte(irte_info->sub_handle, irte_info->irte_index, irte);
+
+   if (cfg->move_in_progress)
+   send_cleanup_vector(cfg);
+
+   cpumask_copy(data->affinity, mask);
+
+   return 0;
+}
+
+static int free_irq(int irq)
+{
+   struct irq_2_iommu *irte_info;
+   struct irq_cfg *cfg;
+
+   cfg = irq_get_chip_data(irq);
+   if (!cfg)
+   return -EINVAL;
+
+   irte_info = >irq_2_iommu;
+
+   free_irte(irte_info->sub_handle, irte_info->irte_index);
+
+   return 0;
+}
+
 #endif
-- 
1.7.9.5


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-09-28 Thread Joerg Roedel
Add the routine to setup interrupt remapping for ioapic
interrupts. Also add a routine to change the affinity of an
irq and to free an irq allocation for interrupt remapping.
The last two functions will also be used for MSI interrupts.

Signed-off-by: Joerg Roedel joerg.roe...@amd.com
---
 drivers/iommu/amd_iommu.c |  126 +
 1 file changed, 126 insertions(+)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index bd277924..3df01b2 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -4000,4 +4000,130 @@ static void free_irte(u16 devid, int index)
iommu_completion_wait(iommu);
 }
 
+static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
+ unsigned int destination, int vector,
+ struct io_apic_irq_attr *attr)
+{
+   struct irq_remap_table *table;
+   struct irq_2_iommu *irte_info;
+   struct irq_cfg *cfg;
+   union irte irte;
+   int ioapic_id;
+   int index;
+   int devid;
+   int ret;
+
+   cfg = irq_get_chip_data(irq);
+   if (!cfg)
+   return -EINVAL;
+
+   irte_info = cfg-irq_2_iommu;
+   ioapic_id = mpc_ioapic_id(attr-ioapic);
+   devid = get_ioapic_devid(ioapic_id);
+
+   if (devid  0)
+   return devid;
+
+   table = get_irq_table(devid, true);
+   if (table == NULL)
+   return -ENOMEM;
+
+   index = attr-ioapic_pin;
+
+   /* Setup IRQ remapping info */
+   irte_info-sub_handle = devid;
+   irte_info-irte_index = index;
+   irte_info-iommu  = (void *)cfg;
+
+   /* Setup IRTE for IOMMU */
+   irte.val= 0;
+   irte.fields.vector  = vector;
+   irte.fields.int_type= apic-irq_delivery_mode;
+   irte.fields.destination = destination;
+   irte.fields.dm  = apic-irq_dest_mode;
+   irte.fields.valid   = 1;
+
+   ret = modify_irte(devid, index, irte);
+   if (ret)
+   return ret;
+
+   /* Setup IOAPIC entry */
+   memset(entry, 0, sizeof(*entry));
+
+   entry-vector= index;
+   entry-mask  = 0;
+   entry-trigger   = attr-trigger;
+   entry-polarity  = attr-polarity;
+
+   /*
+* Mask level triggered irqs.
+* Use IRQ_DELAYED_DISABLE for edge triggered irqs.
+*/
+   if (attr-trigger)
+   entry-mask = 1;
+
+   return 0;
+}
+
+static int set_affinity(struct irq_data *data, const struct cpumask *mask,
+   bool force)
+{
+   struct irq_2_iommu *irte_info;
+   unsigned int dest, irq;
+   struct irq_cfg *cfg;
+   union irte irte;
+   int err;
+
+   if (!config_enabled(CONFIG_SMP))
+   return -1;
+
+   cfg   = data-chip_data;
+   irq   = data-irq;
+   irte_info = cfg-irq_2_iommu;
+
+   if (!cpumask_intersects(mask, cpu_online_mask))
+   return -EINVAL;
+
+   if (get_irte(irte_info-sub_handle, irte_info-irte_index, irte))
+   return -EBUSY;
+
+   if (assign_irq_vector(irq, cfg, mask))
+   return -EBUSY;
+
+   err = apic-cpu_mask_to_apicid_and(cfg-domain, mask, dest);
+   if (err) {
+   if (assign_irq_vector(irq, cfg, data-affinity))
+   pr_err(AMD-Vi: Failed to recover vector for irq %d\n, 
irq);
+   return err;
+   }
+
+   irte.fields.vector  = cfg-vector;
+   irte.fields.destination = dest;
+
+   modify_irte(irte_info-sub_handle, irte_info-irte_index, irte);
+
+   if (cfg-move_in_progress)
+   send_cleanup_vector(cfg);
+
+   cpumask_copy(data-affinity, mask);
+
+   return 0;
+}
+
+static int free_irq(int irq)
+{
+   struct irq_2_iommu *irte_info;
+   struct irq_cfg *cfg;
+
+   cfg = irq_get_chip_data(irq);
+   if (!cfg)
+   return -EINVAL;
+
+   irte_info = cfg-irq_2_iommu;
+
+   free_irte(irte_info-sub_handle, irte_info-irte_index);
+
+   return 0;
+}
+
 #endif
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/16] iommu/amd: Add IOAPIC remapping routines

2012-09-28 Thread Konrad Rzeszutek Wilk
On Fri, Sep 28, 2012 at 02:23:59PM +0200, Joerg Roedel wrote:
 Add the routine to setup interrupt remapping for ioapic
 interrupts. Also add a routine to change the affinity of an
 irq and to free an irq allocation for interrupt remapping.
 The last two functions will also be used for MSI interrupts.
 
 Signed-off-by: Joerg Roedel joerg.roe...@amd.com
 ---
  drivers/iommu/amd_iommu.c |  126 
 +
  1 file changed, 126 insertions(+)
 
 diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
 index bd277924..3df01b2 100644
 --- a/drivers/iommu/amd_iommu.c
 +++ b/drivers/iommu/amd_iommu.c
 @@ -4000,4 +4000,130 @@ static void free_irte(u16 devid, int index)
   iommu_completion_wait(iommu);
  }
  
 +static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
 +   unsigned int destination, int vector,
 +   struct io_apic_irq_attr *attr)
 +{
 + struct irq_remap_table *table;
 + struct irq_2_iommu *irte_info;
 + struct irq_cfg *cfg;
 + union irte irte;
 + int ioapic_id;
 + int index;
 + int devid;
 + int ret;
 +
 + cfg = irq_get_chip_data(irq);
 + if (!cfg)
 + return -EINVAL;
 +
 + irte_info = cfg-irq_2_iommu;
 + ioapic_id = mpc_ioapic_id(attr-ioapic);
 + devid = get_ioapic_devid(ioapic_id);
 +
 + if (devid  0)
 + return devid;
 +
 + table = get_irq_table(devid, true);
 + if (table == NULL)
 + return -ENOMEM;
 +
 + index = attr-ioapic_pin;
 +
 + /* Setup IRQ remapping info */
 + irte_info-sub_handle = devid;
 + irte_info-irte_index = index;
 + irte_info-iommu  = (void *)cfg;
 +
 + /* Setup IRTE for IOMMU */
 + irte.val= 0;
 + irte.fields.vector  = vector;
 + irte.fields.int_type= apic-irq_delivery_mode;
 + irte.fields.destination = destination;
 + irte.fields.dm  = apic-irq_dest_mode;
 + irte.fields.valid   = 1;
 +
 + ret = modify_irte(devid, index, irte);
 + if (ret)
 + return ret;
 +
 + /* Setup IOAPIC entry */
 + memset(entry, 0, sizeof(*entry));
 +
 + entry-vector= index;
 + entry-mask  = 0;
 + entry-trigger   = attr-trigger;
 + entry-polarity  = attr-polarity;
 +
 + /*
 +  * Mask level triggered irqs.
 +  * Use IRQ_DELAYED_DISABLE for edge triggered irqs.

so how come it is not set?

 +  */
 + if (attr-trigger)
 + entry-mask = 1;
 +
 + return 0;
 +}
 +
 +static int set_affinity(struct irq_data *data, const struct cpumask *mask,
 + bool force)
 +{
 + struct irq_2_iommu *irte_info;
 + unsigned int dest, irq;
 + struct irq_cfg *cfg;
 + union irte irte;
 + int err;
 +
 + if (!config_enabled(CONFIG_SMP))
 + return -1;

-1? -ENOx something?
 +
 + cfg   = data-chip_data;
 + irq   = data-irq;
 + irte_info = cfg-irq_2_iommu;
 +
 + if (!cpumask_intersects(mask, cpu_online_mask))
 + return -EINVAL;
 +
 + if (get_irte(irte_info-sub_handle, irte_info-irte_index, irte))
 + return -EBUSY;
 +
 + if (assign_irq_vector(irq, cfg, mask))
 + return -EBUSY;
 +
 + err = apic-cpu_mask_to_apicid_and(cfg-domain, mask, dest);
 + if (err) {
 + if (assign_irq_vector(irq, cfg, data-affinity))
 + pr_err(AMD-Vi: Failed to recover vector for irq %d\n, 
 irq);

If we do OK with the assignment of the vector, should we just continue
on instead of returning error?

 + return err;
 + }
 +
 + irte.fields.vector  = cfg-vector;
 + irte.fields.destination = dest;
 +
 + modify_irte(irte_info-sub_handle, irte_info-irte_index, irte);
 +
 + if (cfg-move_in_progress)
 + send_cleanup_vector(cfg);
 +
 + cpumask_copy(data-affinity, mask);
 +
 + return 0;
 +}
 +
 +static int free_irq(int irq)
 +{
 + struct irq_2_iommu *irte_info;
 + struct irq_cfg *cfg;
 +
 + cfg = irq_get_chip_data(irq);
 + if (!cfg)
 + return -EINVAL;
 +
 + irte_info = cfg-irq_2_iommu;
 +
 + free_irte(irte_info-sub_handle, irte_info-irte_index);
 +
 + return 0;
 +}
 +
  #endif
 -- 
 1.7.9.5
 
 
 ___
 iommu mailing list
 io...@lists.linux-foundation.org
 https://lists.linuxfoundation.org/mailman/listinfo/iommu
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/