|
Olaf Hering |
02cd93 |
From: Wei Hu <weh@microsoft.com>
|
|
Olaf Hering |
02cd93 |
Date: Mon, 9 Dec 2019 15:57:49 +0800
|
|
Olaf Hering |
02cd93 |
Patch-mainline: v5.6-rc1
|
|
Olaf Hering |
02cd93 |
References: bsc#1175306
|
|
Olaf Hering |
02cd93 |
Subject: video: hyperv: hyperv_fb: Use physical memory for fb on HyperV Gen 1 VMs.
|
|
Olaf Hering |
02cd93 |
Git-commit: 3a6fb6c4255c3893ab61e2bd4e9ae01ca6bbcd94
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
On Hyper-V, Generation 1 VMs can directly use VM's physical memory for
|
|
Olaf Hering |
02cd93 |
their framebuffers. This can improve the efficiency of framebuffer and
|
|
Olaf Hering |
02cd93 |
overall performence for VM. The physical memory assigned to framebuffer
|
|
Olaf Hering |
02cd93 |
must be contiguous. We use CMA allocator to get contiguouse physicial
|
|
Olaf Hering |
02cd93 |
memory when the framebuffer size is greater than 4MB. For size under
|
|
Olaf Hering |
02cd93 |
4MB, we use alloc_pages to achieve this.
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
To enable framebuffer memory allocation from CMA, supply a kernel
|
|
Olaf Hering |
02cd93 |
parameter to give enough space to CMA allocator at boot time. For
|
|
Olaf Hering |
02cd93 |
example:
|
|
Olaf Hering |
02cd93 |
cma=130m
|
|
Olaf Hering |
02cd93 |
This gives 130MB memory to CAM allocator that can be allocated to
|
|
Olaf Hering |
02cd93 |
framebuffer. If this fails, we fall back to the old way of using
|
|
Olaf Hering |
02cd93 |
mmio for framebuffer.
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
Reported-by: kbuild test robot <lkp@intel.com>
|
|
Olaf Hering |
02cd93 |
Signed-off-by: Wei Hu <weh@microsoft.com>
|
|
Olaf Hering |
02cd93 |
Acked-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
|
|
Olaf Hering |
02cd93 |
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
Olaf Hering |
02cd93 |
Acked-by: Olaf Hering <ohering@suse.de>
|
|
Olaf Hering |
02cd93 |
---
|
|
Olaf Hering |
02cd93 |
drivers/video/fbdev/Kconfig | 1 +
|
|
Olaf Hering |
02cd93 |
drivers/video/fbdev/hyperv_fb.c | 182 +++++++++++++++++++++++++++++++---------
|
|
Olaf Hering |
02cd93 |
2 files changed, 144 insertions(+), 39 deletions(-)
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
|
|
Olaf Hering |
02cd93 |
--- a/drivers/video/fbdev/Kconfig
|
|
Olaf Hering |
02cd93 |
+++ b/drivers/video/fbdev/Kconfig
|
|
Olaf Hering |
02cd93 |
@@ -2215,6 +2215,7 @@ config FB_HYPERV
|
|
Olaf Hering |
02cd93 |
select FB_CFB_COPYAREA
|
|
Olaf Hering |
02cd93 |
select FB_CFB_IMAGEBLIT
|
|
Olaf Hering |
02cd93 |
select FB_DEFERRED_IO
|
|
Olaf Hering |
02cd93 |
+ select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA
|
|
Olaf Hering |
02cd93 |
help
|
|
Olaf Hering |
02cd93 |
This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
|
|
Olaf Hering |
02cd93 |
--- a/drivers/video/fbdev/hyperv_fb.c
|
|
Olaf Hering |
02cd93 |
+++ b/drivers/video/fbdev/hyperv_fb.c
|
|
Olaf Hering |
02cd93 |
@@ -31,6 +31,16 @@
|
|
Olaf Hering |
02cd93 |
* "set-vmvideo" command. For example
|
|
Olaf Hering |
02cd93 |
* set-vmvideo -vmname name -horizontalresolution:1920 \
|
|
Olaf Hering |
02cd93 |
* -verticalresolution:1200 -resolutiontype single
|
|
Olaf Hering |
02cd93 |
+ *
|
|
Olaf Hering |
02cd93 |
+ * Gen 1 VMs also support direct using VM's physical memory for framebuffer.
|
|
Olaf Hering |
02cd93 |
+ * It could improve the efficiency and performance for framebuffer and VM.
|
|
Olaf Hering |
02cd93 |
+ * This requires to allocate contiguous physical memory from Linux kernel's
|
|
Olaf Hering |
02cd93 |
+ * CMA memory allocator. To enable this, supply a kernel parameter to give
|
|
Olaf Hering |
02cd93 |
+ * enough memory space to CMA allocator for framebuffer. For example:
|
|
Olaf Hering |
02cd93 |
+ * cma=130m
|
|
Olaf Hering |
02cd93 |
+ * This gives 130MB memory to CMA allocator that can be allocated to
|
|
Olaf Hering |
02cd93 |
+ * framebuffer. For reference, 8K resolution (7680x4320) takes about
|
|
Olaf Hering |
02cd93 |
+ * 127MB memory.
|
|
Olaf Hering |
02cd93 |
*/
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
Olaf Hering |
02cd93 |
@@ -228,7 +238,6 @@ struct synthvid_msg {
|
|
Olaf Hering |
02cd93 |
} __packed;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
-
|
|
Olaf Hering |
02cd93 |
/* FB driver definitions and structures */
|
|
Olaf Hering |
02cd93 |
#define HVFB_WIDTH 1152 /* default screen width */
|
|
Olaf Hering |
02cd93 |
#define HVFB_HEIGHT 864 /* default screen height */
|
|
Olaf Hering |
02cd93 |
@@ -258,12 +267,15 @@ struct hvfb_par {
|
|
Olaf Hering |
02cd93 |
/* If true, the VSC notifies the VSP on every framebuffer change */
|
|
Olaf Hering |
02cd93 |
bool synchronous_fb;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
+ /* If true, need to copy from deferred IO mem to framebuffer mem */
|
|
Olaf Hering |
02cd93 |
+ bool need_docopy;
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
struct notifier_block hvfb_panic_nb;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
/* Memory for deferred IO and frame buffer itself */
|
|
Olaf Hering |
02cd93 |
unsigned char *dio_vp;
|
|
Olaf Hering |
02cd93 |
unsigned char *mmio_vp;
|
|
Olaf Hering |
02cd93 |
- unsigned long mmio_pp;
|
|
Olaf Hering |
02cd93 |
+ phys_addr_t mmio_pp;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
/* Dirty rectangle, protected by delayed_refresh_lock */
|
|
Olaf Hering |
02cd93 |
int x1, y1, x2, y2;
|
|
Olaf Hering |
02cd93 |
@@ -434,7 +446,7 @@ static void synthvid_deferred_io(struct fb_info *p,
|
|
Olaf Hering |
02cd93 |
maxy = max_t(int, maxy, y2);
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
/* Copy from dio space to mmio address */
|
|
Olaf Hering |
02cd93 |
- if (par->fb_ready)
|
|
Olaf Hering |
02cd93 |
+ if (par->fb_ready && par->need_docopy)
|
|
Olaf Hering |
02cd93 |
hvfb_docopy(par, start, PAGE_SIZE);
|
|
Olaf Hering |
02cd93 |
}
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
@@ -751,12 +763,12 @@ static void hvfb_update_work(struct work_struct *w)
|
|
Olaf Hering |
02cd93 |
return;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
/* Copy the dirty rectangle to frame buffer memory */
|
|
Olaf Hering |
02cd93 |
- for (j = y1; j < y2; j++) {
|
|
Olaf Hering |
02cd93 |
- hvfb_docopy(par,
|
|
Olaf Hering |
02cd93 |
- j * info->fix.line_length +
|
|
Olaf Hering |
02cd93 |
- (x1 * screen_depth / 8),
|
|
Olaf Hering |
02cd93 |
- (x2 - x1) * screen_depth / 8);
|
|
Olaf Hering |
02cd93 |
- }
|
|
Olaf Hering |
02cd93 |
+ if (par->need_docopy)
|
|
Olaf Hering |
02cd93 |
+ for (j = y1; j < y2; j++)
|
|
Olaf Hering |
02cd93 |
+ hvfb_docopy(par,
|
|
Olaf Hering |
02cd93 |
+ j * info->fix.line_length +
|
|
Olaf Hering |
02cd93 |
+ (x1 * screen_depth / 8),
|
|
Olaf Hering |
02cd93 |
+ (x2 - x1) * screen_depth / 8);
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
/* Refresh */
|
|
Olaf Hering |
02cd93 |
if (par->fb_ready && par->update)
|
|
Olaf Hering |
02cd93 |
@@ -801,7 +813,8 @@ static int hvfb_on_panic(struct notifier_block *nb,
|
|
Olaf Hering |
02cd93 |
par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
|
|
Olaf Hering |
02cd93 |
par->synchronous_fb = true;
|
|
Olaf Hering |
02cd93 |
info = par->info;
|
|
Olaf Hering |
02cd93 |
- hvfb_docopy(par, 0, dio_fb_size);
|
|
Olaf Hering |
02cd93 |
+ if (par->need_docopy)
|
|
Olaf Hering |
02cd93 |
+ hvfb_docopy(par, 0, dio_fb_size);
|
|
Olaf Hering |
02cd93 |
synthvid_update(info, 0, 0, INT_MAX, INT_MAX);
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
return NOTIFY_DONE;
|
|
Olaf Hering |
02cd93 |
@@ -940,6 +953,62 @@ static void hvfb_get_option(struct fb_info *info)
|
|
Olaf Hering |
02cd93 |
return;
|
|
Olaf Hering |
02cd93 |
}
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
+/*
|
|
Olaf Hering |
02cd93 |
+ * Allocate enough contiguous physical memory.
|
|
Olaf Hering |
02cd93 |
+ * Return physical address if succeeded or -1 if failed.
|
|
Olaf Hering |
02cd93 |
+ */
|
|
Olaf Hering |
02cd93 |
+static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
|
|
Olaf Hering |
02cd93 |
+ unsigned int request_size)
|
|
Olaf Hering |
02cd93 |
+{
|
|
Olaf Hering |
02cd93 |
+ struct page *page = NULL;
|
|
Olaf Hering |
02cd93 |
+ dma_addr_t dma_handle;
|
|
Olaf Hering |
02cd93 |
+ void *vmem;
|
|
Olaf Hering |
02cd93 |
+ phys_addr_t paddr = 0;
|
|
Olaf Hering |
02cd93 |
+ unsigned int order = get_order(request_size);
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ if (request_size == 0)
|
|
Olaf Hering |
02cd93 |
+ return -1;
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ if (order < MAX_ORDER) {
|
|
Olaf Hering |
02cd93 |
+ /* Call alloc_pages if the size is less than 2^MAX_ORDER */
|
|
Olaf Hering |
02cd93 |
+ page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
|
|
Olaf Hering |
02cd93 |
+ if (!page)
|
|
Olaf Hering |
02cd93 |
+ return -1;
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ paddr = (page_to_pfn(page) << PAGE_SHIFT);
|
|
Olaf Hering |
02cd93 |
+ } else {
|
|
Olaf Hering |
02cd93 |
+ /* Allocate from CMA */
|
|
Olaf Hering |
02cd93 |
+ hdev->device.coherent_dma_mask = DMA_BIT_MASK(64);
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ vmem = dma_alloc_coherent(&hdev->device,
|
|
Olaf Hering |
02cd93 |
+ round_up(request_size, PAGE_SIZE),
|
|
Olaf Hering |
02cd93 |
+ &dma_handle,
|
|
Olaf Hering |
02cd93 |
+ GFP_KERNEL | __GFP_NOWARN);
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ if (!vmem)
|
|
Olaf Hering |
02cd93 |
+ return -1;
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ paddr = virt_to_phys(vmem);
|
|
Olaf Hering |
02cd93 |
+ }
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ return paddr;
|
|
Olaf Hering |
02cd93 |
+}
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+/* Release contiguous physical memory */
|
|
Olaf Hering |
02cd93 |
+static void hvfb_release_phymem(struct hv_device *hdev,
|
|
Olaf Hering |
02cd93 |
+ phys_addr_t paddr, unsigned int size)
|
|
Olaf Hering |
02cd93 |
+{
|
|
Olaf Hering |
02cd93 |
+ unsigned int order = get_order(size);
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ if (order < MAX_ORDER)
|
|
Olaf Hering |
02cd93 |
+ __free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order);
|
|
Olaf Hering |
02cd93 |
+ else
|
|
Olaf Hering |
02cd93 |
+ dma_free_coherent(&hdev->device,
|
|
Olaf Hering |
02cd93 |
+ round_up(size, PAGE_SIZE),
|
|
Olaf Hering |
02cd93 |
+ phys_to_virt(paddr),
|
|
Olaf Hering |
02cd93 |
+ paddr);
|
|
Olaf Hering |
02cd93 |
+}
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
/* Get framebuffer memory from Hyper-V video pci space */
|
|
Olaf Hering |
02cd93 |
static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
|
|
Olaf Hering |
02cd93 |
@@ -949,22 +1018,61 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
|
|
Olaf Hering |
02cd93 |
void __iomem *fb_virt;
|
|
Olaf Hering |
02cd93 |
int gen2vm = efi_enabled(EFI_BOOT);
|
|
Olaf Hering |
02cd93 |
resource_size_t pot_start, pot_end;
|
|
Olaf Hering |
02cd93 |
+ phys_addr_t paddr;
|
|
Olaf Hering |
02cd93 |
int ret;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
- dio_fb_size =
|
|
Olaf Hering |
02cd93 |
- screen_width * screen_height * screen_depth / 8;
|
|
Olaf Hering |
02cd93 |
+ info->apertures = alloc_apertures(1);
|
|
Olaf Hering |
02cd93 |
+ if (!info->apertures)
|
|
Olaf Hering |
02cd93 |
+ return -ENOMEM;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
- if (gen2vm) {
|
|
Olaf Hering |
02cd93 |
- pot_start = 0;
|
|
Olaf Hering |
02cd93 |
- pot_end = -1;
|
|
Olaf Hering |
02cd93 |
- } else {
|
|
Olaf Hering |
02cd93 |
+ if (!gen2vm) {
|
|
Olaf Hering |
02cd93 |
pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
|
|
Olaf Hering |
02cd93 |
- PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
|
|
Olaf Hering |
02cd93 |
+ PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
|
|
Olaf Hering |
02cd93 |
if (!pdev) {
|
|
Olaf Hering |
02cd93 |
pr_err("Unable to find PCI Hyper-V video\n");
|
|
Olaf Hering |
02cd93 |
+ kfree(info->apertures);
|
|
Olaf Hering |
02cd93 |
return -ENODEV;
|
|
Olaf Hering |
02cd93 |
}
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
+ info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
|
|
Olaf Hering |
02cd93 |
+ info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ /*
|
|
Olaf Hering |
02cd93 |
+ * For Gen 1 VM, we can directly use the contiguous memory
|
|
Olaf Hering |
02cd93 |
+ * from VM. If we succeed, deferred IO happens directly
|
|
Olaf Hering |
02cd93 |
+ * on this allocated framebuffer memory, avoiding extra
|
|
Olaf Hering |
02cd93 |
+ * memory copy.
|
|
Olaf Hering |
02cd93 |
+ */
|
|
Olaf Hering |
02cd93 |
+ paddr = hvfb_get_phymem(hdev, screen_fb_size);
|
|
Olaf Hering |
02cd93 |
+ if (paddr != (phys_addr_t) -1) {
|
|
Olaf Hering |
02cd93 |
+ par->mmio_pp = paddr;
|
|
Olaf Hering |
02cd93 |
+ par->mmio_vp = par->dio_vp = __va(paddr);
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ info->fix.smem_start = paddr;
|
|
Olaf Hering |
02cd93 |
+ info->fix.smem_len = screen_fb_size;
|
|
Olaf Hering |
02cd93 |
+ info->screen_base = par->mmio_vp;
|
|
Olaf Hering |
02cd93 |
+ info->screen_size = screen_fb_size;
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ par->need_docopy = false;
|
|
Olaf Hering |
02cd93 |
+ goto getmem_done;
|
|
Olaf Hering |
02cd93 |
+ }
|
|
Olaf Hering |
02cd93 |
+ pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n");
|
|
Olaf Hering |
02cd93 |
+ } else {
|
|
Olaf Hering |
02cd93 |
+ info->apertures->ranges[0].base = screen_info.lfb_base;
|
|
Olaf Hering |
02cd93 |
+ info->apertures->ranges[0].size = screen_info.lfb_size;
|
|
Olaf Hering |
02cd93 |
+ }
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ /*
|
|
Olaf Hering |
02cd93 |
+ * Cannot use the contiguous physical memory.
|
|
Olaf Hering |
02cd93 |
+ * Allocate mmio space for framebuffer.
|
|
Olaf Hering |
02cd93 |
+ */
|
|
Olaf Hering |
02cd93 |
+ dio_fb_size =
|
|
Olaf Hering |
02cd93 |
+ screen_width * screen_height * screen_depth / 8;
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
+ if (gen2vm) {
|
|
Olaf Hering |
02cd93 |
+ pot_start = 0;
|
|
Olaf Hering |
02cd93 |
+ pot_end = -1;
|
|
Olaf Hering |
02cd93 |
+ } else {
|
|
Olaf Hering |
02cd93 |
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
|
|
Olaf Hering |
02cd93 |
pci_resource_len(pdev, 0) < screen_fb_size) {
|
|
Olaf Hering |
02cd93 |
pr_err("Resource not available or (0x%lx < 0x%lx)\n",
|
|
Olaf Hering |
02cd93 |
@@ -993,20 +1101,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
|
|
Olaf Hering |
02cd93 |
if (par->dio_vp == NULL)
|
|
Olaf Hering |
02cd93 |
goto err3;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
- info->apertures = alloc_apertures(1);
|
|
Olaf Hering |
02cd93 |
- if (!info->apertures)
|
|
Olaf Hering |
02cd93 |
- goto err4;
|
|
Olaf Hering |
02cd93 |
-
|
|
Olaf Hering |
02cd93 |
- if (gen2vm) {
|
|
Olaf Hering |
02cd93 |
- info->apertures->ranges[0].base = screen_info.lfb_base;
|
|
Olaf Hering |
02cd93 |
- info->apertures->ranges[0].size = screen_info.lfb_size;
|
|
Olaf Hering |
02cd93 |
- remove_conflicting_framebuffers(info->apertures,
|
|
Olaf Hering |
02cd93 |
- KBUILD_MODNAME, false);
|
|
Olaf Hering |
02cd93 |
- } else {
|
|
Olaf Hering |
02cd93 |
- info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
|
|
Olaf Hering |
02cd93 |
- info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
|
|
Olaf Hering |
02cd93 |
- }
|
|
Olaf Hering |
02cd93 |
-
|
|
Olaf Hering |
02cd93 |
/* Physical address of FB device */
|
|
Olaf Hering |
02cd93 |
par->mmio_pp = par->mem->start;
|
|
Olaf Hering |
02cd93 |
/* Virtual address of FB device */
|
|
Olaf Hering |
02cd93 |
@@ -1017,13 +1111,15 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
|
|
Olaf Hering |
02cd93 |
info->screen_base = par->dio_vp;
|
|
Olaf Hering |
02cd93 |
info->screen_size = dio_fb_size;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
+getmem_done:
|
|
Olaf Hering |
02cd93 |
+ remove_conflicting_framebuffers(info->apertures,
|
|
Olaf Hering |
02cd93 |
+ KBUILD_MODNAME, false);
|
|
Olaf Hering |
02cd93 |
if (!gen2vm)
|
|
Olaf Hering |
02cd93 |
pci_dev_put(pdev);
|
|
Olaf Hering |
02cd93 |
+ kfree(info->apertures);
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
return 0;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
-err4:
|
|
Olaf Hering |
02cd93 |
- vfree(par->dio_vp);
|
|
Olaf Hering |
02cd93 |
err3:
|
|
Olaf Hering |
02cd93 |
iounmap(fb_virt);
|
|
Olaf Hering |
02cd93 |
err2:
|
|
Olaf Hering |
02cd93 |
@@ -1032,18 +1128,25 @@ err2:
|
|
Olaf Hering |
02cd93 |
err1:
|
|
Olaf Hering |
02cd93 |
if (!gen2vm)
|
|
Olaf Hering |
02cd93 |
pci_dev_put(pdev);
|
|
Olaf Hering |
02cd93 |
+ kfree(info->apertures);
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
return -ENOMEM;
|
|
Olaf Hering |
02cd93 |
}
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
/* Release the framebuffer */
|
|
Olaf Hering |
02cd93 |
-static void hvfb_putmem(struct fb_info *info)
|
|
Olaf Hering |
02cd93 |
+static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
|
|
Olaf Hering |
02cd93 |
{
|
|
Olaf Hering |
02cd93 |
struct hvfb_par *par = info->par;
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
- vfree(par->dio_vp);
|
|
Olaf Hering |
02cd93 |
- iounmap(info->screen_base);
|
|
Olaf Hering |
02cd93 |
- vmbus_free_mmio(par->mem->start, screen_fb_size);
|
|
Olaf Hering |
02cd93 |
+ if (par->need_docopy) {
|
|
Olaf Hering |
02cd93 |
+ vfree(par->dio_vp);
|
|
Olaf Hering |
02cd93 |
+ iounmap(info->screen_base);
|
|
Olaf Hering |
02cd93 |
+ vmbus_free_mmio(par->mem->start, screen_fb_size);
|
|
Olaf Hering |
02cd93 |
+ } else {
|
|
Olaf Hering |
02cd93 |
+ hvfb_release_phymem(hdev, info->fix.smem_start,
|
|
Olaf Hering |
02cd93 |
+ screen_fb_size);
|
|
Olaf Hering |
02cd93 |
+ }
|
|
Olaf Hering |
02cd93 |
+
|
|
Olaf Hering |
02cd93 |
par->mem = NULL;
|
|
Olaf Hering |
02cd93 |
}
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
@@ -1062,6 +1165,7 @@ static int hvfb_probe(struct hv_device *hdev,
|
|
Olaf Hering |
02cd93 |
par = info->par;
|
|
Olaf Hering |
02cd93 |
par->info = info;
|
|
Olaf Hering |
02cd93 |
par->fb_ready = false;
|
|
Olaf Hering |
02cd93 |
+ par->need_docopy = true;
|
|
Olaf Hering |
02cd93 |
init_completion(&par->wait);
|
|
Olaf Hering |
02cd93 |
INIT_DELAYED_WORK(&par->dwork, hvfb_update_work);
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
@@ -1147,7 +1251,7 @@ static int hvfb_probe(struct hv_device *hdev,
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
error:
|
|
Olaf Hering |
02cd93 |
fb_deferred_io_cleanup(info);
|
|
Olaf Hering |
02cd93 |
- hvfb_putmem(info);
|
|
Olaf Hering |
02cd93 |
+ hvfb_putmem(hdev, info);
|
|
Olaf Hering |
02cd93 |
error2:
|
|
Olaf Hering |
02cd93 |
vmbus_close(hdev->channel);
|
|
Olaf Hering |
02cd93 |
error1:
|
|
Olaf Hering |
02cd93 |
@@ -1177,7 +1281,7 @@ static int hvfb_remove(struct hv_device *hdev)
|
|
Olaf Hering |
02cd93 |
vmbus_close(hdev->channel);
|
|
Olaf Hering |
02cd93 |
hv_set_drvdata(hdev, NULL);
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
- hvfb_putmem(info);
|
|
Olaf Hering |
02cd93 |
+ hvfb_putmem(hdev, info);
|
|
Olaf Hering |
02cd93 |
framebuffer_release(info);
|
|
Olaf Hering |
02cd93 |
|
|
Olaf Hering |
02cd93 |
return 0;
|