If I pass through 0:14, won't I loose USB on my host? I have a USB keyboard and mouse and need USB for other things like thumb drives.
Jon On 23 Feb 2016 15:57, "Samuel Holland" <[email protected]> wrote: > Hello, > > On 02/23/2016 06:46 AM, Jonathan Scruggs wrote: > >> How can I pass through the USB ports to the guest so that the items >> plugged into the ports appear to the guest? >> > > In short, "sudo setpci -s0:14.0 0xd0.W=0x0000" will pass through all of > your ports. > > I was planning to write a blog post about it this month, but I haven't > gotten to it yet, so I guess I'll write it here. I have been using this > setup since December, and everything works without any issues. I had > done like you (playing with the firmware options) and gotten nowhere; I > finally found a Google+ post[0] (the user appears to have been deleted) > with a link to the 9 series PCH datasheet[1], which has been immensely > useful. > > I have only tried this with an AsRock Z97E-ITX/ac. It might not work on > your board if your firmware disables switching ports (see section > 16.1.37). Your chipset datasheet is here[2]. The xHCI registers are in > chapter 17 in your datasheet, so you will have to adapt the section > references. > > Step 1: Map your USB ports > ========================== > This is easiest to do if you turn USB3 (xHCI) off completely. First, you > need to map your EHCI controllers to USB buses as seen by the kernel. > These numbers can change when you reboot your machine, so do this after > you have disabled USB3. Run `lspci` and look at the numbers after the > EHCI controllers (#1/#2). Then run the command below. You should get > similar output. > > $ readlink -f /sys/bus/usb/devices/usb? > /sys/devices/pci0000:00/0000:00:14.0/usb1 > /sys/devices/pci0000:00/0000:00:1a.0/usb2 > /sys/devices/pci0000:00/0000:00:1d.0/usb3 > > Run `watch lsusb -t` in a terminal. Take a flash drive/mouse/etc. and > plug it into each port on your machine. There are 14 of them. If you > cannot find some, they might be in a mini-PCIe or M.2 slot, or just not > connected. > > Use the bus numbers you found earlier, and the output of lsusb, to map > physical ports to logical ports on controllers. Eight of them will be on > the EHCI controller marked #1, and the other six will be on #2. Now sort > them, starting with EHCI #1 port 1, and ending with EHCI #2 port 6. > > Next you should turn USB3 back on in your firmware settings. > > Step 2: Pass through your controller > ==================================== > This is the easy part. Just add whichever controller you want to use in > the VM to your libvirt XML or qemu command line. Personally, I only ever > need to use USB2 devices in Windows, so I pass through both EHCI > controllers. However, I believe the EHCI controllers on the PCH do not > support MSI, so that may affect performance with devices like flash > drives. With a keyboard or mouse, it shouldn't make any difference. > > Step 3: Route your USB ports > ============================ > Looking at section 16.1.36, we can connect individual ports to either > the EHCI or xHCI controller. On your sorted list of ports, mark which > ones you want to have available in the VM, and which ones you want to > use on the host. This is switchable at runtime, so you can create > several lists--I have some ports that are routed to EHCI all of the > time, and others I toggle back and forth. > > Turn each list of port routes into a binary mask: 0 for each EHCI port, > and 1 for each xHCI port. The least significant bit is EHCI #1 port 1. > Extend it to 16 bits by setting the two most significant bits to 0. Then > convert it to hexadecimal. It should be something between 0x0000 and > 0x3fff. Finally, run setpci (as root) to change the routing. Moved USB > devices will reset immediately. The command is > > # setpci -s<xHCI PCI address> 0xd0.W=0x<the mask in hex> > > For example, to move everything to the xHCI controller: > > # setpci -s0:14.0 0xd0.W=0x3fff > > Again, even though you are running this command to configure the xHCI > controller, the bits are in the order the ports appear to the EHCI > controllers. If, for some reason, you cannot turn off xHCI to find that > order, use table 2-2 in section 2.2 to map xHCI ports (what you see in > lsusb minus 1) to EHCI ports. > > If you are connecting a USB3 (blue) port to a EHCI controller, there's > one additional step you (probably) need to take. You will need to either > 1) remember to never plug a USB3 device into the port, or 2) turn off > USB3 on that port. See section 16.1.38 for the register to change. I > have not needed to do this, so I am not certain, but I believe the port > numbers here are as they appear to the xHCI controller. > > Step 4: Toggle your port mask > ============================= > If you have more than one keyboard/mouse or a KVM switch or synergy, you > are done. Personally, I use this method to avoid all of that, so I have > to have a way to switch my keyboard back and forth while running the VM. > The first step is to have a service running as root, that will run > setpci for you when you tell it to switch ports. I use the following > python script. You should only need to change the masks and port number > (at the bottom). Hopefully it doesn't get mangled in the email. > > ----------------SNIP---------------- > #!/usr/bin/env python3 > > import socketserver > import subprocess > import syslog > > def change_usb_state(action): > global state > if action == state: return > if action == "toggle": action = "guest" if state == "host" else "host" > syslog.syslog("Setting xHCI port routing mask to > {:#x}".format(masks[action])) > if subprocess.call(["setpci", "-s0:14.0", > "0xd0.L=0x{:08x}".format(masks[action])]) == 0: state = action > else: syslog.syslog("Calling setpci failed. Assuming routing is > unchanged.") > > class PCIHandler(socketserver.StreamRequestHandler): > def handle(self): > for line in self.rfile: > action = line.strip().decode("utf-8") > syslog.syslog("Got action request: {}".format(action)) > if action in ["guest", "host", "toggle"]: > change_usb_state(action) > > class ThreadedTCPServer(socketserver.ThreadingMixIn, > socketserver.TCPServer): pass > > masks = { "guest": 0x0fc, "host": 0x0ff } > state = "host" > server = ThreadedTCPServer(("127.0.0.1", 10), PCIHandler) > server.serve_forever() > ----------------SNIP---------------- > > On Linux, you can then use netcat as any user to toggle your ports. I > use i3, and have a key mapped like so, which toggles my USB ports and > then locks my screen: > > ----------------SNIP---------------- > bindsym Control+Mod1+Menu exec --no-startup-id busybox nc 127.0.0.1 10 <<< > toggle; exec --no-startup-id slock > ----------------SNIP---------------- > > The second part is to connect qemu to your service. (You could also have > the service accept remote connections, but then anyone on your network > could control your USB ports. I only recommend this if you have an > isolated network to use with qemu, and you only have the service listen > on that network.) The simple and secure way to do this is to connect a > serial port in the VM to your service. I use Q35 and qemu directly; you > will have to adapt this to libvirt yourself. > > ----------------SNIP---------------- > -device isa-serial,chardev=com1,index=0 \ > -chardev socket,host=127.0.0.1,id=com1,port=10 > ----------------SNIP---------------- > > Third, you need some way to connect to the serial port from within the > guest. On a Linux guest, you can use picocom, socat, etc. On Windows, > the simple way is to use a PowerShell script: > > ----------------SNIP---------------- > $port = New-Object System.IO.Ports.SerialPort COM1,115200,None,8,One > $port.Open() > $port.WriteLine("toggle") > $port.Close() > ----------------SNIP---------------- > > Personally, I use AutoHotKey to map the same key in Windows to switching > my ports and locking my screen. I'd be happy to share it, but it is too > long to paste here. > > Hopefully that should get you going. I apologize if this is too long, > but I wanted to be thorough. It definitely took a weekend to get set up, > but once it works, it is really rather seamless. > > [0] > https://plus.google.com/wm/quevuelvamatt/app/basic/stream/z13ki3ixwvubfpk4e04chfi45r3lyv4zeiw > [1] > http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/9-series-chipset-pch-datasheet.pdf > [2] > http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/x99-chipset-pch-datasheet.pdf > > (See also sections 5.19-5.21 of the datasheet for more information.) > > -- > Regards, > Samuel Holland <[email protected]> > >
_______________________________________________ vfio-users mailing list [email protected] https://www.redhat.com/mailman/listinfo/vfio-users
