@@ -282,6 +282,8 @@ static uint screen_depth;
282282static uint screen_fb_size ;
283283static uint dio_fb_size ; /* FB size for deferred IO */
284284
285+ static void hvfb_putmem (struct fb_info * info );
286+
285287/* Send message to Hyper-V host */
286288static inline int synthvid_send (struct hv_device * hdev ,
287289 struct synthvid_msg * msg )
@@ -862,6 +864,17 @@ static void hvfb_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width,
862864 hvfb_ondemand_refresh_throttle (par , x , y , width , height );
863865}
864866
867+ /*
868+ * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
869+ * of unregister_framebuffer() or fb_release(). Do any cleanup related to
870+ * framebuffer here.
871+ */
872+ static void hvfb_destroy (struct fb_info * info )
873+ {
874+ hvfb_putmem (info );
875+ framebuffer_release (info );
876+ }
877+
865878/*
866879 * TODO: GEN1 codepaths allocate from system or DMA-able memory. Fix the
867880 * driver to use the _SYSMEM_ or _DMAMEM_ helpers in these cases.
@@ -877,6 +890,7 @@ static const struct fb_ops hvfb_ops = {
877890 .fb_set_par = hvfb_set_par ,
878891 .fb_setcolreg = hvfb_setcolreg ,
879892 .fb_blank = hvfb_blank ,
893+ .fb_destroy = hvfb_destroy ,
880894};
881895
882896/* Get options from kernel paramenter "video=" */
@@ -952,15 +966,15 @@ static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
952966}
953967
954968/* Release contiguous physical memory */
955- static void hvfb_release_phymem (struct hv_device * hdev ,
969+ static void hvfb_release_phymem (struct device * device ,
956970 phys_addr_t paddr , unsigned int size )
957971{
958972 unsigned int order = get_order (size );
959973
960974 if (order <= MAX_PAGE_ORDER )
961975 __free_pages (pfn_to_page (paddr >> PAGE_SHIFT ), order );
962976 else
963- dma_free_coherent (& hdev -> device ,
977+ dma_free_coherent (device ,
964978 round_up (size , PAGE_SIZE ),
965979 phys_to_virt (paddr ),
966980 paddr );
@@ -989,6 +1003,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
9891003
9901004 base = pci_resource_start (pdev , 0 );
9911005 size = pci_resource_len (pdev , 0 );
1006+ aperture_remove_conflicting_devices (base , size , KBUILD_MODNAME );
9921007
9931008 /*
9941009 * For Gen 1 VM, we can directly use the contiguous memory
@@ -1010,11 +1025,21 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
10101025 goto getmem_done ;
10111026 }
10121027 pr_info ("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n" );
1028+ } else {
1029+ aperture_remove_all_conflicting_devices (KBUILD_MODNAME );
10131030 }
10141031
10151032 /*
1016- * Cannot use the contiguous physical memory.
1017- * Allocate mmio space for framebuffer.
1033+ * Cannot use contiguous physical memory, so allocate MMIO space for
1034+ * the framebuffer. At this point in the function, conflicting devices
1035+ * that might have claimed the framebuffer MMIO space based on
1036+ * screen_info.lfb_base must have already been removed so that
1037+ * vmbus_allocate_mmio() does not allocate different MMIO space. If the
1038+ * kdump image were to be loaded using kexec_file_load(), the
1039+ * framebuffer location in the kdump image would be set from
1040+ * screen_info.lfb_base at the time that kdump is enabled. If the
1041+ * framebuffer has moved elsewhere, this could be the wrong location,
1042+ * causing kdump to hang when efifb (for example) loads.
10181043 */
10191044 dio_fb_size =
10201045 screen_width * screen_height * screen_depth / 8 ;
@@ -1051,11 +1076,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
10511076 info -> screen_size = dio_fb_size ;
10521077
10531078getmem_done :
1054- if (base && size )
1055- aperture_remove_conflicting_devices (base , size , KBUILD_MODNAME );
1056- else
1057- aperture_remove_all_conflicting_devices (KBUILD_MODNAME );
1058-
10591079 if (!gen2vm )
10601080 pci_dev_put (pdev );
10611081
@@ -1074,16 +1094,16 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
10741094}
10751095
10761096/* Release the framebuffer */
1077- static void hvfb_putmem (struct hv_device * hdev , struct fb_info * info )
1097+ static void hvfb_putmem (struct fb_info * info )
10781098{
10791099 struct hvfb_par * par = info -> par ;
10801100
10811101 if (par -> need_docopy ) {
10821102 vfree (par -> dio_vp );
1083- iounmap (info -> screen_base );
1103+ iounmap (par -> mmio_vp );
10841104 vmbus_free_mmio (par -> mem -> start , screen_fb_size );
10851105 } else {
1086- hvfb_release_phymem (hdev , info -> fix .smem_start ,
1106+ hvfb_release_phymem (info -> device , info -> fix .smem_start ,
10871107 screen_fb_size );
10881108 }
10891109
@@ -1172,7 +1192,7 @@ static int hvfb_probe(struct hv_device *hdev,
11721192 if (ret )
11731193 goto error ;
11741194
1175- ret = register_framebuffer ( info );
1195+ ret = devm_register_framebuffer ( & hdev -> device , info );
11761196 if (ret ) {
11771197 pr_err ("Unable to register framebuffer\n" );
11781198 goto error ;
@@ -1197,7 +1217,7 @@ static int hvfb_probe(struct hv_device *hdev,
11971217
11981218error :
11991219 fb_deferred_io_cleanup (info );
1200- hvfb_putmem (hdev , info );
1220+ hvfb_putmem (info );
12011221error2 :
12021222 vmbus_close (hdev -> channel );
12031223error1 :
@@ -1220,14 +1240,10 @@ static void hvfb_remove(struct hv_device *hdev)
12201240
12211241 fb_deferred_io_cleanup (info );
12221242
1223- unregister_framebuffer (info );
12241243 cancel_delayed_work_sync (& par -> dwork );
12251244
12261245 vmbus_close (hdev -> channel );
12271246 hv_set_drvdata (hdev , NULL );
1228-
1229- hvfb_putmem (hdev , info );
1230- framebuffer_release (info );
12311247}
12321248
12331249static int hvfb_suspend (struct hv_device * hdev )
0 commit comments