* [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough
@ 2007-09-05 0:08 Kay, Allen M
2007-09-06 23:16 ` John Byrne
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Kay, Allen M @ 2007-09-05 0:08 UTC (permalink / raw)
To: xen-devel; +Cc: Guy Zana, Keir Fraser
The following 6 patches contains merge of Intel VT-d and Neocleus' 1:1
mapping patches for enabling HVM guest direct device access that were
last submitted around end of May. These patches applied cleanly to
changeset 15730.
To enabled xen vt-d code, add "ioapic_ack=old" to xen boot parameter in
grub.conf on systems with VT-d hardware.
To enabled xen 1:1 mapping code, add "enabled_nativedom=1" to xen boot
parameter in grub.conf.
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Signed-off-by: Guy Zana <guy@neocleus.com>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-05 0:08 [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough Kay, Allen M @ 2007-09-06 23:16 ` John Byrne 2007-09-07 0:00 ` Kay, Allen M 2007-09-11 12:49 ` Keir Fraser 2007-09-16 17:26 ` [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mregedcode " Guy Zana 2 siblings, 1 reply; 13+ messages in thread From: John Byrne @ 2007-09-06 23:16 UTC (permalink / raw) To: Kay, Allen M; +Cc: Guy Zana, xen-devel, Keir Fraser When I use these patches and start a nativedom with a directly-assigned NIC and no IOMMU, I get a lock up. Running the same domain/configuration/machine with the direct-io.hg tree worked fine. The crash output is below. If you'd like more information, let me know. John Byrne (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) pt_irq.c:81:d1 invalid assert_option value (XEN) WARNING: send pio with something already pending (9)? (XEN) domain_crash_sync called from hvm.c:485 (XEN) Domain 1 (vcpu#0) crashed on cpu#7: (XEN) ----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]---- (XEN) CPU: 7 (XEN) EIP: 0000:[<00100fcb>] (XEN) EFLAGS: 00000002 CONTEXT: hvm (XEN) eax: 00000064 ebx: 001390c4 ecx: 001390c4 edx: 000000e9 (XEN) esi: 00103762 edi: 00101bf0 ebp: 00139038 esp: 00139038 (XEN) cr0: 00000011 cr4: 00000000 cr3: 00000000 cr2: 00000000 (XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: 0000 cs: 0000 (XEN) domain_crash_sync called from hvm.c:132 (XEN) domain_crash_sync called from hvm.c:132 (XEN) domain_crash_sync called from hvm.c:132 (XEN) domain_crash_sync called from hvm.c:132 .... (XEN) *** [ Xen-3.0-unstable x86_32 debug=n Not tainted ]----(XEN) ----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]----(XEN) e x86_32 debug=n Not tainted ]---- (XEN) ----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]---- (XEN) CPU: 6 (XEN) CPU: 6(XEN) idle_loop+0x1b/0x90+010246 CONTEXT: hypervisor (XEN) EFLAGS: 00010246 CONTEXT: hypervisor (XEN) eax: 00000300 ebx: ffbe7fb4 ecx: 00000000 edx: 00000006 (XEN) esi: ff1a8430 edi: 91d91b27 ebp: 0000001c esp: ffbe7fa8 (XEN) cr0: 8005003b cr4: 000026d0 cr3: 3c6ee000 cr2: b7bf7000 (XEN) ds: e010 es: e010 fs: 0000 gs: 0000 ss: e010 cs: e008 (XEN) do_page_fault+0x45/0x3b0 (XEN) (XEN) Xen stac00010246Xen stac00010246 CR3: 00000000(XEN) ffbea080 ax: 6563696c ebx: 0000e010 ecx: 00010246 edx: ff1b7fb4(XEN) ffbea080 00000001 si: 0000e010 edi: 00000000 ebp: ff1b40ec esp: ff1b40a8(XEN) 00000000 s: e010 es: e010 fs: 0000 gs: 0000 ss: e010(XEN) c1351f90 00000006 00000006 00000006 (XEN) c03d7180 00000000 000e0007 c01013a7 00000061 00000246 c1351f8c 00000069 (XEN) 0000007b 0000007b 00000000 00000000 00000006 ffbea080 (XEN) Xen call trace: (XEN) [<ff1209fb>] idle_loop+0x1b/0x90 (XEN) Kay, Allen M wrote: > The following 6 patches contains merge of Intel VT-d and Neocleus' 1:1 > mapping patches for enabling HVM guest direct device access that were > last submitted around end of May. These patches applied cleanly to > changeset 15730. > > To enabled xen vt-d code, add "ioapic_ack=old" to xen boot parameter in > grub.conf on systems with VT-d hardware. > > To enabled xen 1:1 mapping code, add "enabled_nativedom=1" to xen boot > parameter in grub.conf. > > Signed-off-by: Allen Kay <allen.m.kay@intel.com> > Signed-off-by: Guy Zana <guy@neocleus.com> > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel > ^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-06 23:16 ` John Byrne @ 2007-09-07 0:00 ` Kay, Allen M 2007-09-07 23:44 ` John Byrne 0 siblings, 1 reply; 13+ messages in thread From: Kay, Allen M @ 2007-09-07 0:00 UTC (permalink / raw) To: John Byrne; +Cc: Guy Zana, xen-devel, Keir Fraser Other than minor changes while rebasing from 15521 to 15730. The following files have been modified that might affect functionality: Tools/hvmloader/32bitbios_support.c: removed a hack to increase highbiosarea size. Tools/ioemu/hw/pass-throught.c/pt_pci_write_config(): for is_native=1 case, pass-through pci config writes. Otherwise, pass-through only access to command register (for vt-d case). Note that we will use a different switch variable once it is added. These are minor changes, you might want to replace these file from the ones from direct-io tree to see if it fixes your problem. Allen >-----Original Message----- >From: John Byrne [mailto:john.l.byrne@hp.com] >Sent: Thursday, September 06, 2007 4:16 PM >To: Kay, Allen M >Cc: xen-devel@lists.xensource.com; Guy Zana; Keir Fraser >Subject: Re: [Xen-devel] [VTD-NEO][patch 0/6] Intel >VT-d/Neocleus 1:1 mreged code for PCI passthrough > >When I use these patches and start a nativedom with a >directly-assigned >NIC and no IOMMU, I get a lock up. Running the same >domain/configuration/machine with the direct-io.hg tree worked >fine. The >crash output is below. If you'd like more information, let me know. > >John Byrne > >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) pt_irq.c:81:d1 invalid assert_option value >(XEN) WARNING: send pio with something already pending (9)? >(XEN) domain_crash_sync called from hvm.c:485 >(XEN) Domain 1 (vcpu#0) crashed on cpu#7: >(XEN) ----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]---- >(XEN) CPU: 7 >(XEN) EIP: 0000:[<00100fcb>] >(XEN) EFLAGS: 00000002 CONTEXT: hvm >(XEN) eax: 00000064 ebx: 001390c4 ecx: 001390c4 edx: 000000e9 >(XEN) esi: 00103762 edi: 00101bf0 ebp: 00139038 esp: 00139038 >(XEN) cr0: 00000011 cr4: 00000000 cr3: 00000000 cr2: 00000000 >(XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: 0000 cs: 0000 >(XEN) domain_crash_sync called from hvm.c:132 >(XEN) domain_crash_sync called from hvm.c:132 >(XEN) domain_crash_sync called from hvm.c:132 >(XEN) domain_crash_sync called from hvm.c:132 >.... >(XEN) *** [ Xen-3.0-unstable x86_32 debug=n Not tainted ]----(XEN) >----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]----(XEN) e >x86_32 debug=n Not tainted ]---- >(XEN) ----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]---- >(XEN) CPU: 6 >(XEN) CPU: 6(XEN) idle_loop+0x1b/0x90+010246 CONTEXT: hypervisor > >(XEN) EFLAGS: 00010246 CONTEXT: hypervisor >(XEN) eax: 00000300 ebx: ffbe7fb4 ecx: 00000000 edx: 00000006 >(XEN) esi: ff1a8430 edi: 91d91b27 ebp: 0000001c esp: ffbe7fa8 >(XEN) cr0: 8005003b cr4: 000026d0 cr3: 3c6ee000 cr2: b7bf7000 >(XEN) ds: e010 es: e010 fs: 0000 gs: 0000 ss: e010 cs: e008 >(XEN) do_page_fault+0x45/0x3b0 >(XEN) (XEN) Xen stac00010246Xen stac00010246 >CR3: 00000000(XEN) ffbea080 > ax: 6563696c ebx: 0000e010 ecx: 00010246 edx: ff1b7fb4(XEN) >ffbea080 00000001 > si: 0000e010 edi: 00000000 ebp: ff1b40ec esp: ff1b40a8(XEN) >00000000 > s: e010 es: e010 fs: 0000 gs: 0000 ss: e010(XEN) c1351f90 >00000006 00000006 > 00000006 >(XEN) c03d7180 00000000 000e0007 c01013a7 00000061 00000246 >c1351f8c >00000069 >(XEN) 0000007b 0000007b 00000000 00000000 00000006 ffbea080 >(XEN) Xen call trace: >(XEN) [<ff1209fb>] idle_loop+0x1b/0x90 >(XEN) > > >Kay, Allen M wrote: >> The following 6 patches contains merge of Intel VT-d and >Neocleus' 1:1 >> mapping patches for enabling HVM guest direct device access that were >> last submitted around end of May. These patches applied cleanly to >> changeset 15730. >> >> To enabled xen vt-d code, add "ioapic_ack=old" to xen boot >parameter in >> grub.conf on systems with VT-d hardware. >> >> To enabled xen 1:1 mapping code, add "enabled_nativedom=1" >to xen boot >> parameter in grub.conf. >> >> Signed-off-by: Allen Kay <allen.m.kay@intel.com> >> Signed-off-by: Guy Zana <guy@neocleus.com> >> >> _______________________________________________ >> Xen-devel mailing list >> Xen-devel@lists.xensource.com >> http://lists.xensource.com/xen-devel >> > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-07 0:00 ` Kay, Allen M @ 2007-09-07 23:44 ` John Byrne 0 siblings, 0 replies; 13+ messages in thread From: John Byrne @ 2007-09-07 23:44 UTC (permalink / raw) To: Kay, Allen M; +Cc: Guy Zana, xen-devel, Keir Fraser I replaced the files. The problem still occurs. John Kay, Allen M wrote: > Other than minor changes while rebasing from 15521 to 15730. The > following files have been modified that might affect functionality: > > Tools/hvmloader/32bitbios_support.c: > removed a hack to increase highbiosarea size. > > Tools/ioemu/hw/pass-throught.c/pt_pci_write_config(): > for is_native=1 case, pass-through pci config writes. Otherwise, > pass-through only access to command register (for vt-d case). Note that > we will use a different switch variable once it is added. > > These are minor changes, you might want to replace these file from the > ones from direct-io tree to see if it fixes your problem. > > Allen > > >> -----Original Message----- >> From: John Byrne [mailto:john.l.byrne@hp.com] >> Sent: Thursday, September 06, 2007 4:16 PM >> To: Kay, Allen M >> Cc: xen-devel@lists.xensource.com; Guy Zana; Keir Fraser >> Subject: Re: [Xen-devel] [VTD-NEO][patch 0/6] Intel >> VT-d/Neocleus 1:1 mreged code for PCI passthrough >> >> When I use these patches and start a nativedom with a >> directly-assigned >> NIC and no IOMMU, I get a lock up. Running the same >> domain/configuration/machine with the direct-io.hg tree worked >> fine. The >> crash output is below. If you'd like more information, let me know. >> >> John Byrne >> >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) pt_irq.c:81:d1 invalid assert_option value >> (XEN) WARNING: send pio with something already pending (9)? >> (XEN) domain_crash_sync called from hvm.c:485 >> (XEN) Domain 1 (vcpu#0) crashed on cpu#7: >> (XEN) ----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]---- >> (XEN) CPU: 7 >> (XEN) EIP: 0000:[<00100fcb>] >> (XEN) EFLAGS: 00000002 CONTEXT: hvm >> (XEN) eax: 00000064 ebx: 001390c4 ecx: 001390c4 edx: 000000e9 >> (XEN) esi: 00103762 edi: 00101bf0 ebp: 00139038 esp: 00139038 >> (XEN) cr0: 00000011 cr4: 00000000 cr3: 00000000 cr2: 00000000 >> (XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: 0000 cs: 0000 >> (XEN) domain_crash_sync called from hvm.c:132 >> (XEN) domain_crash_sync called from hvm.c:132 >> (XEN) domain_crash_sync called from hvm.c:132 >> (XEN) domain_crash_sync called from hvm.c:132 >> .... >> (XEN) *** [ Xen-3.0-unstable x86_32 debug=n Not tainted ]----(XEN) >> ----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]----(XEN) e >> x86_32 debug=n Not tainted ]---- >> (XEN) ----[ Xen-3.0-unstable x86_32 debug=n Not tainted ]---- >> (XEN) CPU: 6 >> (XEN) CPU: 6(XEN) idle_loop+0x1b/0x90+010246 CONTEXT: hypervisor >> >> (XEN) EFLAGS: 00010246 CONTEXT: hypervisor >> (XEN) eax: 00000300 ebx: ffbe7fb4 ecx: 00000000 edx: 00000006 >> (XEN) esi: ff1a8430 edi: 91d91b27 ebp: 0000001c esp: ffbe7fa8 >> (XEN) cr0: 8005003b cr4: 000026d0 cr3: 3c6ee000 cr2: b7bf7000 >> (XEN) ds: e010 es: e010 fs: 0000 gs: 0000 ss: e010 cs: e008 >> (XEN) do_page_fault+0x45/0x3b0 >> (XEN) (XEN) Xen stac00010246Xen stac00010246 >> CR3: 00000000(XEN) ffbea080 >> ax: 6563696c ebx: 0000e010 ecx: 00010246 edx: ff1b7fb4(XEN) >> ffbea080 00000001 >> si: 0000e010 edi: 00000000 ebp: ff1b40ec esp: ff1b40a8(XEN) >> 00000000 >> s: e010 es: e010 fs: 0000 gs: 0000 ss: e010(XEN) c1351f90 >> 00000006 00000006 >> 00000006 >> (XEN) c03d7180 00000000 000e0007 c01013a7 00000061 00000246 >> c1351f8c >> 00000069 >> (XEN) 0000007b 0000007b 00000000 00000000 00000006 ffbea080 >> (XEN) Xen call trace: >> (XEN) [<ff1209fb>] idle_loop+0x1b/0x90 >> (XEN) >> >> >> Kay, Allen M wrote: >>> The following 6 patches contains merge of Intel VT-d and >> Neocleus' 1:1 >>> mapping patches for enabling HVM guest direct device access that were >>> last submitted around end of May. These patches applied cleanly to >>> changeset 15730. >>> >>> To enabled xen vt-d code, add "ioapic_ack=old" to xen boot >> parameter in >>> grub.conf on systems with VT-d hardware. >>> >>> To enabled xen 1:1 mapping code, add "enabled_nativedom=1" >> to xen boot >>> parameter in grub.conf. >>> >>> Signed-off-by: Allen Kay <allen.m.kay@intel.com> >>> Signed-off-by: Guy Zana <guy@neocleus.com> >>> >>> _______________________________________________ >>> Xen-devel mailing list >>> Xen-devel@lists.xensource.com >>> http://lists.xensource.com/xen-devel >>> > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-05 0:08 [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough Kay, Allen M 2007-09-06 23:16 ` John Byrne @ 2007-09-11 12:49 ` Keir Fraser 2007-09-11 13:04 ` Keir Fraser 2007-09-11 21:27 ` Kay, Allen M 2007-09-16 17:26 ` [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mregedcode " Guy Zana 2 siblings, 2 replies; 13+ messages in thread From: Keir Fraser @ 2007-09-11 12:49 UTC (permalink / raw) To: Kay, Allen M, xen-devel; +Cc: Guy Zana On 5/9/07 01:08, "Kay, Allen M" <allen.m.kay@intel.com> wrote: > The following 6 patches contains merge of Intel VT-d and Neocleus' 1:1 > mapping patches for enabling HVM guest direct device access that were > last submitted around end of May. These patches applied cleanly to > changeset 15730. The 'include' patch doesn't apply any more, and in any case needs splitting up logically (vtd bits go in vtd patch; neo bits in neo patch; any generic bits in xen patch). The 'pt' (neo) code looks to throw way too much stuff in include/xen/ of which I suspect most is private definitions that really belong in the pt/ directory. Also consider which bits should be in include/asm rather than include/xen. The presence of the E820_1TO1 stuff makes me suspect that the 1:1 area allocation hasn't been cleaned up as much as it should have been. There shouldn't be any need to modify Xen's permanent e820 map I think. Haven't looked any further at the Xen parts, but I'll take a look at the tools patch... -- Keir ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-11 12:49 ` Keir Fraser @ 2007-09-11 13:04 ` Keir Fraser 2007-09-12 1:21 ` Kay, Allen M 2007-09-11 21:27 ` Kay, Allen M 1 sibling, 1 reply; 13+ messages in thread From: Keir Fraser @ 2007-09-11 13:04 UTC (permalink / raw) To: Kay, Allen M, xen-devel; +Cc: Guy Zana On 11/9/07 13:49, "Keir Fraser" <Keir.Fraser@cl.cam.ac.uk> wrote: > Haven't looked any further at the Xen parts, but I'll take a look at the > tools patch... Looking at the tools patch, I see strange interfaces like HVMOP_copy_nativedom_e820_map: 1. Why is this an hvm_op unlike other added domctls? 2. Why is it needed at all? Can't xc_hvm_build.c work out the memory map for itself? It seems like more than necessary is being done in Xen. Looks like splitting solely pt and solely vtd code into separate patches would be a good idea, so the more acdeptable chunks can slide straight in without delay. -- Keir ^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-11 13:04 ` Keir Fraser @ 2007-09-12 1:21 ` Kay, Allen M 2007-09-12 9:03 ` Keir Fraser 0 siblings, 1 reply; 13+ messages in thread From: Kay, Allen M @ 2007-09-12 1:21 UTC (permalink / raw) To: Keir Fraser, xen-devel; +Cc: Guy Zana [-- Attachment #1: Type: text/plain, Size: 1255 bytes --] Attached patches splits vtd and neo changes to tools directory. Applies cleanly to staging tree. Vtd_tools.patch: vt-d and generic changes Neo_tools.patch: neocleus specific changes Signed-off-by: Allen Kay <allen.m.kay@intel.com> Signed-off-by: Guy Zana <guy@neocleus.com> >-----Original Message----- >From: Keir Fraser [mailto:Keir.Fraser@cl.cam.ac.uk] >Sent: Tuesday, September 11, 2007 6:05 AM >To: Kay, Allen M; xen-devel@lists.xensource.com >Cc: Guy Zana >Subject: Re: [Xen-devel] [VTD-NEO][patch 0/6] Intel >VT-d/Neocleus 1:1 mreged code for PCI passthrough > >On 11/9/07 13:49, "Keir Fraser" <Keir.Fraser@cl.cam.ac.uk> wrote: > >> Haven't looked any further at the Xen parts, but I'll take a >look at the >> tools patch... > >Looking at the tools patch, I see strange interfaces like >HVMOP_copy_nativedom_e820_map: > 1. Why is this an hvm_op unlike other added domctls? > 2. Why is it needed at all? Can't xc_hvm_build.c work out the >memory map >for itself? It seems like more than necessary is being done in Xen. > >Looks like splitting solely pt and solely vtd code into >separate patches >would be a good idea, so the more acdeptable chunks can slide >straight in >without delay. > > -- Keir > [-- Attachment #2: vtd_tools.patch --] [-- Type: application/octet-stream, Size: 29380 bytes --] diff -r 9071521d4864 tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/ioemu/Makefile.target Tue Sep 11 16:30:32 2007 -0700 @@ -197,6 +197,7 @@ LIBS+=-lm LIBS+=-lm LIBS+=-L../../libxc -lxenctrl -lxenguest LIBS+=-L../../xenstore -lxenstore +LIBS+=-lpci ifndef CONFIG_USER_ONLY LIBS+=-lz endif @@ -400,6 +401,7 @@ VL_OBJS+= xenstore.o VL_OBJS+= xenstore.o VL_OBJS+= xen_platform.o VL_OBJS+= tpm_tis.o +VL_OBJS+= pass-through.o CPPFLAGS += -DHAS_AUDIO endif ifeq ($(TARGET_BASE_ARCH), ppc) diff -r 9071521d4864 tools/ioemu/hw/pc.c --- a/tools/ioemu/hw/pc.c Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/ioemu/hw/pc.c Tue Sep 11 16:30:32 2007 -0700 @@ -465,7 +465,7 @@ static void pc_init1(uint64_t ram_size, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, - int pci_enabled) + int pci_enabled, const char *direct_pci) { #ifndef NOBIOS char buf[1024]; @@ -480,6 +480,7 @@ static void pc_init1(uint64_t ram_size, int piix3_devfn = -1; CPUState *env; NICInfo *nd; + int rc; linux_boot = (kernel_filename != NULL); @@ -665,6 +666,17 @@ static void pc_init1(uint64_t ram_size, } } + /* Pass-through Initialization */ + if ( pci_enabled && direct_pci ) + { + rc = pt_init(pci_bus, direct_pci); + if ( rc < 0 ) + { + fprintf(logfile, "Error: Initialization failed for pass-through devices\n"); + exit(1); + } + } + rtc_state = rtc_init(0x70, 8); register_ioport_read(0x92, 1, 1, ioport92_read, NULL); @@ -801,12 +813,14 @@ static void pc_init_pci(uint64_t ram_siz int snapshot, const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename) + const char *initrd_filename, + const char *direct_pci) { pc_init1(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, kernel_filename, kernel_cmdline, - initrd_filename, 1); + initrd_filename, 1, + direct_pci); } static void pc_init_isa(uint64_t ram_size, int vga_ram_size, char *boot_device, @@ -814,12 +828,13 @@ static void pc_init_isa(uint64_t ram_siz int snapshot, const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename) + const char *initrd_filename, + const char *unused) { pc_init1(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, kernel_filename, kernel_cmdline, - initrd_filename, 0); + initrd_filename, 0, NULL); } QEMUMachine pc_machine = { diff -r 9071521d4864 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/ioemu/vl.c Tue Sep 11 16:58:42 2007 -0700 @@ -6497,6 +6497,7 @@ enum { QEMU_OPTION_acpi, QEMU_OPTION_vncviewer, QEMU_OPTION_vncunused, + QEMU_OPTION_pci, }; typedef struct QEMUOption { @@ -6594,6 +6595,7 @@ const QEMUOption qemu_options[] = { { "d", HAS_ARG, QEMU_OPTION_d }, { "vcpus", 1, QEMU_OPTION_vcpus }, { "acpi", 0, QEMU_OPTION_acpi }, + { "pci", HAS_ARG, QEMU_OPTION_pci}, { NULL }, }; @@ -7049,9 +7051,9 @@ int main(int argc, char **argv) extern void *buffered_pio_page; #endif sigset_t set; - char qemu_dm_logfilename[128]; - + const char *direct_pci = NULL; + /* Ensure that SIGUSR2 is blocked by default when a new thread is created, then only the threads that use the signal unblock it -- this fixes a race condition in Qcow support where the AIO signal is misdelivered. */ @@ -7544,6 +7546,9 @@ int main(int argc, char **argv) case QEMU_OPTION_vncunused: vncunused++; break; + case QEMU_OPTION_pci: + direct_pci = optarg; + break; } } } @@ -7910,7 +7915,8 @@ int main(int argc, char **argv) machine->init(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, - kernel_filename, kernel_cmdline, initrd_filename); + kernel_filename, kernel_cmdline, initrd_filename, + direct_pci); free(boot_device); /* init USB devices */ diff -r 9071521d4864 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/ioemu/vl.h Tue Sep 11 16:30:32 2007 -0700 @@ -717,7 +717,7 @@ typedef void QEMUMachineInitFunc(uint64_ char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename); + const char *initrd_filename, const char *direct_pci); typedef struct QEMUMachine { const char *name; diff -r 9071521d4864 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/libxc/xc_domain.c Tue Sep 11 16:30:32 2007 -0700 @@ -734,6 +734,114 @@ int xc_domain_setdebugging(int xc_handle return do_domctl(xc_handle, &domctl); } +int xc_assign_device( + int xc_handle, + uint32_t domid, + uint32_t machine_bdf) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_assign_device; + domctl.domain = domid; + domctl.u.assign_device.machine_bdf = machine_bdf; + + return do_domctl(xc_handle, &domctl); +} + +/* Pass-through: binds machine irq to guests irq */ +int xc_domain_bind_pt_irq( + int xc_handle, + uint32_t domid, + uint8_t machine_irq, + uint8_t irq_type, + uint8_t bus, + uint8_t device, + uint8_t intx, + uint8_t isa_irq) +{ + int rc; + xen_domctl_bind_pt_irq_t * bind; + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_bind_pt_irq; + domctl.domain = (domid_t)domid; + + bind = &(domctl.u.bind_pt_irq); + bind->hvm_domid = domid; + bind->irq_type = irq_type; + bind->machine_irq = machine_irq; + bind->u.pci.bus = bus; + bind->u.pci.device = device; + bind->u.pci.intx = intx; + bind->u.isa.isa_irq = isa_irq; + + rc = do_domctl(xc_handle, &domctl); + return rc; +} + +int xc_domain_bind_pt_pci_irq( + int xc_handle, + uint32_t domid, + uint8_t machine_irq, + uint8_t bus, + uint8_t device, + uint8_t intx) +{ + + return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq, + PT_IRQ_TYPE_PCI, bus, device, intx, 0)); +} + +int xc_domain_bind_pt_isa_irq( + int xc_handle, + uint32_t domid, + uint8_t machine_irq) +{ + + return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq, + PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq)); +} + +int xc_domain_memory_mapping( + int xc_handle, + uint32_t domid, + unsigned long first_gfn, + unsigned long first_mfn, + unsigned long nr_mfns, + uint32_t add_mapping) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_memory_mapping; + domctl.domain = domid; + domctl.u.memory_mapping.first_gfn = first_gfn; + domctl.u.memory_mapping.first_mfn = first_mfn; + domctl.u.memory_mapping.nr_mfns = nr_mfns; + domctl.u.memory_mapping.add_mapping = add_mapping; + + return do_domctl(xc_handle, &domctl); +} + +int xc_domain_ioport_mapping( + int xc_handle, + uint32_t domid, + uint32_t first_gport, + uint32_t first_mport, + uint32_t nr_ports, + uint32_t add_mapping) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_ioport_mapping; + domctl.domain = domid; + domctl.u.ioport_mapping.first_gport = first_gport; + domctl.u.ioport_mapping.first_mport = first_mport; + domctl.u.ioport_mapping.nr_ports = nr_ports; + domctl.u.ioport_mapping.add_mapping = add_mapping; + + return do_domctl(xc_handle, &domctl); +} + /* * Local variables: * mode: C diff -r 9071521d4864 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/libxc/xenctrl.h Tue Sep 11 16:30:32 2007 -0700 @@ -901,4 +901,43 @@ int xc_ia64_save_to_nvram(int xc_handle, /* IA64 specific, nvram init */ int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom); +/* HVM guest pass-through */ +int xc_assign_device(int xc_handle, + uint32_t domid, + uint32_t machine_bdf); + +int xc_domain_memory_mapping(int xc_handle, + uint32_t domid, + unsigned long first_gfn, + unsigned long first_mfn, + unsigned long nr_mfns, + uint32_t add_mapping); + +int xc_domain_ioport_mapping(int xc_handle, + uint32_t domid, + uint32_t first_gport, + uint32_t first_mport, + uint32_t nr_ports, + uint32_t add_mapping); + +int xc_domain_bind_pt_irq(int xc_handle, + uint32_t domid, + uint8_t machine_irq, + uint8_t irq_type, + uint8_t bus, + uint8_t device, + uint8_t intx, + uint8_t isa_irq); + +int xc_domain_bind_pt_pci_irq(int xc_handle, + uint32_t domid, + uint8_t machine_irq, + uint8_t bus, + uint8_t device, + uint8_t intx); + +int xc_domain_bind_pt_isa_irq(int xc_handle, + uint32_t domid, + uint8_t machine_irq); + #endif /* XENCTRL_H */ diff -r 9071521d4864 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/python/xen/xend/XendConfig.py Tue Sep 11 16:30:32 2007 -0700 @@ -127,7 +127,7 @@ XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 'nographic', 'pae', 'rtc_timeoffset', 'serial', 'sdl', 'soundhw','stdvga', 'usb', 'usbdevice', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten', - 'vncpasswd', 'vncunused', 'xauthority'] + 'vncpasswd', 'vncunused', 'xauthority', 'pci'] # Xen API console 'other_config' keys. XENAPI_CONSOLE_OTHER_CFG = ['vncunused', 'vncdisplay', 'vnclisten', @@ -168,6 +168,7 @@ XENAPI_CFG_TYPES = { 'tools_version': dict, 'other_config': dict, 'security_label': str, + 'pci': str, } # List of legacy configuration keys that have no equivalent in the diff -r 9071521d4864 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/python/xen/xend/image.py Tue Sep 11 16:30:32 2007 -0700 @@ -309,7 +309,7 @@ class HVMImageHandler(ImageHandler): def parseDeviceModelArgs(self, vmConfig): dmargs = [ 'boot', 'fda', 'fdb', 'soundhw', 'localtime', 'serial', 'stdvga', 'isa', - 'acpi', 'usb', 'usbdevice', 'keymap' ] + 'acpi', 'usb', 'usbdevice', 'keymap', 'pci' ] ret = ['-vcpus', str(self.vm.getVCpuCount())] diff -r 9071521d4864 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Fri Sep 07 11:39:10 2007 +0100 +++ b/tools/python/xen/xm/create.py Tue Sep 11 16:30:32 2007 -0700 @@ -721,7 +721,7 @@ def configure_hvm(config_image, vals): 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', 'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor', - 'acpi', 'apic', 'usb', 'usbdevice', 'keymap' ] + 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci' ] for a in args: if a in vals.__dict__ and vals.__dict__[a] is not None: config_image.append([a, vals.__dict__[a]]) diff -r 9071521d4864 tools/ioemu/hw/pass-through.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/pass-through.c Tue Sep 11 16:59:03 2007 -0700 @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2007, Neocleus Corporation. + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Alex Novik <alex@neocleus.com> + * Allen Kay <allen.m.kay@intel.com> + * Guy Zana <guy@neocleus.com> + * + * This file implements direct PCI assignment to a HVM guest + * + */ +#include "vl.h" +#include "pass-through.h" +#include "pci/header.h" +#include "pci/pci.h" + +extern FILE *logfile; +char *token; + +int pci_devs(const char *direct_pci) +{ + int count = 0; + const char *c; + + /* skip first "[" character */ + c = direct_pci + 1; + while ((c = strchr(c, '[')) != NULL) { + c++; + count++; + } + return (count); +} + +int next_token(char *direct_pci) +{ + if (token == NULL) + token = strtok(direct_pci, ","); + else + token = strtok(NULL, ","); + token = strchr(token, 'x'); + token = token + 1; + return ((int) strtol(token, NULL, 16)); +} + +void next_bdf(char *direct_pci, int *seg, + int *bus, int *dev, int *func) +{ + *seg = next_token(direct_pci); + *bus = next_token(direct_pci); + *dev = next_token(direct_pci); + *func = next_token(direct_pci); +} + +uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap) +{ + int id; + int max_cap = 48; + int pos = PCI_CAPABILITY_LIST; + int status; + + status = pci_read_byte(pci_dev, PCI_STATUS); + if ( (status & PCI_STATUS_CAP_LIST) == 0 ) + return 0; + + while ( max_cap-- ) + { + pos = pci_read_byte(pci_dev, pos); + if ( pos < 0x40 ) + break; + + pos &= ~3; + id = pci_read_byte(pci_dev, pos + PCI_CAP_LIST_ID); + + if ( id == 0xff ) + break; + if ( id == cap ) + return pos; + + pos += PCI_CAP_LIST_NEXT; + } + return 0; +} + +void pdev_flr(struct pci_dev *pci_dev) +{ + int pos; + int dev_cap; + int dev_status; + + pos = find_cap_offset(pci_dev, PCI_CAP_ID_EXP); + if ( pos ) + { + dev_cap = pci_read_long(pci_dev, pos + PCI_EXP_DEVCAP); + if ( dev_cap & PCI_EXP_DEVCAP_FLR ) + { + pci_write_word(pci_dev, pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR); + do { + dev_status = pci_read_long(pci_dev, pos + PCI_EXP_DEVSTA); + } while (dev_status & PCI_EXP_DEVSTA_TRPND); + } + } +} + +/* Being called each time a mmio region has been updated */ +void pt_iomem_map(PCIDevice *d, int i, uint32_t e_phys, uint32_t e_size, + int type) +{ + struct pt_dev *assigned_device = (struct pt_dev *)d; + uint32_t old_ebase = assigned_device->bases[i].e_physbase; + int first_map = ( assigned_device->bases[i].e_size == 0 ); + int ret = 0; + + assigned_device->bases[i].e_physbase = e_phys; + assigned_device->bases[i].e_size= e_size; + + PT_LOG("e_phys=%08x maddr=%08x type=%d len=%08x index=%d\n", + e_phys, assigned_device->bases[i].access.maddr, type, e_size, i); + + if ( e_size == 0 ) + return; + + if ( !first_map ) + { + /* Remove old mapping */ + ret = xc_domain_memory_mapping(xc_handle, domid, old_ebase >> 12, + assigned_device->bases[i].access.maddr >> 12, + (e_size+0xFFF) >> 12, + DPCI_REMOVE_MAPPING); + if ( ret != 0 ) + { + PT_LOG("Error: remove old mapping failed!\n"); + return; + } + } + + /* Create new mapping */ + ret = xc_domain_memory_mapping(xc_handle, domid, + assigned_device->bases[i].e_physbase >> 12, + assigned_device->bases[i].access.maddr >> 12, + (e_size+0xFFF) >> 12, + DPCI_ADD_MAPPING); + if ( ret != 0 ) + PT_LOG("Error: create new mapping failed!\n"); + +} + +/* Being called each time a pio region has been updated */ +void pt_ioport_map(PCIDevice *d, int i, + uint32_t e_phys, uint32_t e_size, int type) +{ + struct pt_dev *assigned_device = (struct pt_dev *)d; + uint32_t old_ebase = assigned_device->bases[i].e_physbase; + int first_map = ( assigned_device->bases[i].e_size == 0 ); + int ret = 0; + + assigned_device->bases[i].e_physbase = e_phys; + assigned_device->bases[i].e_size= e_size; + + PT_LOG("e_phys=%04x pio_base=%04x len=%04x index=%d\n", + (uint16_t)e_phys, (uint16_t)assigned_device->bases[i].access.pio_base, + (uint16_t)e_size, i); + + if ( e_size == 0 ) + return; + + if ( !first_map ) + { + /* Remove old mapping */ + ret = xc_domain_ioport_mapping(xc_handle, domid, old_ebase, + assigned_device->bases[i].access.pio_base, e_size, + DPCI_REMOVE_MAPPING); + if ( ret != 0 ) + { + PT_LOG("Error: remove old mapping failed!\n"); + return; + } + } + + /* Create new mapping */ + ret = xc_domain_ioport_mapping(xc_handle, domid, e_phys, + assigned_device->bases[i].access.pio_base, e_size, + DPCI_ADD_MAPPING); + if ( ret != 0 ) + PT_LOG("Error: create new mapping failed!\n"); + +} + +static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, + int len) +{ + struct pt_dev *assigned_device = (struct pt_dev *)d; + struct pci_dev *pci_dev = assigned_device->pci_dev; + +#ifdef PT_DEBUG_PCI_CONFIG_ACCESS + PT_LOG("(%x.%x): address=%04x val=0x%08x len=%d\n", + (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len); +#endif + + /* Pre-write hooking */ + switch ( address ) { + case 0x0C ... 0x3F: + pci_default_write_config(d, address, val, len); + return; + } + + /* PCI config pass-through */ + if (address == 0x4) { + switch (len){ + case 1: + pci_write_byte(pci_dev, address, val); + break; + case 2: + pci_write_word(pci_dev, address, val); + break; + case 4: + pci_write_long(pci_dev, address, val); + break; + } + } + + if (address == 0x4) { + /* Post-write hooking */ + pci_default_write_config(d, address, val, len); + } +} + +static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t address, int len) +{ + struct pt_dev *assigned_device = (struct pt_dev *)d; + struct pci_dev *pci_dev = assigned_device->pci_dev; + uint32_t val = 0xFF; + + /* Pre-hooking */ + switch ( address ) { + case 0x0C ... 0x3F: + val = pci_default_read_config(d, address, len); + goto exit; + } + + switch ( len ) { + case 1: + val = pci_read_byte(pci_dev, address); + break; + case 2: + val = pci_read_word(pci_dev, address); + break; + case 4: + val = pci_read_long(pci_dev, address); + break; + } + +exit: + +#ifdef PT_DEBUG_PCI_CONFIG_ACCESS + PT_LOG("(%x.%x): address=%04x val=0x%08x len=%d\n", + (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len); +#endif + + return val; +} + +static int pt_register_regions(struct pt_dev *assigned_device) +{ + int i = 0; + uint32_t bar_data = 0; + struct pci_dev *pci_dev = assigned_device->pci_dev; + PCIDevice *d = &assigned_device->dev; + + /* Register PIO/MMIO BARs */ + for ( i=0; i < PCI_BAR_ENTRIES; i++ ) + { + if ( pci_dev->base_addr[i] ) + { + assigned_device->bases[i].e_physbase = pci_dev->base_addr[i]; + assigned_device->bases[i].access.u = pci_dev->base_addr[i]; + + /* Register current region */ + bar_data = *((uint32_t*)(d->config + PCI_BASE_ADDRESS_0) + i); + if ( bar_data & PCI_ADDRESS_SPACE_IO ) + pci_register_io_region((PCIDevice *)assigned_device, i, + (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_IO, + pt_ioport_map); + else if ( bar_data & PCI_ADDRESS_SPACE_MEM_PREFETCH ) + pci_register_io_region((PCIDevice *)assigned_device, i, + (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM_PREFETCH, + pt_iomem_map); + else + pci_register_io_region((PCIDevice *)assigned_device, i, + (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM, + pt_iomem_map); + + PT_LOG("IO region registered (size=0x%08x base_addr=0x%08x)\n", + (uint32_t)(pci_dev->size[i]), + (uint32_t)(pci_dev->base_addr[i])); + } + } + + /* Register expansion ROM address */ + if ( pci_dev->rom_base_addr && pci_dev->rom_size ) + { + assigned_device->bases[PCI_ROM_SLOT].e_physbase = + pci_dev->rom_base_addr; + assigned_device->bases[PCI_ROM_SLOT].access.maddr = + pci_dev->rom_base_addr; + pci_register_io_region((PCIDevice *)assigned_device, PCI_ROM_SLOT, + pci_dev->rom_size, PCI_ADDRESS_SPACE_MEM_PREFETCH, + pt_iomem_map); + + PT_LOG("Expansion ROM registered (size=0x%08x base_addr=0x%08x)\n", + (uint32_t)(pci_dev->rom_size), (uint32_t)(pci_dev->rom_base_addr)); + } + + return 0; +} + +struct pt_dev * register_real_device(PCIBus *e_bus, + const char *e_dev_name, int e_devfn, uint8_t r_bus, uint8_t r_dev, + uint8_t r_func, uint32_t machine_irq, struct pci_access *pci_access) +{ + int rc, i; + struct pt_dev *assigned_device = NULL; + struct pci_dev *pci_dev; + struct pci_config_cf8 machine_bdf; + uint8_t e_device, e_intx; + + PT_LOG("Assigning real physical device %02x:%02x.%x ...\n", + r_bus, r_dev, r_func); + + /* Find real device structure */ + for (pci_dev = pci_access->devices; pci_dev != NULL; + pci_dev = pci_dev->next) + { + if ((r_bus == pci_dev->bus) && (r_dev == pci_dev->dev) + && (r_func == pci_dev->func)) + break; + } + if ( pci_dev == NULL ) + { + PT_LOG("Error: couldn't locate device in libpci structures\n"); + return NULL; + } + + /* Register device */ + assigned_device = (struct pt_dev *) pci_register_device(e_bus, e_dev_name, + sizeof(struct pt_dev), e_devfn, + pt_pci_read_config, pt_pci_write_config); + if ( assigned_device == NULL ) + { + PT_LOG("Error: couldn't register real device\n"); + return NULL; + } + + assigned_device->pci_dev = pci_dev; + + /* Issue PCIe FLR */ + pdev_flr(pci_dev); + + /* Tell XEN vmm to change iommu settings */ + machine_bdf.reg = 0; + machine_bdf.bus = r_bus; + machine_bdf.dev = r_dev; + machine_bdf.func = r_func; + rc = xc_assign_device(xc_handle, domid, machine_bdf.value); + if ( rc < 0 ) + PT_LOG("Error: xc_domain_assign_device error %d\n", rc); + + /* Initialize virtualized PCI configuration (Extended 256 Bytes) */ + for ( i = 0; i < PCI_CONFIG_SIZE; i++ ) + assigned_device->dev.config[i] = pci_read_byte(pci_dev, i); + + /* Handle real device's MMIO/PIO BARs */ + pt_register_regions(assigned_device); + + /* Bind interrupt */ + e_device = (assigned_device->dev.devfn >> 3) & 0x1f; + e_intx = assigned_device->dev.config[0x3d]-1; + + if ( PT_MACHINE_IRQ_AUTO == machine_irq ) + machine_irq = pci_dev->irq; + + /* bind machine_irq to device */ + if ( 0 != machine_irq ) + { + rc = xc_domain_bind_pt_pci_irq(xc_handle, domid, machine_irq, 0, + e_device, e_intx); + if ( rc < 0 ) + { + /* TBD: unregister device in case of an error */ + PT_LOG("Error: Binding of interrupt failed! rc=%d\n", rc); + } + } + else { + /* Disable PCI intx assertion (turn on bit10 of devctl) */ + assigned_device->dev.config[0x05] |= 0x04; + pci_write_word(pci_dev, 0x04, + *(uint16_t *)(&assigned_device->dev.config[0x04])); + } + + PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n", + r_bus, r_dev, r_func); + + return assigned_device; +} + +int pt_init(PCIBus *e_bus, char *direct_pci) +{ + int i; + int seg, b, d, f; + struct pt_dev *pt_dev; + struct pci_access *pci_access; + int dev_count = pci_devs(direct_pci); + + /* Initialize libpci */ + pci_access = pci_alloc(); + if ( pci_access == NULL ) + { + PT_LOG("pci_access is NULL\n"); + return -1; + } + pci_init(pci_access); + pci_scan_bus(pci_access); + + /* Assign given devices to guest */ + for ( i = 0; i < dev_count; i++ ) + { + /* Get next device bdf (bus, device, function) */ + next_bdf(direct_pci, &seg, &b, &d, &f); + + /* Register real device with the emulated bus */ + pt_dev = register_real_device(e_bus, "DIRECT PCI", PT_VIRT_DEVFN_AUTO, + b, d, f, PT_MACHINE_IRQ_AUTO, pci_access); + if ( pt_dev == NULL ) + { + PT_LOG("Error: Registration failed (%02x:%02x.%x)\n", b, d, f); + return -1; + } + } + + /* Success */ + return 0; +} diff -r 9071521d4864 tools/ioemu/hw/pass-through.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/pass-through.h Tue Sep 11 16:30:32 2007 -0700 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2007, Neocleus Corporation. + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PASSTHROUGH_H__ +#define __PASSTHROUGH_H__ + +#include "vl.h" +#include "pci/header.h" +#include "pci/pci.h" + +/* Log acesss */ +#define PT_LOGGING_ENABLED + +#ifdef PT_LOGGING_ENABLED +#define PT_LOG(_f, _a...) fprintf(logfile, "%s: " _f, __func__, ##_a) +#else +#define PT_LOG(_f, _a...) +#endif + +/* Some compilation flags */ +// #define PT_DEBUG_PCI_CONFIG_ACCESS + +#define PT_MACHINE_IRQ_AUTO (0xFFFFFFFF) +#define PT_VIRT_DEVFN_AUTO (-1) + +/* Misc PCI constants that should be moved to a separate library :) */ +#define PCI_CONFIG_SIZE (256) +#define PCI_EXP_DEVCAP_FLR (1 << 28) +#define PCI_EXP_DEVCTL_FLR (0x1b) +#define PCI_BAR_ENTRIES (6) + +struct pt_region { + /* Virtual phys base & size */ + uint32_t e_physbase; + uint32_t e_size; + /* Index of region in qemu */ + uint32_t memory_index; + /* Translation of the emulated address */ + union { + uint32_t maddr; + uint32_t pio_base; + uint32_t u; + } access; +}; + +/* + This structure holds the context of the mapping functions + and data that is relevant for qemu device management. +*/ +struct pt_dev { + PCIDevice dev; + struct pci_dev *pci_dev; /* libpci struct */ + struct pt_region bases[PCI_NUM_REGIONS]; /* Access regions */ +}; + +/* Used for formatting PCI BDF into cf8 format */ +struct pci_config_cf8 { + union { + unsigned int value; + struct { + unsigned int reserved1:2; + unsigned int reg:6; + unsigned int func:3; + unsigned int dev:5; + unsigned int bus:8; + unsigned int reserved2:7; + unsigned int enable:1; + }; + }; +}; + +int pt_init(PCIBus * e_bus, char * direct_pci); + +#endif /* __PASSTHROUGH_H__ */ + [-- Attachment #3: neo_tools.patch --] [-- Type: application/octet-stream, Size: 23787 bytes --] diff -r e10db6df1eae tools/ioemu/vl.c --- a/tools/ioemu/vl.c Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/ioemu/vl.c Tue Sep 11 17:39:41 2007 -0700 @@ -133,6 +133,7 @@ int nographic; int nographic; int vncviewer; int vncunused; +int is_nativedom; const char* keyboard_layout = NULL; int64_t ticks_per_sec; char *boot_device = NULL; @@ -6497,6 +6498,8 @@ enum { QEMU_OPTION_acpi, QEMU_OPTION_vncviewer, QEMU_OPTION_vncunused, + + QEMU_OPTION_nativedom, QEMU_OPTION_pci, }; @@ -6595,7 +6598,10 @@ const QEMUOption qemu_options[] = { { "d", HAS_ARG, QEMU_OPTION_d }, { "vcpus", 1, QEMU_OPTION_vcpus }, { "acpi", 0, QEMU_OPTION_acpi }, + + { "nativedom", HAS_ARG, QEMU_OPTION_nativedom }, { "pci", HAS_ARG, QEMU_OPTION_pci}, + { NULL }, }; @@ -7051,6 +7057,7 @@ int main(int argc, char **argv) extern void *buffered_pio_page; #endif sigset_t set; + char qemu_dm_logfilename[128]; const char *direct_pci = NULL; @@ -7546,6 +7553,9 @@ int main(int argc, char **argv) case QEMU_OPTION_vncunused: vncunused++; break; + case QEMU_OPTION_nativedom: + is_nativedom=1; + break; case QEMU_OPTION_pci: direct_pci = optarg; break; @@ -7606,6 +7616,21 @@ int main(int argc, char **argv) #endif #ifdef CONFIG_DM + xc_handle = xc_interface_open(); + + /* Compute the RAM size of nativedom */ + if ( is_nativedom ) + { + if ( !xc_is_nativedom_enabled(xc_handle) ) + { + fprintf(logfile, "Error: NativeDom is not enabled. Use the enable_nativedom=1 boot parameter\n"); + exit(1); + } + + /* Recompute the size of RAM */ + ram_size = xc_get_nativedom_last_mfn(xc_handle) << 12; + } + bdrv_init(); xenstore_parse_domain_config(domid); #endif /* CONFIG_DM */ @@ -7704,8 +7729,6 @@ int main(int argc, char **argv) #ifdef CONFIG_DM - xc_handle = xc_interface_open(); - #if defined(__i386__) || defined(__x86_64__) if (qemu_map_cache_init()) { diff -r e10db6df1eae tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/libxc/xc_domain.c Tue Sep 11 17:45:03 2007 -0700 @@ -499,6 +499,38 @@ int xc_domain_memory_decrease_reservatio DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n", domid, nr_extents, extent_order); errno = EINVAL; + err = -1; + } + + return err; +} + +int xc_domain_1to1_memory_populate_physmap(int xc_handle, + uint32_t domid, + unsigned long nr_extents, + unsigned int extent_order, + unsigned int address_bits, + xen_pfn_t *extent_start) +{ + int err; + struct xen_memory_reservation reservation = { + .nr_extents = nr_extents, + .extent_order = extent_order, + .address_bits = address_bits, + .domid = domid + }; + set_xen_guest_handle(reservation.extent_start, extent_start); + + err = xc_memory_op(xc_handle, XENMEM_populate_1to1_physmap, &reservation); + + if ( err == nr_extents ) + return 0; + + if ( err >= 0 ) + { + DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n", + domid, nr_extents, extent_order); + errno = EBUSY; err = -1; } @@ -757,7 +789,7 @@ int xc_domain_bind_pt_irq( uint8_t bus, uint8_t device, uint8_t intx, - uint8_t isa_irq) + uint8_t isa_irq) { int rc; xen_domctl_bind_pt_irq_t * bind; diff -r e10db6df1eae tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/libxc/xc_hvm_build.c Tue Sep 11 17:39:41 2007 -0700 @@ -10,6 +10,7 @@ #include "xg_private.h" #include "xc_private.h" +#include "xg_save_restore.h" /* PFN_TO_KB */ #include <xen/foreign/x86_32.h> #include <xen/foreign/x86_64.h> @@ -108,6 +109,45 @@ static void build_e820map(void *e820_pag *(((unsigned char *)e820_page) + HVM_E820_NR_OFFSET) = nr_map; } +int xc_is_nativedom_enabled(int xc_handle) +{ + DECLARE_HYPERCALL; + int rc; + + hypercall.op = __HYPERVISOR_hvm_op; + hypercall.arg[0] = HVMOP_is_nativedom_enabled; + + rc = do_xen_hypercall(xc_handle, &hypercall); + + return rc; +} + +int xc_get_nativedom_last_mfn(int xc_handle) +{ + return (xc_memory_op(xc_handle, XENMEM_maximum_ram_page_nativedom, NULL)); +} + +int xc_build_nativedom_e820map(int handle, uint32_t dom) +{ + DECLARE_HYPERCALL; + xen_hvm_copy_nativedom_e820_map_t arg; + int rc; + + hypercall.op = __HYPERVISOR_hvm_op; + hypercall.arg[0] = HVMOP_copy_nativedom_e820_map; + hypercall.arg[1] = (unsigned long)&arg; + + arg.domid = dom; + + if ( lock_pages(&arg, sizeof(arg)) != 0 ) + return -1; + + rc = do_xen_hypercall(handle, &hypercall); + unlock_pages(&arg, sizeof(arg)); + + return rc; +} + static int loadelfimage( struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray) { @@ -155,14 +195,14 @@ static int setup_guest(int xc_handle, static int setup_guest(int xc_handle, uint32_t dom, int memsize, char *image, unsigned long image_size, - vcpu_guest_context_either_t *ctxt) + vcpu_guest_context_either_t *ctxt, int is_nativedom) { xen_pfn_t *page_array = NULL; + void *e820_page = NULL; unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT); unsigned long shared_page_nr; struct xen_add_to_physmap xatp; struct shared_info *shared_info; - void *e820_page; struct elf_binary elf; uint64_t v_start, v_end; int rc; @@ -175,8 +215,28 @@ static int setup_guest(int xc_handle, if ( elf_init(&elf, image, image_size) != 0 ) goto error_out; elf_parse_binary(&elf); - v_start = 0; - v_end = (unsigned long long)memsize << 20; + + if ( !is_nativedom ) + { + v_start = 0; + v_end = (unsigned long long)memsize << 20; + } + else + { + nr_pages = xc_get_nativedom_last_mfn(xc_handle); + v_start = 0; + v_end = nr_pages << PAGE_SHIFT; + + DPRINTF("NativeDom: last page = %lu\n", nr_pages-1); + + /* set the max memory in KB */ + rc = xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(nr_pages)); + if ( 0 != rc ) + { + PERROR("NativeDom: Couldn't set domain's maxmem\n"); + goto error_out; + } + } if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 ) { @@ -209,28 +269,53 @@ static int setup_guest(int xc_handle, for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < nr_pages; i++ ) page_array[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; - /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */ - rc = xc_domain_memory_populate_physmap( - xc_handle, dom, 0xa0, 0, 0, &page_array[0x00]); - if ( rc == 0 ) + if ( !is_nativedom ) + { + /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */ rc = xc_domain_memory_populate_physmap( - xc_handle, dom, nr_pages - 0xc0, 0, 0, &page_array[0xc0]); - if ( rc != 0 ) - { - PERROR("Could not allocate memory for HVM guest.\n"); - goto error_out; - } - + xc_handle, dom, 0xa0, 0, 0, &page_array[0x00]); + if ( rc == 0 ) + rc = xc_domain_memory_populate_physmap( + xc_handle, dom, nr_pages - 0xc0, 0, 0, &page_array[0xc0]); + if ( rc != 0 ) + { + PERROR("Could not allocate memory for HVM guest.\n"); + goto error_out; + } + } + else + { + rc = xc_domain_1to1_memory_populate_physmap(xc_handle, dom, nr_pages, 0, 0, &page_array[0x00]); + if ( rc != 0 ) + { + PERROR("NativeDom: Couldn't populate 1:1 mapping.\n"); + goto error_out; + } + } + if ( loadelfimage(&elf, xc_handle, dom, page_array) != 0 ) goto error_out; - if ( (e820_page = xc_map_foreign_range( - xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, - HVM_E820_PAGE >> PAGE_SHIFT)) == NULL ) - goto error_out; - memset(e820_page, 0, PAGE_SIZE); - build_e820map(e820_page, v_end); - munmap(e820_page, PAGE_SIZE); + if ( !is_nativedom ) + { + if ( (e820_page = xc_map_foreign_range( + xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, + HVM_E820_PAGE >> PAGE_SHIFT)) == NULL ) + goto error_out; + memset(e820_page, 0, PAGE_SIZE); + build_e820map(e820_page, v_end); + munmap(e820_page, PAGE_SIZE); + } + else + { + /* Use a hypercall to build the guest e820 table */ + rc = xc_build_nativedom_e820map(xc_handle, dom); + if ( rc != 0 ) + { + PERROR("NativeDom: Couldn't build e820 memory map\n"); + goto error_out; + } + } /* Map and initialise shared_info page. */ xatp.domid = dom; @@ -288,7 +373,8 @@ static int xc_hvm_build_internal(int xc_ uint32_t domid, int memsize, char *image, - unsigned long image_size) + unsigned long image_size, + int is_nativedom) { struct xen_domctl launch_domctl; vcpu_guest_context_either_t ctxt; @@ -302,7 +388,8 @@ static int xc_hvm_build_internal(int xc_ memset(&ctxt, 0, sizeof(ctxt)); - if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt) < 0 ) + if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt, + is_nativedom) < 0 ) { goto error_out; } @@ -340,7 +427,8 @@ int xc_hvm_build(int xc_handle, int xc_hvm_build(int xc_handle, uint32_t domid, int memsize, - const char *image_name) + const char *image_name, + int is_nativedom) { char *image; int sts; @@ -350,7 +438,13 @@ int xc_hvm_build(int xc_handle, ((image = xc_read_image(image_name, &image_size)) == NULL) ) return -1; - sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size); + if ( (is_nativedom) && (!xc_is_nativedom_enabled(xc_handle)) ) + { + ERROR("Couldn't start NativeDom since it's not enabled. Add enable_nativedom=1 as a boot parameter"); + return -1; + } + + sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size, is_nativedom); free(image); @@ -364,7 +458,8 @@ int xc_hvm_build_mem(int xc_handle, uint32_t domid, int memsize, const char *image_buffer, - unsigned long image_size) + unsigned long image_size, + int is_nativedom) { int sts; unsigned long img_len; @@ -386,7 +481,7 @@ int xc_hvm_build_mem(int xc_handle, } sts = xc_hvm_build_internal(xc_handle, domid, memsize, - img, img_len); + img, img_len, is_nativedom); /* xc_inflate_buffer may return the original buffer pointer (for for already inflated buffers), so exercise some care in freeing */ diff -r e10db6df1eae tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/libxc/xc_private.c Tue Sep 11 17:39:41 2007 -0700 @@ -225,6 +225,7 @@ int xc_memory_op(int xc_handle, { case XENMEM_increase_reservation: case XENMEM_decrease_reservation: + case XENMEM_populate_1to1_physmap: case XENMEM_populate_physmap: if ( lock_pages(reservation, sizeof(*reservation)) != 0 ) { @@ -280,6 +281,7 @@ int xc_memory_op(int xc_handle, { case XENMEM_increase_reservation: case XENMEM_decrease_reservation: + case XENMEM_populate_1to1_physmap: case XENMEM_populate_physmap: unlock_pages(reservation, sizeof(*reservation)); get_xen_guest_handle(extent_start, reservation->extent_start); diff -r e10db6df1eae tools/libxc/xc_private.h --- a/tools/libxc/xc_private.h Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/libxc/xc_private.h Tue Sep 11 17:39:41 2007 -0700 @@ -49,21 +49,21 @@ #define MAX_PAGECACHE_USAGE (4*1024) #if INFO -#define IPRINTF(_f, _a...) printf(_f , ## _a) +#define IPRINTF(_f, _a...) fprintf(stderr, "[INFO] " _f , ## _a) #else #define IPRINTF(_f, _a...) ((void)0) #endif #if DEBUG -#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) +#define DPRINTF(_f, _a...) fprintf(stderr, "[DEBUG] " _f , ## _a) #else #define DPRINTF(_f, _a...) ((void)0) #endif #if PROGRESS -#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) +#define PPRINTF(_f, _a...) fprintf(stderr, "[PROGRESS] " _f , ## _a) #else -#define PPRINTF(_f, _a...) +#define PPRINTF(_f, _a...) ((void)0) #endif char *safe_strerror(int errcode); diff -r e10db6df1eae tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/libxc/xenctrl.h Tue Sep 11 17:39:41 2007 -0700 @@ -596,6 +596,13 @@ int xc_domain_memory_populate_physmap(in unsigned int address_bits, xen_pfn_t *extent_start); +int xc_domain_1to1_memory_populate_physmap(int xc_handle, + uint32_t domid, + unsigned long nr_extents, + unsigned int extent_order, + unsigned int address_bits, + xen_pfn_t *extent_start); + int xc_domain_ioport_permission(int xc_handle, uint32_t domid, uint32_t first_port, diff -r e10db6df1eae tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/libxc/xenguest.h Tue Sep 11 17:39:41 2007 -0700 @@ -128,13 +128,20 @@ int xc_hvm_build(int xc_handle, int xc_hvm_build(int xc_handle, uint32_t domid, int memsize, - const char *image_name); + const char *image_name, + int is_nativedom); int xc_hvm_build_mem(int xc_handle, uint32_t domid, int memsize, const char *image_buffer, - unsigned long image_size); + unsigned long image_size, + int is_nativedom); + +/* NativeDom support */ +int xc_is_nativedom_enabled(int xc_handle); +int xc_get_nativedom_last_mfn(int xc_handle); +int xc_build_nativedom_e820map(int handle, uint32_t dom); /* PowerPC specific. */ int xc_prose_build(int xc_handle, diff -r e10db6df1eae tools/libxc/xg_private.c --- a/tools/libxc/xg_private.c Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/libxc/xg_private.c Tue Sep 11 17:39:41 2007 -0700 @@ -192,7 +192,8 @@ __attribute__((weak)) int xc_hvm_build(int xc_handle, uint32_t domid, int memsize, - const char *image_name) + const char *image_name, + int is_nativedom) { errno = ENOSYS; return -1; diff -r e10db6df1eae tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/python/xen/lowlevel/xc/xc.c Tue Sep 11 17:39:41 2007 -0700 @@ -536,18 +536,18 @@ static PyObject *pyxc_hvm_build(XcObject int i; #endif char *image; - int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1; + int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1, is_nativedom = 0; unsigned long store_mfn; static char *kwd_list[] = { "domid", "store_evtchn", "memsize", "image", "vcpus", "pae", "acpi", - "apic", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list, + "apic", "nativedom", NULL }; + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiiii", kwd_list, &dom, &store_evtchn, &memsize, - &image, &vcpus, &pae, &acpi, &apic) ) - return NULL; - - if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 ) + &image, &vcpus, &pae, &acpi, &apic, &is_nativedom) ) + return NULL; + + if ( xc_hvm_build(self->xc_handle, dom, memsize, image, is_nativedom) != 0 ) return pyxc_error_to_exception(); #if !defined(__ia64__) @@ -576,6 +576,8 @@ static PyObject *pyxc_hvm_build(XcObject #endif xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn); + + xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_IS_NATIVEDOM, is_nativedom); return Py_BuildValue("{s:i}", "store_mfn", store_mfn); } diff -r e10db6df1eae tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/python/xen/xend/XendConfig.py Tue Sep 11 17:39:41 2007 -0700 @@ -33,8 +33,8 @@ from xen.util.blkif import blkdev_name_t from xen.util.blkif import blkdev_name_to_number from xen.util import xsconstants -log = logging.getLogger("xend.XendConfig") -log.setLevel(logging.WARN) +log = logging.getLogger("xend.XendDomainInfo") +#log.setLevel(logging.WARN) """ @@ -127,7 +127,8 @@ XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 'nographic', 'pae', 'rtc_timeoffset', 'serial', 'sdl', 'soundhw','stdvga', 'usb', 'usbdevice', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten', - 'vncpasswd', 'vncunused', 'xauthority', 'pci'] + 'vncpasswd', 'vncunused', 'xauthority', 'nativedom', + 'pci'] # Xen API console 'other_config' keys. XENAPI_CONSOLE_OTHER_CFG = ['vncunused', 'vncdisplay', 'vnclisten', @@ -169,6 +170,7 @@ XENAPI_CFG_TYPES = { 'other_config': dict, 'security_label': str, 'pci': str, + 'nativedom': int, } # List of legacy configuration keys that have no equivalent in the diff -r e10db6df1eae tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Sep 11 17:39:41 2007 -0700 @@ -343,7 +343,15 @@ class XendDomainInfo: self.domid = self.info.get('domid') else: self.domid = domid - + + try: + hvm_platform = self.info.get('platform', {}) + self.is_nativedom = bool(hvm_platform['nativedom']) + except: + self.is_nativedom = False + + log.debug("NativeDom: %s" % self.is_nativedom) + #REMOVE: uuid is now generated in XendConfig #if not self._infoIsSet('uuid'): # self.info['uuid'] = uuid.toString(uuid.create()) @@ -1578,6 +1586,8 @@ class XendDomainInfo: except RuntimeError, exn: raise XendError(str(exn)) + def _isNativeDom(self): + return self.is_nativedom def _initDomain(self): log.debug('XendDomainInfo.initDomain: %s %s', @@ -1618,11 +1628,14 @@ class XendDomainInfo: # takes MiB and we must not round down and end up under-providing. shadow = ((shadow + 1023) / 1024) * 1024 - # set memory limit - xc.domain_setmaxmem(self.domid, maxmem) - - # Make sure there's enough RAM available for the domain - balloon.free(memory + shadow) + if (not self._isNativeDom()): + # set memory limit + xc.domain_setmaxmem(self.domid, maxmem) + + # Make sure there's enough RAM available for the domain + balloon.free(memory + shadow) + else: + balloon.free(shadow) # Set up the shadow memory shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024) diff -r e10db6df1eae tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/python/xen/xend/image.py Tue Sep 11 17:39:41 2007 -0700 @@ -277,6 +277,7 @@ class HVMImageHandler(ImageHandler): self.pae = int(vmConfig['platform'].get('pae', 0)) self.apic = int(vmConfig['platform'].get('apic', 0)) self.acpi = int(vmConfig['platform'].get('acpi', 0)) + self.nativedom = int(vmConfig['platform'].get('nativedom', 0)) def buildDomain(self): @@ -292,6 +293,8 @@ class HVMImageHandler(ImageHandler): log.debug("pae = %d", self.pae) log.debug("acpi = %d", self.acpi) log.debug("apic = %d", self.apic) + log.debug("nativedom = %d", self.nativedom) + rc = xc.hvm_build(domid = self.vm.getDomid(), image = self.kernel, @@ -300,7 +303,8 @@ class HVMImageHandler(ImageHandler): vcpus = self.vm.getVCpuCount(), pae = self.pae, acpi = self.acpi, - apic = self.apic) + apic = self.apic, + nativedom = self.nativedom) rc['notes'] = { 'SUSPEND_CANCEL': 1 } return rc @@ -309,7 +313,7 @@ class HVMImageHandler(ImageHandler): def parseDeviceModelArgs(self, vmConfig): dmargs = [ 'boot', 'fda', 'fdb', 'soundhw', 'localtime', 'serial', 'stdvga', 'isa', - 'acpi', 'usb', 'usbdevice', 'keymap', 'pci' ] + 'acpi', 'usb', 'usbdevice', 'keymap', 'pci', 'nativedom' ] ret = ['-vcpus', str(self.vm.getVCpuCount())] diff -r e10db6df1eae tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Tue Sep 11 17:34:15 2007 -0700 +++ b/tools/python/xen/xm/create.py Tue Sep 11 17:39:41 2007 -0700 @@ -281,6 +281,10 @@ gopts.var('disk', val='phy:DEV,VDEV,MODE is 'r', read-write if MODE is 'w'. If DOM is specified it defines the backend driver domain to use for the disk. The option may be repeated to add more than one disk.""") + +gopts.var('nativedom', val='no|yes', + fn=set_bool, default=0, + use="Tells whether the domain is NativeDom") gopts.var('pci', val='BUS:DEV.FUNC', fn=append_value, default=[], @@ -721,7 +725,7 @@ def configure_hvm(config_image, vals): 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', 'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor', - 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci' ] + 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'nativedom', 'pci' ] for a in args: if a in vals.__dict__ and vals.__dict__[a] is not None: config_image.append([a, vals.__dict__[a]]) [-- Attachment #4: Type: text/plain, Size: 138 bytes --] _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-12 1:21 ` Kay, Allen M @ 2007-09-12 9:03 ` Keir Fraser 2007-09-12 22:37 ` Kay, Allen M 0 siblings, 1 reply; 13+ messages in thread From: Keir Fraser @ 2007-09-12 9:03 UTC (permalink / raw) To: Kay, Allen M, xen-devel; +Cc: Guy Zana Vtd_tools patch breaks the build on my box. Cannot find pci/header.h or pci/pci.h. Probably because libpci is not such a standard install component after all? I'm trying to build on Debian 3.1. Either the dependency needs to be avoided, or we need to be sure that the dependency is easy to resolve on most distros, and we need a tools/check script to check for and warn/error on the dependency. -- Keir On 12/9/07 02:21, "Kay, Allen M" <allen.m.kay@intel.com> wrote: > Attached patches splits vtd and neo changes to tools directory. Applies > cleanly to staging tree. > > Vtd_tools.patch: vt-d and generic changes > Neo_tools.patch: neocleus specific changes > > Signed-off-by: Allen Kay <allen.m.kay@intel.com> > Signed-off-by: Guy Zana <guy@neocleus.com> > >> -----Original Message----- >> From: Keir Fraser [mailto:Keir.Fraser@cl.cam.ac.uk] >> Sent: Tuesday, September 11, 2007 6:05 AM >> To: Kay, Allen M; xen-devel@lists.xensource.com >> Cc: Guy Zana >> Subject: Re: [Xen-devel] [VTD-NEO][patch 0/6] Intel >> VT-d/Neocleus 1:1 mreged code for PCI passthrough >> >> On 11/9/07 13:49, "Keir Fraser" <Keir.Fraser@cl.cam.ac.uk> wrote: >> >>> Haven't looked any further at the Xen parts, but I'll take a >> look at the >>> tools patch... >> >> Looking at the tools patch, I see strange interfaces like >> HVMOP_copy_nativedom_e820_map: >> 1. Why is this an hvm_op unlike other added domctls? >> 2. Why is it needed at all? Can't xc_hvm_build.c work out the >> memory map >> for itself? It seems like more than necessary is being done in Xen. >> >> Looks like splitting solely pt and solely vtd code into >> separate patches >> would be a good idea, so the more acdeptable chunks can slide >> straight in >> without delay. >> >> -- Keir >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-12 9:03 ` Keir Fraser @ 2007-09-12 22:37 ` Kay, Allen M 0 siblings, 0 replies; 13+ messages in thread From: Kay, Allen M @ 2007-09-12 22:37 UTC (permalink / raw) To: Keir Fraser, xen-devel; +Cc: Guy Zana [-- Attachment #1: Type: text/plain, Size: 2948 bytes --] I have added CONFIG_PASSTHROUGH in ioemu/Makefile.target and ioemu/hw/pc.c in attached vtd_tools2.patch. This should turn off libpci usage by default until user specifically enables it. This can be safely check-in without breaking builds for people who do not care about pass-through devices. I will try to think of a better way to enable this. Also, can you check-in vtd_dir.patch if you don't have any objections? This is a separate vt-d specific directory in hvm/vmx/vtd. It should not interfere with anything else. I'm current working on getting xen.patch part to work with latest staging tree. I will send it in as soon as I get it working. Allen Signed-off-by: Allen Kay <allen.m.kay@intel.com> Signed-off-by: Guy Zana <guy@neocleus.com> >-----Original Message----- >From: Keir Fraser [mailto:Keir.Fraser@cl.cam.ac.uk] >Sent: Wednesday, September 12, 2007 2:04 AM >To: Kay, Allen M; xen-devel@lists.xensource.com >Cc: Guy Zana >Subject: Re: [Xen-devel] [VTD-NEO][patch 0/6] Intel >VT-d/Neocleus 1:1 mreged code for PCI passthrough > >Vtd_tools patch breaks the build on my box. Cannot find pci/header.h or >pci/pci.h. Probably because libpci is not such a standard >install component >after all? I'm trying to build on Debian 3.1. > >Either the dependency needs to be avoided, or we need to be >sure that the >dependency is easy to resolve on most distros, and we need a >tools/check >script to check for and warn/error on the dependency. > > -- Keir > >On 12/9/07 02:21, "Kay, Allen M" <allen.m.kay@intel.com> wrote: > >> Attached patches splits vtd and neo changes to tools >directory. Applies >> cleanly to staging tree. >> >> Vtd_tools.patch: vt-d and generic changes >> Neo_tools.patch: neocleus specific changes >> >> Signed-off-by: Allen Kay <allen.m.kay@intel.com> >> Signed-off-by: Guy Zana <guy@neocleus.com> >> >>> -----Original Message----- >>> From: Keir Fraser [mailto:Keir.Fraser@cl.cam.ac.uk] >>> Sent: Tuesday, September 11, 2007 6:05 AM >>> To: Kay, Allen M; xen-devel@lists.xensource.com >>> Cc: Guy Zana >>> Subject: Re: [Xen-devel] [VTD-NEO][patch 0/6] Intel >>> VT-d/Neocleus 1:1 mreged code for PCI passthrough >>> >>> On 11/9/07 13:49, "Keir Fraser" <Keir.Fraser@cl.cam.ac.uk> wrote: >>> >>>> Haven't looked any further at the Xen parts, but I'll take a >>> look at the >>>> tools patch... >>> >>> Looking at the tools patch, I see strange interfaces like >>> HVMOP_copy_nativedom_e820_map: >>> 1. Why is this an hvm_op unlike other added domctls? >>> 2. Why is it needed at all? Can't xc_hvm_build.c work out the >>> memory map >>> for itself? It seems like more than necessary is being done in Xen. >>> >>> Looks like splitting solely pt and solely vtd code into >>> separate patches >>> would be a good idea, so the more acdeptable chunks can slide >>> straight in >>> without delay. >>> >>> -- Keir >>> > [-- Attachment #2: vtd_tools2.patch --] [-- Type: application/octet-stream, Size: 29481 bytes --] diff -r ca495837a722 tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/ioemu/Makefile.target Wed Sep 12 14:26:24 2007 -0700 @@ -197,6 +197,9 @@ LIBS+=-lm LIBS+=-lm LIBS+=-L../../libxc -lxenctrl -lxenguest LIBS+=-L../../xenstore -lxenstore +ifdef CONFIG_PASSTHROUGH +LIBS+=-lpci +endif ifndef CONFIG_USER_ONLY LIBS+=-lz endif @@ -400,6 +403,9 @@ VL_OBJS+= xenstore.o VL_OBJS+= xenstore.o VL_OBJS+= xen_platform.o VL_OBJS+= tpm_tis.o +ifdef CONFIG_PASSTHROUGH +VL_OBJS+= pass-through.o +endif CPPFLAGS += -DHAS_AUDIO endif ifeq ($(TARGET_BASE_ARCH), ppc) diff -r ca495837a722 tools/ioemu/hw/pc.c --- a/tools/ioemu/hw/pc.c Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/ioemu/hw/pc.c Wed Sep 12 14:32:59 2007 -0700 @@ -465,7 +465,7 @@ static void pc_init1(uint64_t ram_size, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, - int pci_enabled) + int pci_enabled, const char *direct_pci) { #ifndef NOBIOS char buf[1024]; @@ -480,6 +480,7 @@ static void pc_init1(uint64_t ram_size, int piix3_devfn = -1; CPUState *env; NICInfo *nd; + int rc; linux_boot = (kernel_filename != NULL); @@ -665,6 +666,19 @@ static void pc_init1(uint64_t ram_size, } } +#ifdef CONFIG_PASSTHROUGH + /* Pass-through Initialization */ + if ( pci_enabled && direct_pci ) + { + rc = pt_init(pci_bus, direct_pci); + if ( rc < 0 ) + { + fprintf(logfile, "Error: Initialization failed for pass-through devices\n"); + exit(1); + } + } +#endif + rtc_state = rtc_init(0x70, 8); register_ioport_read(0x92, 1, 1, ioport92_read, NULL); @@ -801,12 +815,14 @@ static void pc_init_pci(uint64_t ram_siz int snapshot, const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename) + const char *initrd_filename, + const char *direct_pci) { pc_init1(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, kernel_filename, kernel_cmdline, - initrd_filename, 1); + initrd_filename, 1, + direct_pci); } static void pc_init_isa(uint64_t ram_size, int vga_ram_size, char *boot_device, @@ -814,12 +830,13 @@ static void pc_init_isa(uint64_t ram_siz int snapshot, const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename) + const char *initrd_filename, + const char *unused) { pc_init1(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, kernel_filename, kernel_cmdline, - initrd_filename, 0); + initrd_filename, 0, NULL); } QEMUMachine pc_machine = { diff -r ca495837a722 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/ioemu/vl.c Wed Sep 12 10:25:42 2007 -0700 @@ -6513,6 +6513,7 @@ enum { QEMU_OPTION_acpi, QEMU_OPTION_vncviewer, QEMU_OPTION_vncunused, + QEMU_OPTION_pci, }; typedef struct QEMUOption { @@ -6610,6 +6611,7 @@ const QEMUOption qemu_options[] = { { "d", HAS_ARG, QEMU_OPTION_d }, { "vcpus", 1, QEMU_OPTION_vcpus }, { "acpi", 0, QEMU_OPTION_acpi }, + { "pci", HAS_ARG, QEMU_OPTION_pci}, { NULL }, }; @@ -7065,9 +7067,9 @@ int main(int argc, char **argv) extern void *buffered_pio_page; #endif sigset_t set; - char qemu_dm_logfilename[128]; - + const char *direct_pci = NULL; + /* Ensure that SIGUSR2 is blocked by default when a new thread is created, then only the threads that use the signal unblock it -- this fixes a race condition in Qcow support where the AIO signal is misdelivered. */ @@ -7560,6 +7562,9 @@ int main(int argc, char **argv) case QEMU_OPTION_vncunused: vncunused++; break; + case QEMU_OPTION_pci: + direct_pci = optarg; + break; } } } @@ -7926,7 +7931,8 @@ int main(int argc, char **argv) machine->init(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, - kernel_filename, kernel_cmdline, initrd_filename); + kernel_filename, kernel_cmdline, initrd_filename, + direct_pci); free(boot_device); /* init USB devices */ diff -r ca495837a722 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/ioemu/vl.h Wed Sep 12 10:25:42 2007 -0700 @@ -717,7 +717,7 @@ typedef void QEMUMachineInitFunc(uint64_ char *boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename); + const char *initrd_filename, const char *direct_pci); typedef struct QEMUMachine { const char *name; diff -r ca495837a722 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/libxc/xc_domain.c Wed Sep 12 10:25:42 2007 -0700 @@ -734,6 +734,114 @@ int xc_domain_setdebugging(int xc_handle return do_domctl(xc_handle, &domctl); } +int xc_assign_device( + int xc_handle, + uint32_t domid, + uint32_t machine_bdf) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_assign_device; + domctl.domain = domid; + domctl.u.assign_device.machine_bdf = machine_bdf; + + return do_domctl(xc_handle, &domctl); +} + +/* Pass-through: binds machine irq to guests irq */ +int xc_domain_bind_pt_irq( + int xc_handle, + uint32_t domid, + uint8_t machine_irq, + uint8_t irq_type, + uint8_t bus, + uint8_t device, + uint8_t intx, + uint8_t isa_irq) +{ + int rc; + xen_domctl_bind_pt_irq_t * bind; + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_bind_pt_irq; + domctl.domain = (domid_t)domid; + + bind = &(domctl.u.bind_pt_irq); + bind->hvm_domid = domid; + bind->irq_type = irq_type; + bind->machine_irq = machine_irq; + bind->u.pci.bus = bus; + bind->u.pci.device = device; + bind->u.pci.intx = intx; + bind->u.isa.isa_irq = isa_irq; + + rc = do_domctl(xc_handle, &domctl); + return rc; +} + +int xc_domain_bind_pt_pci_irq( + int xc_handle, + uint32_t domid, + uint8_t machine_irq, + uint8_t bus, + uint8_t device, + uint8_t intx) +{ + + return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq, + PT_IRQ_TYPE_PCI, bus, device, intx, 0)); +} + +int xc_domain_bind_pt_isa_irq( + int xc_handle, + uint32_t domid, + uint8_t machine_irq) +{ + + return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq, + PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq)); +} + +int xc_domain_memory_mapping( + int xc_handle, + uint32_t domid, + unsigned long first_gfn, + unsigned long first_mfn, + unsigned long nr_mfns, + uint32_t add_mapping) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_memory_mapping; + domctl.domain = domid; + domctl.u.memory_mapping.first_gfn = first_gfn; + domctl.u.memory_mapping.first_mfn = first_mfn; + domctl.u.memory_mapping.nr_mfns = nr_mfns; + domctl.u.memory_mapping.add_mapping = add_mapping; + + return do_domctl(xc_handle, &domctl); +} + +int xc_domain_ioport_mapping( + int xc_handle, + uint32_t domid, + uint32_t first_gport, + uint32_t first_mport, + uint32_t nr_ports, + uint32_t add_mapping) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_ioport_mapping; + domctl.domain = domid; + domctl.u.ioport_mapping.first_gport = first_gport; + domctl.u.ioport_mapping.first_mport = first_mport; + domctl.u.ioport_mapping.nr_ports = nr_ports; + domctl.u.ioport_mapping.add_mapping = add_mapping; + + return do_domctl(xc_handle, &domctl); +} + /* * Local variables: * mode: C diff -r ca495837a722 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/libxc/xenctrl.h Wed Sep 12 10:25:42 2007 -0700 @@ -897,4 +897,43 @@ int xc_ia64_save_to_nvram(int xc_handle, /* IA64 specific, nvram init */ int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom); +/* HVM guest pass-through */ +int xc_assign_device(int xc_handle, + uint32_t domid, + uint32_t machine_bdf); + +int xc_domain_memory_mapping(int xc_handle, + uint32_t domid, + unsigned long first_gfn, + unsigned long first_mfn, + unsigned long nr_mfns, + uint32_t add_mapping); + +int xc_domain_ioport_mapping(int xc_handle, + uint32_t domid, + uint32_t first_gport, + uint32_t first_mport, + uint32_t nr_ports, + uint32_t add_mapping); + +int xc_domain_bind_pt_irq(int xc_handle, + uint32_t domid, + uint8_t machine_irq, + uint8_t irq_type, + uint8_t bus, + uint8_t device, + uint8_t intx, + uint8_t isa_irq); + +int xc_domain_bind_pt_pci_irq(int xc_handle, + uint32_t domid, + uint8_t machine_irq, + uint8_t bus, + uint8_t device, + uint8_t intx); + +int xc_domain_bind_pt_isa_irq(int xc_handle, + uint32_t domid, + uint8_t machine_irq); + #endif /* XENCTRL_H */ diff -r ca495837a722 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/python/xen/xend/XendConfig.py Wed Sep 12 10:25:42 2007 -0700 @@ -127,7 +127,7 @@ XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 'nographic', 'pae', 'rtc_timeoffset', 'serial', 'sdl', 'soundhw','stdvga', 'usb', 'usbdevice', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten', - 'vncpasswd', 'vncunused', 'xauthority'] + 'vncpasswd', 'vncunused', 'xauthority', 'pci'] # Xen API console 'other_config' keys. XENAPI_CONSOLE_OTHER_CFG = ['vncunused', 'vncdisplay', 'vnclisten', @@ -168,6 +168,7 @@ XENAPI_CFG_TYPES = { 'tools_version': dict, 'other_config': dict, 'security_label': str, + 'pci': str, } # List of legacy configuration keys that have no equivalent in the diff -r ca495837a722 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/python/xen/xend/image.py Wed Sep 12 10:25:42 2007 -0700 @@ -309,7 +309,7 @@ class HVMImageHandler(ImageHandler): def parseDeviceModelArgs(self, vmConfig): dmargs = [ 'boot', 'fda', 'fdb', 'soundhw', 'localtime', 'serial', 'stdvga', 'isa', - 'acpi', 'usb', 'usbdevice', 'keymap' ] + 'acpi', 'usb', 'usbdevice', 'keymap', 'pci' ] ret = ['-vcpus', str(self.vm.getVCpuCount())] diff -r ca495837a722 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Wed Sep 12 15:42:39 2007 +0100 +++ b/tools/python/xen/xm/create.py Wed Sep 12 10:25:42 2007 -0700 @@ -721,7 +721,7 @@ def configure_hvm(config_image, vals): 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', 'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor', - 'acpi', 'apic', 'usb', 'usbdevice', 'keymap' ] + 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci' ] for a in args: if a in vals.__dict__ and vals.__dict__[a] is not None: config_image.append([a, vals.__dict__[a]]) diff -r ca495837a722 tools/ioemu/hw/pass-through.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/pass-through.c Wed Sep 12 10:25:42 2007 -0700 @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2007, Neocleus Corporation. + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Alex Novik <alex@neocleus.com> + * Allen Kay <allen.m.kay@intel.com> + * Guy Zana <guy@neocleus.com> + * + * This file implements direct PCI assignment to a HVM guest + * + */ +#include "vl.h" +#include "pass-through.h" +#include "pci/header.h" +#include "pci/pci.h" + +extern FILE *logfile; +char *token; + +int pci_devs(const char *direct_pci) +{ + int count = 0; + const char *c; + + /* skip first "[" character */ + c = direct_pci + 1; + while ((c = strchr(c, '[')) != NULL) { + c++; + count++; + } + return (count); +} + +int next_token(char *direct_pci) +{ + if (token == NULL) + token = strtok(direct_pci, ","); + else + token = strtok(NULL, ","); + token = strchr(token, 'x'); + token = token + 1; + return ((int) strtol(token, NULL, 16)); +} + +void next_bdf(char *direct_pci, int *seg, + int *bus, int *dev, int *func) +{ + *seg = next_token(direct_pci); + *bus = next_token(direct_pci); + *dev = next_token(direct_pci); + *func = next_token(direct_pci); +} + +uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap) +{ + int id; + int max_cap = 48; + int pos = PCI_CAPABILITY_LIST; + int status; + + status = pci_read_byte(pci_dev, PCI_STATUS); + if ( (status & PCI_STATUS_CAP_LIST) == 0 ) + return 0; + + while ( max_cap-- ) + { + pos = pci_read_byte(pci_dev, pos); + if ( pos < 0x40 ) + break; + + pos &= ~3; + id = pci_read_byte(pci_dev, pos + PCI_CAP_LIST_ID); + + if ( id == 0xff ) + break; + if ( id == cap ) + return pos; + + pos += PCI_CAP_LIST_NEXT; + } + return 0; +} + +void pdev_flr(struct pci_dev *pci_dev) +{ + int pos; + int dev_cap; + int dev_status; + + pos = find_cap_offset(pci_dev, PCI_CAP_ID_EXP); + if ( pos ) + { + dev_cap = pci_read_long(pci_dev, pos + PCI_EXP_DEVCAP); + if ( dev_cap & PCI_EXP_DEVCAP_FLR ) + { + pci_write_word(pci_dev, pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR); + do { + dev_status = pci_read_long(pci_dev, pos + PCI_EXP_DEVSTA); + } while (dev_status & PCI_EXP_DEVSTA_TRPND); + } + } +} + +/* Being called each time a mmio region has been updated */ +void pt_iomem_map(PCIDevice *d, int i, uint32_t e_phys, uint32_t e_size, + int type) +{ + struct pt_dev *assigned_device = (struct pt_dev *)d; + uint32_t old_ebase = assigned_device->bases[i].e_physbase; + int first_map = ( assigned_device->bases[i].e_size == 0 ); + int ret = 0; + + assigned_device->bases[i].e_physbase = e_phys; + assigned_device->bases[i].e_size= e_size; + + PT_LOG("e_phys=%08x maddr=%08x type=%d len=%08x index=%d\n", + e_phys, assigned_device->bases[i].access.maddr, type, e_size, i); + + if ( e_size == 0 ) + return; + + if ( !first_map ) + { + /* Remove old mapping */ + ret = xc_domain_memory_mapping(xc_handle, domid, old_ebase >> 12, + assigned_device->bases[i].access.maddr >> 12, + (e_size+0xFFF) >> 12, + DPCI_REMOVE_MAPPING); + if ( ret != 0 ) + { + PT_LOG("Error: remove old mapping failed!\n"); + return; + } + } + + /* Create new mapping */ + ret = xc_domain_memory_mapping(xc_handle, domid, + assigned_device->bases[i].e_physbase >> 12, + assigned_device->bases[i].access.maddr >> 12, + (e_size+0xFFF) >> 12, + DPCI_ADD_MAPPING); + if ( ret != 0 ) + PT_LOG("Error: create new mapping failed!\n"); + +} + +/* Being called each time a pio region has been updated */ +void pt_ioport_map(PCIDevice *d, int i, + uint32_t e_phys, uint32_t e_size, int type) +{ + struct pt_dev *assigned_device = (struct pt_dev *)d; + uint32_t old_ebase = assigned_device->bases[i].e_physbase; + int first_map = ( assigned_device->bases[i].e_size == 0 ); + int ret = 0; + + assigned_device->bases[i].e_physbase = e_phys; + assigned_device->bases[i].e_size= e_size; + + PT_LOG("e_phys=%04x pio_base=%04x len=%04x index=%d\n", + (uint16_t)e_phys, (uint16_t)assigned_device->bases[i].access.pio_base, + (uint16_t)e_size, i); + + if ( e_size == 0 ) + return; + + if ( !first_map ) + { + /* Remove old mapping */ + ret = xc_domain_ioport_mapping(xc_handle, domid, old_ebase, + assigned_device->bases[i].access.pio_base, e_size, + DPCI_REMOVE_MAPPING); + if ( ret != 0 ) + { + PT_LOG("Error: remove old mapping failed!\n"); + return; + } + } + + /* Create new mapping */ + ret = xc_domain_ioport_mapping(xc_handle, domid, e_phys, + assigned_device->bases[i].access.pio_base, e_size, + DPCI_ADD_MAPPING); + if ( ret != 0 ) + PT_LOG("Error: create new mapping failed!\n"); + +} + +static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, + int len) +{ + struct pt_dev *assigned_device = (struct pt_dev *)d; + struct pci_dev *pci_dev = assigned_device->pci_dev; + +#ifdef PT_DEBUG_PCI_CONFIG_ACCESS + PT_LOG("(%x.%x): address=%04x val=0x%08x len=%d\n", + (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len); +#endif + + /* Pre-write hooking */ + switch ( address ) { + case 0x0C ... 0x3F: + pci_default_write_config(d, address, val, len); + return; + } + + /* PCI config pass-through */ + if (address == 0x4) { + switch (len){ + case 1: + pci_write_byte(pci_dev, address, val); + break; + case 2: + pci_write_word(pci_dev, address, val); + break; + case 4: + pci_write_long(pci_dev, address, val); + break; + } + } + + if (address == 0x4) { + /* Post-write hooking */ + pci_default_write_config(d, address, val, len); + } +} + +static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t address, int len) +{ + struct pt_dev *assigned_device = (struct pt_dev *)d; + struct pci_dev *pci_dev = assigned_device->pci_dev; + uint32_t val = 0xFF; + + /* Pre-hooking */ + switch ( address ) { + case 0x0C ... 0x3F: + val = pci_default_read_config(d, address, len); + goto exit; + } + + switch ( len ) { + case 1: + val = pci_read_byte(pci_dev, address); + break; + case 2: + val = pci_read_word(pci_dev, address); + break; + case 4: + val = pci_read_long(pci_dev, address); + break; + } + +exit: + +#ifdef PT_DEBUG_PCI_CONFIG_ACCESS + PT_LOG("(%x.%x): address=%04x val=0x%08x len=%d\n", + (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len); +#endif + + return val; +} + +static int pt_register_regions(struct pt_dev *assigned_device) +{ + int i = 0; + uint32_t bar_data = 0; + struct pci_dev *pci_dev = assigned_device->pci_dev; + PCIDevice *d = &assigned_device->dev; + + /* Register PIO/MMIO BARs */ + for ( i=0; i < PCI_BAR_ENTRIES; i++ ) + { + if ( pci_dev->base_addr[i] ) + { + assigned_device->bases[i].e_physbase = pci_dev->base_addr[i]; + assigned_device->bases[i].access.u = pci_dev->base_addr[i]; + + /* Register current region */ + bar_data = *((uint32_t*)(d->config + PCI_BASE_ADDRESS_0) + i); + if ( bar_data & PCI_ADDRESS_SPACE_IO ) + pci_register_io_region((PCIDevice *)assigned_device, i, + (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_IO, + pt_ioport_map); + else if ( bar_data & PCI_ADDRESS_SPACE_MEM_PREFETCH ) + pci_register_io_region((PCIDevice *)assigned_device, i, + (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM_PREFETCH, + pt_iomem_map); + else + pci_register_io_region((PCIDevice *)assigned_device, i, + (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM, + pt_iomem_map); + + PT_LOG("IO region registered (size=0x%08x base_addr=0x%08x)\n", + (uint32_t)(pci_dev->size[i]), + (uint32_t)(pci_dev->base_addr[i])); + } + } + + /* Register expansion ROM address */ + if ( pci_dev->rom_base_addr && pci_dev->rom_size ) + { + assigned_device->bases[PCI_ROM_SLOT].e_physbase = + pci_dev->rom_base_addr; + assigned_device->bases[PCI_ROM_SLOT].access.maddr = + pci_dev->rom_base_addr; + pci_register_io_region((PCIDevice *)assigned_device, PCI_ROM_SLOT, + pci_dev->rom_size, PCI_ADDRESS_SPACE_MEM_PREFETCH, + pt_iomem_map); + + PT_LOG("Expansion ROM registered (size=0x%08x base_addr=0x%08x)\n", + (uint32_t)(pci_dev->rom_size), (uint32_t)(pci_dev->rom_base_addr)); + } + + return 0; +} + +struct pt_dev * register_real_device(PCIBus *e_bus, + const char *e_dev_name, int e_devfn, uint8_t r_bus, uint8_t r_dev, + uint8_t r_func, uint32_t machine_irq, struct pci_access *pci_access) +{ + int rc, i; + struct pt_dev *assigned_device = NULL; + struct pci_dev *pci_dev; + struct pci_config_cf8 machine_bdf; + uint8_t e_device, e_intx; + + PT_LOG("Assigning real physical device %02x:%02x.%x ...\n", + r_bus, r_dev, r_func); + + /* Find real device structure */ + for (pci_dev = pci_access->devices; pci_dev != NULL; + pci_dev = pci_dev->next) + { + if ((r_bus == pci_dev->bus) && (r_dev == pci_dev->dev) + && (r_func == pci_dev->func)) + break; + } + if ( pci_dev == NULL ) + { + PT_LOG("Error: couldn't locate device in libpci structures\n"); + return NULL; + } + + /* Register device */ + assigned_device = (struct pt_dev *) pci_register_device(e_bus, e_dev_name, + sizeof(struct pt_dev), e_devfn, + pt_pci_read_config, pt_pci_write_config); + if ( assigned_device == NULL ) + { + PT_LOG("Error: couldn't register real device\n"); + return NULL; + } + + assigned_device->pci_dev = pci_dev; + + /* Issue PCIe FLR */ + pdev_flr(pci_dev); + + /* Tell XEN vmm to change iommu settings */ + machine_bdf.reg = 0; + machine_bdf.bus = r_bus; + machine_bdf.dev = r_dev; + machine_bdf.func = r_func; + rc = xc_assign_device(xc_handle, domid, machine_bdf.value); + if ( rc < 0 ) + PT_LOG("Error: xc_domain_assign_device error %d\n", rc); + + /* Initialize virtualized PCI configuration (Extended 256 Bytes) */ + for ( i = 0; i < PCI_CONFIG_SIZE; i++ ) + assigned_device->dev.config[i] = pci_read_byte(pci_dev, i); + + /* Handle real device's MMIO/PIO BARs */ + pt_register_regions(assigned_device); + + /* Bind interrupt */ + e_device = (assigned_device->dev.devfn >> 3) & 0x1f; + e_intx = assigned_device->dev.config[0x3d]-1; + + if ( PT_MACHINE_IRQ_AUTO == machine_irq ) + machine_irq = pci_dev->irq; + + /* bind machine_irq to device */ + if ( 0 != machine_irq ) + { + rc = xc_domain_bind_pt_pci_irq(xc_handle, domid, machine_irq, 0, + e_device, e_intx); + if ( rc < 0 ) + { + /* TBD: unregister device in case of an error */ + PT_LOG("Error: Binding of interrupt failed! rc=%d\n", rc); + } + } + else { + /* Disable PCI intx assertion (turn on bit10 of devctl) */ + assigned_device->dev.config[0x05] |= 0x04; + pci_write_word(pci_dev, 0x04, + *(uint16_t *)(&assigned_device->dev.config[0x04])); + } + + PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n", + r_bus, r_dev, r_func); + + return assigned_device; +} + +int pt_init(PCIBus *e_bus, char *direct_pci) +{ + int i; + int seg, b, d, f; + struct pt_dev *pt_dev; + struct pci_access *pci_access; + int dev_count = pci_devs(direct_pci); + + /* Initialize libpci */ + pci_access = pci_alloc(); + if ( pci_access == NULL ) + { + PT_LOG("pci_access is NULL\n"); + return -1; + } + pci_init(pci_access); + pci_scan_bus(pci_access); + + /* Assign given devices to guest */ + for ( i = 0; i < dev_count; i++ ) + { + /* Get next device bdf (bus, device, function) */ + next_bdf(direct_pci, &seg, &b, &d, &f); + + /* Register real device with the emulated bus */ + pt_dev = register_real_device(e_bus, "DIRECT PCI", PT_VIRT_DEVFN_AUTO, + b, d, f, PT_MACHINE_IRQ_AUTO, pci_access); + if ( pt_dev == NULL ) + { + PT_LOG("Error: Registration failed (%02x:%02x.%x)\n", b, d, f); + return -1; + } + } + + /* Success */ + return 0; +} diff -r ca495837a722 tools/ioemu/hw/pass-through.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/pass-through.h Wed Sep 12 10:25:42 2007 -0700 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2007, Neocleus Corporation. + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PASSTHROUGH_H__ +#define __PASSTHROUGH_H__ + +#include "vl.h" +#include "pci/header.h" +#include "pci/pci.h" + +/* Log acesss */ +#define PT_LOGGING_ENABLED + +#ifdef PT_LOGGING_ENABLED +#define PT_LOG(_f, _a...) fprintf(logfile, "%s: " _f, __func__, ##_a) +#else +#define PT_LOG(_f, _a...) +#endif + +/* Some compilation flags */ +// #define PT_DEBUG_PCI_CONFIG_ACCESS + +#define PT_MACHINE_IRQ_AUTO (0xFFFFFFFF) +#define PT_VIRT_DEVFN_AUTO (-1) + +/* Misc PCI constants that should be moved to a separate library :) */ +#define PCI_CONFIG_SIZE (256) +#define PCI_EXP_DEVCAP_FLR (1 << 28) +#define PCI_EXP_DEVCTL_FLR (0x1b) +#define PCI_BAR_ENTRIES (6) + +struct pt_region { + /* Virtual phys base & size */ + uint32_t e_physbase; + uint32_t e_size; + /* Index of region in qemu */ + uint32_t memory_index; + /* Translation of the emulated address */ + union { + uint32_t maddr; + uint32_t pio_base; + uint32_t u; + } access; +}; + +/* + This structure holds the context of the mapping functions + and data that is relevant for qemu device management. +*/ +struct pt_dev { + PCIDevice dev; + struct pci_dev *pci_dev; /* libpci struct */ + struct pt_region bases[PCI_NUM_REGIONS]; /* Access regions */ +}; + +/* Used for formatting PCI BDF into cf8 format */ +struct pci_config_cf8 { + union { + unsigned int value; + struct { + unsigned int reserved1:2; + unsigned int reg:6; + unsigned int func:3; + unsigned int dev:5; + unsigned int bus:8; + unsigned int reserved2:7; + unsigned int enable:1; + }; + }; +}; + +int pt_init(PCIBus * e_bus, char * direct_pci); + +#endif /* __PASSTHROUGH_H__ */ + [-- Attachment #3: Type: text/plain, Size: 138 bytes --] _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel ^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-11 12:49 ` Keir Fraser 2007-09-11 13:04 ` Keir Fraser @ 2007-09-11 21:27 ` Kay, Allen M 2007-09-12 9:01 ` Keir Fraser 1 sibling, 1 reply; 13+ messages in thread From: Kay, Allen M @ 2007-09-11 21:27 UTC (permalink / raw) To: Keir Fraser, xen-devel; +Cc: Guy Zana [-- Attachment #1: Type: text/plain, Size: 1842 bytes --] Attached are header file patches I rebased to cs# 15837. I moved neo's include file from xen to xen/asm. I couldn't move them to xen/arch/x86/pt directory because some generic file reference them. Vtd_inc.patch: include generic changes and one vt-d file (intel-iommu.h) P2m_inc.patch: changes to p2m.h Neo_inc.patch: Neocleus specific changes Signed-off-by: Allen Kay <allen.m.kay@intel.com> Signed-off-by: Guy Zana <guy@neocleus.com> Allen >-----Original Message----- >From: Keir Fraser [mailto:Keir.Fraser@cl.cam.ac.uk] >Sent: Tuesday, September 11, 2007 5:50 AM >To: Kay, Allen M; xen-devel@lists.xensource.com >Cc: Guy Zana >Subject: Re: [Xen-devel] [VTD-NEO][patch 0/6] Intel >VT-d/Neocleus 1:1 mreged code for PCI passthrough > >On 5/9/07 01:08, "Kay, Allen M" <allen.m.kay@intel.com> wrote: > >> The following 6 patches contains merge of Intel VT-d and >Neocleus' 1:1 >> mapping patches for enabling HVM guest direct device access that were >> last submitted around end of May. These patches applied cleanly to >> changeset 15730. > >The 'include' patch doesn't apply any more, and in any case >needs splitting >up logically (vtd bits go in vtd patch; neo bits in neo patch; >any generic >bits in xen patch). The 'pt' (neo) code looks to throw way too >much stuff in >include/xen/ of which I suspect most is private definitions that really >belong in the pt/ directory. Also consider which bits should be in >include/asm rather than include/xen. > >The presence of the E820_1TO1 stuff makes me suspect that the 1:1 area >allocation hasn't been cleaned up as much as it should have been. There >shouldn't be any need to modify Xen's permanent e820 map I think. > >Haven't looked any further at the Xen parts, but I'll take a >look at the >tools patch... > > -- Keir > [-- Attachment #2: vtd_inc.patch --] [-- Type: application/octet-stream, Size: 27691 bytes --] diff -r 9071521d4864 xen/include/asm-x86/acpi.h --- a/xen/include/asm-x86/acpi.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/acpi.h Tue Sep 11 11:34:53 2007 -0700 @@ -196,4 +196,6 @@ extern u8 x86_acpiid_to_apicid[]; extern u8 x86_acpiid_to_apicid[]; #define MAX_LOCAL_APIC 256 +extern int acpi_dmar_init(void); + #endif /*_ASM_ACPI_H*/ diff -r 9071521d4864 xen/include/asm-x86/fixmap.h --- a/xen/include/asm-x86/fixmap.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/fixmap.h Tue Sep 11 11:34:53 2007 -0700 @@ -17,6 +17,7 @@ #include <asm/acpi.h> #include <asm/page.h> #include <xen/kexec.h> +#include <asm/iommu.h> /* * Here we define all the compile-time 'special' virtual @@ -40,6 +41,8 @@ enum fixed_addresses { FIX_KEXEC_BASE_0, FIX_KEXEC_BASE_END = FIX_KEXEC_BASE_0 \ + ((KEXEC_XEN_NO_PAGES >> 1) * KEXEC_IMAGE_NR) - 1, + FIX_IOMMU_REGS_BASE_0, + FIX_IOMMU_REGS_END = FIX_IOMMU_REGS_BASE_0 + MAX_IOMMUS-1, __end_of_fixed_addresses }; diff -r 9071521d4864 xen/include/asm-x86/hvm/domain.h --- a/xen/include/asm-x86/hvm/domain.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/hvm/domain.h Tue Sep 11 11:34:53 2007 -0700 @@ -21,10 +21,12 @@ #ifndef __ASM_X86_HVM_DOMAIN_H__ #define __ASM_X86_HVM_DOMAIN_H__ +#include <asm/iommu.h> #include <asm/hvm/irq.h> #include <asm/hvm/vpt.h> #include <asm/hvm/vlapic.h> #include <asm/hvm/io.h> +#include <asm/hvm/iommu.h> #include <public/hvm/params.h> #include <public/hvm/save.h> @@ -57,6 +59,9 @@ struct hvm_domain { uint64_t params[HVM_NR_PARAMS]; unsigned long vmx_apic_access_mfn; + + /* Pass-through */ + struct hvm_iommu hvm_iommu; }; #endif /* __ASM_X86_HVM_DOMAIN_H__ */ diff -r 9071521d4864 xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/hvm/io.h Tue Sep 11 11:34:53 2007 -0700 @@ -151,6 +151,7 @@ extern void handle_mmio(unsigned long gp extern void handle_mmio(unsigned long gpa); extern void hvm_interrupt_post(struct vcpu *v, int vector, int type); extern void hvm_io_assist(void); +extern void hvm_dpci_eoi(unsigned int guest_irq, union vioapic_redir_entry *ent); #endif /* __ASM_X86_HVM_IO_H__ */ diff -r 9071521d4864 xen/include/asm-x86/hvm/irq.h --- a/xen/include/asm-x86/hvm/irq.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/hvm/irq.h Tue Sep 11 11:34:53 2007 -0700 @@ -28,6 +28,16 @@ #include <asm/hvm/vpic.h> #include <asm/hvm/vioapic.h> #include <public/hvm/save.h> + +struct hvm_irq_mapping { + uint8_t valid; + uint8_t device; + uint8_t intx; + union { + uint8_t guest_gsi; + uint8_t machine_gsi; + }; +}; struct hvm_irq { /* @@ -88,6 +98,12 @@ struct hvm_irq { /* Last VCPU that was delivered a LowestPrio interrupt. */ u8 round_robin_prev_vcpu; + + /* machine irq to guest device/intx mapping */ + struct hvm_irq_mapping mirq[NR_IRQS]; + /* guest irq to guest device/intx mapping */ + struct hvm_irq_mapping girq[NR_IRQS]; + DECLARE_BITMAP(dirq_mask, NR_IRQS); }; #define hvm_pci_intx_gsi(dev, intx) \ diff -r 9071521d4864 xen/include/asm-x86/system.h --- a/xen/include/asm-x86/system.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/system.h Tue Sep 11 11:34:53 2007 -0700 @@ -13,6 +13,9 @@ #define wbinvd() \ __asm__ __volatile__ ("wbinvd": : :"memory"); + +#define clflush(a) \ + __asm__ __volatile__ ("clflush (%0)": :"r"(a)); #define nop() __asm__ __volatile__ ("nop") diff -r 9071521d4864 xen/include/public/domctl.h --- a/xen/include/public/domctl.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/public/domctl.h Tue Sep 11 11:37:30 2007 -0700 @@ -432,7 +432,68 @@ typedef struct xen_domctl_sendtrigger xe typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t); - + +#define DPCI_ADD_MAPPING 1 +#define DPCI_REMOVE_MAPPING 0 + +#define XEN_DOMCTL_assign_device 37 +struct xen_domctl_assign_device { + uint32_t machine_bdf; /* machine PCI ID of assigned device */ +}; +typedef struct xen_domctl_assign_device xen_domctl_assign_device_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t); + + +typedef enum pt_irq_type_e { + PT_IRQ_TYPE_PCI, + PT_IRQ_TYPE_ISA +} pt_irq_type_t; + +/* pass-through interrupts: create a bind real_irq -> hvm devfn */ +#define XEN_DOMCTL_bind_pt_irq 38 +struct xen_domctl_bind_pt_irq { + uint32_t machine_irq; + pt_irq_type_t irq_type; + uint32_t hvm_domid; + + union { + struct { + uint8_t isa_irq; + } isa; + struct { + uint8_t bus; + uint8_t device; + uint8_t intx; + } pci; + } u; +}; +typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_pt_irq_t); + + +#define XEN_DOMCTL_memory_mapping 39 +struct xen_domctl_memory_mapping { + uint64_t first_gfn; /* first page (hvm guest physical page in range */ + uint64_t first_mfn; /* first page (machine page) in range */ + uint64_t nr_mfns; /* number of pages in range (>0) */ + uint32_t add_mapping; /* add or remove mapping */ + uint32_t padding; /* padding for 64-bit aligned structure */ +}; +typedef struct xen_domctl_memory_mapping xen_domctl_memory_mapping_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_memory_mapping_t); + + +#define XEN_DOMCTL_ioport_mapping 40 +struct xen_domctl_ioport_mapping { + uint32_t first_gport; /* first guest IO port*/ + uint32_t first_mport; /* first machine IO port */ + uint32_t nr_ports; /* size of port range */ + uint32_t add_mapping; /* add or remove mapping */ +}; +typedef struct xen_domctl_ioport_mapping xen_domctl_ioport_mapping_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_mapping_t); + + struct xen_domctl { uint32_t cmd; uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ @@ -462,6 +523,10 @@ struct xen_domctl { struct xen_domctl_hvmcontext hvmcontext; struct xen_domctl_address_size address_size; struct xen_domctl_sendtrigger sendtrigger; + struct xen_domctl_assign_device assign_device; + struct xen_domctl_bind_pt_irq bind_pt_irq; + struct xen_domctl_memory_mapping memory_mapping; + struct xen_domctl_ioport_mapping ioport_mapping; uint8_t pad[128]; } u; }; diff -r 9071521d4864 xen/include/xen/acpi.h --- a/xen/include/xen/acpi.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/xen/acpi.h Tue Sep 11 11:34:53 2007 -0700 @@ -367,8 +367,78 @@ enum acpi_table_id { ACPI_SPMI, ACPI_HPET, ACPI_MCFG, + ACPI_DMAR, ACPI_TABLE_COUNT }; + +/* DMA Remapping Reporting Table (DMAR) */ + +#define DMAR_FLAGS_INTR_REMAP 0x1 /* intr remap supported */ +struct acpi_table_dmar { + struct acpi_table_header header; + u8 haw; /* Host address Width */ + u8 flags; + u8 reserved[10]; +} __attribute__ ((packed)); + +struct acpi_dmar_entry_header { + u16 type; + u16 length; +} __attribute__((packed)); + +enum acpi_dmar_entry_type { + ACPI_DMAR_DRHD = 0, + ACPI_DMAR_RMRR, + ACPI_DMAR_ATSR, + ACPI_DMAR_ENTRY_COUNT +}; + +#define DRHD_FLAGS_INCLUDE_ALL 0x1 /* drhd remaps remaining devices */ +struct acpi_table_drhd { + struct acpi_dmar_entry_header header; + u8 flags; + u8 reserved; + u16 segment; + u64 address; /* register base address for this drhd */ +} __attribute__ ((packed)); + +struct acpi_table_rmrr { + struct acpi_dmar_entry_header header; + u16 reserved; + u16 segment; + u64 base_address; + u64 end_address; +} __attribute__ ((packed)); + +struct acpi_table_atsr { + struct acpi_dmar_entry_header header; + u8 flags; + u8 reserved; + u16 segment; +} __attribute__ ((packed)); + +enum acpi_dev_scope_type { + ACPI_DEV_ENDPOINT=0x01, /* PCI Endpoing device */ + ACPI_DEV_P2PBRIDGE, /* PCI-PCI Bridge */ + ACPI_DEV_IOAPIC, /* IOAPIC device*/ + ACPI_DEV_MSI_HPET, /* MSI capable HPET*/ + ACPI_DEV_ENTRY_COUNT +}; + +struct acpi_dev_scope { + u8 dev_type; + u8 length; + u8 reserved[2]; + u8 enum_id; + u8 start_bus; +} __attribute__((packed)); + +struct acpi_pci_path { + u8 dev; + u8 fn; +} __attribute__((packed)); + +typedef int (*acpi_dmar_entry_handler) (struct acpi_dmar_entry_header *header, const unsigned long end); typedef int (*acpi_table_handler) (unsigned long phys_addr, unsigned long size); diff -r 9071521d4864 xen/include/xen/irq.h --- a/xen/include/xen/irq.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/xen/irq.h Tue Sep 11 11:34:53 2007 -0700 @@ -64,6 +64,9 @@ extern irq_desc_t irq_desc[NR_IRQS]; extern int setup_irq(unsigned int, struct irqaction *); extern void free_irq(unsigned int); +extern int request_irq(unsigned int irq, + void (*handler)(int, void *, struct cpu_user_regs *), + unsigned long irqflags, const char * devname, void *dev_id); extern hw_irq_controller no_irq_type; extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs); diff -r 9071521d4864 xen/include/asm-x86/hvm/iommu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/hvm/iommu.h Tue Sep 11 11:34:53 2007 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Copyright (C) Allen Kay <allen.m.kay@intel.com> + */ + +#ifndef __ASM_X86_HVM_IOMMU_H__ +#define __ASM_X86_HVM_IOMMU_H__ + +#include <asm/iommu.h> +#include <asm/hvm/irq.h> +#include <asm/hvm/vpt.h> +#include <asm/hvm/vlapic.h> +#include <asm/hvm/io.h> +#include <public/hvm/params.h> +#include <public/hvm/save.h> + +struct hvm_iommu { + spinlock_t iommu_list_lock; /* protect iommu specific lists */ + struct list_head pdev_list; /* direct accessed pci devices */ + struct dma_pte *pgd; /* io page directory root */ + spinlock_t mapping_lock; /* io page table lock */ + int agaw; /* adjusted guest address width, 0 is level 2 30-bit */ + struct list_head g2m_ioport_list; /* guest to machine ioport mapping */ +}; + +#endif // __ASM_X86_HVM_IOMMU_H__ diff -r 9071521d4864 xen/include/asm-x86/hvm/vmx/intel-iommu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/hvm/vmx/intel-iommu.h Tue Sep 11 11:34:53 2007 -0700 @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Copyright (C) Ashok Raj <ashok.raj@intel.com> + */ + +#ifndef _INTEL_IOMMU_H_ +#define _INTEL_IOMMU_H_ + +#include <xen/types.h> + +/* + * Intel IOMMU register specification per version 1.0 public spec. + */ + +#define DMAR_VER_REG 0x0 /* Arch version supported by this IOMMU */ +#define DMAR_CAP_REG 0x8 /* Hardware supported capabilities */ +#define DMAR_ECAP_REG 0x10 /* Extended capabilities supported */ +#define DMAR_GCMD_REG 0x18 /* Global command register */ +#define DMAR_GSTS_REG 0x1c /* Global status register */ +#define DMAR_RTADDR_REG 0x20 /* Root entry table */ +#define DMAR_CCMD_REG 0x28 /* Context command reg */ +#define DMAR_FSTS_REG 0x34 /* Fault Status register */ +#define DMAR_FECTL_REG 0x38 /* Fault control register */ +#define DMAR_FEDATA_REG 0x3c /* Fault event interrupt data register */ +#define DMAR_FEADDR_REG 0x40 /* Fault event interrupt addr register */ +#define DMAR_FEUADDR_REG 0x44 /* Upper address register */ +#define DMAR_AFLOG_REG 0x58 /* Advanced Fault control */ +#define DMAR_PMEN_REG 0x64 /* Enable Protected Memory Region */ +#define DMAR_PLMBASE_REG 0x68 /* PMRR Low addr */ +#define DMAR_PLMLIMIT_REG 0x6c /* PMRR low limit */ +#define DMAR_PHMBASE_REG 0x70 /* pmrr high base addr */ +#define DMAR_PHMLIMIT_REG 0x78 /* pmrr high limit */ +#define DMAR_IQH_REG 0x80 /* invalidation queue head */ +#define DMAR_IQT_REG 0x88 /* invalidation queue tail */ +#define DMAR_IQA_REG 0x90 /* invalidation queue addr */ +#define DMAR_IRTA_REG 0xB8 /* intr remap */ + +#define OFFSET_STRIDE (9) +#define dmar_readl(dmar, reg) readl(dmar + reg) +#define dmar_writel(dmar, reg, val) writel(val, dmar + reg) +#define dmar_readq(dmar, reg) ({ \ + u32 lo, hi; \ + lo = dmar_readl(dmar, reg); \ + hi = dmar_readl(dmar, reg + 4); \ + (((u64) hi) << 32) + lo; }) +#define dmar_writeq(dmar, reg, val) do {\ + dmar_writel(dmar, reg, (u32)val); \ + dmar_writel(dmar, reg + 4, (u32)((u64) val >> 32)); \ + } while (0) + +#define VER_MAJOR(v) (((v) & 0xf0) >> 4) +#define VER_MINOR(v) ((v) & 0x0f) + +/* + * Decoding Capability Register + */ +#define cap_read_drain(c) (((c) >> 55) & 1) +#define cap_write_drain(c) (((c) >> 54) & 1) +#define cap_max_amask_val(c) (((c) >> 48) & 0x3f) +#define cap_num_fault_regs(c) ((((c) >> 40) & 0xff) + 1) +#define cap_pgsel_inv(c) (((c) >> 39) & 1) + +#define cap_super_page_val(c) (((c) >> 34) & 0xf) +#define cap_super_offset(c) (((find_first_bit(&cap_super_page_val(c), 4)) \ + * OFFSET_STRIDE) + 21) + +#define cap_fault_reg_offset(c) ((((c) >> 24) & 0x3ff) * 16) + +#define cap_isoch(c) (((c) >> 23) & 1) +#define cap_qos(c) (((c) >> 22) & 1) +#define cap_mgaw(c) ((((c) >> 16) & 0x3f) + 1) +#define cap_sagaw(c) (((c) >> 8) & 0x1f) +#define cap_caching_mode(c) (((c) >> 7) & 1) +#define cap_phmr(c) (((c) >> 6) & 1) +#define cap_plmr(c) (((c) >> 5) & 1) +#define cap_rwbf(c) (((c) >> 4) & 1) +#define cap_afl(c) (((c) >> 3) & 1) +#define cap_ndoms(c) (2 ^ (4 + 2 * ((c) & 0x7))) +/* + * Extended Capability Register + */ + +#define ecap_niotlb_iunits(e) ((((e) >> 24) & 0xff) + 1) +#define ecap_iotlb_offset(e) ((((e) >> 8) & 0x3ff) * 16) +#define ecap_coherent(e) ((e >> 0) & 0x1) +#define ecap_queued_inval(e) ((e >> 1) & 0x1) +#define ecap_dev_iotlb(e) ((e >> 2) & 0x1) +#define ecap_intr_remap(e) ((e >> 3) & 0x1) +#define ecap_ext_intr(e) ((e >> 4) & 0x1) +#define ecap_cache_hints(e) ((e >> 5) & 0x1) +#define ecap_pass_thru(e) ((e >> 6) & 0x1) + +#define PAGE_SHIFT_4K (12) +#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K) +#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K) +#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K) + +/* IOTLB_REG */ +#define DMA_TLB_FLUSH_GRANU_OFFSET 60 +#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60) +#define DMA_TLB_DSI_FLUSH (((u64)2) << 60) +#define DMA_TLB_PSI_FLUSH (((u64)3) << 60) +#define DMA_TLB_IIRG(x) (((x) >> 60) & 7) +#define DMA_TLB_IAIG(val) (((val) >> 57) & 7) +#define DMA_TLB_DID(x) (((u64)(x & 0xffff)) << 32) + +#define DMA_TLB_READ_DRAIN (((u64)1) << 49) +#define DMA_TLB_WRITE_DRAIN (((u64)1) << 48) +#define DMA_TLB_IVT (((u64)1) << 63) + +#define DMA_TLB_IVA_ADDR(x) ((((u64)x) >> 12) << 12) +#define DMA_TLB_IVA_HINT(x) ((((u64)x) & 1) << 6) + +/* GCMD_REG */ +#define DMA_GCMD_TE (((u64)1) << 31) +#define DMA_GCMD_SRTP (((u64)1) << 30) +#define DMA_GCMD_SFL (((u64)1) << 29) +#define DMA_GCMD_EAFL (((u64)1) << 28) +#define DMA_GCMD_WBF (((u64)1) << 27) +#define DMA_GCMD_QIE (((u64)1) << 26) +#define DMA_GCMD_IRE (((u64)1) << 25) +#define DMA_GCMD_SIRTP (((u64)1) << 24) + +/* GSTS_REG */ +#define DMA_GSTS_TES (((u64)1) << 31) +#define DMA_GSTS_RTPS (((u64)1) << 30) +#define DMA_GSTS_FLS (((u64)1) << 29) +#define DMA_GSTS_AFLS (((u64)1) << 28) +#define DMA_GSTS_WBFS (((u64)1) << 27) +#define DMA_GSTS_IRTPS (((u64)1) << 24) +#define DMA_GSTS_QIES (((u64)1) <<26) +#define DMA_GSTS_IRES (((u64)1) <<25) + +/* CCMD_REG */ +#define DMA_CCMD_INVL_GRANU_OFFSET 61 +#define DMA_CCMD_ICC (((u64)1) << 63) +#define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61) +#define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61) +#define DMA_CCMD_DEVICE_INVL (((u64)3) << 61) +#define DMA_CCMD_FM(m) (((u64)((m) & 0x3)) << 32) +#define DMA_CCMD_CIRG(x) ((((u64)3) << 61) & x) +#define DMA_CCMD_MASK_NOBIT 0 +#define DMA_CCMD_MASK_1BIT 1 +#define DMA_CCMD_MASK_2BIT 2 +#define DMA_CCMD_MASK_3BIT 3 +#define DMA_CCMD_SID(s) (((u64)((s) & 0xffff)) << 16) +#define DMA_CCMD_DID(d) ((u64)((d) & 0xffff)) + +#define DMA_CCMD_CAIG_MASK(x) (((u64)x) & ((u64) 0x3 << 59)) + +/* FECTL_REG */ +#define DMA_FECTL_IM (((u64)1) << 31) + +/* FSTS_REG */ +#define DMA_FSTS_PPF ((u64)2) +#define DMA_FSTS_PFO ((u64)1) +#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff) + +/* FRCD_REG, 32 bits access */ +#define DMA_FRCD_F (((u64)1) << 31) +#define dma_frcd_type(d) ((d >> 30) & 1) +#define dma_frcd_fault_reason(c) (c & 0xff) +#define dma_frcd_source_id(c) (c & 0xffff) +#define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */ + +/* + * 0: Present + * 1-11: Reserved + * 12-63: Context Ptr (12 - (haw-1)) + * 64-127: Reserved + */ +struct root_entry { + u64 val; + u64 rsvd1; +}; +#define root_present(root) ((root).val & 1) +#define set_root_present(root) do {(root).val |= 1;} while(0) +#define get_context_addr(root) ((root).val & PAGE_MASK_4K) +#define set_root_value(root, value) \ + do {(root).val |= ((value) & PAGE_MASK_4K);} while(0) + +struct context_entry { + u64 lo; + u64 hi; +}; +#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry)) +#define context_present(c) ((c).lo & 1) +#define context_fault_disable(c) (((c).lo >> 1) & 1) +#define context_translation_type(c) (((c).lo >> 2) & 3) +#define context_address_root(c) ((c).lo & PAGE_MASK_4K) +#define context_address_width(c) ((c).hi & 7) +#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1)) + +#define context_set_present(c) do {(c).lo |= 1;} while(0) +#define context_clear_present(c) do {(c).lo &= ~1;} while(0) +#define context_set_fault_enable(c) \ + do {(c).lo &= (((u64)-1) << 2) | 1;} while(0) + +#define context_set_translation_type(c, val) do { \ + (c).lo &= (((u64)-1) << 4) | 3; \ + (c).lo |= (val & 3) << 2; \ + } while(0) +#define CONTEXT_TT_MULTI_LEVEL 0 +#define CONTEXT_TT_DEV_IOTLB 1 +#define CONTEXT_TT_PASS_THRU 2 + +#define context_set_address_root(c, val) \ + do {(c).lo &= 0xfff; (c).lo |= (val) & PAGE_MASK_4K ;} while(0) +#define context_set_address_width(c, val) \ + do {(c).hi &= 0xfffffff8; (c).hi |= (val) & 7;} while(0) +#define context_set_domain_id(c, val) \ + do {(c).hi &= 0xff; (c).hi |= ((val + 1) & ((1 << 16) - 1)) << 8;} while(0) +#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while(0) + +/* + * 0: readable + * 1: writable + * 2-6: reserved + * 7: super page + * 8-11: available + * 12-63: Host physcial address + */ +struct dma_pte { + u64 val; +}; +#define dma_clear_pte(p) do {(p).val = 0;} while(0) +#define dma_set_pte_readable(p) do {(p).val |= 1;} while(0) +#define dma_set_pte_writable(p) do {(p).val |= 2;} while(0) +#define dma_set_pte_superpage(p) do {(p).val |= 8;} while(0) +#define dma_set_pte_prot(p, prot) do { (p).val = (((p).val >> 2) << 2) | ((prot) & 3);} while (0) +#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K) +#define dma_set_pte_addr(p, addr) do {(p).val |= ((addr) >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K;} while(0) +#define DMA_PTE_READ (1) +#define DMA_PTE_WRITE (2) +#define dma_pte_present(p) (((p).val & 3) != 0) + +/* interrupt remap entry */ +struct iremap_entry { + struct { + u64 present : 1, + fpd : 1, + dm : 1, + rh : 1, + tm : 1, + dlm : 3, + avail : 4, + res_1 : 4, + vector : 8, + res_2 : 8, + dst : 32; + }lo; + struct { + u64 sid : 16, + sq : 2, + svt : 2, + res_1 : 44; + }hi; +}; +#define IREMAP_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct iremap_entry)) +#define iremap_present(v) ((v).lo & 1) +#define iremap_fault_disable(v) (((v).lo >> 1) & 1) + +#define iremap_set_present(v) do {(v).lo |= 1;} while(0) +#define iremap_clear_present(v) do {(v).lo &= ~1;} while(0) + +/* queue invalidation entry */ +struct qinval_entry { + union { + struct { + struct { + u64 type : 4, + granu : 2, + res_1 : 10, + did : 16, + sid : 16, + fm : 2, + res_2 : 14; + }lo; + struct { + u64 res; + }hi; + }cc_inv_dsc; + struct { + struct { + u64 type : 4, + granu : 2, + dw : 1, + dr : 1, + res_1 : 8, + did : 16, + res_2 : 32; + }lo; + struct { + u64 am : 6, + ih : 1, + res_1 : 5, + addr : 52; + }hi; + }iotlb_inv_dsc; + struct { + struct { + u64 type : 4, + res_1 : 12, + max_invs_pend: 5, + res_2 : 11, + sid : 16, + res_3 : 16; + }lo; + struct { + u64 size : 1, + res_1 : 11, + addr : 52; + }hi; + }dev_iotlb_inv_dsc; + struct { + struct { + u64 type : 4, + granu : 1, + res_1 : 22, + im : 5, + iidx : 16, + res_2 : 16; + }lo; + struct { + u64 res; + }hi; + }iec_inv_dsc; + struct { + struct { + u64 type : 4, + iflag : 1, + sw : 1, + fn : 1, + res_1 : 25, + sdata : 32; + }lo; + struct { + u64 res_1 : 2, + saddr : 62; + }hi; + }inv_wait_dsc; + }q; +}; + +struct poll_info { + u64 saddr; + u32 udata; +}; + +#define QINVAL_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct qinval_entry)) +#define qinval_present(v) ((v).lo & 1) +#define qinval_fault_disable(v) (((v).lo >> 1) & 1) + +#define qinval_set_present(v) do {(v).lo |= 1;} while(0) +#define qinval_clear_present(v) do {(v).lo &= ~1;} while(0) + +#define RESERVED_VAL 0 + +#define TYPE_INVAL_CONTEXT 1 +#define TYPE_INVAL_IOTLB 2 +#define TYPE_INVAL_DEVICE_IOTLB 3 +#define TYPE_INVAL_IEC 4 +#define TYPE_INVAL_WAIT 5 + +#define NOTIFY_TYPE_POLL 1 +#define NOTIFY_TYPE_INTR 1 +#define INTERRUTP_FLAG 1 +#define STATUS_WRITE 1 +#define FENCE_FLAG 1 + +#define IEC_GLOBAL_INVL 0 +#define IEC_INDEX_INVL 1 + +#define VTD_PAGE_TABLE_LEVEL_3 3 +#define VTD_PAGE_TABLE_LEVEL_4 4 + +typedef paddr_t dma_addr_t; + +#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 +#define MAX_IOMMUS 32 +#define MAX_IOMMU_REGS 0xc0 + +extern struct list_head acpi_drhd_units; +extern struct list_head acpi_rmrr_units; +extern struct list_head acpi_ioapic_units; + +#endif diff -r 9071521d4864 xen/include/asm-x86/iommu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/iommu.h Tue Sep 11 11:34:53 2007 -0700 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Copyright (C) Allen Kay <allen.m.kay@intel.com> + */ + +#ifndef _IOMMU_H_ +#define _IOMMU_H_ + +#include <xen/init.h> +#include <xen/bitmap.h> +#include <xen/irq.h> +#include <xen/spinlock.h> +#include <xen/mm.h> +#include <xen/xmalloc.h> +#include <asm/hvm/vmx/intel-iommu.h> +#include <public/hvm/ioreq.h> + +extern int vtd_enabled; + +#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu) +#define domain_vmx_iommu(d) (&d->arch.hvm_domain.hvm_iommu.vmx_iommu) + +/* + * The PCI interface treats multi-function devices as independent + * devices. The slot/function address of each device is encoded + * in a single byte as follows: + * + * 15:8 = bus + * 7:3 = slot + * 2:0 = function + */ +#define PCI_DEVFN(slot,func) (((slot & 0x1f) << 3) | (func & 0x07)) +#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) +#define PCI_FUNC(devfn) ((devfn) & 0x07) + +struct pci_dev { + struct list_head list; + u8 bus; + u8 devfn; +}; + +struct iommu { + struct list_head list; + void __iomem *reg; /* Pointer to hardware regs, virtual addr */ + u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ + u64 cap; + u64 ecap; + spinlock_t lock; /* protect context, domain ids */ + spinlock_t register_lock; /* protect iommu register handling */ + struct root_entry *root_entry; /* virtual address */ + unsigned int vector; +}; + +int iommu_setup(void); +int iommu_domain_init(struct domain *d); +int assign_device(struct domain *d, u8 bus, u8 devfn); +int release_devices(struct domain *d); +int iommu_map_page(struct domain *d, dma_addr_t gfn, dma_addr_t mfn); +int iommu_unmap_page(struct domain *d, dma_addr_t gfn); +void iommu_flush(struct domain *d, dma_addr_t gfn, u64 *p2m_entry); +void iommu_set_pgd(struct domain *d); +void iommu_domain_teardown(struct domain *d); +int hvm_do_IRQ_dpci(struct domain *d, unsigned int irq); + +#endif // _IOMMU_H_ [-- Attachment #3: p2m_inc.patch --] [-- Type: application/octet-stream, Size: 1605 bytes --] diff -r 9071521d4864 xen/include/asm-x86/p2m.h --- a/xen/include/asm-x86/p2m.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/p2m.h Tue Sep 11 09:51:05 2007 -0700 @@ -26,6 +26,7 @@ #ifndef _XEN_P2M_H #define _XEN_P2M_H +#include <xen/iocap.h> /* The phys_to_machine_mapping is the reversed mapping of MPT for full * virtualization. It is only used by shadow_mode_translate()==true @@ -87,11 +88,17 @@ static inline unsigned long get_mfn_from return mfn_x(gfn_to_mfn_current(pfn)); } -/* Is this guest address an mmio one? (i.e. not defined in p2m map) */ +/* + Is this guest address an mmio address of an emulated device? + (i.e. not defined in p2m map and not belongs to a pass-through device) +*/ static inline int mmio_space(paddr_t gpa) { unsigned long gfn = gpa >> PAGE_SHIFT; - return !mfn_valid(mfn_x(gfn_to_mfn_current(gfn))); + unsigned long gmfn = mfn_x(gfn_to_mfn_current(gfn)); + + return ( !mfn_valid(gmfn) && + !iomem_access_permitted(current->domain, gmfn, gmfn) ); } /* Translate the frame number held in an l1e from guest to machine */ @@ -130,6 +137,10 @@ void guest_physmap_remove_page(struct do void guest_physmap_remove_page(struct domain *d, unsigned long gfn, unsigned long mfn); +/* Set mmio addresses in the p2m table (for pass-through) */ +int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn); +int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn); + /* set P2M table l1e flags */ void p2m_set_flags_global(struct domain *d, u32 l1e_flags); [-- Attachment #4: neo_inc.patch --] [-- Type: application/octet-stream, Size: 12013 bytes --] diff -r 9071521d4864 xen/include/asm-x86/e820.h --- a/xen/include/asm-x86/e820.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/e820.h Tue Sep 11 09:52:37 2007 -0700 @@ -8,7 +8,8 @@ #define E820_RESERVED 2 #define E820_ACPI 3 #define E820_NVS 4 -#define E820_UNUSABLE 5 +#define E820_1TO1 5 +#define E820_UNUSABLE 6 struct e820entry { uint64_t addr; diff -r 9071521d4864 xen/include/asm-x86/mm.h --- a/xen/include/asm-x86/mm.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/asm-x86/mm.h Tue Sep 11 09:51:05 2007 -0700 @@ -142,6 +142,7 @@ extern struct page_info *frame_table; extern struct page_info *frame_table; extern unsigned long max_page; extern unsigned long total_pages; +extern unsigned long max_page_nativedom; void init_frametable(void); int alloc_page_type(struct page_info *page, unsigned long type); diff -r 9071521d4864 xen/include/public/hvm/e820.h --- a/xen/include/public/hvm/e820.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/public/hvm/e820.h Tue Sep 11 09:51:05 2007 -0700 @@ -27,7 +27,7 @@ #define HVM_E820_NR_OFFSET 0x000001E8 #define HVM_E820_OFFSET 0x000002D0 -#define HVM_BELOW_4G_RAM_END 0xF0000000 +#define HVM_BELOW_4G_RAM_END 0xC0000000 #define HVM_BELOW_4G_MMIO_START HVM_BELOW_4G_RAM_END #define HVM_BELOW_4G_MMIO_LENGTH ((1ULL << 32) - HVM_BELOW_4G_MMIO_START) diff -r 9071521d4864 xen/include/public/hvm/hvm_op.h --- a/xen/include/public/hvm/hvm_op.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/public/hvm/hvm_op.h Tue Sep 11 10:07:51 2007 -0700 @@ -73,4 +73,16 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_ /* Flushes all VCPU TLBs: @arg must be NULL. */ #define HVMOP_flush_tlbs 5 +/* Tells whether the 1:1 mapping is enabled */ +#define HVMOP_is_nativedom_enabled 6 + +/* Builds e820 map for NativeDom */ +#define HVMOP_copy_nativedom_e820_map 7 +struct xen_hvm_copy_nativedom_e820_map { + /* Domain */ + domid_t domid; +}; +typedef struct xen_hvm_copy_nativedom_e820_map xen_hvm_copy_nativedom_e820_map_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_copy_nativedom_e820_map_t); + #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ diff -r 9071521d4864 xen/include/public/hvm/params.h --- a/xen/include/public/hvm/params.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/public/hvm/params.h Tue Sep 11 09:51:05 2007 -0700 @@ -52,9 +52,10 @@ #ifdef __ia64__ #define HVM_PARAM_NVRAM_FD 7 -#define HVM_NR_PARAMS 8 #else -#define HVM_NR_PARAMS 7 +#define HVM_PARAM_IS_NATIVEDOM 7 #endif +#define HVM_NR_PARAMS 8 + #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff -r 9071521d4864 xen/include/public/memory.h --- a/xen/include/public/memory.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/public/memory.h Tue Sep 11 09:51:05 2007 -0700 @@ -32,9 +32,10 @@ * number of extents successfully allocated or freed. * arg == addr of struct xen_memory_reservation. */ -#define XENMEM_increase_reservation 0 -#define XENMEM_decrease_reservation 1 -#define XENMEM_populate_physmap 6 +#define XENMEM_increase_reservation 0 +#define XENMEM_decrease_reservation 1 +#define XENMEM_populate_physmap 6 +#define XENMEM_populate_1to1_physmap 15 struct xen_memory_reservation { /* @@ -118,7 +119,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_excha * This command always succeeds (it never returns an error code). * arg == NULL. */ -#define XENMEM_maximum_ram_page 2 +#define XENMEM_maximum_ram_page 2 +#define XENMEM_maximum_ram_page_nativedom 16 /* * Returns the current or maximum memory reservation, in pages, of the diff -r 9071521d4864 xen/include/xen/hypercall.h --- a/xen/include/xen/hypercall.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/xen/hypercall.h Tue Sep 11 09:51:05 2007 -0700 @@ -47,7 +47,7 @@ do_platform_op( * at what point in the page list to resume. For this purpose I steal the * high-order bits of the @cmd parameter, which are otherwise unused and zero. */ -#define MEMOP_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ +#define MEMOP_EXTENT_SHIFT 5 /* cmd[:5] == start_extent */ #define MEMOP_CMD_MASK ((1 << MEMOP_EXTENT_SHIFT) - 1) extern long diff -r 9071521d4864 xen/include/xen/mm.h --- a/xen/include/xen/mm.h Fri Sep 07 11:39:10 2007 +0100 +++ b/xen/include/xen/mm.h Tue Sep 11 09:51:05 2007 -0700 @@ -66,6 +66,11 @@ unsigned long avail_domheap_pages(void); void scrub_heap_pages(void); +/* 1:1 Mapping */ +unsigned long alloc_1to1_page(unsigned long gpfn, struct domain * d, + unsigned int memflags); +void free_1to1_page(struct page_info *pg); + int assign_pages( struct domain *d, struct page_info *pg, diff -r 9071521d4864 xen/include/asm-x86/irq_bind.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/irq_bind.h Tue Sep 11 09:51:05 2007 -0700 @@ -0,0 +1,60 @@ +/* Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) */ +#ifndef __IRQ_BIND_H__ +#define __IRQ_BIND_H__ + +#include <xen/types.h> +#include <xen/domain.h> +#include <public/domctl.h> /* xen_domctl_bind_pt_irq_t */ + +/* Describes the _physical_ irq bind type */ +typedef enum pt_irq_bind_s { + PT_IRQ_BIND_NOT_IMPLEMENTED, + PT_IRQ_BIND_EDGE, + PT_IRQ_BIND_LEVEL_IOAPIC, + PT_IRQ_BIND_LEVEL_PIC /* Not implemented */ +} pt_irq_bind_t; + +/* Assertion state update on VMENTRY context */ +typedef enum pt_irq_assert_update_s { + PT_NOP, + PT_ASSERT, + PT_DEASSERT +} pt_irq_assert_update_t; + +/* Contains bind information per vector */ +typedef struct pt_vector_bind_s { + struct domain * d; + spinlock_t lock; + xen_domctl_bind_pt_irq_t bind; + pt_irq_bind_t bind_type; + uint32_t hvm_vector; + + struct { + uint8_t is_inuse:1; + /* Edge - one time mask, enable pass-through interrupt when guest enables it */ + uint8_t is_enabled:1; + /* Reflects the state of the assertion whitin the HVM */ + uint8_t is_hvm_asserted:1; + /* Command - how to update the assertion state in VMNTRY context */ + pt_irq_assert_update_t assert_update:2; + uint8_t pad:3; + } state; + + } __cacheline_aligned pt_vector_bind_t; + +int pt_irq_init(void); + +/* Create and remove mirq->girq bindings */ +int pt_irq_create_bind_neo(xen_domctl_bind_pt_irq_t * pt_irq_bind); +int pt_irq_create_bind_vtd(struct domain *d, + xen_domctl_bind_pt_irq_t * pt_irq_bind); +int pt_irq_remove_bind(unsigned long mirq); + +void pt_assert_irq(unsigned int vector); +void pt_deassert_irq(unsigned int vector); + +/* An assistance function that manages PT irqs for nativedom */ +void pt_intr_assist(struct domain * d); + +#endif /* __IRQ_BIND_H__ */ + diff -r 9071521d4864 xen/include/asm-x86/mm_early.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/mm_early.h Tue Sep 11 09:51:05 2007 -0700 @@ -0,0 +1,101 @@ +/***************************************************************************** + + Altering the memory map at the Xen early boot process, + Relevant for booting NativeDom properly. + + Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) + +******************************************************************************/ +#ifndef __MM_EARLY_H__ +#define __MM_EARLY_H__ + +#include <xen/types.h> +#include <xen/init.h> +#include <asm/e820.h> + +extern struct e820map e820_nativedom; + +/* + duplicated or just remapped for NativeDom. The first 12MB of the machine memory are being + duplicated on the x86_32 platform. +*/ +#define MAX_NR_DUPAREAS (10) +typedef struct nd_duplicated_area_s { + uint64_t real_addr; + uint64_t duplicated_addr; + uint64_t size; + /* can be 1 or 0, we distinguish between two types of regions that we protect, + those that are duplicated and those that are just remapped */ + unsigned char is_duplicated; +} nd_duplicated_area_t; + +#define MAX_NR_MMIOAREAS (10) +typedef struct nd_mmio_area_s { + uint64_t addr; + uint64_t size; +} nd_mmio_area_t; + +#define MAX_NR_PROTECTEDAREAS (MAX_NR_DUPAREAS) +typedef struct nd_protected_area_s { + uint64_t addr; + uint64_t size; +} nd_protected_area_t; + +typedef struct nd_areas_s { + /* Remapped or duplicated areas in nativedom's address space */ + struct { + unsigned long nr; + nd_duplicated_area_t areas[MAX_NR_DUPAREAS]; + } dups; + + struct { + unsigned long nr; + nd_mmio_area_t areas[MAX_NR_MMIOAREAS]; + } mmio; + + /* Protected areas */ + struct { + unsigned long nr; + nd_protected_area_t areas[MAX_NR_PROTECTEDAREAS]; + } protected; +} nd_areas_t; + +/* Non-iommu 1:1 mapping special regions */ +extern nd_areas_t nd_areas; + +/* percentage of E820_RAM that goes for Xen/Dom0 */ +#define MM_XEN_PORTION_OF_RAM (20) +#define MM_XEN_PORTION_OF_RAM_MINIMUM_MB (350) +#define MM_XEN_PORTION_OF_RAM_MAXIMUM_MB (512) +#define MM_DMADOM_FOR_XEN (300 * 1024 * 1024) + +#define MM_12MB (0x00C00000) +#define MM_16MB (0x01000000) + +/* The ROMs are duplicated for security reasons, + The 1-12MB Region is mapped on x86_32 platofrms, since Xen resides at 1MB */ +#define MM_DUP_1MB_ADDR (0x00000000) +#define MM_DUP_1MB_SIZE (0x00100000) +#define MM_REMAP_XEN_ADDR (0x00100000) +#define MM_REMAP_XEN_SIZE (0x00100000) +#define MM_DUP_12MB_ADDR (0x00200000) +#define MM_DUP_12MB_SIZE (MM_12MB - MM_DUP_12MB_ADDR) + +/* E820 Handy functions */ +int __init nd_duplicate_e820_entry(struct e820map * a_e820, + uint32_t index, uint32_t dups_nr); +int __init nd_setup_e820(void); +int __init nd_remap_areas(void); +int __init nd_init_mmio_areas(void); +uint32_t __init nd_get_last_ram_pfn(struct e820map * e820_map); + +/* Builds a memory map for NativeDom */ +int __init nd_build_nativedom_e820(void); + +/* Initializes the list of protected areas */ +int __init nd_init_protected_areas(void); +int __init nd_add_protected_area(uint64_t addr, uint64_t size); +int __init nativedom_init(void); + +#endif /* __MM_EARLY_H__ */ + diff -r 9071521d4864 xen/include/asm-x86/pt_irq.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/pt_irq.h Tue Sep 11 10:13:50 2007 -0700 @@ -0,0 +1,38 @@ +/* Copyright (c) 2007, Neocleus (alex/guy@neocleus.com) */ + +#ifndef __PT_IRQ_H__ +#define __PT_IRQ_H__ + +#include <asm/domain.h> +#include <asm/irq_bind.h> + +extern pt_vector_bind_t pt_vector_binds[NR_VECTORS]; + +void pt_assert_irq(unsigned int vector); +void pt_deassert_irq(unsigned int vector); +void pt_start_up_isa_irqs(int vpic, unsigned int imr); +void pt_intr_assist(struct domain * d); +int pt_irq_init(void); + +static inline int pt_irq_is_asserted(unsigned int vector) +{ + return pt_vector_binds[vector].state.is_hvm_asserted; +} + +static inline int pt_irq_is_inuse(unsigned int vector) +{ + return pt_vector_binds[vector].state.is_inuse; +} + +static inline int pt_irq_is_enabled(unsigned int vector) +{ + return pt_vector_binds[vector].state.is_enabled; +} + +static inline int pt_irq_trigger_mode(unsigned int vector) +{ + return pt_vector_binds[vector].bind_type; +} + +#endif /* __PT_IRQ_H__ */ + diff -r 9071521d4864 xen/include/asm-x86/pass-through.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/pass-through.h Tue Sep 11 11:52:17 2007 -0700 @@ -0,0 +1,23 @@ +/* + Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana +*/ +#ifndef __PASSTHROUGH_H__ +#define __PASSTHROUGH_H__ + +#include <xen/list.h> + +extern int opt_nativedom; +extern struct e820map e820_nativedom; + +struct g2m_ioport { + struct list_head list; + unsigned int gport; + unsigned int mport; + unsigned int np; +}; + +int passthrough_domain_init(struct domain *domain); +int dpci_ioport_intercept(ioreq_t *p); + +#endif /* __PASSTHROUGH_H__ */ + [-- Attachment #5: Type: text/plain, Size: 138 bytes --] _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough 2007-09-11 21:27 ` Kay, Allen M @ 2007-09-12 9:01 ` Keir Fraser 0 siblings, 0 replies; 13+ messages in thread From: Keir Fraser @ 2007-09-12 9:01 UTC (permalink / raw) To: Kay, Allen M, xen-devel; +Cc: Guy Zana Vtd_inc is applied. p2m_inc does not apply. Neo_inc not taken at this time for reasons stated in previous emails. -- Keir On 11/9/07 22:27, "Kay, Allen M" <allen.m.kay@intel.com> wrote: > Attached are header file patches I rebased to cs# 15837. I moved neo's > include file from xen to xen/asm. I couldn't move them to > xen/arch/x86/pt directory because some generic file reference them. > > Vtd_inc.patch: include generic changes and one vt-d file > (intel-iommu.h) > P2m_inc.patch: changes to p2m.h > Neo_inc.patch: Neocleus specific changes > > Signed-off-by: Allen Kay <allen.m.kay@intel.com> > Signed-off-by: Guy Zana <guy@neocleus.com> > > Allen > >> -----Original Message----- >> From: Keir Fraser [mailto:Keir.Fraser@cl.cam.ac.uk] >> Sent: Tuesday, September 11, 2007 5:50 AM >> To: Kay, Allen M; xen-devel@lists.xensource.com >> Cc: Guy Zana >> Subject: Re: [Xen-devel] [VTD-NEO][patch 0/6] Intel >> VT-d/Neocleus 1:1 mreged code for PCI passthrough >> >> On 5/9/07 01:08, "Kay, Allen M" <allen.m.kay@intel.com> wrote: >> >>> The following 6 patches contains merge of Intel VT-d and >> Neocleus' 1:1 >>> mapping patches for enabling HVM guest direct device access that were >>> last submitted around end of May. These patches applied cleanly to >>> changeset 15730. >> >> The 'include' patch doesn't apply any more, and in any case >> needs splitting >> up logically (vtd bits go in vtd patch; neo bits in neo patch; >> any generic >> bits in xen patch). The 'pt' (neo) code looks to throw way too >> much stuff in >> include/xen/ of which I suspect most is private definitions that really >> belong in the pt/ directory. Also consider which bits should be in >> include/asm rather than include/xen. >> >> The presence of the E820_1TO1 stuff makes me suspect that the 1:1 area >> allocation hasn't been cleaned up as much as it should have been. There >> shouldn't be any need to modify Xen's permanent e820 map I think. >> >> Haven't looked any further at the Xen parts, but I'll take a >> look at the >> tools patch... >> >> -- Keir >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mregedcode for PCI passthrough 2007-09-05 0:08 [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough Kay, Allen M 2007-09-06 23:16 ` John Byrne 2007-09-11 12:49 ` Keir Fraser @ 2007-09-16 17:26 ` Guy Zana 2007-09-17 8:25 ` Keir Fraser 2 siblings, 1 reply; 13+ messages in thread From: Guy Zana @ 2007-09-16 17:26 UTC (permalink / raw) To: Kay, Allen M, xen-devel; +Cc: Keir Fraser That will be "enable_nativedom=1" (without the 'd'). Thanks, Guy. > -----Original Message----- > From: xen-devel-bounces@lists.xensource.com > [mailto:xen-devel-bounces@lists.xensource.com] On Behalf Of > Kay, Allen M > Sent: Wednesday, September 05, 2007 3:09 AM > To: xen-devel@lists.xensource.com > Cc: Guy Zana; Keir Fraser > Subject: [Xen-devel] [VTD-NEO][patch 0/6] Intel VT-d/Neocleus > 1:1 mregedcode for PCI passthrough > > The following 6 patches contains merge of Intel VT-d and > Neocleus' 1:1 mapping patches for enabling HVM guest direct > device access that were last submitted around end of May. > These patches applied cleanly to changeset 15730. > > To enabled xen vt-d code, add "ioapic_ack=old" to xen boot > parameter in grub.conf on systems with VT-d hardware. > > To enabled xen 1:1 mapping code, add "enabled_nativedom=1" to > xen boot parameter in grub.conf. > > Signed-off-by: Allen Kay <allen.m.kay@intel.com> > Signed-off-by: Guy Zana <guy@neocleus.com> > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mregedcode for PCI passthrough 2007-09-16 17:26 ` [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mregedcode " Guy Zana @ 2007-09-17 8:25 ` Keir Fraser 0 siblings, 0 replies; 13+ messages in thread From: Keir Fraser @ 2007-09-17 8:25 UTC (permalink / raw) To: Guy Zana, xen-devel Better to use a boolean param called 'nativedom'. Then the user can automatically specify any one of 'nativedom', 'nativedom=on', 'nativedom=1', 'nativedom=true', ... -- Keir On 16/9/07 18:26, "Guy Zana" <guy@neocleus.com> wrote: > That will be "enable_nativedom=1" (without the 'd'). > > Thanks, > Guy. > >> -----Original Message----- >> From: xen-devel-bounces@lists.xensource.com >> [mailto:xen-devel-bounces@lists.xensource.com] On Behalf Of >> Kay, Allen M >> Sent: Wednesday, September 05, 2007 3:09 AM >> To: xen-devel@lists.xensource.com >> Cc: Guy Zana; Keir Fraser >> Subject: [Xen-devel] [VTD-NEO][patch 0/6] Intel VT-d/Neocleus >> 1:1 mregedcode for PCI passthrough >> >> The following 6 patches contains merge of Intel VT-d and >> Neocleus' 1:1 mapping patches for enabling HVM guest direct >> device access that were last submitted around end of May. >> These patches applied cleanly to changeset 15730. >> >> To enabled xen vt-d code, add "ioapic_ack=old" to xen boot >> parameter in grub.conf on systems with VT-d hardware. >> >> To enabled xen 1:1 mapping code, add "enabled_nativedom=1" to >> xen boot parameter in grub.conf. >> >> Signed-off-by: Allen Kay <allen.m.kay@intel.com> >> Signed-off-by: Guy Zana <guy@neocleus.com> >> >> _______________________________________________ >> Xen-devel mailing list >> Xen-devel@lists.xensource.com >> http://lists.xensource.com/xen-devel >> > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-09-17 8:25 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-09-05 0:08 [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mreged code for PCI passthrough Kay, Allen M 2007-09-06 23:16 ` John Byrne 2007-09-07 0:00 ` Kay, Allen M 2007-09-07 23:44 ` John Byrne 2007-09-11 12:49 ` Keir Fraser 2007-09-11 13:04 ` Keir Fraser 2007-09-12 1:21 ` Kay, Allen M 2007-09-12 9:03 ` Keir Fraser 2007-09-12 22:37 ` Kay, Allen M 2007-09-11 21:27 ` Kay, Allen M 2007-09-12 9:01 ` Keir Fraser 2007-09-16 17:26 ` [VTD-NEO][patch 0/6] Intel VT-d/Neocleus 1:1 mregedcode " Guy Zana 2007-09-17 8:25 ` Keir Fraser
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.