int kvm_share_hyp(void *from, void *to)
{
phys_addr_t start, end, cur;
+ int ret = 0;
u64 pfn;
- int ret;
if (is_kernel_in_hyp_mode())
return 0;
pfn = __phys_to_pfn(cur);
ret = share_pfn_hyp(pfn);
if (ret)
- return ret;
+ break;
}
- return 0;
+ if (!ret)
+ return 0;
+
+ /*
+ * Roll back the pages shared by this call. A failed unshare leaks
+ * the page (it stays shared with the hypervisor and is no longer
+ * reusable for pKVM) but breaks no isolation guarantee, so warn and
+ * continue. Not expected in practice.
+ */
+ for (end = cur, cur = start; cur < end; cur += PAGE_SIZE) {
+ pfn = __phys_to_pfn(cur);
+ WARN_ON(unshare_pfn_hyp(pfn));
+ }
+
+ return ret;
}
void kvm_unshare_hyp(void *from, void *to)