Re: [PATCH v2 3/3] KVM: PPC: Book3S: MMIO emulation support for little endian guests
On Wed, Oct 09, 2013 at 01:46:29AM +0200, Alexander Graf wrote: Am 09.10.2013 um 01:31 schrieb Paul Mackerras pau...@samba.org: True, until we get to POWER8 with its split little-endian support, where instructions and data can have different endianness... How exactly does that work? They added an extra MSR bit called SLE which enables the split-endian mode. It's bit 5 (IBM numbering). For backwards compatibility, the LE bit controls instruction endianness, and data endianness depends on LE ^ SLE, that is, with SLE = 0 things work as before. With SLE=1 and LE=0 you get little-endian data and big-endian instructions, and vice versa with SLE=1 and LE=1. There is also a user accessible mtsle instruction that sets the value of the SLE bit. This enables programs to flip their data endianness back and forth quickly, so it's usable for short instruction sequences, without the need to generate instructions of the opposite endianness. Paul. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] KVM: PPC: Book3S: MMIO emulation support for little endian guests
Am 09.10.2013 um 07:59 schrieb Paul Mackerras pau...@samba.org: On Wed, Oct 09, 2013 at 01:46:29AM +0200, Alexander Graf wrote: Am 09.10.2013 um 01:31 schrieb Paul Mackerras pau...@samba.org: True, until we get to POWER8 with its split little-endian support, where instructions and data can have different endianness... How exactly does that work? They added an extra MSR bit called SLE which enables the split-endian mode. It's bit 5 (IBM numbering). For backwards compatibility, the LE bit controls instruction endianness, and data endianness depends on LE ^ SLE, that is, with SLE = 0 things work as before. With SLE=1 and LE=0 you get little-endian data and big-endian instructions, and vice versa with SLE=1 and LE=1. So ld32 should only honor LE and get_last_inst only looks at SLE and swaps even the vcpu cached version if it's set, no? Alex There is also a user accessible mtsle instruction that sets the value of the SLE bit. This enables programs to flip their data endianness back and forth quickly, so it's usable for short instruction sequences, without the need to generate instructions of the opposite endianness. Paul. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] KVM: PPC: Book3S: MMIO emulation support for little endian guests
On 10/09/2013 10:29 AM, Alexander Graf wrote: Am 09.10.2013 um 07:59 schrieb Paul Mackerras pau...@samba.org: On Wed, Oct 09, 2013 at 01:46:29AM +0200, Alexander Graf wrote: Am 09.10.2013 um 01:31 schrieb Paul Mackerras pau...@samba.org: True, until we get to POWER8 with its split little-endian support, where instructions and data can have different endianness... How exactly does that work? They added an extra MSR bit called SLE which enables the split-endian mode. It's bit 5 (IBM numbering). For backwards compatibility, the LE bit controls instruction endianness, and data endianness depends on LE ^ SLE, that is, with SLE = 0 things work as before. With SLE=1 and LE=0 you get little-endian data and big-endian instructions, and vice versa with SLE=1 and LE=1. So ld32 should only honor LE and get_last_inst only looks at SLE and swaps even the vcpu cached version if it's set, no? Here is the table (PowerISA) illustrating the endian modes for all combinations : SLE LE DataInstruction 0 0 Big Big 0 1 Little Little 1 0 Little Big 1 1 Big Little My understanding is that when reading instructions, we should test MSR[LE] and for data, test MSR[SLE] ^ MSR[LE]. This has to be done in conjunction with the host endian order to determine if we should byte-swap or not, but we can assume the host is big endian for the moment and fix the byte-swapping later. C. There is also a user accessible mtsle instruction that sets the value of the SLE bit. This enables programs to flip their data endianness back and forth quickly, so it's usable for short instruction sequences, without the need to generate instructions of the opposite endianness. Paul. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 3/4] kvm: powerpc: define a linux pte lookup function
-Original Message- From: Wood Scott-B07421 Sent: Wednesday, October 09, 2013 3:07 AM To: Bhushan Bharat-R65777 Cc: ag...@suse.de; Yoder Stuart-B08248; k...@vger.kernel.org; kvm- p...@vger.kernel.org; pau...@samba.org; Bhushan Bharat-R65777 Subject: Re: [PATCH 3/4] kvm: powerpc: define a linux pte lookup function On Tue, 2013-10-08 at 11:33 +0530, Bharat Bhushan wrote: We need to search linux pte to get pte attributes for setting TLB in KVM. This patch defines a linux_pte_lookup() function for same. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/include/asm/pgtable.h | 35 +++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index 7d6eacf..fd26c04 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -223,6 +223,41 @@ extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, #endif pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift); + +static inline pte_t lookup_linux_pte(pgd_t *pgdir, unsigned long hva, +unsigned long *pte_sizep) +{ + pte_t *ptep; + pte_t pte; + unsigned long ps = *pte_sizep; + unsigned int shift; + + ptep = find_linux_pte_or_hugepte(pgdir, hva, shift); + if (!ptep) + return __pte(0); + if (shift) + *pte_sizep = 1ul shift; + else + *pte_sizep = PAGE_SIZE; + + if (ps *pte_sizep) + return __pte(0); + + /* wait until _PAGE_BUSY is clear */ + while (1) { + pte = pte_val(*ptep); + if (unlikely(pte _PAGE_BUSY)) { + cpu_relax(); + continue; + } + } + + /* If pte is not present return None */ + if (unlikely(!(pte _PAGE_PRESENT))) + return __pte(0); + + return pte; +} Can lookup_linux_pte_and_update() call lookup_linux_pte()? What lookup_linux_pte_and_update() does:- - find_linux_pte_or_hugepte() - does size and some other trivial checks - Then atomically update the pte:- = while() = wait till _PAGE_BUSY is clear = atomically update the pte = if not updated then go back to while() above else break While what lookup_linux_pte() does:- - find_linux_pte_or_hugepte() - does size and some other trivial checks - wait till _PAGE_BUSY is clear - return pte I am finding it difficult to call lookup_linux_pte() from lookup_linux_pte_and_update(). Thanks -Bharat -Scott
Re: [PATCH 3/4] kvm: powerpc: define a linux pte lookup function
On Wed, 2013-10-09 at 03:48 -0500, Bhushan Bharat-R65777 wrote: -Original Message- From: Wood Scott-B07421 Sent: Wednesday, October 09, 2013 3:07 AM To: Bhushan Bharat-R65777 Cc: ag...@suse.de; Yoder Stuart-B08248; k...@vger.kernel.org; kvm- p...@vger.kernel.org; pau...@samba.org; Bhushan Bharat-R65777 Subject: Re: [PATCH 3/4] kvm: powerpc: define a linux pte lookup function On Tue, 2013-10-08 at 11:33 +0530, Bharat Bhushan wrote: We need to search linux pte to get pte attributes for setting TLB in KVM. This patch defines a linux_pte_lookup() function for same. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/include/asm/pgtable.h | 35 +++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index 7d6eacf..fd26c04 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -223,6 +223,41 @@ extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, #endif pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift); + +static inline pte_t lookup_linux_pte(pgd_t *pgdir, unsigned long hva, + unsigned long *pte_sizep) +{ + pte_t *ptep; + pte_t pte; + unsigned long ps = *pte_sizep; + unsigned int shift; + + ptep = find_linux_pte_or_hugepte(pgdir, hva, shift); + if (!ptep) + return __pte(0); + if (shift) + *pte_sizep = 1ul shift; + else + *pte_sizep = PAGE_SIZE; + + if (ps *pte_sizep) + return __pte(0); + + /* wait until _PAGE_BUSY is clear */ + while (1) { + pte = pte_val(*ptep); + if (unlikely(pte _PAGE_BUSY)) { + cpu_relax(); + continue; + } + } + + /* If pte is not present return None */ + if (unlikely(!(pte _PAGE_PRESENT))) + return __pte(0); + + return pte; +} Can lookup_linux_pte_and_update() call lookup_linux_pte()? What lookup_linux_pte_and_update() does:- - find_linux_pte_or_hugepte() - does size and some other trivial checks - Then atomically update the pte:- = while() = wait till _PAGE_BUSY is clear = atomically update the pte = if not updated then go back to while() above else break While what lookup_linux_pte() does:- - find_linux_pte_or_hugepte() - does size and some other trivial checks - wait till _PAGE_BUSY is clear - return pte I am finding it difficult to call lookup_linux_pte() from lookup_linux_pte_and_update(). You could factor out a common lookup_linux_ptep(). -Scott -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html