Re: [Xen-devel] ioperm problem

Konrad Rzeszutek Wilk
Thu, 17 Nov 2011 17:30:10 -0000

On Thu, Nov 17, 2011 at 08:56:34AM -0500, Ben Guthro
wrote:
> Attached is our patch to work around issues with the ioports with
> some older nVidia cards.
>
> This, admittedly is a bit of a hack, and not exactly something that
> I would see upstream wanting to carry, for a variety of reasons. It
> really should all be predicated on whether the kernel is the initial
> domain, etc.
>
> This opens up the legacy VGA ports in the VGA arbiter code.

Was there a userspace program that did this? As in it would
call ioperm?

>
> Konrad - I think that you had suggested an alternate way of doing
> this, IIRC, but I can''t seem to find it in my inbox. Due to
> competing demands, and my nVidia hardware disappearing, I never went
> back to rework this code.

Ah, I might have some code that I just uncovered from Jeremy''s old
git tree.

I''ve put it up on devel/ioperm - it nicely wraps the ioperm
call to go the native or paravirt.

>
> As written, however, it did solve the problem at hand - however
> hacky it may be.

<nods>

Pavel,

Can you try to merge the #devel/ioperm patches in your tree and see
if they fix your problem?

The git tree is at
git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen.git
>
> /btg
>
> On 11/16/2011 09:57 AM, Konrad Rzeszutek Wilk wrote:
> >On Sun, Nov 13, 2011 at 10:19:06PM +0100, Pavel Matěja wrote:
> >>Hi,
> >>I''m trying to port AMD VGA passthru patch to the latest
XEN and vanila kernel
> >>and I got SIGSEGV in
> >>
> >>static void ati_hw_out(uint16_t hport, uint32_t data)
> >>{
> >>     ioperm(gfx_info.host_pio_base, gfx_info.pio_size, 1);
> >>     asm volatile ("out %1,
%0"::"Nd"(hport),"a"(data));
> >>     ioperm(gfx_info.host_pio_base, gfx_info.pio_size, 0);
> >>}
> >
> >Does it work under baremetal?
> >
> >What is the host_pio_base?
> >
> >Is the host_pio_base part of the permitted IO ports? (you can
> >see that if you run ''xl debug-keys q'' and it should
show you something
> >like this:
> >
> >(XEN) Rangesets belonging to domain 1:
> >(XEN)     I/O Ports  { b400-b41f, b800-b81f }
> >(XEN)     Interrupts { 18-19, 54-55 }
> >(XEN)     I/O Memory { fe940-fe9ff }
> >(XEN) Memory pages belonging to domain 1:
> >
> >(you can get that from xm dmesg).
> >
> >As you can see, the b400->b41f are allowed in the domain 1. Is your
> >host_pio_base in there?
> >
> >
> >>
> >>I tried old 2.6.32 XEN kernel and there is no such problem.
> >>It looks related to arch/x86/kernel/ioport.c but I''m not
sure.
> >>Is anyone here familiar with that code?
> >
> >Yes, and I think I saw somebody ask me about that too.
> >
> >Lets rope them in this converstation - they got it to work
> >but my memory is foggy at what was required.
> >
> >Ben, Thomas,
> >
> >I remember you guys had a tough time with vd86 which did something
similar
> >and it ultimately was due to to /dev/mem not passing in VM_IO. But the
> >ioperm/outb sounds familiar too. Was there a missing hypercall when
> >forking/copying the ioperm bitmap?

> diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
> index ace2b16..d488426 100644
> --- a/drivers/gpu/vga/vgaarb.c
> +++ b/drivers/gpu/vga/vgaarb.c
> @@ -421,6 +421,50 @@ bail:
>  }
>  EXPORT_SYMBOL(vga_put);
>
> +#ifdef CONFIG_XEN
> +#include <xen/xen.h>
> +#include <xen/interface/physdev.h>
> +#include <xen/interface/xen.h>
> +#include <asm/xen/hypervisor.h>
> +#include <asm/xen/hypercall.h>
> +
> +#define IO_BITMAP_BITS 65536
> +#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
> +
> +#define VGA_START_PORT 0x3B0
> +#define VGA_END_PORT 0x3DF
> +
> +static void
> +vga_ioport_map(struct pci_dev *pdev)
> +{
> +	unsigned int i, j;
> +	struct physdev_set_iobitmap op;
> +	uint8_t *bitmap;
> +
> +	bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
> +	memset(bitmap, 0xff, IO_BITMAP_BYTES);
> +
> +	/* PCI io bars */
> +	for (i = 0; i < PCI_NUM_RESOURCES; i++)
> +		if (pci_resource_flags(pdev, i) & IORESOURCE_IO)
> +			for (j = pci_resource_start(pdev, i);
> +				j <= pci_resource_end(pdev, i); j++)
> +				__clear_bit(j, (unsigned long*)bitmap);
> +
> +	/* legacy vga */
> +	for (i = VGA_START_PORT; i <= VGA_END_PORT; i++)
> +		__clear_bit(i, (unsigned long*)bitmap);
> +
> +	op.bitmap = bitmap;
> +	op.nr_ports = IO_BITMAP_BITS;
> +	if(HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &op) != 0)
> +		pr_info("PHYSDEVOP_set_iobitmap failed\n");
> +
> +}
> +#else
> +#define vga_ioport_map(x)
> +#endif
> +
>  /*
>   * Currently, we assume that the "initial" setup of the system
is
>   * not sane, that is we come up with conflicting devices and let
> @@ -509,6 +553,7 @@ static bool vga_arbiter_add_pci_device(struct pci_dev
*pdev)
>  		vga_iostate_to_str(vgadev->owns),
>  		vga_iostate_to_str(vgadev->locks));
>
> +	vga_ioport_map(pdev);
>  	spin_unlock_irqrestore(&vga_lock, flags);
>  	return true;
>  fail:

> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel