linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
@ 2016-07-01 19:29 Alexander Popov
  2016-07-06 11:17 ` Thomas Gleixner
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Popov @ 2016-07-01 19:29 UTC (permalink / raw)
  To: Jiang Liu, Marc Zyngier, Thomas Gleixner, linux-kernel, Alexander Popov

Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being
able to work with irq_domain hierarchy in modules.

Signed-off-by: Alexander Popov <alex.popov@linux.com>
---
 kernel/irq/irqdomain.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8798b6c..0ad85be 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1225,6 +1225,7 @@ out_free_desc:
 	irq_free_descs(virq, nr_irqs);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(__irq_domain_alloc_irqs);
 
 /**
  * irq_domain_free_irqs - Free IRQ number and associated data structures
@@ -1249,6 +1250,7 @@ void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs)
 	irq_domain_free_irq_data(virq, nr_irqs);
 	irq_free_descs(virq, nr_irqs);
 }
+EXPORT_SYMBOL_GPL(irq_domain_free_irqs);
 
 /**
  * irq_domain_alloc_irqs_parent - Allocate interrupts from parent domain
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-01 19:29 [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() Alexander Popov
@ 2016-07-06 11:17 ` Thomas Gleixner
  2016-07-08  8:34   ` Alexander Popov
  0 siblings, 1 reply; 10+ messages in thread
From: Thomas Gleixner @ 2016-07-06 11:17 UTC (permalink / raw)
  To: Alexander Popov; +Cc: Marc Zyngier, LKML

On Fri, 1 Jul 2016, Alexander Popov wrote:

> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being
> able to work with irq_domain hierarchy in modules.

We usually export only when we have a proper use case which is supposed to go
into the kernel tree proper. What's yours?
 
Thanks,

	tglx

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-06 11:17 ` Thomas Gleixner
@ 2016-07-08  8:34   ` Alexander Popov
  2016-07-16  1:33     ` Alexander Popov
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Popov @ 2016-07-08  8:34 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: Marc Zyngier, LKML, Alexander Popov

On 06.07.2016 14:17, Thomas Gleixner wrote:
> On Fri, 1 Jul 2016, Alexander Popov wrote:
> 
>> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being
>> able to work with irq_domain hierarchy in modules.
> 
> We usually export only when we have a proper use case which is supposed to go
> into the kernel tree proper. What's yours?

Hello, Thomas,

I work at Positive Technologies ( https://www.ptsecurity.com/ ). We develop
a bare-metal hypervisor, which targets x86_64 and supports Linux as a guest OS.

Intel VT-x allows hypervisor to inject interrupts into virtual machines.
We want to handle these interrupts in guest Linux.

So I wrote a simple kernel module creating an irq_domain, which has
x86_vector_domain as a parent in the hierarchy. In this module I just call:
- irq_domain_alloc_irqs() to allocate irqs and allow calling request_irq()
   for them;
- irqd_cfg(irq_get_irq_data()) to get the APIC vectors of the allocated irqs;
- irq_domain_free_irqs() to free the resources at the end.

It allows to handle interrupts injected by the hypervisor in guest Linux easily,
without emulating MSI-capable PCI device at the hypervisor side.

Everything works fine if __irq_domain_alloc_irqs() and irq_domain_free_irqs()
are exported. Is it a proper use-case?

Do you think my module could be useful for the mainline in some form?
It took me some time to understand irq_domain hierarchy design, so I can
prepare some patch or share my code to help others.

Best regards,
Alexander

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-08  8:34   ` Alexander Popov
@ 2016-07-16  1:33     ` Alexander Popov
  2016-07-16  8:22       ` Marc Zyngier
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Popov @ 2016-07-16  1:33 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: Marc Zyngier, LKML

On 08.07.2016 11:34, Alexander Popov wrote:
> On 06.07.2016 14:17, Thomas Gleixner wrote:
>> On Fri, 1 Jul 2016, Alexander Popov wrote:
>>
>>> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being
>>> able to work with irq_domain hierarchy in modules.
>>
>> We usually export only when we have a proper use case which is supposed to go
>> into the kernel tree proper. What's yours?
> 
> Hello, Thomas,
> 
> I work at Positive Technologies ( https://www.ptsecurity.com/ ). We develop
> a bare-metal hypervisor, which targets x86_64 and supports Linux as a guest OS.
> 
> Intel VT-x allows hypervisor to inject interrupts into virtual machines.
> We want to handle these interrupts in guest Linux.
> 
> So I wrote a simple kernel module creating an irq_domain, which has
> x86_vector_domain as a parent in the hierarchy. In this module I just call:
> - irq_domain_alloc_irqs() to allocate irqs and allow calling request_irq()
>    for them;
> - irqd_cfg(irq_get_irq_data()) to get the APIC vectors of the allocated irqs;
> - irq_domain_free_irqs() to free the resources at the end.
> 
> It allows to handle interrupts injected by the hypervisor in guest Linux easily,
> without emulating MSI-capable PCI device at the hypervisor side.
> 
> Everything works fine if __irq_domain_alloc_irqs() and irq_domain_free_irqs()
> are exported. Is it a proper use-case?

Hello again, Thomas,

Did I properly answer your question? Will you accept my patch exporting these
two functions?

> Do you think my module could be useful for the mainline in some form?
> It took me some time to understand irq_domain hierarchy design, so I can
> prepare some patch or share my code to help others.

Do you think my paravirtualization code registering a child irq_domain
for x86_vector_domain could bring any profit to the mainline?
I would be glad to put effort and do it.

Thanks again, sorry for disturbing.

Best regards,
Alexander

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-16  1:33     ` Alexander Popov
@ 2016-07-16  8:22       ` Marc Zyngier
  2016-07-18 12:34         ` Alexander Popov
  0 siblings, 1 reply; 10+ messages in thread
From: Marc Zyngier @ 2016-07-16  8:22 UTC (permalink / raw)
  To: Alexander Popov; +Cc: Thomas Gleixner, LKML

On Sat, 16 Jul 2016 04:33:59 +0300
Alexander Popov <alex.popov@linux.com> wrote:

> On 08.07.2016 11:34, Alexander Popov wrote:
> > On 06.07.2016 14:17, Thomas Gleixner wrote:  
> >> On Fri, 1 Jul 2016, Alexander Popov wrote:
> >>  
> >>> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being
> >>> able to work with irq_domain hierarchy in modules.  
> >>
> >> We usually export only when we have a proper use case which is supposed to go
> >> into the kernel tree proper. What's yours?  
> > 
> > Hello, Thomas,
> > 
> > I work at Positive Technologies ( https://www.ptsecurity.com/ ). We develop
> > a bare-metal hypervisor, which targets x86_64 and supports Linux as a guest OS.
> > 
> > Intel VT-x allows hypervisor to inject interrupts into virtual machines.
> > We want to handle these interrupts in guest Linux.
> > 
> > So I wrote a simple kernel module creating an irq_domain, which has
> > x86_vector_domain as a parent in the hierarchy. In this module I just call:
> > - irq_domain_alloc_irqs() to allocate irqs and allow calling request_irq()
> >    for them;
> > - irqd_cfg(irq_get_irq_data()) to get the APIC vectors of the allocated irqs;
> > - irq_domain_free_irqs() to free the resources at the end.
> > 
> > It allows to handle interrupts injected by the hypervisor in guest Linux easily,
> > without emulating MSI-capable PCI device at the hypervisor side.
> > 
> > Everything works fine if __irq_domain_alloc_irqs() and irq_domain_free_irqs()
> > are exported. Is it a proper use-case?  
> 
> Hello again, Thomas,
> 
> Did I properly answer your question? Will you accept my patch exporting these
> two functions?
> 
> > Do you think my module could be useful for the mainline in some form?
> > It took me some time to understand irq_domain hierarchy design, so I can
> > prepare some patch or share my code to help others.  
> 
> Do you think my paravirtualization code registering a child irq_domain
> for x86_vector_domain could bring any profit to the mainline?
> I would be glad to put effort and do it.

I think that without any in-tree modular users of these symbols, the
incentive for exporting those is pretty low. I can't really say
anything about your particular use-case, but I'd really to see some
code before taking that kind of patch.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-16  8:22       ` Marc Zyngier
@ 2016-07-18 12:34         ` Alexander Popov
  2016-07-25 19:35           ` Alexander Popov
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Popov @ 2016-07-18 12:34 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: Thomas Gleixner, LKML, Alexander Popov

On 16.07.2016 11:22, Marc Zyngier wrote:
> On Sat, 16 Jul 2016 04:33:59 +0300
> Alexander Popov <alex.popov@linux.com> wrote:
> 
>> On 08.07.2016 11:34, Alexander Popov wrote:
>>> On 06.07.2016 14:17, Thomas Gleixner wrote:  
>>>> On Fri, 1 Jul 2016, Alexander Popov wrote:
>>>>  
>>>>> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being
>>>>> able to work with irq_domain hierarchy in modules.  
>>>>
>>>> We usually export only when we have a proper use case which is supposed to go
>>>> into the kernel tree proper. What's yours?  

...

>> Did I properly answer your question? Will you accept my patch exporting these
>> two functions?
> 
> I think that without any in-tree modular users of these symbols, the
> incentive for exporting those is pretty low. I can't really say
> anything about your particular use-case, but I'd really to see some
> code before taking that kind of patch.

Thanks for your answer, Mark.

Here is the module which uses __irq_domain_alloc_irqs() and
irq_domain_free_irqs() and allows registering IRQ handlers for interrupts
injected by the hypervisor on x86_64. Large hypervisors usually emulate
an MSI-capable PCI device to do this job, but that way is inappropriate
for lightweight hypervisors.


/*
 * The module is for registering IRQ handlers for interrupts injected
 * by the hypervisor using Intel VT-x technology. This module targets
 * x86_64 platform.
 *
 * It works fine if __irq_domain_alloc_irqs() and irq_domain_free_irqs()
 * are exported.
 */

#include <linux/module.h>
#include <linux/irq.h>
#include <linux/irqdesc.h>
#include <linux/irqnr.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <asm/hw_irq.h>
#include <asm/irqdomain.h>

#define PARAVIRT_IRQS_N 10

struct irq_domain *paravirq_domain = NULL;
static int paravirq_irqbase = -EINVAL;
static int paravirq_irqs[PARAVIRT_IRQS_N] =
				{[0 ... PARAVIRT_IRQS_N - 1] = -EINVAL};

static irqreturn_t paravirq_irq_handler(int irq, void *cookie)
{
	printk("\tparavirq_irq_handler: virq %d\n", irq);

	/* ... some job ... */

	return IRQ_HANDLED;
}

static void paravirq_chip_irq_mask(struct irq_data *data)
{
	printk("\tparavirq_chip_irq_mask\n");

	/* ... tell the hypervisor not to inject the interrupt ... */
}

static void paravirq_chip_irq_unmask(struct irq_data *data)
{
	printk("\tparavirq_chip_irq_UNmask\n");

	/* ... allow the hypervisor to inject the interrupt ... */
}

static void paravirq_chip_ack(struct irq_data *data)
{
	data = data->parent_data;
	data->chip->irq_ack(data);
}

static struct irq_chip paravirq_chip __read_mostly = {
	.name			= "PARAVIRQ",
	.irq_mask		= paravirq_chip_irq_mask,
	.irq_unmask		= paravirq_chip_irq_unmask,
	.irq_ack		= paravirq_chip_ack,
};

static int paravirq_domain_alloc(struct irq_domain *domain,
			unsigned int virq, unsigned int nr_irqs, void *arg)
{
	int ret = 0;
	unsigned int i = 0;
	unsigned int irq = 0;

	printk("\tparavirq_domain_alloc: virq %u, nr_irqs %u, arg 0x%p\n",
							virq, nr_irqs, arg);
	for (i = 0; i < nr_irqs; i++) {
		irq = virq + i;

		ret = irq_domain_set_hwirq_and_chip(domain,
						irq, i, &paravirq_chip, NULL);
		if (ret) {
			printk("\t\tsetting chip, hwirq for %d failed\n", irq);
			return ret;
		}

		__irq_set_handler(irq, handle_edge_irq, 0, "edge");
	}

	return 0;
}

static void paravirq_domain_free(struct irq_domain *domain, unsigned int virq,
		     unsigned int nr_irqs)
{
	int ret = 0;
	unsigned int i = 0;
	unsigned int irq = 0;

	printk("\tparavirq_domain_free: virq %u, nr_irqs %u\n", virq, nr_irqs);

	for (i = 0; i < nr_irqs; i++) {
		irq = virq + i;

		ret = irq_set_chip(irq, NULL);
		if (ret)
			printk("\t\tunsetting chip for %d failed\n", irq);
	}
}

const struct irq_domain_ops paravirq_irqdomain_ops = {
	.alloc	= paravirq_domain_alloc,
	.free	= paravirq_domain_free,
};

static int __init paravirq_init(void)
{
	int ret = 0;
	int i = 0;
	struct irq_alloc_info info = { 0 };
	struct irq_cfg *cfg = NULL;

	printk("paravirq_init\n");

	paravirq_domain = irq_domain_add_linear(NULL, PARAVIRT_IRQS_N,
						&paravirq_irqdomain_ops, NULL);
	if (!paravirq_domain) {
		ret = -ENOMEM;
		goto err0;
	}

	paravirq_domain->name = paravirq_chip.name;
	paravirq_domain->parent = x86_vector_domain;
	paravirq_domain->flags |= IRQ_DOMAIN_FLAG_AUTO_RECURSIVE;
	printk("\tparavirq_domain %s (0x%p) is created\n",
					paravirq_domain->name, paravirq_domain);

	printk("\tcall irq_domain_alloc_irqs with info 0x%p\n", &info);
	paravirq_irqbase = irq_domain_alloc_irqs(paravirq_domain,
					PARAVIRT_IRQS_N, NUMA_NO_NODE, &info);
	if (paravirq_irqbase < 0) {
		printk("\tallocating irqs failed: %d\n", paravirq_irqbase);
		ret = paravirq_irqbase;
		goto err1;
	}

	printk("\tsuccessfully allocated %d irqs beginning from %d\n",
					PARAVIRT_IRQS_N, paravirq_irqbase);

	for (i = 0; i < PARAVIRT_IRQS_N; i++) {
		int irq = paravirq_irqbase + i;

		ret = request_irq(irq, paravirq_irq_handler,
						0, "paravirq_mod", NULL);
		if (ret) {
			printk("\trequest_irq %d failed: %d\n", irq, ret);
			goto err2;
		} else {
			printk("\tvirq %d is requested!\n", irq);
			paravirq_irqs[i] = irq;
		}
	}

	printk("\tSo, paravirq_mod grabbed %d irqs:\n", PARAVIRT_IRQS_N);
	for (i = 0; i < PARAVIRT_IRQS_N; i++) {
		cfg = irqd_cfg(irq_get_irq_data(paravirq_irqs[i]));
		if (!cfg) {
			printk("\t\tirq #%d: NULL irq_cfg\n", paravirq_irqs[i]);
			goto err2;
		}

		printk("\t\tirq #%d: virq %d, vector %d\n",
					i, paravirq_irqs[i], cfg->vector);
	}

	return 0;

err2:
	for (i = 0; i < PARAVIRT_IRQS_N; i++) {
		if (paravirq_irqs[i] >= 0) {
			printk("\tfreeing virq %d\n", paravirq_irqs[i]);
			free_irq(paravirq_irqs[i], NULL);
		}
	}
	irq_domain_free_irqs(paravirq_irqbase, PARAVIRT_IRQS_N);
err1:
	irq_domain_remove(paravirq_domain);
err0:
	return ret;
}

static void __exit paravirq_exit(void)
{
	int i;

	printk("paravirq_exit\n");

	for (i = 0; i < PARAVIRT_IRQS_N; i++) {
		if (paravirq_irqs[i] > 0) {
			printk("\tfreeing virq %d\n", paravirq_irqs[i]);
			free_irq(paravirq_irqs[i], NULL);
		}
	}

	if (paravirq_irqbase >= 0)
		irq_domain_free_irqs(paravirq_irqbase, PARAVIRT_IRQS_N);

	if (paravirq_domain)
		irq_domain_remove(paravirq_domain);
}

module_init(paravirq_init)
module_exit(paravirq_exit)

MODULE_AUTHOR("Alexander Popov <alex.popov@linux.com>");
MODULE_DESCRIPTION("The module for handling interrupts from the hypervisor");
MODULE_LICENSE("GPL v2");

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-18 12:34         ` Alexander Popov
@ 2016-07-25 19:35           ` Alexander Popov
  2016-07-27 11:22             ` Christoph Hellwig
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Popov @ 2016-07-25 19:35 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Thomas Gleixner, LKML, Paolo Bonzini, Radim Krčmář,
	Joerg Roedel, kvm

On 18.07.2016 15:34, Alexander Popov wrote:
> On 16.07.2016 11:22, Marc Zyngier wrote:
>> On Sat, 16 Jul 2016 04:33:59 +0300
>> Alexander Popov <alex.popov@linux.com> wrote:
>>
>>> On 08.07.2016 11:34, Alexander Popov wrote:
>>>> On 06.07.2016 14:17, Thomas Gleixner wrote:  
>>>>> On Fri, 1 Jul 2016, Alexander Popov wrote:
>>>>>  
>>>>>> Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() for being
>>>>>> able to work with irq_domain hierarchy in modules.  
>>>>>
>>>>> We usually export only when we have a proper use case which is supposed to go
>>>>> into the kernel tree proper. What's yours?  
> 
> ...
> 
>>> Did I properly answer your question? Will you accept my patch exporting these
>>> two functions?
>>
>> I think that without any in-tree modular users of these symbols, the
>> incentive for exporting those is pretty low. I can't really say
>> anything about your particular use-case, but I'd really to see some
>> code before taking that kind of patch.
> 
> Thanks for your answer, Mark.
> 
> Here is the module which uses __irq_domain_alloc_irqs() and
> irq_domain_free_irqs() and allows registering IRQ handlers for interrupts
> injected by the hypervisor on x86_64. Large hypervisors usually emulate
> an MSI-capable PCI device to do this job, but that way is inappropriate
> for lightweight hypervisors.


I hope that the code below is a valid use-case of irq_domain hierarchy API.
Such simple registration of IRQ handlers for interrupts injected by a hypervisor
is great for lightweight hypervisors, which avoid as much emulation as possible.

It only needs __irq_domain_alloc_irqs() and irq_domain_free_irqs() to be
exported to modules. Will you apply my patch which exports them?

[Add CC to KVM people to share the idea and, hopefully, find anybody interested]


> /*
>  * The module for registering IRQ handlers for interrupts injected
>  * by the hypervisor using Intel VT-x technology. This module targets
>  * x86_64 platform.
>  *
>  * It works fine if __irq_domain_alloc_irqs() and irq_domain_free_irqs()
>  * are exported.
>  */
> 
> #include <linux/module.h>
> #include <linux/irq.h>
> #include <linux/irqdesc.h>
> #include <linux/irqnr.h>
> #include <linux/irqdomain.h>
> #include <linux/interrupt.h>
> #include <asm/hw_irq.h>
> #include <asm/irqdomain.h>
> 
> #define PARAVIRT_IRQS_N 10
> 
> struct irq_domain *paravirq_domain = NULL;
> static int paravirq_irqbase = -EINVAL;
> static int paravirq_irqs[PARAVIRT_IRQS_N] =
> 				{[0 ... PARAVIRT_IRQS_N - 1] = -EINVAL};
> 
> static irqreturn_t paravirq_irq_handler(int irq, void *cookie)
> {
> 	printk("\tparavirq_irq_handler: virq %d\n", irq);
> 
> 	/* ... some job ... */
> 
> 	return IRQ_HANDLED;
> }
> 
> static void paravirq_chip_irq_mask(struct irq_data *data)
> {
> 	printk("\tparavirq_chip_irq_mask\n");
> 
> 	/* ... tell the hypervisor not to inject the interrupt ... */
> }
> 
> static void paravirq_chip_irq_unmask(struct irq_data *data)
> {
> 	printk("\tparavirq_chip_irq_UNmask\n");
> 
> 	/* ... allow the hypervisor to inject the interrupt ... */
> }
> 
> static void paravirq_chip_ack(struct irq_data *data)
> {
> 	data = data->parent_data;
> 	data->chip->irq_ack(data);
> }
> 
> static struct irq_chip paravirq_chip __read_mostly = {
> 	.name			= "PARAVIRQ",
> 	.irq_mask		= paravirq_chip_irq_mask,
> 	.irq_unmask		= paravirq_chip_irq_unmask,
> 	.irq_ack		= paravirq_chip_ack,
> };
> 
> static int paravirq_domain_alloc(struct irq_domain *domain,
> 			unsigned int virq, unsigned int nr_irqs, void *arg)
> {
> 	int ret = 0;
> 	unsigned int i = 0;
> 	unsigned int irq = 0;
> 
> 	printk("\tparavirq_domain_alloc: virq %u, nr_irqs %u, arg 0x%p\n",
> 							virq, nr_irqs, arg);
> 	for (i = 0; i < nr_irqs; i++) {
> 		irq = virq + i;
> 
> 		ret = irq_domain_set_hwirq_and_chip(domain,
> 						irq, i, &paravirq_chip, NULL);
> 		if (ret) {
> 			printk("\t\tsetting chip, hwirq for %d failed\n", irq);
> 			return ret;
> 		}
> 
> 		__irq_set_handler(irq, handle_edge_irq, 0, "edge");
> 	}
> 
> 	return 0;
> }
> 
> static void paravirq_domain_free(struct irq_domain *domain, unsigned int virq,
> 		     unsigned int nr_irqs)
> {
> 	int ret = 0;
> 	unsigned int i = 0;
> 	unsigned int irq = 0;
> 
> 	printk("\tparavirq_domain_free: virq %u, nr_irqs %u\n", virq, nr_irqs);
> 
> 	for (i = 0; i < nr_irqs; i++) {
> 		irq = virq + i;
> 
> 		ret = irq_set_chip(irq, NULL);
> 		if (ret)
> 			printk("\t\tunsetting chip for %d failed\n", irq);
> 	}
> }
> 
> const struct irq_domain_ops paravirq_irqdomain_ops = {
> 	.alloc	= paravirq_domain_alloc,
> 	.free	= paravirq_domain_free,
> };
> 
> static int __init paravirq_init(void)
> {
> 	int ret = 0;
> 	int i = 0;
> 	struct irq_alloc_info info = { 0 };
> 	struct irq_cfg *cfg = NULL;
> 
> 	printk("paravirq_init\n");
> 
> 	paravirq_domain = irq_domain_add_linear(NULL, PARAVIRT_IRQS_N,
> 						&paravirq_irqdomain_ops, NULL);
> 	if (!paravirq_domain) {
> 		ret = -ENOMEM;
> 		goto err0;
> 	}
> 
> 	paravirq_domain->name = paravirq_chip.name;
> 	paravirq_domain->parent = x86_vector_domain;
> 	paravirq_domain->flags |= IRQ_DOMAIN_FLAG_AUTO_RECURSIVE;
> 	printk("\tparavirq_domain %s (0x%p) is created\n",
> 					paravirq_domain->name, paravirq_domain);
> 
> 	printk("\tcall irq_domain_alloc_irqs with info 0x%p\n", &info);
> 	paravirq_irqbase = irq_domain_alloc_irqs(paravirq_domain,
> 					PARAVIRT_IRQS_N, NUMA_NO_NODE, &info);
> 	if (paravirq_irqbase < 0) {
> 		printk("\tallocating irqs failed: %d\n", paravirq_irqbase);
> 		ret = paravirq_irqbase;
> 		goto err1;
> 	}
> 
> 	printk("\tsuccessfully allocated %d irqs beginning from %d\n",
> 					PARAVIRT_IRQS_N, paravirq_irqbase);
> 
> 	for (i = 0; i < PARAVIRT_IRQS_N; i++) {
> 		int irq = paravirq_irqbase + i;
> 
> 		ret = request_irq(irq, paravirq_irq_handler,
> 						0, "paravirq_mod", NULL);
> 		if (ret) {
> 			printk("\trequest_irq %d failed: %d\n", irq, ret);
> 			goto err2;
> 		} else {
> 			printk("\tvirq %d is requested!\n", irq);
> 			paravirq_irqs[i] = irq;
> 		}
> 	}
> 
> 	printk("\tSo, paravirq_mod grabbed %d irqs:\n", PARAVIRT_IRQS_N);
> 	for (i = 0; i < PARAVIRT_IRQS_N; i++) {
> 		cfg = irqd_cfg(irq_get_irq_data(paravirq_irqs[i]));
> 		if (!cfg) {
> 			printk("\t\tirq #%d: NULL irq_cfg\n", paravirq_irqs[i]);
> 			goto err2;
> 		}
> 
> 		printk("\t\tirq #%d: virq %d, vector %d\n",
> 					i, paravirq_irqs[i], cfg->vector);
> 	}
> 
> 	return 0;
> 
> err2:
> 	for (i = 0; i < PARAVIRT_IRQS_N; i++) {
> 		if (paravirq_irqs[i] >= 0) {
> 			printk("\tfreeing virq %d\n", paravirq_irqs[i]);
> 			free_irq(paravirq_irqs[i], NULL);
> 		}
> 	}
> 	irq_domain_free_irqs(paravirq_irqbase, PARAVIRT_IRQS_N);
> err1:
> 	irq_domain_remove(paravirq_domain);
> err0:
> 	return ret;
> }
> 
> static void __exit paravirq_exit(void)
> {
> 	int i;
> 
> 	printk("paravirq_exit\n");
> 
> 	for (i = 0; i < PARAVIRT_IRQS_N; i++) {
> 		if (paravirq_irqs[i] > 0) {
> 			printk("\tfreeing virq %d\n", paravirq_irqs[i]);
> 			free_irq(paravirq_irqs[i], NULL);
> 		}
> 	}
> 
> 	if (paravirq_irqbase >= 0)
> 		irq_domain_free_irqs(paravirq_irqbase, PARAVIRT_IRQS_N);
> 
> 	if (paravirq_domain)
> 		irq_domain_remove(paravirq_domain);
> }
> 
> module_init(paravirq_init)
> module_exit(paravirq_exit)
> 
> MODULE_AUTHOR("Alexander Popov <alex.popov@linux.com>");
> MODULE_DESCRIPTION("The module for handling interrupts from the hypervisor");
> MODULE_LICENSE("GPL v2");
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-25 19:35           ` Alexander Popov
@ 2016-07-27 11:22             ` Christoph Hellwig
  2016-07-29 23:21               ` Alexander Popov
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2016-07-27 11:22 UTC (permalink / raw)
  To: Alexander Popov
  Cc: Marc Zyngier, Thomas Gleixner, LKML, Paolo Bonzini,
	Radim Kr??m????,
	Joerg Roedel, kvm

Hi Alex,

just submit your PV irq chip for the kernel.  It's so small that there
propbably is not need to even make it modular.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-27 11:22             ` Christoph Hellwig
@ 2016-07-29 23:21               ` Alexander Popov
  2016-08-01 11:28                 ` Jason Cooper
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Popov @ 2016-07-29 23:21 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Marc Zyngier, Thomas Gleixner, LKML, Paolo Bonzini, Radim Krcmar,
	Joerg Roedel, kvm

On 27.07.2016 14:22, Christoph Hellwig wrote:
> Hi Alex,
> 
> just submit your PV irq chip for the kernel.  It's so small that there
> propbably is not need to even make it modular.

Hello, Christoph,

Thanks a lot for your reply!
I'll try to do that and come up with a patch.

Best regards,
Alexander

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs()
  2016-07-29 23:21               ` Alexander Popov
@ 2016-08-01 11:28                 ` Jason Cooper
  0 siblings, 0 replies; 10+ messages in thread
From: Jason Cooper @ 2016-08-01 11:28 UTC (permalink / raw)
  To: Alexander Popov
  Cc: Christoph Hellwig, Marc Zyngier, Thomas Gleixner, LKML,
	Paolo Bonzini, Radim Krcmar, Joerg Roedel, kvm

Hi Alexander,

On Sat, Jul 30, 2016 at 02:21:21AM +0300, Alexander Popov wrote:
> On 27.07.2016 14:22, Christoph Hellwig wrote:
> > just submit your PV irq chip for the kernel.  It's so small that there
> > propbably is not need to even make it modular.
> 
> Thanks a lot for your reply!
> I'll try to do that and come up with a patch.

Please include me in the Cc when you send.

thx,

Jason.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-08-01 11:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-01 19:29 [PATCH 1/1] irqdomain: Export __irq_domain_alloc_irqs() and irq_domain_free_irqs() Alexander Popov
2016-07-06 11:17 ` Thomas Gleixner
2016-07-08  8:34   ` Alexander Popov
2016-07-16  1:33     ` Alexander Popov
2016-07-16  8:22       ` Marc Zyngier
2016-07-18 12:34         ` Alexander Popov
2016-07-25 19:35           ` Alexander Popov
2016-07-27 11:22             ` Christoph Hellwig
2016-07-29 23:21               ` Alexander Popov
2016-08-01 11:28                 ` Jason Cooper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).