Message ID | 4A991B64.3050903@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 08/29/2009 03:13 PM, Roel Kluin wrote: > prevent read from desc->shadow_ptes[-1] > > Signed-off-by: Roel Kluin<roel.kluin@gmail.com> > --- > If in rmap_remove() (bottom) we do: > > while (desc) { > for (i = 0; i< RMAP_EXT&& desc->shadow_ptes[i]; ++i) > if (desc->shadow_ptes[i] == spte) { > rmap_desc_remove_entry(rmapp, > desc, i, > prev_desc); > return; > } > prev_desc = desc; > desc = desc->more; > } > > If in the first iteration esc->shadow_ptes[0] == spte, then we > call rmap_desc_remove_entry() with i == 0, and then we read in > the last iteration from desc->shadow_ptes[-1]. > > I found this by code analysis. > > diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c > index 0ef5bb2..e1b2e46 100644 > --- a/arch/x86/kvm/mmu.c > +++ b/arch/x86/kvm/mmu.c > @@ -541,7 +541,7 @@ static void rmap_desc_remove_entry(unsigned long *rmapp, > { > int j; > > - for (j = RMAP_EXT - 1; !desc->shadow_ptes[j]&& j> i; --j) > + for (j = RMAP_EXT - 1; j> i&& !desc->shadow_ptes[j]; --j) > ; > desc->shadow_ptes[i] = desc->shadow_ptes[j]; > desc->shadow_ptes[j] = NULL; > There is never a case when j < 0. The loop finds the highest j that has a non-NULL shadow_pte[j], and that is guaranteed to exist. I think the j > i test is redundant. Not sure though.
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 0ef5bb2..e1b2e46 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -541,7 +541,7 @@ static void rmap_desc_remove_entry(unsigned long *rmapp, { int j; - for (j = RMAP_EXT - 1; !desc->shadow_ptes[j] && j > i; --j) + for (j = RMAP_EXT - 1; j > i && !desc->shadow_ptes[j]; --j) ; desc->shadow_ptes[i] = desc->shadow_ptes[j]; desc->shadow_ptes[j] = NULL;
prevent read from desc->shadow_ptes[-1] Signed-off-by: Roel Kluin <roel.kluin@gmail.com> --- If in rmap_remove() (bottom) we do: while (desc) { for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) if (desc->shadow_ptes[i] == spte) { rmap_desc_remove_entry(rmapp, desc, i, prev_desc); return; } prev_desc = desc; desc = desc->more; } If in the first iteration esc->shadow_ptes[0] == spte, then we call rmap_desc_remove_entry() with i == 0, and then we read in the last iteration from desc->shadow_ptes[-1]. I found this by code analysis. -- 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