@@ -282,6 +282,8 @@ static uint screen_depth;
282
282
static uint screen_fb_size ;
283
283
static uint dio_fb_size ; /* FB size for deferred IO */
284
284
285
+ static void hvfb_putmem (struct fb_info * info );
286
+
285
287
/* Send message to Hyper-V host */
286
288
static inline int synthvid_send (struct hv_device * hdev ,
287
289
struct synthvid_msg * msg )
@@ -862,6 +864,17 @@ static void hvfb_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width,
862
864
hvfb_ondemand_refresh_throttle (par , x , y , width , height );
863
865
}
864
866
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
+
865
878
/*
866
879
* TODO: GEN1 codepaths allocate from system or DMA-able memory. Fix the
867
880
* driver to use the _SYSMEM_ or _DMAMEM_ helpers in these cases.
@@ -877,6 +890,7 @@ static const struct fb_ops hvfb_ops = {
877
890
.fb_set_par = hvfb_set_par ,
878
891
.fb_setcolreg = hvfb_setcolreg ,
879
892
.fb_blank = hvfb_blank ,
893
+ .fb_destroy = hvfb_destroy ,
880
894
};
881
895
882
896
/* Get options from kernel paramenter "video=" */
@@ -952,15 +966,15 @@ static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
952
966
}
953
967
954
968
/* Release contiguous physical memory */
955
- static void hvfb_release_phymem (struct hv_device * hdev ,
969
+ static void hvfb_release_phymem (struct device * device ,
956
970
phys_addr_t paddr , unsigned int size )
957
971
{
958
972
unsigned int order = get_order (size );
959
973
960
974
if (order <= MAX_PAGE_ORDER )
961
975
__free_pages (pfn_to_page (paddr >> PAGE_SHIFT ), order );
962
976
else
963
- dma_free_coherent (& hdev -> device ,
977
+ dma_free_coherent (device ,
964
978
round_up (size , PAGE_SIZE ),
965
979
phys_to_virt (paddr ),
966
980
paddr );
@@ -989,6 +1003,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
989
1003
990
1004
base = pci_resource_start (pdev , 0 );
991
1005
size = pci_resource_len (pdev , 0 );
1006
+ aperture_remove_conflicting_devices (base , size , KBUILD_MODNAME );
992
1007
993
1008
/*
994
1009
* 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)
1010
1025
goto getmem_done ;
1011
1026
}
1012
1027
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 );
1013
1030
}
1014
1031
1015
1032
/*
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.
1018
1043
*/
1019
1044
dio_fb_size =
1020
1045
screen_width * screen_height * screen_depth / 8 ;
@@ -1051,11 +1076,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
1051
1076
info -> screen_size = dio_fb_size ;
1052
1077
1053
1078
getmem_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
-
1059
1079
if (!gen2vm )
1060
1080
pci_dev_put (pdev );
1061
1081
@@ -1074,16 +1094,16 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
1074
1094
}
1075
1095
1076
1096
/* 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 )
1078
1098
{
1079
1099
struct hvfb_par * par = info -> par ;
1080
1100
1081
1101
if (par -> need_docopy ) {
1082
1102
vfree (par -> dio_vp );
1083
- iounmap (info -> screen_base );
1103
+ iounmap (par -> mmio_vp );
1084
1104
vmbus_free_mmio (par -> mem -> start , screen_fb_size );
1085
1105
} else {
1086
- hvfb_release_phymem (hdev , info -> fix .smem_start ,
1106
+ hvfb_release_phymem (info -> device , info -> fix .smem_start ,
1087
1107
screen_fb_size );
1088
1108
}
1089
1109
@@ -1172,7 +1192,7 @@ static int hvfb_probe(struct hv_device *hdev,
1172
1192
if (ret )
1173
1193
goto error ;
1174
1194
1175
- ret = register_framebuffer ( info );
1195
+ ret = devm_register_framebuffer ( & hdev -> device , info );
1176
1196
if (ret ) {
1177
1197
pr_err ("Unable to register framebuffer\n" );
1178
1198
goto error ;
@@ -1197,7 +1217,7 @@ static int hvfb_probe(struct hv_device *hdev,
1197
1217
1198
1218
error :
1199
1219
fb_deferred_io_cleanup (info );
1200
- hvfb_putmem (hdev , info );
1220
+ hvfb_putmem (info );
1201
1221
error2 :
1202
1222
vmbus_close (hdev -> channel );
1203
1223
error1 :
@@ -1220,14 +1240,10 @@ static void hvfb_remove(struct hv_device *hdev)
1220
1240
1221
1241
fb_deferred_io_cleanup (info );
1222
1242
1223
- unregister_framebuffer (info );
1224
1243
cancel_delayed_work_sync (& par -> dwork );
1225
1244
1226
1245
vmbus_close (hdev -> channel );
1227
1246
hv_set_drvdata (hdev , NULL );
1228
-
1229
- hvfb_putmem (hdev , info );
1230
- framebuffer_release (info );
1231
1247
}
1232
1248
1233
1249
static int hvfb_suspend (struct hv_device * hdev )
0 commit comments