On Thu, 2008-07-17 at 15:52 +0800, Han, Weidong wrote: > Ben-Ami Yassour wrote: > > From: Or Sagi <[EMAIL PROTECTED]> > > > > From: Nir Peleg <[EMAIL PROTECTED]> > > From: Amit Shah <[EMAIL PROTECTED]> > > From: Glauber de Oliveira Costa <[EMAIL PROTECTED]> > > > > We can assign a device from the host machine to a guest. The > > original code comes from Neocleus. > > > > A new command-line option, -pcidevice is added. > > For example, to invoke it for an Ethernet device sitting at > > PCI bus:dev.fn 04:08.0 with host IRQ 18, use this: > > > > -pcidevice Ethernet/04:08.0 > > > > The host ethernet driver is to be removed before doing the > > passthrough. If not, the device assignment fails but the > > guest continues without the assignment. > > > > If kvm uses the in-kernel irqchip, interrupts are routed to the > > guest via the kvm module (accompanied kernel changes are necessary). > > > > If -no-kvm-irqchip is used, the 'irqhook' module, available > > separately, is to be used for interrupt injection into the guest. In > > this case, an extra parameter, -<intr-number> is to be appended to > > the above-mentioned pcidevice parameter. > > > > Signed-off-by: Amit Shah <[EMAIL PROTECTED]> > > --- > > +static pt_dev_t *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) > > +{ > > + int rc; > > + pt_dev_t *pci_dev; > > + uint8_t e_device, e_intx; > > + > > + DEBUG("register_real_device: Registering real physical " > > + "device %s (devfn=0x%x)\n", e_dev_name, e_devfn); > > + > > + pci_dev = (pt_dev_t *) pci_register_device(e_bus, e_dev_name, > > + sizeof(pt_dev_t), > e_devfn, > > + pt_pci_read_config, > > + pt_pci_write_config); > > + > > + if (NULL == pci_dev) { > > + fprintf(stderr, "register_real_device: Error: Couldn't " > > + "register real device %s\n", e_dev_name); > > + return NULL; > > + } > > + if (pt_get_real_device(pci_dev, r_bus, r_dev, r_func)) { > > + fprintf(stderr, "register_real_device: Error: Couldn't > get " > > + "real device (%s)!\n", e_dev_name); > > + return NULL; > > + } > > + > > + /* handle real device's MMIO/PIO BARs */ > > + if (pt_register_regions(pci_dev->real_device.regions, > > + pci_dev->real_device.region_number, > pci_dev)) > > + return NULL; > > + > > + /* handle interrupt routing */ > > + e_device = (pci_dev->dev.devfn >> 3) & 0x1f; > > + e_intx = pci_dev->dev.config[0x3d] - 1; > > + pci_dev->intpin = e_intx; > > + pci_dev->run = 0; > > + pci_dev->girq = 0; > > + pci_dev->h_busnr = r_bus; > > + pci_dev->h_devfn = PCI_DEVFN(r_dev, r_func); > > + > > +#ifdef KVM_CAP_PCI_PASSTHROUGH > > + if (kvm_enabled()) { > > + struct kvm_pci_passthrough_dev pci_pt_dev; > > + > > + memset(&pci_pt_dev, 0, sizeof(pci_pt_dev)); > > + pci_pt_dev.guest.busnr = pci_bus_num(e_bus); > > + pci_pt_dev.guest.devfn = PCI_DEVFN(e_device, r_func); > > Why combine e_device and r_func? The guest devfn is e_devfn. the current assumption is that e_func and r_func are identical.
> > > + pci_pt_dev.host.busnr = pci_dev->h_busnr; > > + pci_pt_dev.host.devfn = pci_dev->h_devfn; > > + > > + /* We'll set the value of the guest irq as and when > > + * the piix config gets updated. See pci_pt_update_irq. > > + * The host irq field never gets used anyway > > + */ > > + > > + rc = kvm_update_pci_pt_device(kvm_context, &pci_pt_dev); > > + if (rc < 0) { > > + fprintf(stderr, "Could not notify kernel about " > > + "passthrough device\n"); > > + perror("pt-ioctl"); > > + return NULL; > > + } > > + } > > +#endif > > + > > + fprintf(logfile, "Registered host PCI device %02x:%02x.%1x " > > + "as guest device %02x:%02x.%1x\n", > > + r_bus, r_dev, r_func, > > + pci_bus_num(e_bus), e_device, r_func); > > Second "r_func" should replaced by e_devfn & 0x7. same as above. > > Randy (Weidong) > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html