From patchwork Thu Dec 17 15:04:46 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 68534 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id nBI4ixur005715 for ; Fri, 18 Dec 2009 04:47:41 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762453AbZLQPEx (ORCPT ); Thu, 17 Dec 2009 10:04:53 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1762489AbZLQPEu (ORCPT ); Thu, 17 Dec 2009 10:04:50 -0500 Received: from cantor2.suse.de ([195.135.220.15]:46073 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1762290AbZLQPEs (ORCPT ); Thu, 17 Dec 2009 10:04:48 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id E1FBD89B67; Thu, 17 Dec 2009 16:04:46 +0100 (CET) From: Alexander Graf To: kvm list Cc: Gleb Natapov , "Michael S. Tsirkin" , Muli Ben-Yehuda , Chris Wright , "Daniel P. Berrange" Subject: [PATCH 3/3] Inform users about busy device assignment attempt Date: Thu, 17 Dec 2009 16:04:46 +0100 Message-Id: <1261062286-12860-4-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1261062286-12860-1-git-send-email-agraf@suse.de> References: <1261062286-12860-1-git-send-email-agraf@suse.de> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 566671c..d6d44eb 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -756,6 +756,54 @@ static uint32_t calc_assigned_dev_id(uint8_t bus, uint8_t devfn) return (uint32_t)bus << 8 | (uint32_t)devfn; } +static void assign_failed_examine(AssignedDevice *dev) +{ + char name[PATH_MAX], dir[PATH_MAX], driver[PATH_MAX] = {}, *ns; + uint16_t vendor_id, device_id; + int r; + + /* XXX implement multidomain */ + sprintf(dir, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/", + dev->host.bus, dev->host.dev, dev->host.func); + + sprintf(name, "%sdriver", dir); + + r = readlink(name, driver, sizeof(driver)); + if ((r <= 0) || r >= sizeof(driver) || !(ns = strrchr(driver, '/'))) { + goto fail; + } + + ns++; + + if (get_real_vendor_id(dir, &vendor_id) || + get_real_device_id(dir, &device_id)) { + goto fail; + } + + fprintf(stderr, "*** The driver '%s' is occupying your device " + "%02x:%02x.%x.\n", + ns, dev->host.bus, dev->host.dev, dev->host.func); + fprintf(stderr, "***\n"); + fprintf(stderr, "*** You can try the following commands to free it:\n"); + fprintf(stderr, "***\n"); + fprintf(stderr, "*** $ echo \"%04x %04x\" > /sys/bus/pci/drivers/pci-stub/" + "new_id\n", vendor_id, device_id); + fprintf(stderr, "*** $ echo \"0000:%02x:%02x.%x\" > /sys/bus/pci/drivers/" + "%s/unbind\n", + dev->host.bus, dev->host.dev, dev->host.func, ns); + fprintf(stderr, "*** $ echo \"0000:%02x:%02x.%x\" > /sys/bus/pci/drivers/" + "pci-stub/bind\n", + dev->host.bus, dev->host.dev, dev->host.func); + fprintf(stderr, "*** $ echo \"%04x %04x\" > /sys/bus/pci/drivers/pci-stub" + "/remove_id\n", vendor_id, device_id); + fprintf(stderr, "***\n"); + + return; + +fail: + fprintf(stderr, "Couldn't find out why.\n"); +} + static int assign_device(AssignedDevice *dev) { struct kvm_assigned_pci_dev assigned_dev_data; @@ -781,9 +829,18 @@ static int assign_device(AssignedDevice *dev) #endif r = kvm_assign_pci_device(kvm_context, &assigned_dev_data); - if (r < 0) - fprintf(stderr, "Failed to assign device \"%s\" : %s\n", + if (r < 0) { + fprintf(stderr, "Failed to assign device \"%s\" : %s\n", dev->dev.qdev.id, strerror(-r)); + + switch (r) { + case -EBUSY: + assign_failed_examine(dev); + break; + default: + break; + } + } return r; }