From: Isaku Yamahata <[email protected]>
This patch series is to implement test cases for the KVM gmem error_remove_page
method.
- Update punch hole method to truncate pages
- Add a new ioctl KVM_GUEST_MEMORY_FAILURE to inject memory failure on
offset of gmem
TODO:
- Update TDX KVM to handle it and Add test cases for TDX.
This will be done by its own patch series.
Changes:
v2:
- rebased to [RFC PATCH v12 00/33] KVM: guest_memfd() and per-page attributes
https://lore.kernel.org/all/[email protected]/
- introduce new ioctl to inject memory fault on gmem and drop FIBMAP hack
- Implement test cases
v1:
https://lore.kernel.org/all/[email protected]/
Isaku Yamahata (6):
KVM: gmem: Truncate pages on punch hole
KVM: selftests: Add negative test cases for punch hole for
guest_memfd()
KVM: selftests: Add tests for punch hole on guest_memfd
KVM: gmem: Add ioctl to inject memory failure on guest memfd
KVM: selftests: Add test cases for KVM_GUEST_MEMORY_FAILURE
KVM: guest_memfd: selftest: Add test case for error_remove_page method
include/uapi/linux/kvm.h | 6 +
tools/testing/selftests/kvm/Makefile | 1 +
.../testing/selftests/kvm/guest_memfd_test.c | 80 ++++
.../kvm/x86_64/private_mem_conversions_test.c | 26 +-
.../kvm/x86_64/private_mem_hwpoison_test.c | 367 ++++++++++++++++++
virt/kvm/guest_mem.c | 82 +++-
6 files changed, 554 insertions(+), 8 deletions(-)
create mode 100644 tools/testing/selftests/kvm/x86_64/private_mem_hwpoison_test.c
base-commit: 42dc814987c1feb6410904e58cfd4c36c4146150
prerequisite-patch-id: 3c646922da088ceebe447974a90217f377b76e4a
prerequisite-patch-id: 635c4dca26af8d105a4fd8f603e4a9cf830395c7
prerequisite-patch-id: eede5382aa76c0602a853fc93a1450995c651345
prerequisite-patch-id: 5549aad02248eb5a0c2853058dc7c102044c7a9d
prerequisite-patch-id: ab6557f79edb77246ee1e9955be81a10841e65fd
prerequisite-patch-id: bf75388851ee37a83b37bfa7cb0084f27301f6bc
prerequisite-patch-id: cecffe9a2445f2ea01b9fdb1356b1c87eb6b8fe7
prerequisite-patch-id: e1692d657690f974d836ba3efdd277ea82e675ca
prerequisite-patch-id: 747debe72334ef0cd12bbb42d1acb281eb59cd98
prerequisite-patch-id: 2d1df1bad8af51577ec15a37510ea8bf018b0d4f
prerequisite-patch-id: d05f7429ca893fe0fe3beb460bba1400379cd0d1
prerequisite-patch-id: 9916b6553a61beb9a5435bc0b1fcacf0a87165ea
prerequisite-patch-id: 313219882d617e4d4cb226760d1f071f52b3f882
prerequisite-patch-id: 5412c4037793bc0999377f9732290b9944257b7c
prerequisite-patch-id: b737a534d8da531f6d030be5e864a3097ca97384
prerequisite-patch-id: cafe1f6964532d261b950e1879e091dc8c0b4386
prerequisite-patch-id: 20a5d5b1f853828061ccb07ed08459b9922e5214
prerequisite-patch-id: 756402fa0914a86ac7db59aa54e36a7bca9d0770
prerequisite-patch-id: 0e93d19cb59f3a052a377a56ff0a4399046818aa
prerequisite-patch-id: 8576bf7ec9f786870e72b78299dcab5dd4eb0d23
prerequisite-patch-id: 0693f3aa65226ff9ffa1f70b6f6da2410ebd0588
prerequisite-patch-id: 301dbdf8448175ea609664c890a3694750ecf740
prerequisite-patch-id: 8f67d4366ca5c9875c4ef7f445941e3ad3162c75
prerequisite-patch-id: 2d62d84b4f9db4148af35495ce1b188c6b46f421
prerequisite-patch-id: b4526dee5b5a95da0a13116ae0c73d4e69efa3c6
prerequisite-patch-id: 8a2b4167ea632413ba8f6d39788ddf19eb928ab0
prerequisite-patch-id: 5618d2414a1ef641b4c247b5e28076f67a765b24
prerequisite-patch-id: 4415e2df6492fbb64746e3503deba6e991a0e08b
prerequisite-patch-id: ba50138fe73e9a5f58e19eebaab2c17a2dc231e3
prerequisite-patch-id: 1225df90aeae430a74354bc5ad0ddf508d0707db
prerequisite-patch-id: 4c0e6ab89b9a3ed3a2cb236e942b5842926bf868
prerequisite-patch-id: 59f78d417ca58088e336f8e2a9540d1c95bd2f6c
prerequisite-patch-id: b6a6a8916fe89e7da1fadefb7d311960732e0faf
--
2.25.1
From: Isaku Yamahata <[email protected]>
Although kvm_gmem_punch_hole() keeps all pages in mapping on punching hole,
it's common expectation that pages are truncated. Truncate pages on
punching hole. As page contents can be encrypted, avoid zeroing partial
folio by refusing partial punch hole.
Signed-off-by: Isaku Yamahata <[email protected]>
---
virt/kvm/guest_mem.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/guest_mem.c b/virt/kvm/guest_mem.c
index a819367434e9..01fb4ca861d0 100644
--- a/virt/kvm/guest_mem.c
+++ b/virt/kvm/guest_mem.c
@@ -130,22 +130,32 @@ static void kvm_gmem_invalidate_end(struct kvm_gmem *gmem, pgoff_t start,
static long kvm_gmem_punch_hole(struct inode *inode, loff_t offset, loff_t len)
{
struct list_head *gmem_list = &inode->i_mapping->private_list;
+ struct address_space *mapping = inode->i_mapping;
pgoff_t start = offset >> PAGE_SHIFT;
pgoff_t end = (offset + len) >> PAGE_SHIFT;
struct kvm_gmem *gmem;
+ /*
+ * punch hole may result in zeroing partial area. As pages can be
+ * encrypted, prohibit zeroing partial area.
+ */
+ if (offset & ~PAGE_MASK || len & ~PAGE_MASK)
+ return -EINVAL;
+
/*
* Bindings must stable across invalidation to ensure the start+end
* are balanced.
*/
- filemap_invalidate_lock(inode->i_mapping);
+ filemap_invalidate_lock(mapping);
list_for_each_entry(gmem, gmem_list, entry) {
kvm_gmem_invalidate_begin(gmem, start, end);
kvm_gmem_invalidate_end(gmem, start, end);
}
- filemap_invalidate_unlock(inode->i_mapping);
+ truncate_inode_pages_range(mapping, offset, offset + len - 1);
+
+ filemap_invalidate_unlock(mapping);
return 0;
}
--
2.25.1
On Fri, Sep 22, 2023, Isaku Yamahata wrote:
> On Thu, Sep 21, 2023 at 01:29:59PM -0700,
> Sean Christopherson <[email protected]> wrote:
>
> > On Thu, Sep 21, 2023, [email protected] wrote:
> > > From: Isaku Yamahata <[email protected]>
> > >
> > > This patch series is to implement test cases for the KVM gmem error_remove_page
> > > method.
> > > - Update punch hole method to truncate pages
> > > - Add a new ioctl KVM_GUEST_MEMORY_FAILURE to inject memory failure on
> > > offset of gmem
> >
> > Doh. Please try to communicate what you're working on. I was just about to hit
> > SEND on a series to fix the truncation bug, and to add a similar test. I would
> > have happily punted that in your direction, but I had no idea that you were aware
> > of the bug[*], let alone working on a fix. I could have explicitly stated that
> > I was going to fix the bug, but I thought that it was implied that I needed to
> > clean up my own mess.
>
> Oops sorry. Now I'm considering about machine check injection.
> i.e. somehow trigger kvm_machine_check() and its own test cases.
Unless we can't extend fadvise() for some reason, I think we should pursue
FADV_HWPOISION. The enabling should be downright trivial, e.g. just implement
file_operations.fadvise() for guest_memfd, have it handle FADV_HWPOISON, and pass
everything else to generic_fadvise().
It'll basically be your ioctl() just without a dedicated ioctl().
At the very least, we should run the idea past the fs maintainers.
On 9/22/23 22:32, Sean Christopherson wrote:
> Unless we can't extend fadvise() for some reason, I think we should pursue
> FADV_HWPOISION. The enabling should be downright trivial, e.g. just implement
> file_operations.fadvise() for guest_memfd, have it handle FADV_HWPOISON, and pass
> everything else to generic_fadvise().
>
> It'll basically be your ioctl() just without a dedicated ioctl().
>
> At the very least, we should run the idea past the fs maintainers.
fadvise() is different from madvise() though and not necessarily a great
match. Looking at the list of flags in advise(), something like
FADV_POPULATE_READ, FADV_PAGEOUT or FADV_COLD would make sense, but I
can't really think of any other flag that would be useful in a general
case for fadvise. Everything else would have to be very spcific to
memfd or guest_memfd.
In particular FADV_HWPOISON would not make sense for anything that is
not backend by memory. There are some flags that could be useful on
gmem file descriptors, such as hypothetically {WIPE,KEEP}ONFORK or
SOFT_OFFLINE, but again they're not something that can be applied to
fadvise().
So a ioctl implementation does have some advantages after all. I
suggest that we reuse MADV_* flags in the ioctl arguments, to leave the
door open for future extensions and avoid ioctl proliferation. The
ioctl could be implemented by memfd, too, and perhaps even by /dev/zero.
Paolo
On Thu, 21 Sep 2023 13:14:33 -0700, [email protected] wrote:
> From: Isaku Yamahata <[email protected]>
>
> This patch series is to implement test cases for the KVM gmem error_remove_page
> method.
> - Update punch hole method to truncate pages
> - Add a new ioctl KVM_GUEST_MEMORY_FAILURE to inject memory failure on
> offset of gmem
>
> [...]
Applied the punch hole negative test to kvm-x86 guest_memfd, thanks!
[2/6] KVM: selftests: Add negative test cases for punch hole for guest_memfd()
https://github.com/kvm-x86/linux/commit/e2bbfd5549be
--
https://github.com/kvm-x86/linux/tree/next