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

Reply via email to