diff mbox

[1/2] KVM: fix cache stale memslot info with correct mmio generation number

Message ID 53F30FCD.3080109@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Xiao Guangrong Aug. 19, 2014, 8:50 a.m. UTC
On 08/19/2014 04:28 PM, Paolo Bonzini wrote:
> Il 19/08/2014 05:50, Xiao Guangrong ha scritto:
>>
>> Note in the step *, my approach detects the invalid generation-number which
>> will invalidate the mmio spte properly .
> 
> You are right, in fact my mail included another part: "Another 
> alternative could be to use the low bit to mark an in-progress change, 
> *and skip the caching if the low bit is set*."

Okay, what confused me it that it seems that the single line patch
is ok to you. :)

Now, do we really need to care the case 2? like David said:
"Sorry I didn't explain myself very well: Since we can get a single wrong
mmio exit no matter what, it has to be handled in userspace. So my point
was, it doesn't really help to fix that one very specific way that it can
happen, because it can just happen in other ways. (E.g. update memslots
occurs after is_noslot_pfn() and before mmio exit)."

What's your idea?

> 
> I think if you always treat the low bit as zero in mmio sptes, you can 
> do that without losing a bit of the generation.

What's you did is avoiding cache a invalid generation number into spte, but
actually if we can figure it out when we check mmio access, it's ok. Like the
updated patch i posted should fix it, that way avoids doubly increase the number.

Okay, if you're interested increasing the number doubly, there is the simpler
one:


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Paolo Bonzini Aug. 19, 2014, 9:03 a.m. UTC | #1
Il 19/08/2014 10:50, Xiao Guangrong ha scritto:
> Okay, what confused me it that it seems that the single line patch
> is ok to you. :)

No, it was late and I was confused. :)

> Now, do we really need to care the case 2? like David said:
> "Sorry I didn't explain myself very well: Since we can get a single wrong
> mmio exit no matter what, it has to be handled in userspace. So my point
> was, it doesn't really help to fix that one very specific way that it can
> happen, because it can just happen in other ways. (E.g. update memslots
> occurs after is_noslot_pfn() and before mmio exit)."
> 
> What's your idea?
> 
> > I think if you always treat the low bit as zero in mmio sptes, you can 
> > do that without losing a bit of the generation.
> 
> What's you did is avoiding cache a invalid generation number into spte, but
> actually if we can figure it out when we check mmio access, it's ok. Like the
> updated patch i posted should fix it, that way avoids doubly increase the number.

Yes.

> Okay, if you're interested increasing the number doubly, there is the simpler
> one:

This wastes a bit in the mmio spte though.  My idea is to increase the
memslots generation twice, but drop the low bit in the mmio spte.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Xiao Guangrong Aug. 20, 2014, 12:29 a.m. UTC | #2
On 08/19/2014 05:03 PM, Paolo Bonzini wrote:
> Il 19/08/2014 10:50, Xiao Guangrong ha scritto:
>> Okay, what confused me it that it seems that the single line patch
>> is ok to you. :)
> 
> No, it was late and I was confused. :)
> 
>> Now, do we really need to care the case 2? like David said:
>> "Sorry I didn't explain myself very well: Since we can get a single wrong
>> mmio exit no matter what, it has to be handled in userspace. So my point
>> was, it doesn't really help to fix that one very specific way that it can
>> happen, because it can just happen in other ways. (E.g. update memslots
>> occurs after is_noslot_pfn() and before mmio exit)."
>>
>> What's your idea?
>>
>>> I think if you always treat the low bit as zero in mmio sptes, you can 
>>> do that without losing a bit of the generation.
>>
>> What's you did is avoiding cache a invalid generation number into spte, but
>> actually if we can figure it out when we check mmio access, it's ok. Like the
>> updated patch i posted should fix it, that way avoids doubly increase the number.
> 
> Yes.
> 
>> Okay, if you're interested increasing the number doubly, there is the simpler
>> one:
> 
> This wastes a bit in the mmio spte though.  My idea is to increase the
> memslots generation twice, but drop the low bit in the mmio spte.

Yeah, really smart idea. :)

Paolo/David, would you mind making a patch for this (+ the comments in David's
patch)?

Please feel free to add my:
Reviewed-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Matlack Aug. 20, 2014, 1:03 a.m. UTC | #3
On Tue, Aug 19, 2014 at 5:29 PM, Xiao Guangrong
<xiaoguangrong@linux.vnet.ibm.com> wrote:
> On 08/19/2014 05:03 PM, Paolo Bonzini wrote:
>> Il 19/08/2014 10:50, Xiao Guangrong ha scritto:
>>> Okay, what confused me it that it seems that the single line patch
>>> is ok to you. :)
>>
>> No, it was late and I was confused. :)
>>
>>> Now, do we really need to care the case 2? like David said:
>>> "Sorry I didn't explain myself very well: Since we can get a single wrong
>>> mmio exit no matter what, it has to be handled in userspace. So my point
>>> was, it doesn't really help to fix that one very specific way that it can
>>> happen, because it can just happen in other ways. (E.g. update memslots
>>> occurs after is_noslot_pfn() and before mmio exit)."
>>>
>>> What's your idea?
>>>
>>>> I think if you always treat the low bit as zero in mmio sptes, you can
>>>> do that without losing a bit of the generation.
>>>
>>> What's you did is avoiding cache a invalid generation number into spte, but
>>> actually if we can figure it out when we check mmio access, it's ok. Like the
>>> updated patch i posted should fix it, that way avoids doubly increase the number.
>>
>> Yes.
>>
>>> Okay, if you're interested increasing the number doubly, there is the simpler
>>> one:
>>
>> This wastes a bit in the mmio spte though.  My idea is to increase the
>> memslots generation twice, but drop the low bit in the mmio spte.
>
> Yeah, really smart idea. :)
>
> Paolo/David, would you mind making a patch for this (+ the comments in David's
> patch)?

Paolo, since it was your idea would you like to write it? I don't mind either
way.

>
> Please feel free to add my:
> Reviewed-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini Aug. 20, 2014, 8:38 a.m. UTC | #4
Il 20/08/2014 03:03, David Matlack ha scritto:
> On Tue, Aug 19, 2014 at 5:29 PM, Xiao Guangrong
> <xiaoguangrong@linux.vnet.ibm.com> wrote:
>> On 08/19/2014 05:03 PM, Paolo Bonzini wrote:
>>> Il 19/08/2014 10:50, Xiao Guangrong ha scritto:
>>>> Okay, what confused me it that it seems that the single line patch
>>>> is ok to you. :)
>>>
>>> No, it was late and I was confused. :)
>>>
>>>> Now, do we really need to care the case 2? like David said:
>>>> "Sorry I didn't explain myself very well: Since we can get a single wrong
>>>> mmio exit no matter what, it has to be handled in userspace. So my point
>>>> was, it doesn't really help to fix that one very specific way that it can
>>>> happen, because it can just happen in other ways. (E.g. update memslots
>>>> occurs after is_noslot_pfn() and before mmio exit)."
>>>>
>>>> What's your idea?
>>>>
>>>>> I think if you always treat the low bit as zero in mmio sptes, you can
>>>>> do that without losing a bit of the generation.
>>>>
>>>> What's you did is avoiding cache a invalid generation number into spte, but
>>>> actually if we can figure it out when we check mmio access, it's ok. Like the
>>>> updated patch i posted should fix it, that way avoids doubly increase the number.
>>>
>>> Yes.
>>>
>>>> Okay, if you're interested increasing the number doubly, there is the simpler
>>>> one:
>>>
>>> This wastes a bit in the mmio spte though.  My idea is to increase the
>>> memslots generation twice, but drop the low bit in the mmio spte.
>>
>> Yeah, really smart idea. :)
>>
>> Paolo/David, would you mind making a patch for this (+ the comments in David's
>> patch)?
> 
> Paolo, since it was your idea would you like to write it? I don't mind either
> way.

Sure, I'll post the patch for review.

Paolo

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 9314678..bf49170 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -236,6 +236,9 @@  static unsigned int get_mmio_spte_generation(u64 spte)

 static unsigned int kvm_current_mmio_generation(struct kvm *kvm)
 {
+       /* The initialized generation number should be even. */
+       BUILD_BUG_ON((MMIO_MAX_GEN - 150) & 0x1);
+
        /*
         * Init kvm generation close to MMIO_MAX_GEN to easily test the
         * code of handling generation number wrap-around.
@@ -292,6 +295,14 @@  static bool check_mmio_spte(struct kvm *kvm, u64 spte)
        kvm_gen = kvm_current_mmio_generation(kvm);
        spte_gen = get_mmio_spte_generation(spte);

+       /*
+        * Aha, we cached a being-updated generation number or
+        * generation number is currnetly being updated, let do the
+        * real check for mmio access.
+        */
+       if ((kvm_gen | spte_gen) & 0x1)
+               return false;
+
        trace_check_mmio_spte(spte, kvm_gen, spte_gen);
        return likely(kvm_gen == spte_gen);
 }
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 33712fb..5c3f7b7 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -725,7 +725,7 @@  static struct kvm_memslots *install_new_memslots(struct kvm *kvm,
        update_memslots(slots, new, kvm->memslots->generation);
        rcu_assign_pointer(kvm->memslots, slots);
        synchronize_srcu_expedited(&kvm->srcu);
-
+       kvm->memslots->generation++;
        kvm_arch_memslots_updated(kvm);

        return old_memslots;