public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* KVM: MMU: only write protect mappings at pagetable level
@ 2010-12-22 11:01 Marcelo Tosatti
  2010-12-22 11:07 ` Avi Kivity
  2010-12-22 17:48 ` Alex Williamson
  0 siblings, 2 replies; 7+ messages in thread
From: Marcelo Tosatti @ 2010-12-22 11:01 UTC (permalink / raw)
  To: kvm; +Cc: Avi Kivity


If a pagetable contains a writeable large spte, all of its sptes will be
write protected, including non-leaf ones, leading to endless pagefaults.

Do not write protect pages above PT_PAGE_TABLE_LEVEL, as the spte fault
paths assume non-leaf sptes are writable.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index c3853d5..c716ff8 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -3442,6 +3442,9 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
 		if (!test_bit(slot, sp->slot_bitmap))
 			continue;
 
+		if (sp->role.level != PT_PAGE_TABLE_LEVEL)
+			continue;
+
 		pt = sp->spt;
 		for (i = 0; i < PT64_ENT_PER_PAGE; ++i)
 			/* avoid RMW */

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: KVM: MMU: only write protect mappings at pagetable level
  2010-12-22 11:01 KVM: MMU: only write protect mappings at pagetable level Marcelo Tosatti
@ 2010-12-22 11:07 ` Avi Kivity
  2010-12-22 11:12   ` Marcelo Tosatti
  2010-12-22 17:48 ` Alex Williamson
  1 sibling, 1 reply; 7+ messages in thread
From: Avi Kivity @ 2010-12-22 11:07 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm

On 12/22/2010 01:01 PM, Marcelo Tosatti wrote:
> If a pagetable contains a writeable large spte, all of its sptes will be

non-writeable

> write protected, including non-leaf ones, leading to endless pagefaults.
>
> Do not write protect pages above PT_PAGE_TABLE_LEVEL, as the spte fault
> paths assume non-leaf sptes are writable.
>
> Signed-off-by: Marcelo Tosatti<mtosatti@redhat.com>
>
> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> index c3853d5..c716ff8 100644
> --- a/arch/x86/kvm/mmu.c
> +++ b/arch/x86/kvm/mmu.c
> @@ -3442,6 +3442,9 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
>   		if (!test_bit(slot, sp->slot_bitmap))
>   			continue;
>
> +		if (sp->role.level != PT_PAGE_TABLE_LEVEL)
> +			continue;
> +
>   		pt = sp->spt;
>   		for (i = 0; i<  PT64_ENT_PER_PAGE; ++i)
>   			/* avoid RMW */

But what about large leaf sptes?  Don't we want to write protect, or 
perhaps drop them?

I think write-protecting leaf sptes and ignoring nonleaf sptes should work.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: KVM: MMU: only write protect mappings at pagetable level
  2010-12-22 11:07 ` Avi Kivity
@ 2010-12-22 11:12   ` Marcelo Tosatti
  2010-12-22 13:01     ` Avi Kivity
  0 siblings, 1 reply; 7+ messages in thread
From: Marcelo Tosatti @ 2010-12-22 11:12 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm

On Wed, Dec 22, 2010 at 01:07:23PM +0200, Avi Kivity wrote:
> On 12/22/2010 01:01 PM, Marcelo Tosatti wrote:
> >If a pagetable contains a writeable large spte, all of its sptes will be
> 
> non-writeable
> 
> >write protected, including non-leaf ones, leading to endless pagefaults.
> >
> >Do not write protect pages above PT_PAGE_TABLE_LEVEL, as the spte fault
> >paths assume non-leaf sptes are writable.
> >
> >Signed-off-by: Marcelo Tosatti<mtosatti@redhat.com>
> >
> >diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> >index c3853d5..c716ff8 100644
> >--- a/arch/x86/kvm/mmu.c
> >+++ b/arch/x86/kvm/mmu.c
> >@@ -3442,6 +3442,9 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
> >  		if (!test_bit(slot, sp->slot_bitmap))
> >  			continue;
> >
> >+		if (sp->role.level != PT_PAGE_TABLE_LEVEL)
> >+			continue;
> >+
> >  		pt = sp->spt;
> >  		for (i = 0; i<  PT64_ENT_PER_PAGE; ++i)
> >  			/* avoid RMW */
> 
> But what about large leaf sptes?  Don't we want to write protect, or
> perhaps drop them?
> 
> I think write-protecting leaf sptes and ignoring nonleaf sptes should work.

When dirty logging is enabled large sptes are nuked and creation of new
ones is not allowed. So i don't see the need? 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: KVM: MMU: only write protect mappings at pagetable level
  2010-12-22 11:12   ` Marcelo Tosatti
@ 2010-12-22 13:01     ` Avi Kivity
  2010-12-22 13:06       ` Marcelo Tosatti
  0 siblings, 1 reply; 7+ messages in thread
From: Avi Kivity @ 2010-12-22 13:01 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm

On 12/22/2010 01:12 PM, Marcelo Tosatti wrote:
> On Wed, Dec 22, 2010 at 01:07:23PM +0200, Avi Kivity wrote:
> >  On 12/22/2010 01:01 PM, Marcelo Tosatti wrote:
> >  >If a pagetable contains a writeable large spte, all of its sptes will be
> >
> >  non-writeable
> >
> >  >write protected, including non-leaf ones, leading to endless pagefaults.
> >  >
> >  >Do not write protect pages above PT_PAGE_TABLE_LEVEL, as the spte fault
> >  >paths assume non-leaf sptes are writable.
> >  >
> >  >Signed-off-by: Marcelo Tosatti<mtosatti@redhat.com>
> >  >
> >  >diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> >  >index c3853d5..c716ff8 100644
> >  >--- a/arch/x86/kvm/mmu.c
> >  >+++ b/arch/x86/kvm/mmu.c
> >  >@@ -3442,6 +3442,9 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
> >  >   		if (!test_bit(slot, sp->slot_bitmap))
> >  >   			continue;
> >  >
> >  >+		if (sp->role.level != PT_PAGE_TABLE_LEVEL)
> >  >+			continue;
> >  >+
> >  >   		pt = sp->spt;
> >  >   		for (i = 0; i<   PT64_ENT_PER_PAGE; ++i)
> >  >   			/* avoid RMW */
> >
> >  But what about large leaf sptes?  Don't we want to write protect, or
> >  perhaps drop them?
> >
> >  I think write-protecting leaf sptes and ignoring nonleaf sptes should work.
>
> When dirty logging is enabled large sptes are nuked and creation of new
> ones is not allowed. So i don't see the need?

Where does this nuking happen?

All I see is the call to kvm_mmu_slot_remove_write_access().

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: KVM: MMU: only write protect mappings at pagetable level
  2010-12-22 13:01     ` Avi Kivity
@ 2010-12-22 13:06       ` Marcelo Tosatti
  2010-12-22 14:06         ` Avi Kivity
  0 siblings, 1 reply; 7+ messages in thread
From: Marcelo Tosatti @ 2010-12-22 13:06 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm

On Wed, Dec 22, 2010 at 03:01:19PM +0200, Avi Kivity wrote:
> On 12/22/2010 01:12 PM, Marcelo Tosatti wrote:
> >On Wed, Dec 22, 2010 at 01:07:23PM +0200, Avi Kivity wrote:
> >>  On 12/22/2010 01:01 PM, Marcelo Tosatti wrote:
> >>  >If a pagetable contains a writeable large spte, all of its sptes will be
> >>
> >>  non-writeable
> >>
> >>  >write protected, including non-leaf ones, leading to endless pagefaults.
> >>  >
> >>  >Do not write protect pages above PT_PAGE_TABLE_LEVEL, as the spte fault
> >>  >paths assume non-leaf sptes are writable.
> >>  >
> >>  >Signed-off-by: Marcelo Tosatti<mtosatti@redhat.com>
> >>  >
> >>  >diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> >>  >index c3853d5..c716ff8 100644
> >>  >--- a/arch/x86/kvm/mmu.c
> >>  >+++ b/arch/x86/kvm/mmu.c
> >>  >@@ -3442,6 +3442,9 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
> >>  >   		if (!test_bit(slot, sp->slot_bitmap))
> >>  >   			continue;
> >>  >
> >>  >+		if (sp->role.level != PT_PAGE_TABLE_LEVEL)
> >>  >+			continue;
> >>  >+
> >>  >   		pt = sp->spt;
> >>  >   		for (i = 0; i<   PT64_ENT_PER_PAGE; ++i)
> >>  >   			/* avoid RMW */
> >>
> >>  But what about large leaf sptes?  Don't we want to write protect, or
> >>  perhaps drop them?
> >>
> >>  I think write-protecting leaf sptes and ignoring nonleaf sptes should work.
> >
> >When dirty logging is enabled large sptes are nuked and creation of new
> >ones is not allowed. So i don't see the need?
> 
> Where does this nuking happen?
> 
> All I see is the call to kvm_mmu_slot_remove_write_access().

set_memory_region:

                /* destroy any largepage mappings for dirty tracking */
                if (old.npages)
                        flush_shadow = 1;


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: KVM: MMU: only write protect mappings at pagetable level
  2010-12-22 13:06       ` Marcelo Tosatti
@ 2010-12-22 14:06         ` Avi Kivity
  0 siblings, 0 replies; 7+ messages in thread
From: Avi Kivity @ 2010-12-22 14:06 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm

On 12/22/2010 03:06 PM, Marcelo Tosatti wrote:
> On Wed, Dec 22, 2010 at 03:01:19PM +0200, Avi Kivity wrote:
> >  On 12/22/2010 01:12 PM, Marcelo Tosatti wrote:
> >  >On Wed, Dec 22, 2010 at 01:07:23PM +0200, Avi Kivity wrote:
> >  >>   On 12/22/2010 01:01 PM, Marcelo Tosatti wrote:
> >  >>   >If a pagetable contains a writeable large spte, all of its sptes will be
> >  >>
> >  >>   non-writeable
> >  >>
> >  >>   >write protected, including non-leaf ones, leading to endless pagefaults.
> >  >>   >
> >  >>   >Do not write protect pages above PT_PAGE_TABLE_LEVEL, as the spte fault
> >  >>   >paths assume non-leaf sptes are writable.
> >  >>   >
> >  >>   >Signed-off-by: Marcelo Tosatti<mtosatti@redhat.com>
> >  >>   >
> >  >>   >diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> >  >>   >index c3853d5..c716ff8 100644
> >  >>   >--- a/arch/x86/kvm/mmu.c
> >  >>   >+++ b/arch/x86/kvm/mmu.c
> >  >>   >@@ -3442,6 +3442,9 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
> >  >>   >    		if (!test_bit(slot, sp->slot_bitmap))
> >  >>   >    			continue;
> >  >>   >
> >  >>   >+		if (sp->role.level != PT_PAGE_TABLE_LEVEL)
> >  >>   >+			continue;
> >  >>   >+
> >  >>   >    		pt = sp->spt;
> >  >>   >    		for (i = 0; i<    PT64_ENT_PER_PAGE; ++i)
> >  >>   >    			/* avoid RMW */
> >  >>
> >  >>   But what about large leaf sptes?  Don't we want to write protect, or
> >  >>   perhaps drop them?
> >  >>
> >  >>   I think write-protecting leaf sptes and ignoring nonleaf sptes should work.
> >  >
> >  >When dirty logging is enabled large sptes are nuked and creation of new
> >  >ones is not allowed. So i don't see the need?
> >
> >  Where does this nuking happen?
> >
> >  All I see is the call to kvm_mmu_slot_remove_write_access().
>
> set_memory_region:
>
>                  /* destroy any largepage mappings for dirty tracking */
>                  if (old.npages)
>                          flush_shadow = 1;
>

You're right, patch is fine.

We should drop this though, and replace it by an ordinary 
remove_write_access() enhanced to drop large sptes.  Should be done 
independently of the fix, of course.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: KVM: MMU: only write protect mappings at pagetable level
  2010-12-22 11:01 KVM: MMU: only write protect mappings at pagetable level Marcelo Tosatti
  2010-12-22 11:07 ` Avi Kivity
@ 2010-12-22 17:48 ` Alex Williamson
  1 sibling, 0 replies; 7+ messages in thread
From: Alex Williamson @ 2010-12-22 17:48 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm, Avi Kivity

On Wed, 2010-12-22 at 09:01 -0200, Marcelo Tosatti wrote:
> If a pagetable contains a writeable large spte, all of its sptes will be
> write protected, including non-leaf ones, leading to endless pagefaults.
> 
> Do not write protect pages above PT_PAGE_TABLE_LEVEL, as the spte fault
> paths assume non-leaf sptes are writable.
> 
> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
> 
> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> index c3853d5..c716ff8 100644
> --- a/arch/x86/kvm/mmu.c
> +++ b/arch/x86/kvm/mmu.c
> @@ -3442,6 +3442,9 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
>  		if (!test_bit(slot, sp->slot_bitmap))
>  			continue;
>  
> +		if (sp->role.level != PT_PAGE_TABLE_LEVEL)
> +			continue;
> +
>  		pt = sp->spt;
>  		for (i = 0; i < PT64_ENT_PER_PAGE; ++i)
>  			/* avoid RMW */

Works for me.

Tested-by: Alex Williamson <alex.williamson@redhat.com>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-12-22 17:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-22 11:01 KVM: MMU: only write protect mappings at pagetable level Marcelo Tosatti
2010-12-22 11:07 ` Avi Kivity
2010-12-22 11:12   ` Marcelo Tosatti
2010-12-22 13:01     ` Avi Kivity
2010-12-22 13:06       ` Marcelo Tosatti
2010-12-22 14:06         ` Avi Kivity
2010-12-22 17:48 ` Alex Williamson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox