diff options
Diffstat (limited to 'arch/powerpc/include')
| -rw-r--r-- | arch/powerpc/include/asm/cputime.h | 12 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/fsl_guts.h (renamed from arch/powerpc/include/asm/immap_86xx.h) | 111 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/fsldma.h | 137 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/highmem.h | 9 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/hydra.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_asm.h | 4 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_book3s.h | 31 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 21 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_para.h | 139 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_ppc.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/pgtable-ppc32.h | 8 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/pgtable-ppc64.h | 2 | 
13 files changed, 261 insertions, 217 deletions
| diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index 8bdc6a9e5773..1cf20bdfbeca 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -124,23 +124,23 @@ static inline u64 cputime64_to_jiffies64(const cputime_t ct)  }  /* - * Convert cputime <-> milliseconds + * Convert cputime <-> microseconds   */  extern u64 __cputime_msec_factor; -static inline unsigned long cputime_to_msecs(const cputime_t ct) +static inline unsigned long cputime_to_usecs(const cputime_t ct)  { -	return mulhdu(ct, __cputime_msec_factor); +	return mulhdu(ct, __cputime_msec_factor) * USEC_PER_MSEC;  } -static inline cputime_t msecs_to_cputime(const unsigned long ms) +static inline cputime_t usecs_to_cputime(const unsigned long us)  {  	cputime_t ct;  	unsigned long sec;  	/* have to be a little careful about overflow */ -	ct = ms % 1000; -	sec = ms / 1000; +	ct = us % 1000000; +	sec = us / 1000000;  	if (ct) {  		ct *= tb_ticks_per_sec;  		do_div(ct, 1000); diff --git a/arch/powerpc/include/asm/immap_86xx.h b/arch/powerpc/include/asm/fsl_guts.h index 0f165e59c326..bebd12463ec9 100644 --- a/arch/powerpc/include/asm/immap_86xx.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -1,5 +1,5 @@  /** - * MPC86xx Internal Memory Map + * Freecale 85xx and 86xx Global Utilties register set   *   * Authors: Jeff Brown   *          Timur Tabi <[email protected]> @@ -10,73 +10,112 @@   * under  the terms of  the GNU General  Public License as published by the   * Free Software Foundation;  either version 2 of the  License, or (at your   * option) any later version. - * - * This header file defines structures for various 86xx SOC devices that are - * used by multiple source files.   */ -#ifndef __ASM_POWERPC_IMMAP_86XX_H__ -#define __ASM_POWERPC_IMMAP_86XX_H__ +#ifndef __ASM_POWERPC_FSL_GUTS_H__ +#define __ASM_POWERPC_FSL_GUTS_H__  #ifdef __KERNEL__ -/* Global Utility Registers */ -struct ccsr_guts { +/* + * These #ifdefs are safe because it's not possible to build a kernel that + * runs on e500 and e600 cores. + */ + +#if !defined(CONFIG_PPC_85xx) && !defined(CONFIG_PPC_86xx) +#error Only 85xx and 86xx SOCs are supported +#endif + +/** + * Global Utility Registers. + * + * Not all registers defined in this structure are available on all chips, so + * you are expected to know whether a given register actually exists on your + * chip before you access it. + * + * Also, some registers are similar on different chips but have slightly + * different names.  In these cases, one name is chosen to avoid extraneous + * #ifdefs. + */ +#ifdef CONFIG_PPC_85xx +struct ccsr_guts_85xx { +#else +struct ccsr_guts_86xx { +#endif  	__be32	porpllsr;	/* 0x.0000 - POR PLL Ratio Status Register */  	__be32	porbmsr;	/* 0x.0004 - POR Boot Mode Status Register */  	__be32	porimpscr;	/* 0x.0008 - POR I/O Impedance Status and Control Register */  	__be32	pordevsr;	/* 0x.000c - POR I/O Device Status Register */  	__be32	pordbgmsr;	/* 0x.0010 - POR Debug Mode Status Register */ -	u8	res1[0x20 - 0x14]; +	__be32	pordevsr2;	/* 0x.0014 - POR device status register 2 */ +	u8	res018[0x20 - 0x18];  	__be32	porcir;		/* 0x.0020 - POR Configuration Information Register */ -	u8	res2[0x30 - 0x24]; +	u8	res024[0x30 - 0x24];  	__be32	gpiocr;		/* 0x.0030 - GPIO Control Register */ -	u8	res3[0x40 - 0x34]; +	u8	res034[0x40 - 0x34];  	__be32	gpoutdr;	/* 0x.0040 - General-Purpose Output Data Register */ -	u8	res4[0x50 - 0x44]; +	u8	res044[0x50 - 0x44];  	__be32	gpindr;		/* 0x.0050 - General-Purpose Input Data Register */ -	u8	res5[0x60 - 0x54]; +	u8	res054[0x60 - 0x54];  	__be32	pmuxcr;		/* 0x.0060 - Alternate Function Signal Multiplex Control */ -	u8	res6[0x70 - 0x64]; +        __be32  pmuxcr2;	/* 0x.0064 - Alternate function signal multiplex control 2 */ +        __be32  dmuxcr;		/* 0x.0068 - DMA Mux Control Register */ +        u8	res06c[0x70 - 0x6c];  	__be32	devdisr;	/* 0x.0070 - Device Disable Control */  	__be32	devdisr2;	/* 0x.0074 - Device Disable Control 2 */ -	u8	res7[0x80 - 0x78]; +	u8	res078[0x7c - 0x78]; +	__be32  pmjcr;		/* 0x.007c - 4 Power Management Jog Control Register */  	__be32	powmgtcsr;	/* 0x.0080 - Power Management Status and Control Register */ -	u8	res8[0x90 - 0x84]; +	__be32  pmrccr;		/* 0x.0084 - Power Management Reset Counter Configuration Register */ +	__be32  pmpdccr;	/* 0x.0088 - Power Management Power Down Counter Configuration Register */ +	__be32  pmcdr;		/* 0x.008c - 4Power management clock disable register */  	__be32	mcpsumr;	/* 0x.0090 - Machine Check Summary Register */  	__be32	rstrscr;	/* 0x.0094 - Reset Request Status and Control Register */ -	u8	res9[0xA0 - 0x98]; +	__be32  ectrstcr;	/* 0x.0098 - Exception reset control register */ +	__be32  autorstsr;	/* 0x.009c - Automatic reset status register */  	__be32	pvr;		/* 0x.00a0 - Processor Version Register */  	__be32	svr;		/* 0x.00a4 - System Version Register */ -	u8	res10[0xB0 - 0xA8]; +	u8	res0a8[0xb0 - 0xa8];  	__be32	rstcr;		/* 0x.00b0 - Reset Control Register */ -	u8	res11[0xC0 - 0xB4]; +	u8	res0b4[0xc0 - 0xb4]; +#ifdef CONFIG_PPC_85xx +	__be32  iovselsr;	/* 0x.00c0 - I/O voltage select status register */ +#else  	__be32	elbcvselcr;	/* 0x.00c0 - eLBC Voltage Select Ctrl Reg */ -	u8	res12[0x800 - 0xC4]; +#endif +	u8	res0c4[0x224 - 0xc4]; +	__be32  iodelay1;	/* 0x.0224 - IO delay control register 1 */ +	__be32  iodelay2;	/* 0x.0228 - IO delay control register 2 */ +	u8	res22c[0x800 - 0x22c];  	__be32	clkdvdr;	/* 0x.0800 - Clock Divide Register */ -	u8	res13[0x900 - 0x804]; +	u8	res804[0x900 - 0x804];  	__be32	ircr;		/* 0x.0900 - Infrared Control Register */ -	u8	res14[0x908 - 0x904]; +	u8	res904[0x908 - 0x904];  	__be32	dmacr;		/* 0x.0908 - DMA Control Register */ -	u8	res15[0x914 - 0x90C]; +	u8	res90c[0x914 - 0x90c];  	__be32	elbccr;		/* 0x.0914 - eLBC Control Register */ -	u8	res16[0xB20 - 0x918]; +	u8	res918[0xb20 - 0x918];  	__be32	ddr1clkdr;	/* 0x.0b20 - DDR1 Clock Disable Register */  	__be32	ddr2clkdr;	/* 0x.0b24 - DDR2 Clock Disable Register */  	__be32	ddrclkdr;	/* 0x.0b28 - DDR Clock Disable Register */ -	u8	res17[0xE00 - 0xB2C]; +	u8	resb2c[0xe00 - 0xb2c];  	__be32	clkocr;		/* 0x.0e00 - Clock Out Select Register */ -	u8	res18[0xE10 - 0xE04]; +	u8	rese04[0xe10 - 0xe04];  	__be32	ddrdllcr;	/* 0x.0e10 - DDR DLL Control Register */ -	u8	res19[0xE20 - 0xE14]; +	u8	rese14[0xe20 - 0xe14];  	__be32	lbcdllcr;	/* 0x.0e20 - LBC DLL Control Register */ -	u8	res20[0xF04 - 0xE24]; +	__be32  cpfor;		/* 0x.0e24 - L2 charge pump fuse override register */ +	u8	rese28[0xf04 - 0xe28];  	__be32	srds1cr0;	/* 0x.0f04 - SerDes1 Control Register 0 */  	__be32	srds1cr1;	/* 0x.0f08 - SerDes1 Control Register 0 */ -	u8	res21[0xF40 - 0xF0C]; -	__be32	srds2cr0;	/* 0x.0f40 - SerDes1 Control Register 0 */ -	__be32	srds2cr1;	/* 0x.0f44 - SerDes1 Control Register 0 */ +	u8	resf0c[0xf2c - 0xf0c]; +	__be32  itcr;		/* 0x.0f2c - Internal transaction control register */ +	u8	resf30[0xf40 - 0xf30]; +	__be32	srds2cr0;	/* 0x.0f40 - SerDes2 Control Register 0 */ +	__be32	srds2cr1;	/* 0x.0f44 - SerDes2 Control Register 0 */  } __attribute__ ((packed)); +#ifdef CONFIG_PPC_86xx +  #define CCSR_GUTS_DMACR_DEV_SSI	0	/* DMA controller/channel set to SSI */  #define CCSR_GUTS_DMACR_DEV_IR	1	/* DMA controller/channel set to IR */ @@ -93,7 +132,7 @@ struct ccsr_guts {   * ch: The channel on the DMA controller (0, 1, 2, or 3)   * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx)   */ -static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts, +static inline void guts_set_dmacr(struct ccsr_guts_86xx __iomem *guts,  	unsigned int co, unsigned int ch, unsigned int device)  {  	unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch)); @@ -129,7 +168,7 @@ static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,   * ch: The channel on the DMA controller (0, 1, 2, or 3)   * value: the new value for the bit (0 or 1)   */ -static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts, +static inline void guts_set_pmuxcr_dma(struct ccsr_guts_86xx __iomem *guts,  	unsigned int co, unsigned int ch, unsigned int value)  {  	if ((ch == 0) || (ch == 3)) { @@ -152,5 +191,7 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,  #define CCSR_GUTS_CLKDVDR_SSICLK_MASK	0x000000FF  #define CCSR_GUTS_CLKDVDR_SSICLK(x) ((x) & CCSR_GUTS_CLKDVDR_SSICLK_MASK) -#endif /* __ASM_POWERPC_IMMAP_86XX_H__ */ -#endif /* __KERNEL__ */ +#endif + +#endif +#endif diff --git a/arch/powerpc/include/asm/fsldma.h b/arch/powerpc/include/asm/fsldma.h deleted file mode 100644 index debc5ed96d6e..000000000000 --- a/arch/powerpc/include/asm/fsldma.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Freescale MPC83XX / MPC85XX DMA Controller - * - * Copyright (c) 2009 Ira W. Snyder <[email protected]> - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#ifndef __ARCH_POWERPC_ASM_FSLDMA_H__ -#define __ARCH_POWERPC_ASM_FSLDMA_H__ - -#include <linux/slab.h> -#include <linux/dmaengine.h> - -/* - * Definitions for the Freescale DMA controller's DMA_SLAVE implemention - * - * The Freescale DMA_SLAVE implementation was designed to handle many-to-many - * transfers. An example usage would be an accelerated copy between two - * scatterlists. Another example use would be an accelerated copy from - * multiple non-contiguous device buffers into a single scatterlist. - * - * A DMA_SLAVE transaction is defined by a struct fsl_dma_slave. This - * structure contains a list of hardware addresses that should be copied - * to/from the scatterlist passed into device_prep_slave_sg(). The structure - * also has some fields to enable hardware-specific features. - */ - -/** - * struct fsl_dma_hw_addr - * @entry: linked list entry - * @address: the hardware address - * @length: length to transfer - * - * Holds a single physical hardware address / length pair for use - * with the DMAEngine DMA_SLAVE API. - */ -struct fsl_dma_hw_addr { -	struct list_head entry; - -	dma_addr_t address; -	size_t length; -}; - -/** - * struct fsl_dma_slave - * @addresses: a linked list of struct fsl_dma_hw_addr structures - * @request_count: value for DMA request count - * @src_loop_size: setup and enable constant source-address DMA transfers - * @dst_loop_size: setup and enable constant destination address DMA transfers - * @external_start: enable externally started DMA transfers - * @external_pause: enable externally paused DMA transfers - * - * Holds a list of address / length pairs for use with the DMAEngine - * DMA_SLAVE API implementation for the Freescale DMA controller. - */ -struct fsl_dma_slave { - -	/* List of hardware address/length pairs */ -	struct list_head addresses; - -	/* Support for extra controller features */ -	unsigned int request_count; -	unsigned int src_loop_size; -	unsigned int dst_loop_size; -	bool external_start; -	bool external_pause; -}; - -/** - * fsl_dma_slave_append - add an address/length pair to a struct fsl_dma_slave - * @slave: the &struct fsl_dma_slave to add to - * @address: the hardware address to add - * @length: the length of bytes to transfer from @address - * - * Add a hardware address/length pair to a struct fsl_dma_slave. Returns 0 on - * success, -ERRNO otherwise. - */ -static inline int fsl_dma_slave_append(struct fsl_dma_slave *slave, -				       dma_addr_t address, size_t length) -{ -	struct fsl_dma_hw_addr *addr; - -	addr = kzalloc(sizeof(*addr), GFP_ATOMIC); -	if (!addr) -		return -ENOMEM; - -	INIT_LIST_HEAD(&addr->entry); -	addr->address = address; -	addr->length = length; - -	list_add_tail(&addr->entry, &slave->addresses); -	return 0; -} - -/** - * fsl_dma_slave_free - free a struct fsl_dma_slave - * @slave: the struct fsl_dma_slave to free - * - * Free a struct fsl_dma_slave and all associated address/length pairs - */ -static inline void fsl_dma_slave_free(struct fsl_dma_slave *slave) -{ -	struct fsl_dma_hw_addr *addr, *tmp; - -	if (slave) { -		list_for_each_entry_safe(addr, tmp, &slave->addresses, entry) { -			list_del(&addr->entry); -			kfree(addr); -		} - -		kfree(slave); -	} -} - -/** - * fsl_dma_slave_alloc - allocate a struct fsl_dma_slave - * @gfp: the flags to pass to kmalloc when allocating this structure - * - * Allocate a struct fsl_dma_slave for use by the DMA_SLAVE API. Returns a new - * struct fsl_dma_slave on success, or NULL on failure. - */ -static inline struct fsl_dma_slave *fsl_dma_slave_alloc(gfp_t gfp) -{ -	struct fsl_dma_slave *slave; - -	slave = kzalloc(sizeof(*slave), gfp); -	if (!slave) -		return NULL; - -	INIT_LIST_HEAD(&slave->addresses); -	return slave; -} - -#endif /* __ARCH_POWERPC_ASM_FSLDMA_H__ */ diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h index d10d64a4be38..dbc264010d0b 100644 --- a/arch/powerpc/include/asm/highmem.h +++ b/arch/powerpc/include/asm/highmem.h @@ -60,9 +60,8 @@ extern pte_t *pkmap_page_table;  extern void *kmap_high(struct page *page);  extern void kunmap_high(struct page *page); -extern void *kmap_atomic_prot(struct page *page, enum km_type type, -			      pgprot_t prot); -extern void kunmap_atomic_notypecheck(void *kvaddr, enum km_type type); +extern void *kmap_atomic_prot(struct page *page, pgprot_t prot); +extern void __kunmap_atomic(void *kvaddr);  static inline void *kmap(struct page *page)  { @@ -80,9 +79,9 @@ static inline void kunmap(struct page *page)  	kunmap_high(page);  } -static inline void *kmap_atomic(struct page *page, enum km_type type) +static inline void *__kmap_atomic(struct page *page)  { -	return kmap_atomic_prot(page, type, kmap_prot); +	return kmap_atomic_prot(page, kmap_prot);  }  static inline struct page *kmap_atomic_to_page(void *ptr) diff --git a/arch/powerpc/include/asm/hydra.h b/arch/powerpc/include/asm/hydra.h index 1ad4eed07fbe..5b0c98bd46ab 100644 --- a/arch/powerpc/include/asm/hydra.h +++ b/arch/powerpc/include/asm/hydra.h @@ -10,7 +10,7 @@   *   *	© Copyright 1995 Apple Computer, Inc. All rights reserved.   * - *  It's available online from http://chrp.apple.com/MacTech.pdf. + *  It's available online from http://www.cpu.lu/~mlan/ftp/MacTech.pdf   *  You can obtain paper copies of this book from computer bookstores or by   *  writing Morgan Kaufmann Publishers, Inc., 340 Pine Street, Sixth Floor, San   *  Francisco, CA 94104. Reference ISBN 1-55860-393-X. diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 6c5547d82bbe..18ea6963ad77 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -86,5 +86,6 @@ struct kvm_guest_debug_arch {  #define KVM_INTERRUPT_SET	-1U  #define KVM_INTERRUPT_UNSET	-2U +#define KVM_INTERRUPT_SET_LEVEL	-3U  #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index c5ea4cda34b3..5b7504674397 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h @@ -58,6 +58,7 @@  #define BOOK3S_INTERRUPT_INST_STORAGE	0x400  #define BOOK3S_INTERRUPT_INST_SEGMENT	0x480  #define BOOK3S_INTERRUPT_EXTERNAL	0x500 +#define BOOK3S_INTERRUPT_EXTERNAL_LEVEL	0x501  #define BOOK3S_INTERRUPT_ALIGNMENT	0x600  #define BOOK3S_INTERRUPT_PROGRAM	0x700  #define BOOK3S_INTERRUPT_FP_UNAVAIL	0x800 @@ -84,7 +85,8 @@  #define BOOK3S_IRQPRIO_EXTERNAL			13  #define BOOK3S_IRQPRIO_DECREMENTER		14  #define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR	15 -#define BOOK3S_IRQPRIO_MAX			16 +#define BOOK3S_IRQPRIO_EXTERNAL_LEVEL		16 +#define BOOK3S_IRQPRIO_MAX			17  #define BOOK3S_HFLAG_DCBZ32			0x1  #define BOOK3S_HFLAG_SLB			0x2 diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 8274a2d43925..d62e703f1214 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -38,15 +38,6 @@ struct kvmppc_slb {  	bool class	: 1;  }; -struct kvmppc_sr { -	u32 raw; -	u32 vsid; -	bool Ks		: 1; -	bool Kp		: 1; -	bool nx		: 1; -	bool valid	: 1; -}; -  struct kvmppc_bat {  	u64 raw;  	u32 bepi; @@ -69,6 +60,13 @@ struct kvmppc_sid_map {  #define SID_MAP_NUM     (1 << SID_MAP_BITS)  #define SID_MAP_MASK    (SID_MAP_NUM - 1) +#ifdef CONFIG_PPC_BOOK3S_64 +#define SID_CONTEXTS	1 +#else +#define SID_CONTEXTS	128 +#define VSID_POOL_SIZE	(SID_CONTEXTS * 16) +#endif +  struct kvmppc_vcpu_book3s {  	struct kvm_vcpu vcpu;  	struct kvmppc_book3s_shadow_vcpu *shadow_vcpu; @@ -79,20 +77,22 @@ struct kvmppc_vcpu_book3s {  		u64 vsid;  	} slb_shadow[64];  	u8 slb_shadow_max; -	struct kvmppc_sr sr[16];  	struct kvmppc_bat ibat[8];  	struct kvmppc_bat dbat[8];  	u64 hid[6];  	u64 gqr[8];  	int slb_nr; -	u32 dsisr;  	u64 sdr1;  	u64 hior;  	u64 msr_mask; -	u64 vsid_first;  	u64 vsid_next; +#ifdef CONFIG_PPC_BOOK3S_32 +	u32 vsid_pool[VSID_POOL_SIZE]; +#else +	u64 vsid_first;  	u64 vsid_max; -	int context_id; +#endif +	int context_id[SID_CONTEXTS];  	ulong prog_flags; /* flags to inject when giving a 700 trap */  }; @@ -131,9 +131,10 @@ extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,  			   bool upper, u32 val);  extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);  extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu); +extern pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn); -extern u32 kvmppc_trampoline_lowmem; -extern u32 kvmppc_trampoline_enter; +extern ulong kvmppc_trampoline_lowmem; +extern ulong kvmppc_trampoline_enter;  extern void kvmppc_rmcall(ulong srr0, ulong srr1);  extern void kvmppc_load_up_fpu(void);  extern void kvmppc_load_up_altivec(void); diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index b0b23c007d6e..bba3b9b72a39 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -25,6 +25,7 @@  #include <linux/interrupt.h>  #include <linux/types.h>  #include <linux/kvm_types.h> +#include <linux/kvm_para.h>  #include <asm/kvm_asm.h>  #define KVM_MAX_VCPUS 1 @@ -41,12 +42,17 @@  #define HPTEG_CACHE_NUM			(1 << 15)  #define HPTEG_HASH_BITS_PTE		13 +#define HPTEG_HASH_BITS_PTE_LONG	12  #define HPTEG_HASH_BITS_VPTE		13  #define HPTEG_HASH_BITS_VPTE_LONG	5  #define HPTEG_HASH_NUM_PTE		(1 << HPTEG_HASH_BITS_PTE) +#define HPTEG_HASH_NUM_PTE_LONG		(1 << HPTEG_HASH_BITS_PTE_LONG)  #define HPTEG_HASH_NUM_VPTE		(1 << HPTEG_HASH_BITS_VPTE)  #define HPTEG_HASH_NUM_VPTE_LONG	(1 << HPTEG_HASH_BITS_VPTE_LONG) +/* Physical Address Mask - allowed range of real mode RAM access */ +#define KVM_PAM			0x0fffffffffffffffULL +  struct kvm;  struct kvm_run;  struct kvm_vcpu; @@ -159,8 +165,10 @@ struct kvmppc_mmu {  struct hpte_cache {  	struct hlist_node list_pte; +	struct hlist_node list_pte_long;  	struct hlist_node list_vpte;  	struct hlist_node list_vpte_long; +	struct rcu_head rcu_head;  	u64 host_va;  	u64 pfn;  	ulong slot; @@ -210,28 +218,20 @@ struct kvm_vcpu_arch {  	u32 cr;  #endif -	ulong msr;  #ifdef CONFIG_PPC_BOOK3S  	ulong shadow_msr;  	ulong hflags;  	ulong guest_owned_ext;  #endif  	u32 mmucr; -	ulong sprg0; -	ulong sprg1; -	ulong sprg2; -	ulong sprg3;  	ulong sprg4;  	ulong sprg5;  	ulong sprg6;  	ulong sprg7; -	ulong srr0; -	ulong srr1;  	ulong csrr0;  	ulong csrr1;  	ulong dsrr0;  	ulong dsrr1; -	ulong dear;  	ulong esr;  	u32 dec;  	u32 decar; @@ -290,12 +290,17 @@ struct kvm_vcpu_arch {  	struct tasklet_struct tasklet;  	u64 dec_jiffies;  	unsigned long pending_exceptions; +	struct kvm_vcpu_arch_shared *shared; +	unsigned long magic_page_pa; /* phys addr to map the magic page to */ +	unsigned long magic_page_ea; /* effect. addr to map the magic page to */  #ifdef CONFIG_PPC_BOOK3S  	struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE]; +	struct hlist_head hpte_hash_pte_long[HPTEG_HASH_NUM_PTE_LONG];  	struct hlist_head hpte_hash_vpte[HPTEG_HASH_NUM_VPTE];  	struct hlist_head hpte_hash_vpte_long[HPTEG_HASH_NUM_VPTE_LONG];  	int hpte_cache_count; +	spinlock_t mmu_lock;  #endif  }; diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index 2d48f6a63d0b..50533f9adf40 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -20,16 +20,153 @@  #ifndef __POWERPC_KVM_PARA_H__  #define __POWERPC_KVM_PARA_H__ +#include <linux/types.h> + +struct kvm_vcpu_arch_shared { +	__u64 scratch1; +	__u64 scratch2; +	__u64 scratch3; +	__u64 critical;		/* Guest may not get interrupts if == r1 */ +	__u64 sprg0; +	__u64 sprg1; +	__u64 sprg2; +	__u64 sprg3; +	__u64 srr0; +	__u64 srr1; +	__u64 dar; +	__u64 msr; +	__u32 dsisr; +	__u32 int_pending;	/* Tells the guest if we have an interrupt */ +	__u32 sr[16]; +}; + +#define KVM_SC_MAGIC_R0		0x4b564d21 /* "KVM!" */ +#define HC_VENDOR_KVM		(42 << 16) +#define HC_EV_SUCCESS		0 +#define HC_EV_UNIMPLEMENTED	12 + +#define KVM_FEATURE_MAGIC_PAGE	1 + +#define KVM_MAGIC_FEAT_SR	(1 << 0) +  #ifdef __KERNEL__ +#ifdef CONFIG_KVM_GUEST + +#include <linux/of.h> + +static inline int kvm_para_available(void) +{ +	struct device_node *hyper_node; + +	hyper_node = of_find_node_by_path("/hypervisor"); +	if (!hyper_node) +		return 0; + +	if (!of_device_is_compatible(hyper_node, "linux,kvm")) +		return 0; + +	return 1; +} + +extern unsigned long kvm_hypercall(unsigned long *in, +				   unsigned long *out, +				   unsigned long nr); + +#else +  static inline int kvm_para_available(void)  {  	return 0;  } +static unsigned long kvm_hypercall(unsigned long *in, +				   unsigned long *out, +				   unsigned long nr) +{ +	return HC_EV_UNIMPLEMENTED; +} + +#endif + +static inline long kvm_hypercall0_1(unsigned int nr, unsigned long *r2) +{ +	unsigned long in[8]; +	unsigned long out[8]; +	unsigned long r; + +	r = kvm_hypercall(in, out, nr | HC_VENDOR_KVM); +	*r2 = out[0]; + +	return r; +} + +static inline long kvm_hypercall0(unsigned int nr) +{ +	unsigned long in[8]; +	unsigned long out[8]; + +	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM); +} + +static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) +{ +	unsigned long in[8]; +	unsigned long out[8]; + +	in[0] = p1; +	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM); +} + +static inline long kvm_hypercall2(unsigned int nr, unsigned long p1, +				  unsigned long p2) +{ +	unsigned long in[8]; +	unsigned long out[8]; + +	in[0] = p1; +	in[1] = p2; +	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM); +} + +static inline long kvm_hypercall3(unsigned int nr, unsigned long p1, +				  unsigned long p2, unsigned long p3) +{ +	unsigned long in[8]; +	unsigned long out[8]; + +	in[0] = p1; +	in[1] = p2; +	in[2] = p3; +	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM); +} + +static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, +				  unsigned long p2, unsigned long p3, +				  unsigned long p4) +{ +	unsigned long in[8]; +	unsigned long out[8]; + +	in[0] = p1; +	in[1] = p2; +	in[2] = p3; +	in[3] = p4; +	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM); +} + +  static inline unsigned int kvm_arch_para_features(void)  { -	return 0; +	unsigned long r; + +	if (!kvm_para_available()) +		return 0; + +	if(kvm_hypercall0_1(KVM_HC_FEATURES, &r)) +		return 0; + +	return r;  }  #endif /* __KERNEL__ */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 18d139ec2d22..ecb3bc74c344 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -107,6 +107,7 @@ extern int kvmppc_booke_init(void);  extern void kvmppc_booke_exit(void);  extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu); +extern int kvmppc_kvm_pv(struct kvm_vcpu *vcpu);  /*   * Cuts out inst bits with ordering according to spec. diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h index a7db96f2b5c3..47edde8c3556 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h @@ -308,12 +308,8 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)  #define pte_offset_kernel(dir, addr)	\  	((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr))  #define pte_offset_map(dir, addr)		\ -	((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE0) + pte_index(addr)) -#define pte_offset_map_nested(dir, addr)	\ -	((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE1) + pte_index(addr)) - -#define pte_unmap(pte)		kunmap_atomic(pte, KM_PTE0) -#define pte_unmap_nested(pte)	kunmap_atomic(pte, KM_PTE1) +	((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr)) +#define pte_unmap(pte)		kunmap_atomic(pte)  /*   * Encode and decode a swap entry. diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index 49865045d56f..2b09cd522d33 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -193,9 +193,7 @@    (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))  #define pte_offset_map(dir,addr)	pte_offset_kernel((dir), (addr)) -#define pte_offset_map_nested(dir,addr)	pte_offset_kernel((dir), (addr))  #define pte_unmap(pte)			do { } while(0) -#define pte_unmap_nested(pte)		do { } while(0)  /* to find an entry in a kernel page-table-directory */  /* This now only contains the vmalloc pages */ |