|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 7/7] xen/x86: use PCID feature
On 29/03/18 16:19, Jan Beulich wrote:
>>>> On 27.03.18 at 11:07, <jgross@xxxxxxxx> wrote:
>> --- a/xen/arch/x86/domain_page.c
>> +++ b/xen/arch/x86/domain_page.c
>> @@ -51,7 +51,7 @@ static inline struct vcpu *mapcache_current_vcpu(void)
>> if ( (v = idle_vcpu[smp_processor_id()]) == current )
>> sync_local_execstate();
>> /* We must now be running on the idle page table. */
>> - ASSERT(read_cr3() == __pa(idle_pg_table));
>> + ASSERT((read_cr3() & ~X86_CR3_PCID_MASK) == __pa(idle_pg_table));
>
> This would better use X86_CR3_ADDR_MASK as well.
Right.
>
>> @@ -102,7 +103,21 @@ void write_cr3_cr4(unsigned long cr3, unsigned long cr4)
>> t = pre_flush();
>>
>> if ( read_cr4() & X86_CR4_PGE )
>> + /*
>> + * X86_CR4_PGE set means PCID being inactive.
>> + * We have to purge the TLB via flipping cr4.pge.
>> + */
>> write_cr4(cr4 & ~X86_CR4_PGE);
>> + else if ( cpu_has_invpcid )
>> + /*
>> + * If we are using PCID purge the TLB via INVPCID as loading cr3
>> + * will affect the current PCID only.
>
> s/current/new/ ?
Okay.
>
>> + * If INVPCID is not supported we don't use PCIDs so loading cr3
>> + * will purge the TLB (we are in the "global pages off" branch).
>> + * invpcid_flush_all_nonglobals() seems to be faster than
>> + * invpcid_flush_all().
>> + */
>> + invpcid_flush_all_nonglobals();
>>
>> asm volatile ( "mov %0, %%cr3" : : "r" (cr3) : "memory" );
>
> What about the TLB entries that have been re-created between
> the INVPCID and the write of CR3? It's not obvious to me that
> leaving them around is not going to be a problem subsequently,
> the more that you write cr3 frequently with the no-flush bit set.
The no-flush bit should not make any difference here. It controls only
flushing of TLB-entries with the new PCID.
> Don't you need to do a single context invalidation for the prior
> PCID (if different from the new one)?
Hmm, I don't think so, as the mov to %cr3 is a serializing instruction
acting as a speculation barrier. So the only TLB entries which could
survive would be the ones for the few instruction bytes after the
invpcid instruction until the end of the mov to %cr3. Those are harmless
as they are associated with the hypervisor PCID value, so there is no
risk of any data leak to a guest. Maybe a comment explaining that would
be a good idea.
>
>> @@ -499,7 +500,26 @@ void free_shared_domheap_page(struct page_info *page)
>>
>> void make_cr3(struct vcpu *v, mfn_t mfn)
>> {
>> + struct domain *d = v->domain;
>> +
>> v->arch.cr3 = mfn_x(mfn) << PAGE_SHIFT;
>> + if ( is_pv_domain(d) && d->arch.pv_domain.pcid )
>> + v->arch.cr3 |= get_pcid_bits(v, false);
>> +}
>> +
>> +unsigned long pv_guest_cr4_to_real_cr4(struct vcpu *v)
>
> const
Okay (for the other cases, too).
>
>> +{
>> + struct domain *d = v->domain;
>
> again
>
>> @@ -298,11 +362,21 @@ int pv_domain_initialise(struct domain *d)
>>
>> static void _toggle_guest_pt(struct vcpu *v, bool force_cr3)
>> {
>> + struct domain *d = v->domain;
>
> and one more
>
>> --- a/xen/include/asm-x86/x86-defns.h
>> +++ b/xen/include/asm-x86/x86-defns.h
>> @@ -45,7 +45,9 @@
>> /*
>> * Intel CPU flags in CR3
>> */
>> -#define X86_CR3_NOFLUSH (_AC(1, ULL) << 63)
>> +#define X86_CR3_NOFLUSH (_AC(1, ULL) << 63)
>> +#define X86_CR3_ADDR_MASK (PAGE_MASK & ~X86_CR3_NOFLUSH)
>
> This would better be PAGE_MASK & PADDR_MASK: bits 52...62
> are reserved (the respective figure in chapter 2 of the SDM is not to
> be trusted, the tables in the "4-level paging" section are more likely to
> be correct).
Okay.
Juergen
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |