@@ -206,6 +206,39 @@ int uv_convert_from_secure_pte(pte_t pte)
206206 return uv_convert_from_secure_folio (pfn_folio (pte_pfn (pte )));
207207}
208208
209+ /**
210+ * should_export_before_import - Determine whether an export is needed
211+ * before an import-like operation
212+ * @uvcb: the Ultravisor control block of the UVC to be performed
213+ * @mm: the mm of the process
214+ *
215+ * Returns whether an export is needed before every import-like operation.
216+ * This is needed for shared pages, which don't trigger a secure storage
217+ * exception when accessed from a different guest.
218+ *
219+ * Although considered as one, the Unpin Page UVC is not an actual import,
220+ * so it is not affected.
221+ *
222+ * No export is needed also when there is only one protected VM, because the
223+ * page cannot belong to the wrong VM in that case (there is no "other VM"
224+ * it can belong to).
225+ *
226+ * Return: true if an export is needed before every import, otherwise false.
227+ */
228+ static bool should_export_before_import (struct uv_cb_header * uvcb , struct mm_struct * mm )
229+ {
230+ /*
231+ * The misc feature indicates, among other things, that importing a
232+ * shared page from a different protected VM will automatically also
233+ * transfer its ownership.
234+ */
235+ if (uv_has_feature (BIT_UV_FEAT_MISC ))
236+ return false;
237+ if (uvcb -> cmd == UVC_CMD_UNPIN_PAGE_SHARED )
238+ return false;
239+ return atomic_read (& mm -> context .protected_count ) > 1 ;
240+ }
241+
209242/*
210243 * Calculate the expected ref_count for a folio that would otherwise have no
211244 * further pins. This was cribbed from similar functions in other places in
@@ -228,7 +261,7 @@ static int expected_folio_refs(struct folio *folio)
228261}
229262
230263/**
231- * make_folio_secure () - make a folio secure
264+ * __make_folio_secure () - make a folio secure
232265 * @folio: the folio to make secure
233266 * @uvcb: the uvcb that describes the UVC to be used
234267 *
@@ -237,20 +270,18 @@ static int expected_folio_refs(struct folio *folio)
237270 *
238271 * Return: 0 on success;
239272 * -EBUSY if the folio is in writeback or has too many references;
240- * -E2BIG if the folio is large;
241273 * -EAGAIN if the UVC needs to be attempted again;
242274 * -ENXIO if the address is not mapped;
243275 * -EINVAL if the UVC failed for other reasons.
244276 *
245277 * Context: The caller must hold exactly one extra reference on the folio
246- * (it's the same logic as split_folio())
278+ * (it's the same logic as split_folio()), and the folio must be
279+ * locked.
247280 */
248- int make_folio_secure (struct folio * folio , struct uv_cb_header * uvcb )
281+ static int __make_folio_secure (struct folio * folio , struct uv_cb_header * uvcb )
249282{
250283 int expected , cc = 0 ;
251284
252- if (folio_test_large (folio ))
253- return - E2BIG ;
254285 if (folio_test_writeback (folio ))
255286 return - EBUSY ;
256287 expected = expected_folio_refs (folio ) + 1 ;
@@ -277,7 +308,98 @@ int make_folio_secure(struct folio *folio, struct uv_cb_header *uvcb)
277308 return - EAGAIN ;
278309 return uvcb -> rc == 0x10a ? - ENXIO : - EINVAL ;
279310}
280- EXPORT_SYMBOL_GPL (make_folio_secure );
311+
312+ static int make_folio_secure (struct mm_struct * mm , struct folio * folio , struct uv_cb_header * uvcb )
313+ {
314+ int rc ;
315+
316+ if (!folio_trylock (folio ))
317+ return - EAGAIN ;
318+ if (should_export_before_import (uvcb , mm ))
319+ uv_convert_from_secure (folio_to_phys (folio ));
320+ rc = __make_folio_secure (folio , uvcb );
321+ folio_unlock (folio );
322+
323+ return rc ;
324+ }
325+
326+ /**
327+ * s390_wiggle_split_folio() - try to drain extra references to a folio and optionally split.
328+ * @mm: the mm containing the folio to work on
329+ * @folio: the folio
330+ * @split: whether to split a large folio
331+ *
332+ * Context: Must be called while holding an extra reference to the folio;
333+ * the mm lock should not be held.
334+ * Return: 0 if the folio was split successfully;
335+ * -EAGAIN if the folio was not split successfully but another attempt
336+ * can be made, or if @split was set to false;
337+ * -EINVAL in case of other errors. See split_folio().
338+ */
339+ static int s390_wiggle_split_folio (struct mm_struct * mm , struct folio * folio , bool split )
340+ {
341+ int rc ;
342+
343+ lockdep_assert_not_held (& mm -> mmap_lock );
344+ folio_wait_writeback (folio );
345+ lru_add_drain_all ();
346+ if (split ) {
347+ folio_lock (folio );
348+ rc = split_folio (folio );
349+ folio_unlock (folio );
350+
351+ if (rc != - EBUSY )
352+ return rc ;
353+ }
354+ return - EAGAIN ;
355+ }
356+
357+ int make_hva_secure (struct mm_struct * mm , unsigned long hva , struct uv_cb_header * uvcb )
358+ {
359+ struct vm_area_struct * vma ;
360+ struct folio_walk fw ;
361+ struct folio * folio ;
362+ int rc ;
363+
364+ mmap_read_lock (mm );
365+ vma = vma_lookup (mm , hva );
366+ if (!vma ) {
367+ mmap_read_unlock (mm );
368+ return - EFAULT ;
369+ }
370+ folio = folio_walk_start (& fw , vma , hva , 0 );
371+ if (!folio ) {
372+ mmap_read_unlock (mm );
373+ return - ENXIO ;
374+ }
375+
376+ folio_get (folio );
377+ /*
378+ * Secure pages cannot be huge and userspace should not combine both.
379+ * In case userspace does it anyway this will result in an -EFAULT for
380+ * the unpack. The guest is thus never reaching secure mode.
381+ * If userspace plays dirty tricks and decides to map huge pages at a
382+ * later point in time, it will receive a segmentation fault or
383+ * KVM_RUN will return -EFAULT.
384+ */
385+ if (folio_test_hugetlb (folio ))
386+ rc = - EFAULT ;
387+ else if (folio_test_large (folio ))
388+ rc = - E2BIG ;
389+ else if (!pte_write (fw .pte ) || (pte_val (fw .pte ) & _PAGE_INVALID ))
390+ rc = - ENXIO ;
391+ else
392+ rc = make_folio_secure (mm , folio , uvcb );
393+ folio_walk_end (& fw , vma );
394+ mmap_read_unlock (mm );
395+
396+ if (rc == - E2BIG || rc == - EBUSY )
397+ rc = s390_wiggle_split_folio (mm , folio , rc == - E2BIG );
398+ folio_put (folio );
399+
400+ return rc ;
401+ }
402+ EXPORT_SYMBOL_GPL (make_hva_secure );
281403
282404/*
283405 * To be called with the folio locked or with an extra reference! This will
0 commit comments