 vhost_vdpa: fix the crash in unmap a large memory · gregkh/linux@8b258a3 · GitHub Skip to content Navigation Menu Toggle navigation Sign in Appearance settings Platform AI CODE CREATION GitHub Copilot Write better code with AI GitHub Spark Build and deploy intelligent apps GitHub Models Manage and compare prompts MCP Registry New Integrate external tools DEVELOPER WORKFLOWS Actions Automate any workflow Codespaces Instant dev environments Issues Plan and track work Code Review Manage code changes APPLICATION SECURITY GitHub Advanced Security Find and fix vulnerabilities Code security Secure your code as you build Secret protection  EXPLORE Why GitHub Documentation Blog Changelog Marketplace View all features Solutions BY COMPANY SIZE Enterprises Small and medium teams Startups Nonprofits BY USE CASE App Modernization DevSecOps DevOps CI/CD View all use cases BY INDUSTRY Healthcare Financial services Manufacturing Government View all industries View all solutions Resources EXPLORE BY TOPIC AI Software Development DevOps Security View all topics EXPLORE BY TYPE Customer stories Events &amp; webinars Ebooks &amp; reports Business insights GitHub Skills SUPPORT &amp; SERVICES Documentation Customer support Community forum Trust center Partners View all resources Open Source COMMUNITY GitHub Sponsors Fund open source developers PROGRAMS Security Lab Maintainer Community Accelerator GitHub Stars Archive Program REPOSITORIES Topics Trending Collections Enterprise ENTERPRISE SOLUTIONS Enterprise platform AI-powered developer platform AVAILABLE ADD-ONS GitHub Advanced Security Enterprise-grade security features Copilot for Business Enterprise-grade AI features Premium Support Enterprise-grade 24/7 support Pricing Search or jump to... Search code, repositories, users, issues, pull requests... --> Search Clear Search syntax tips Provide feedback --> We read every piece of feedback, and take your input very seriously.  Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly --> Name Query To see all available qualifiers, see our documentation . Cancel Create saved search Sign in Sign up Appearance settings Resetting focus You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} gregkh / linux Public Notifications You must be signed in to change notification settings Fork 676 Star 636 Code Actions Security and quality 0 Insights Additional navigation options Code Actions Security and quality Insights Commit 8b258a3 Browse files Browse files Cindy Lu authored and gregkh committed vhost_vdpa: fix the crash in unmap a large memory commit e794070 upstream. While testing in vIOMMU, sometimes Guest will unmap very large memory, which will cause the crash. To fix this, add a new function vhost_vdpa_general_unmap(). This function will only unmap the memory that saved in iotlb. Call Trace: [ 647.820144] ------------[ cut here ]------------ [ 647.820848] kernel BUG at drivers/iommu/intel/iommu.c:1174! [ 647.821486] invalid opcode: 0000 [#1] PREEMPT SMP PTI [ 647.822082] CPU: 10 PID: 1181 Comm: qemu-system-x86 Not tainted 6.0.0-rc1home_lulu_2452_lulu7_vhost+ #62 [ 647.823139] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.15.0-29-g6a62e0cb0dfe-prebuilt.qem4 [ 647.824365] RIP: 0010:domain_unmap+0x48/0x110 [ 647.825424] Code: 48 89 fb 8d 4c f6 1e 39 c1 0f 4f c8 83 e9 0c 83 f9 3f 7f 18 48 89 e8 48 d3 e8 48 85 c0 75 59 [ 647.828064] RSP: 0018:ffffae5340c0bbf0 EFLAGS: 00010202 [ 647.828973] RAX: 0000000000000001 RBX: ffff921793d10540 RCX: 000000000000001b [ 647.830083] RDX: 00000000080000ff RSI: 0000000000000001 RDI: ffff921793d10540 [ 647.831214] RBP: 0000000007fc0100 R08: ffffae5340c0bcd0 R09: 0000000000000003 [ 647.832388] R10: 0000007fc0100000 R11: 0000000000100000 R12: 00000000080000ff [ 647.833668] R13: ffffae5340c0bcd0 R14: ffff921793d10590 R15: 0000008000100000 [ 647.834782] FS: 00007f772ec90640(0000) GS:ffff921ce7a80000(0000) knlGS:0000000000000000 [ 647.836004] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 647.836990] CR2: 00007f02c27a3a20 CR3: 0000000101b0c006 CR4: 0000000000372ee0 [ 647.838107] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 647.839283] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 647.840666] Call Trace: [ 647.841437] &lt;TASK&gt; [ 647.842107] intel_iommu_unmap_pages+0x93/0x140 [ 647.843112] __iommu_unmap+0x91/0x1b0 [ 647.844003] iommu_unmap+0x6a/0x95 [ 647.844885] vhost_vdpa_unmap+0x1de/0x1f0 [vhost_vdpa] [ 647.845985] vhost_vdpa_process_iotlb_msg+0xf0/0x90b [vhost_vdpa] [ 647.847235] ? _raw_spin_unlock+0x15/0x30 [ 647.848181] ? _copy_from_iter+0x8c/0x580 [ 647.849137] vhost_chr_write_iter+0xb3/0x430 [vhost] [ 647.850126] vfs_write+0x1e4/0x3a0 [ 647.850897] ksys_write+0x53/0xd0 [ 647.851688] do_syscall_64+0x3a/0x90 [ 647.852508] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 647.853457] RIP: 0033:0x7f7734ef9f4f [ 647.854408] Code: 89 54 24 18 48 89 74 24 10 89 7c 24 08 e8 29 76 f8 ff 48 8b 54 24 18 48 8b 74 24 10 41 89 c8 [ 647.857217] RSP: 002b:00007f772ec8f040 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 [ 647.858486] RAX: ffffffffffffffda RBX: 00000000fef00000 RCX: 00007f7734ef9f4f [ 647.859713] RDX: 0000000000000048 RSI: 00007f772ec8f090 RDI: 0000000000000010 [ 647.860942] RBP: 00007f772ec8f1a0 R08: 0000000000000000 R09: 0000000000000000 [ 647.862206] R10: 0000000000000001 R11: 0000000000000293 R12: 0000000000000010 [ 647.863446] R13: 0000000000000002 R14: 0000000000000000 R15: ffffffff01100000 [ 647.864692] &lt;/TASK&gt; [ 647.865458] Modules linked in: rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache netfs v] [ 647.874688] ---[ end trace 0000000000000000 ]--- Cc: stable@vger.kernel.org Fixes: 4c8cf31 ("vhost: introduce vDPA-based backend") Signed-off-by: Cindy Lu &lt;lulu@redhat.com&gt; Message-Id: &lt;20221219073331.556140-1-lulu@redhat.com&gt; Signed-off-by: Michael S. Tsirkin &lt;mst@redhat.com&gt; Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt; 1 parent ed2d0e1 commit 8b258a3 Copy full SHA for 8b258a3 1 file changed + 26 - 20 Lines changed: 26 additions &amp; 20 deletions File tree Expand file tree Collapse file tree Open diff view settings Filter options drivers/vhost vdpa.c Expand file tree Collapse file tree Open diff view settings Collapse file ‎ drivers/vhost/vdpa.c ‎ Copy file name to clipboard Expand all lines: drivers/vhost/vdpa.c + 26 - 20 Lines changed: 26 additions &amp; 20 deletions Original file line number Diff line number Diff line change @@ -66,8 +66,8 @@ static DEFINE_IDA(vhost_vdpa_ida); 66 66 static dev_t vhost_vdpa_major ; 67 67 68 68 static void vhost_vdpa_iotlb_unmap ( struct vhost_vdpa * v , 69 - struct vhost_iotlb * iotlb , 70 - u64 start , u64 last ); 69 + struct vhost_iotlb * iotlb , u64 start , 70 + u64 last , u32 asid ); 71 71 72 72 static inline u32 iotlb_to_asid ( struct vhost_iotlb * iotlb ) 73 73 { @@ -139,7 +139,7 @@ static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid) 139 139 return - EINVAL ; 140 140 141 141 hlist_del ( &amp; as -&gt; hash_link ); 142 - vhost_vdpa_iotlb_unmap ( v , &amp; as -&gt; iotlb , 0ULL , 0ULL - 1 ); 142 + vhost_vdpa_iotlb_unmap ( v , &amp; as -&gt; iotlb , 0ULL , 0ULL - 1 , asid ); 143 143 kfree ( as ); 144 144 145 145 return 0 ; @@ -687,10 +687,20 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, 687 687 mutex_unlock ( &amp; d -&gt; mutex ); 688 688 return r ; 689 689 } 690 + static void vhost_vdpa_general_unmap ( struct vhost_vdpa * v , 691 + struct vhost_iotlb_map * map , u32 asid ) 692 + { 693 + struct vdpa_device * vdpa = v -&gt; vdpa ; 694 + const struct vdpa_config_ops * ops = vdpa -&gt; config ; 695 + if ( ops -&gt; dma_map ) { 696 + ops -&gt; dma_unmap ( vdpa , asid , map -&gt; start , map -&gt; size ); 697 + } else if ( ops -&gt; set_map == NULL ) { 698 + iommu_unmap ( v -&gt; domain , map -&gt; start , map -&gt; size ); 699 + } 700 + } 690 701 691 - static void vhost_vdpa_pa_unmap ( struct vhost_vdpa * v , 692 - struct vhost_iotlb * iotlb , 693 - u64 start , u64 last ) 702 + static void vhost_vdpa_pa_unmap ( struct vhost_vdpa * v , struct vhost_iotlb * iotlb , 703 + u64 start , u64 last , u32 asid ) 694 704 { 695 705 struct vhost_dev * dev = &amp; v -&gt; vdev ; 696 706 struct vhost_iotlb_map * map ; @@ -707,13 +717,13 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, 707 717 unpin_user_page ( page ); 708 718 } 709 719 atomic64_sub ( PFN_DOWN ( map -&gt; size ), &amp; dev -&gt; mm -&gt; pinned_vm ); 720 + vhost_vdpa_general_unmap ( v , map , asid ); 710 721 vhost_iotlb_map_free ( iotlb , map ); 711 722 } 712 723 } 713 724 714 - static void vhost_vdpa_va_unmap ( struct vhost_vdpa * v , 715 - struct vhost_iotlb * iotlb , 716 - u64 start , u64 last ) 725 + static void vhost_vdpa_va_unmap ( struct vhost_vdpa * v , struct vhost_iotlb * iotlb , 726 + u64 start , u64 last , u32 asid ) 717 727 { 718 728 struct vhost_iotlb_map * map ; 719 729 struct vdpa_map_file * map_file ; @@ -722,20 +732,21 @@ static void vhost_vdpa_va_unmap(struct vhost_vdpa *v, 722 732 map_file = ( struct vdpa_map_file * ) map -&gt; opaque ; 723 733 fput ( map_file -&gt; file ); 724 734 kfree ( map_file ); 735 + vhost_vdpa_general_unmap ( v , map , asid ); 725 736 vhost_iotlb_map_free ( iotlb , map ); 726 737 } 727 738 } 728 739 729 740 static void vhost_vdpa_iotlb_unmap ( struct vhost_vdpa * v , 730 - struct vhost_iotlb * iotlb , 731 - u64 start , u64 last ) 741 + struct vhost_iotlb * iotlb , u64 start , 742 + u64 last , u32 asid ) 732 743 { 733 744 struct vdpa_device * vdpa = v -&gt; vdpa ; 734 745 735 746 if ( vdpa -&gt; use_va ) 736 - return vhost_vdpa_va_unmap ( v , iotlb , start , last ); 747 + return vhost_vdpa_va_unmap ( v , iotlb , start , last , asid ); 737 748 738 - return vhost_vdpa_pa_unmap ( v , iotlb , start , last ); 749 + return vhost_vdpa_pa_unmap ( v , iotlb , start , last , asid ); 739 750 } 740 751 741 752 static int perm_to_iommu_flags ( u32 perm ) @@ -802,17 +813,12 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v, 802 813 const struct vdpa_config_ops * ops = vdpa -&gt; config ; 803 814 u32 asid = iotlb_to_asid ( iotlb ); 804 815 805 - vhost_vdpa_iotlb_unmap ( v , iotlb , iova , iova + size - 1 ); 816 + vhost_vdpa_iotlb_unmap ( v , iotlb , iova , iova + size - 1 , asid ); 806 817 807 - if ( ops -&gt; dma_map ) { 808 - ops -&gt; dma_unmap ( vdpa , asid , iova , size ); 809 - } else if ( ops -&gt; set_map ) { 818 + if ( ops -&gt; set_map ) { 810 819 if (! v -&gt; in_batch ) 811 820 ops -&gt; set_map ( vdpa , asid , iotlb ); 812 - } else { 813 - iommu_unmap ( v -&gt; domain , iova , size ); 814 821 } 815 - 816 822 /* If we are in the middle of batch processing, delay the free 817 823 * of AS until BATCH_END. 818 824 */ 0 commit comments Comments 0 ( 0 ) Footer &copy; 2026 GitHub,&nbsp;Inc. Footer navigation Terms Privacy Security Status Community Docs Contact Manage cookies Do not share my personal information You can’t perform that action at this time. 