diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index 53b8b7ca0d..6f5aa6da29 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -345,8 +345,10 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(
 static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type,
                            const Service::FileSystem::FileSystemController& fs_controller) {
     const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
+    const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
     if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
-        load_dir == nullptr || load_dir->GetSize() <= 0) {
+        ((load_dir == nullptr || load_dir->GetSize() <= 0) &&
+         (sdmc_load_dir == nullptr || sdmc_load_dir->GetSize() <= 0))) {
         return;
     }
 
@@ -356,7 +358,10 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
     }
 
     const auto& disabled = Settings::values.disabled_addons[title_id];
-    auto patch_dirs = load_dir->GetSubdirectories();
+    std::vector<VirtualDir> patch_dirs = load_dir->GetSubdirectories();
+    if (std::find(disabled.cbegin(), disabled.cend(), "SDMC") == disabled.cend()) {
+        patch_dirs.push_back(sdmc_load_dir);
+    }
     std::sort(patch_dirs.begin(), patch_dirs.end(),
               [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); });
 
@@ -524,6 +529,28 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
         }
     }
 
+    // SDMC mod directory (LayeredFS)
+    const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
+    if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0) {
+        std::string types;
+
+        const auto exefs_dir = FindSubdirectoryCaseless(sdmc_mod_dir, "exefs");
+        if (IsDirValidAndNonEmpty(exefs_dir)) {
+            bool layeredfs = false;
+
+            if (layeredfs)
+                AppendCommaIfNotEmpty(types, "LayeredExeFS");
+        }
+        if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs")))
+            AppendCommaIfNotEmpty(types, "LayeredFS");
+
+        if (!types.empty()) {
+            const auto mod_disabled =
+                std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end();
+            out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", types);
+        }
+    }
+
     // DLC
     const auto dlc_entries =
         content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data);
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp
index cb56d8f2db..f4dba8f163 100644
--- a/src/core/file_sys/sdmc_factory.cpp
+++ b/src/core/file_sys/sdmc_factory.cpp
@@ -27,6 +27,13 @@ ResultVal<VirtualDir> SDMCFactory::Open() const {
     return MakeResult<VirtualDir>(dir);
 }
 
+VirtualDir SDMCFactory::GetSDMCModificationLoadRoot(u64 title_id) const {
+    // LayeredFS doesn't work on updates and title id-less homebrew
+    if (title_id == 0 || (title_id & 0xFFF) == 0x800)
+        return nullptr;
+    return GetOrCreateDirectoryRelative(dir, fmt::format("/atmosphere/contents/{:016X}", title_id));
+}
+
 VirtualDir SDMCFactory::GetSDMCContentDirectory() const {
     return GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents");
 }
diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h
index 2bb92ba936..c57514938f 100644
--- a/src/core/file_sys/sdmc_factory.h
+++ b/src/core/file_sys/sdmc_factory.h
@@ -21,6 +21,7 @@ public:
 
     ResultVal<VirtualDir> Open() const;
 
+    VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const;
     VirtualDir GetSDMCContentDirectory() const;
 
     RegisteredCache* GetSDMCContents() const;
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 3c16fe6c71..9191f19fe8 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -703,6 +703,15 @@ FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id)
     return bis_factory->GetModificationLoadRoot(title_id);
 }
 
+FileSys::VirtualDir FileSystemController::GetSDMCModificationLoadRoot(u64 title_id) const {
+    LOG_TRACE(Service_FS, "Opening SDMC mod load root for tid={:016X}", title_id);
+
+    if (sdmc_factory == nullptr)
+        return nullptr;
+
+    return sdmc_factory->GetSDMCModificationLoadRoot(title_id);
+}
+
 FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const {
     LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id);
 
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index b6b1b92207..d387af3cbe 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -115,6 +115,7 @@ public:
     FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const;
     FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const;
 
+    FileSys::VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const;
     FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const;
     FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const;