Skip to content

Commit

Permalink
drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
Browse files Browse the repository at this point in the history
This patch changes the logic in hv_vmbus to record all of the ranges in the
VM's firmware (BIOS or UEFI) that offer regions of memory-mapped I/O space for
use by paravirtual front-end drivers.  The old logic just found one range
above 4GB and called it good.  This logic will find any ranges above 1MB.

It would have been possible with this patch to just use existing resource
allocation functions, rather than keep track of the entire set of Hyper-V
related MMIO regions in VMBus.  This strategy, however, is not sufficient
when the resource allocator needs to be aware of the constraints of a
Hyper-V virtual machine, which is what happens in the next patch in the series.
So this first patch exists to show the first steps in reworking the MMIO
allocation paths for Hyper-V front-end drivers.

Signed-off-by: Jake Oshins <jakeo@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Jake Oshins authored and Greg Kroah-Hartman committed Aug 5, 2015
1 parent f368ed6 commit 7f163a6
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 28 deletions.
116 changes: 90 additions & 26 deletions drivers/hv/vmbus_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,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)
Expand Down Expand Up @@ -1013,30 +1010,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;

Expand All @@ -1046,35 +1118,27 @@ 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,
METHOD_NAME__CRS,
vmbus_walk_resources, NULL);
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;
}

static int vmbus_acpi_remove(struct acpi_device *device)
{
int ret = 0;

if (hyperv_mmio.start && hyperv_mmio.end)
ret = release_resource(&hyperv_mmio);
return ret;
}

static const struct acpi_device_id vmbus_acpi_device_ids[] = {
{"VMBUS", 0},
{"VMBus", 0},
Expand Down
2 changes: 1 addition & 1 deletion drivers/video/fbdev/hyperv_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion include/linux/hyperv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *,

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.
Expand Down

0 comments on commit 7f163a6

Please sign in to comment.