From: jakeo@microsoft.com
To: gregkh@linuxfoundation.org, kys@microsoft.com,
linux-kernel@vger.kernel.org, devel@linuxdriverproject.org,
olaf@aepfle.de, apw@canonical.com, vkuznets@redhat.com,
linux-pci@vger.kernel.org, bhelgaas@google.com,
mebersol@microsoft.com, haiyangz@microsoft.com
Cc: Jake Oshins <jakeo@microsoft.com>
Subject: [PATCH 1/6] drivers:hv: Modify vmbus to search for all MMIO ranges available
Date: Thu, 11 Jun 2015 16:22:22 +0000 [thread overview]
Message-ID: <1434039747-44535-2-git-send-email-jakeo@microsoft.com> (raw)
In-Reply-To: <1434039747-44535-1-git-send-email-jakeo@microsoft.com>
From: Jake Oshins <jakeo@microsoft.com>
Signed-off-by: Jake Oshins <jakeo@microsoft.com>
---
drivers/hv/vmbus_drv.c | 105 ++++++++++++++++++++++++++++++++++------
drivers/video/fbdev/hyperv_fb.c | 2 +-
include/linux/hyperv.h | 2 +-
3 files changed, 92 insertions(+), 17 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index c85235e..d0e8832 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -72,10 +72,7 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
};
-struct resource hyperv_mmio = {
- .name = "hyperv mmio",
- .flags = IORESOURCE_MEM,
-};
+struct resource *hyperv_mmio;
EXPORT_SYMBOL_GPL(hyperv_mmio);
static int vmbus_exists(void)
@@ -982,30 +979,105 @@ void vmbus_device_unregister(struct hv_device *device_obj)
/*
- * VMBUS is an acpi enumerated device. Get the the information we
+ * VMBUS is an acpi enumerated device. Get the information we
* need from DSDT.
*/
-
+#define VTPM_BASE_ADDRESS 0xfed40000
static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
{
+ resource_size_t start = 0;
+ resource_size_t end = 0;
+ struct resource *new_res;
+ struct resource **old_res = &hyperv_mmio;
+ struct resource **prev_res = NULL;
+
switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ:
irq = res->data.irq.interrupts[0];
+ return AE_OK;
+
+ /*
+ * "Address" descriptors are for bus windows. Ignore
+ * "memory" descriptors, which are for registers on
+ * devices.
+ */
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ start = res->data.address32.address.minimum;
+ end = res->data.address32.address.maximum;
break;
case ACPI_RESOURCE_TYPE_ADDRESS64:
- hyperv_mmio.start = res->data.address64.address.minimum;
- hyperv_mmio.end = res->data.address64.address.maximum;
+ start = res->data.address64.address.minimum;
+ end = res->data.address64.address.maximum;
break;
+
+ default:
+ /* Unused resource type */
+ return AE_OK;
+
}
+ /*
+ * Ignore ranges that are below 1MB, as they're not
+ * necessary or useful here.
+ */
+ if (end < 0x100000)
+ return AE_OK;
+
+ new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC);
+ if (!new_res)
+ return AE_NO_MEMORY;
+
+ /* If this range overlaps the virtual TPM, truncate it. */
+ if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS)
+ end = VTPM_BASE_ADDRESS;
+
+ new_res->name = "hyperv mmio";
+ new_res->flags = IORESOURCE_MEM;
+ new_res->start = start;
+ new_res->end = end;
+
+ do {
+ if (!*old_res) {
+ *old_res = new_res;
+ break;
+ }
+
+ if ((*old_res)->end < new_res->start) {
+ new_res->sibling = *old_res;
+ if (prev_res)
+ (*prev_res)->sibling = new_res;
+ *old_res = new_res;
+ break;
+ }
+
+ prev_res = old_res;
+ old_res = &(*old_res)->sibling;
+
+ } while (1);
return AE_OK;
}
+static int vmbus_acpi_remove(struct acpi_device *device)
+{
+ struct resource *cur_res;
+ struct resource *next_res;
+
+ if (hyperv_mmio) {
+ for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
+ next_res = cur_res->sibling;
+ kfree(cur_res);
+ }
+ }
+
+ return 0;
+}
+
static int vmbus_acpi_add(struct acpi_device *device)
{
acpi_status result;
int ret_val = -ENODEV;
+ struct acpi_device *ancestor;
hv_acpi_dev = device;
@@ -1015,23 +1087,25 @@ static int vmbus_acpi_add(struct acpi_device *device)
if (ACPI_FAILURE(result))
goto acpi_walk_err;
/*
- * The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that
- * has the mmio ranges. Get that.
+ * Some ancestor of the vmbus acpi device (Gen1 or Gen2
+ * firmware) is the VMOD that has the mmio ranges. Get that.
*/
- if (device->parent) {
- result = acpi_walk_resources(device->parent->handle,
+ for (ancestor = device->parent; ancestor; ancestor = ancestor->parent) {
+ result = acpi_walk_resources(ancestor->handle,
METHOD_NAME__CRS,
vmbus_walk_resources, NULL);
if (ACPI_FAILURE(result))
- goto acpi_walk_err;
- if (hyperv_mmio.start && hyperv_mmio.end)
- request_resource(&iomem_resource, &hyperv_mmio);
+ continue;
+ if (hyperv_mmio)
+ break;
}
ret_val = 0;
acpi_walk_err:
complete(&probe_event);
+ if (ret_val)
+ vmbus_acpi_remove(device);
return ret_val;
}
@@ -1047,6 +1121,7 @@ static struct acpi_driver vmbus_acpi_driver = {
.ids = vmbus_acpi_device_ids,
.ops = {
.add = vmbus_acpi_add,
+ .remove = vmbus_acpi_remove,
},
};
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 807ee22..b54ee1c 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -688,7 +688,7 @@ static int hvfb_getmem(struct fb_info *info)
par->mem.name = KBUILD_MODNAME;
par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
if (gen2vm) {
- ret = allocate_resource(&hyperv_mmio, &par->mem,
+ ret = allocate_resource(hyperv_mmio, &par->mem,
screen_fb_size,
0, -1,
screen_fb_size,
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 902c37a..21fa867 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1245,7 +1245,7 @@ void hv_vss_deinit(void);
void hv_vss_onchannelcallback(void *);
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
-extern struct resource hyperv_mmio;
+extern struct resource *hyperv_mmio;
/*
* Negotiated version with the Host.
--
1.9.1
next prev parent reply other threads:[~2015-06-11 16:22 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-11 16:22 [PATCH 0/6] Front-end driver for PCIe Pass-through on Hyper-V jakeo
2015-06-11 16:22 ` jakeo [this message]
2015-06-11 16:22 ` [PATCH 2/6] drivers:hv: Move MMIO range picking from hyper_fb.mod to hv_vmbus.mod jakeo
2015-06-11 17:46 ` Greg KH
2015-06-11 16:22 ` [PATCH 3/6] arch:x86:hv: Add mechanism for Hyper-V paravirt drivers to hook msi message creation jakeo
2015-06-11 16:22 ` [PATCH 4/6] drivers:hv: Export a function that maps Linux proc num onto Hyper-V proc num jakeo
2015-06-11 16:22 ` [PATCH 5/6] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through jakeo
2015-06-11 16:22 ` [PATCH 6/6] drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs jakeo
2015-06-11 17:46 ` Greg KH
2015-06-12 8:44 ` Paul Bolle
2015-06-12 15:11 ` Jake Oshins
2015-06-12 15:11 ` Jake Oshins
2015-06-12 16:14 ` gregkh
2015-06-11 17:47 ` [PATCH 0/6] Front-end driver for PCIe Pass-through on Hyper-V Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1434039747-44535-2-git-send-email-jakeo@microsoft.com \
--to=jakeo@microsoft.com \
--cc=apw@canonical.com \
--cc=bhelgaas@google.com \
--cc=devel@linuxdriverproject.org \
--cc=gregkh@linuxfoundation.org \
--cc=haiyangz@microsoft.com \
--cc=kys@microsoft.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mebersol@microsoft.com \
--cc=olaf@aepfle.de \
--cc=vkuznets@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.