* [PATCH v2 00/13] MIPS: Add mips_paravirt
@ 2014-05-28 21:52 Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 01/13] MIPS: OCTEON: Enable use of FPU Andreas Herrmann
` (12 more replies)
0 siblings, 13 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm
Hi,
This is v2 of patches to add support for paravirtualized guest on mips
(mips_paravirt). Some of the patches add basic support to run it on
octeon3.
The core of mips_paravirt is David's work.
I've run it using lkvm on a host with KVM MIPS-VZ support (on
octeon3). I've tested guest kernels built for CPU_MIPS64_R2 and
CPU_MIPS32_R2.
When the guest kernel is built for CPU_CAVIUM_OCTEON it requires an
additional patch to avoid usage of octeon_send_ipi_single in
octeon_flush_icache_all_cores. Latest patch for this is not yet
included as it caused a regression and needs some rework.
To built a mips_paravirt guest kernel it's easiest to start with
mips_paravirt_defconfig, check/modify CPU selection (defconfig has
CPU_MIPS64_R2), and kick off kernel built.
Patches are against linux-next/master as of today (next-20140528).
(To make use of __BITFIELD_FIELD macro.)
Diffstat is
arch/mips/Kbuild.platforms | 1 +
arch/mips/Kconfig | 30 +-
arch/mips/cavium-octeon/Kconfig | 23 +-
arch/mips/configs/mips_paravirt_defconfig | 103 ++++++
arch/mips/include/asm/cpu-features.h | 9 +-
arch/mips/include/asm/cpu-type.h | 1 +
arch/mips/include/asm/kvm_para.h | 91 +++++
.../asm/mach-cavium-octeon/cpu-feature-overrides.h | 1 -
.../asm/mach-paravirt/cpu-feature-overrides.h | 36 ++
arch/mips/include/asm/mach-paravirt/irq.h | 19 +
.../include/asm/mach-paravirt/kernel-entry-init.h | 50 +++
arch/mips/include/asm/mach-paravirt/war.h | 25 ++
arch/mips/include/asm/mipsregs.h | 9 +
arch/mips/include/asm/r4kcache.h | 2 +
arch/mips/include/uapi/asm/kvm_para.h | 6 +-
arch/mips/kernel/Makefile | 2 +-
arch/mips/kernel/branch.c | 6 +-
arch/mips/kernel/cpu-probe.c | 2 +-
arch/mips/kernel/octeon_switch.S | 84 +++--
arch/mips/kernel/r4k_switch.S | 3 +
arch/mips/math-emu/cp1emu.c | 6 +-
arch/mips/mm/c-r4k.c | 48 ++-
arch/mips/mm/tlbex.c | 2 +-
arch/mips/paravirt/Kconfig | 6 +
arch/mips/paravirt/Makefile | 14 +
arch/mips/paravirt/Platform | 9 +
arch/mips/paravirt/paravirt-irq.c | 369 ++++++++++++++++++++
arch/mips/paravirt/paravirt-smp.c | 148 ++++++++
arch/mips/paravirt/serial.c | 40 +++
arch/mips/paravirt/setup.c | 67 ++++
arch/mips/pci/Makefile | 2 +-
arch/mips/pci/pci-virtio-guest.c | 131 +++++++
include/uapi/linux/kvm_para.h | 3 +
33 files changed, 1295 insertions(+), 53 deletions(-)
Changelog:
v2:
- Rebased patches on latest linux-next
- Define hypercalls and HC numbers for MIPS in kvm_para.h header files
- Misc changes to pci-virtio-guest.c:
* Make use of __BITFIELD_FIELD macro
* Calculate IO address for in[lwb] and out[lwb] depending on size
as usually done throughout the kernel.
* I still kept this driver version. Once that "Generic
Configuration Access Mechanism support"
(https://lkml.org/lkml/2014/5/18/54) is mainline I might have to
think about how to make use of that instead.
- Provide minimal defconfig
- Renaming mips_cpunum to get_ebase_cpunum
- Provide _machine_halt function with initial patch of paravirt code
* No _machine_restart so far. I have to look into this separately
from this initial patch set -- I think it requires additionl
kvm-tool changes.
- Fix barriers when booting secondary CPUs
- Replace check for 64-bit kernel by common macro
- Remove R4600_HIT_CACHEOP_WAR_IMPL from r4k_blast_dcache_page_dc128()
- Use switch statement in r4k_blast_dcache_page_setup()]
- Remove mistakenly introduced config options from patch
"MIPS: OCTEON: Move CAVIUM_OCTEON_CVMSEG_SIZE to CPU_CAVIUM_OCTEON"
- Use on_each_cpu unconditionally in irq_core_bus_sync_unlock
- Misc minor changes after review of v1
- Remove call to irq_reserve_irq from irq_init_core as linux-next
contains a patches to remove this function and friends
v1:
- http://marc.info/?i=1400597236-11352-1-git-send-email-andreas.herrmann@caviumnetworks.com
Comments are welcome.
Thanks,
Andreas
PS: 1, or 2 comments from mailing list after 1st submission are still
not addressed. I'll look into this asap but I thought sending out v2
shouldn't be delayed.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 01/13] MIPS: OCTEON: Enable use of FPU
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 02/13] MIPS: Move system level config items from CPU_CAVIUM_OCTEON to CAVIUM_OCTEON_SOC Andreas Herrmann
` (11 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
Some versions of the assembler will not assemble CFC1 for OCTEON, so
override the ISA for these.
Add r4k_fpu.o to handle low level FPU initialization.
Modify octeon_switch.S to save the FPU registers. And include
r4k_switch.S to pick up more FPU support.
Get rid of "#define cpu_has_fpu 0"
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
.../asm/mach-cavium-octeon/cpu-feature-overrides.h | 1 -
arch/mips/kernel/Makefile | 2 +-
arch/mips/kernel/branch.c | 6 +-
arch/mips/kernel/octeon_switch.S | 84 ++++++++++++++------
arch/mips/kernel/r4k_switch.S | 3 +
arch/mips/math-emu/cp1emu.c | 6 +-
6 files changed, 75 insertions(+), 27 deletions(-)
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index 94ed063..cf80228 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -22,7 +22,6 @@
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 0
#define cpu_has_tx39_cache 0
-#define cpu_has_fpu 0
#define cpu_has_counter 1
#define cpu_has_watch 1
#define cpu_has_divec 1
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 8f8b531..e00a1eb 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -41,7 +41,7 @@ obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += r4k_fpu.o octeon_switch.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SMP_UP) += smp-up.o
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 101ab9a..7b2df22 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -562,7 +562,11 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
case cop1_op:
preempt_disable();
if (is_fpu_owner())
- asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+ asm volatile(
+ ".set push\n"
+ "\t.set mips1\n"
+ "\tcfc1\t%0,$31\n"
+ "\t.set pop" : "=r" (fcr31));
else
fcr31 = current->thread.fpu.fcr31;
preempt_enable();
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index 029e002..f654768 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -10,24 +10,12 @@
* Copyright (C) 2000 MIPS Technologies, Inc.
* written by Carsten Langgaard, carstenl@mips.com
*/
-#include <asm/asm.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/asm-offsets.h>
-#include <asm/pgtable-bits.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/thread_info.h>
-
-#include <asm/asmmacro.h>
-
-/*
- * Offset to the current process status flags, the first 32 bytes of the
- * stack are not used.
- */
-#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
+#define USE_ALTERNATE_RESUME_IMPL 1
+ .set push
+ .set arch=mips64r2
+#include "r4k_switch.S"
+ .set pop
/*
* task_struct *resume(task_struct *prev, task_struct *next,
* struct thread_info *next_ti, int usedfpu)
@@ -40,6 +28,61 @@
cpu_save_nonscratch a0
LONG_S ra, THREAD_REG31(a0)
+ /*
+ * check if we need to save FPU registers
+ */
+ PTR_L t3, TASK_THREAD_INFO(a0)
+ LONG_L t0, TI_FLAGS(t3)
+ li t1, _TIF_USEDFPU
+ and t2, t0, t1
+ beqz t2, 1f
+ nor t1, zero, t1
+
+ and t0, t0, t1
+ LONG_S t0, TI_FLAGS(t3)
+
+ /*
+ * clear saved user stack CU1 bit
+ */
+ LONG_L t0, ST_OFF(t3)
+ li t1, ~ST0_CU1
+ and t0, t0, t1
+ LONG_S t0, ST_OFF(t3)
+
+ .set push
+ .set arch=mips64r2
+ fpu_save_double a0 t0 t1 # c0_status passed in t0
+ # clobbers t1
+ .set pop
+1:
+
+ /* check if we need to save COP2 registers */
+ PTR_L t2, TASK_THREAD_INFO(a0)
+ LONG_L t0, ST_OFF(t2)
+ bbit0 t0, 30, 1f
+
+ /* Disable COP2 in the stored process state */
+ li t1, ST0_CU2
+ xor t0, t1
+ LONG_S t0, ST_OFF(t2)
+
+ /* Enable COP2 so we can save it */
+ mfc0 t0, CP0_STATUS
+ or t0, t1
+ mtc0 t0, CP0_STATUS
+
+ /* Save COP2 */
+ daddu a0, THREAD_CP2
+ jal octeon_cop2_save
+ dsubu a0, THREAD_CP2
+
+ /* Disable COP2 now that we are done */
+ mfc0 t0, CP0_STATUS
+ li t1, ST0_CU2
+ xor t0, t1
+ mtc0 t0, CP0_STATUS
+
+1:
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
/* Check if we need to store CVMSEG state */
mfc0 t0, $11,7 /* CvmMemCtl */
@@ -85,12 +128,7 @@
move $28, a2
cpu_restore_nonscratch a1
-#if (_THREAD_SIZE - 32) < 0x8000
- PTR_ADDIU t0, $28, _THREAD_SIZE - 32
-#else
- PTR_LI t0, _THREAD_SIZE - 32
- PTR_ADDU t0, $28
-#endif
+ PTR_ADDU t0, $28, _THREAD_SIZE - 32
set_saved_sp t0, t1, t2
mfc0 t1, CP0_STATUS /* Do we really need this? */
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 547c522..81ca3f7 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -28,6 +28,7 @@
*/
#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
+#ifndef USE_ALTERNATE_RESUME_IMPL
/*
* task_struct *resume(task_struct *prev, task_struct *next,
* struct thread_info *next_ti, s32 fp_save)
@@ -99,6 +100,8 @@
jr ra
END(resume)
+#endif /* USE_ALTERNATE_RESUME_IMPL */
+
/*
* Save a thread's fp context.
*/
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 08e6a74..5afda3c 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -584,7 +584,11 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
if (insn.i_format.rs == bc_op) {
preempt_disable();
if (is_fpu_owner())
- asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+ asm volatile(
+ ".set push\n"
+ "\t.set mips1\n"
+ "\tcfc1\t%0,$31\n"
+ "\t.set pop" : "=r" (fcr31));
else
fcr31 = current->thread.fpu.fcr31;
preempt_enable();
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 02/13] MIPS: Move system level config items from CPU_CAVIUM_OCTEON to CAVIUM_OCTEON_SOC
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 01/13] MIPS: OCTEON: Enable use of FPU Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 03/13] MIPS: OCTEON: Move CAVIUM_OCTEON_CVMSEG_SIZE to CPU_CAVIUM_OCTEON Andreas Herrmann
` (10 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
They are a property of the SoC not the CPU itself.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/Kconfig | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 125edd4..d540945 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -730,6 +730,11 @@ config CAVIUM_OCTEON_SOC
select ZONE_DMA32
select HOLES_IN_ZONE
select ARCH_REQUIRE_GPIOLIB
+ select LIBFDT
+ select USE_OF
+ select ARCH_SPARSEMEM_ENABLE
+ select SYS_SUPPORTS_SMP
+ select NR_CPUS_DEFAULT_16
help
This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon
@@ -1408,16 +1413,11 @@ config CPU_SB1
config CPU_CAVIUM_OCTEON
bool "Cavium Octeon processor"
depends on SYS_HAS_CPU_CAVIUM_OCTEON
- select ARCH_SPARSEMEM_ENABLE
select CPU_HAS_PREFETCH
select CPU_SUPPORTS_64BIT_KERNEL
- select SYS_SUPPORTS_SMP
- select NR_CPUS_DEFAULT_16
select WEAK_ORDERING
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
- select LIBFDT
- select USE_OF
select USB_EHCI_BIG_ENDIAN_MMIO
select MIPS_L1_CACHE_SHIFT_7
help
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 03/13] MIPS: OCTEON: Move CAVIUM_OCTEON_CVMSEG_SIZE to CPU_CAVIUM_OCTEON
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 01/13] MIPS: OCTEON: Enable use of FPU Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 02/13] MIPS: Move system level config items from CPU_CAVIUM_OCTEON to CAVIUM_OCTEON_SOC Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 04/13] MIPS: Don't use RI/XI with 32-bit kernels on 64-bit CPUs Andreas Herrmann
` (9 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
CVMSEG is related to the CPU core not the SoC system. So needs to be
configurable there.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/cavium-octeon/Kconfig | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
index 227705d..6028666 100644
--- a/arch/mips/cavium-octeon/Kconfig
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -10,6 +10,17 @@ config CAVIUM_CN63XXP1
non-CN63XXP1 hardware, so it is recommended to select "n"
unless it is known the workarounds are needed.
+config CAVIUM_OCTEON_CVMSEG_SIZE
+ int "Number of L1 cache lines reserved for CVMSEG memory"
+ range 0 54
+ default 1
+ help
+ CVMSEG LM is a segment that accesses portions of the dcache as a
+ local memory; the larger CVMSEG is, the smaller the cache is.
+ This selects the size of CVMSEG LM, which is in cache blocks. The
+ legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
+ between zero and 6192 bytes).
+
endif # CPU_CAVIUM_OCTEON
if CAVIUM_OCTEON_SOC
@@ -23,17 +34,6 @@ config CAVIUM_OCTEON_2ND_KERNEL
with this option to be run at the same time as one built without this
option.
-config CAVIUM_OCTEON_CVMSEG_SIZE
- int "Number of L1 cache lines reserved for CVMSEG memory"
- range 0 54
- default 1
- help
- CVMSEG LM is a segment that accesses portions of the dcache as a
- local memory; the larger CVMSEG is, the smaller the cache is.
- This selects the size of CVMSEG LM, which is in cache blocks. The
- legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
- between zero and 6192 bytes).
-
config CAVIUM_OCTEON_LOCK_L2
bool "Lock often used kernel code in the L2"
default "y"
@@ -86,7 +86,6 @@ config SWIOTLB
select IOMMU_HELPER
select NEED_SG_DMA_LENGTH
-
config OCTEON_ILM
tristate "Module to measure interrupt latency using Octeon CIU Timer"
help
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 04/13] MIPS: Don't use RI/XI with 32-bit kernels on 64-bit CPUs
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (2 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 03/13] MIPS: OCTEON: Move CAVIUM_OCTEON_CVMSEG_SIZE to CPU_CAVIUM_OCTEON Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 05/13] MIPS: Don't build fast TLB refill handler with 32-bit kernels Andreas Herrmann
` (8 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
The TLB handlers cannot handle this case, so disable it for now.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/include/asm/cpu-features.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index f75dd70..c7d8c99 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -110,9 +110,15 @@
#ifndef cpu_has_smartmips
#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
#endif
+
#ifndef cpu_has_rixi
-#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
+# ifdef CONFIG_64BIT
+# define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
+# else /* CONFIG_32BIT */
+# define cpu_has_rixi ((cpu_data[0].options & MIPS_CPU_RIXI) && !cpu_has_64bits)
+# endif
#endif
+
#ifndef cpu_has_mmips
# ifdef CONFIG_SYS_SUPPORTS_MICROMIPS
# define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS)
@@ -120,6 +126,7 @@
# define cpu_has_mmips 0
# endif
#endif
+
#ifndef cpu_has_vtag_icache
#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
#endif
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 05/13] MIPS: Don't build fast TLB refill handler with 32-bit kernels
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (3 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 04/13] MIPS: Don't use RI/XI with 32-bit kernels on 64-bit CPUs Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 06/13] MIPS: Add minimal support for OCTEON3 to c-r4k.c Andreas Herrmann
` (7 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
The fast handler only supports 64-bit kernels.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/mm/tlbex.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index f99ec587..af91f3e 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -1250,13 +1250,17 @@ static void build_r4000_tlb_refill_handler(void)
unsigned int final_len;
struct mips_huge_tlb_info htlb_info __maybe_unused;
enum vmalloc64_mode vmalloc_mode __maybe_unused;
-
+#ifdef CONFIG_64BIT
+ bool is64bit = true;
+#else
+ bool is64bit = false;
+#endif
memset(tlb_handler, 0, sizeof(tlb_handler));
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
memset(final_handler, 0, sizeof(final_handler));
- if ((scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
+ if (is64bit && (scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
scratch_reg);
vmalloc_mode = refill_scratch;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 06/13] MIPS: Add minimal support for OCTEON3 to c-r4k.c
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (4 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 05/13] MIPS: Don't build fast TLB refill handler with 32-bit kernels Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 07/13] MIPS: Add function get_ebase_cpunum Andreas Herrmann
` (6 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
These are needed to boot a generic mips64r2 kernel on OCTEONIII.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/include/asm/r4kcache.h | 2 ++
arch/mips/mm/c-r4k.c | 48 ++++++++++++++++++++++++++++++++++----
2 files changed, 46 insertions(+), 4 deletions(-)
[andreas.herrmann:
* Remove R4600_HIT_CACHEOP_WAR_IMPL from r4k_blast_dcache_page_dc128()
* Use switch statement in r4k_blast_dcache_page_setup()]
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
index fe8d1b6..0b8bd28 100644
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -523,6 +523,8 @@ __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32,
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, )
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, )
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, )
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, )
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, )
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, )
__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, )
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 5c21282..3eb7270 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -108,18 +108,34 @@ static inline void r4k_blast_dcache_page_dc64(unsigned long addr)
blast_dcache64_page(addr);
}
+static inline void r4k_blast_dcache_page_dc128(unsigned long addr)
+{
+ blast_dcache128_page(addr);
+}
+
static void r4k_blast_dcache_page_setup(void)
{
unsigned long dc_lsize = cpu_dcache_line_size();
- if (dc_lsize == 0)
+ switch (dc_lsize) {
+ case 0:
r4k_blast_dcache_page = (void *)cache_noop;
- else if (dc_lsize == 16)
+ break;
+ case 16:
r4k_blast_dcache_page = blast_dcache16_page;
- else if (dc_lsize == 32)
+ break;
+ case 32:
r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
- else if (dc_lsize == 64)
+ break;
+ case 64:
r4k_blast_dcache_page = r4k_blast_dcache_page_dc64;
+ break;
+ case 128:
+ r4k_blast_dcache_page = r4k_blast_dcache_page_dc128;
+ break;
+ default:
+ break;
+ }
}
#ifndef CONFIG_EVA
@@ -158,6 +174,8 @@ static void r4k_blast_dcache_page_indexed_setup(void)
r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
else if (dc_lsize == 64)
r4k_blast_dcache_page_indexed = blast_dcache64_page_indexed;
+ else if (dc_lsize == 128)
+ r4k_blast_dcache_page_indexed = blast_dcache128_page_indexed;
}
void (* r4k_blast_dcache)(void);
@@ -175,6 +193,8 @@ static void r4k_blast_dcache_setup(void)
r4k_blast_dcache = blast_dcache32;
else if (dc_lsize == 64)
r4k_blast_dcache = blast_dcache64;
+ else if (dc_lsize == 128)
+ r4k_blast_dcache = blast_dcache128;
}
/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */
@@ -264,6 +284,8 @@ static void r4k_blast_icache_page_setup(void)
r4k_blast_icache_page = blast_icache32_page;
else if (ic_lsize == 64)
r4k_blast_icache_page = blast_icache64_page;
+ else if (ic_lsize == 128)
+ r4k_blast_icache_page = blast_icache128_page;
}
#ifndef CONFIG_EVA
@@ -337,6 +359,8 @@ static void r4k_blast_icache_setup(void)
r4k_blast_icache = blast_icache32;
} else if (ic_lsize == 64)
r4k_blast_icache = blast_icache64;
+ else if (ic_lsize == 128)
+ r4k_blast_icache = blast_icache128;
}
static void (* r4k_blast_scache_page)(unsigned long addr);
@@ -1093,6 +1117,21 @@ static void probe_pcache(void)
c->dcache.waybit = 0;
break;
+ case CPU_CAVIUM_OCTEON3:
+ /* For now lie about the number of ways. */
+ c->icache.linesz = 128;
+ c->icache.sets = 16;
+ c->icache.ways = 8;
+ c->icache.flags |= MIPS_CACHE_VTAG;
+ icache_size = c->icache.sets * c->icache.ways * c->icache.linesz;
+
+ c->dcache.linesz = 128;
+ c->dcache.ways = 8;
+ c->dcache.sets = 8;
+ dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz;
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+
default:
if (!(config & MIPS_CONF_M))
panic("Don't know how to probe P-caches on this cpu.");
@@ -1413,6 +1452,7 @@ static void setup_scache(void)
loongson3_sc_init();
return;
+ case CPU_CAVIUM_OCTEON3:
case CPU_XLP:
/* don't need to worry about L2, fully coherent */
return;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 07/13] MIPS: Add function get_ebase_cpunum
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (5 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 06/13] MIPS: Add minimal support for OCTEON3 to c-r4k.c Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 08/13] MIPS: OCTEON: Add OCTEON3 to __get_cpu_type Andreas Herrmann
` (5 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
This returns the CPUNum from the low order Ebase bits.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/include/asm/mipsregs.h | 9 +++++++++
arch/mips/kernel/cpu-probe.c | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
[andreas.herrmann:
* Renamed function from mips_cpunum
* Make use of function in cpu-probe.c]
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index fb2d174..98e9754 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1792,6 +1792,15 @@ __BUILD_SET_C0(brcm_cmt_ctrl)
__BUILD_SET_C0(brcm_config)
__BUILD_SET_C0(brcm_mode)
+/*
+ * Return low 10 bits of ebase.
+ * Note that under KVM (MIPSVZ) this returns vcpu id.
+ */
+static inline unsigned int get_ebase_cpunum(void)
+{
+ return read_c0_ebase() & 0x3ff;
+}
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_MIPSREGS_H */
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index e8638c5..dfc6f62 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -423,7 +423,7 @@ static void decode_configs(struct cpuinfo_mips *c)
#ifndef CONFIG_MIPS_CPS
if (cpu_has_mips_r2) {
- c->core = read_c0_ebase() & 0x3ff;
+ c->core = get_ebase_cpunum();
if (cpu_has_mipsmt)
c->core >>= fls(core_nvpes()) - 1;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 08/13] MIPS: OCTEON: Add OCTEON3 to __get_cpu_type
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (6 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 07/13] MIPS: Add function get_ebase_cpunum Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 09/13] MIPS: Add functions for hypervisor call Andreas Herrmann
` (4 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm
Otherwise __builtin_unreachable might be called.
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/include/asm/cpu-type.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h
index e3308b4..b4e2bd8 100644
--- a/arch/mips/include/asm/cpu-type.h
+++ b/arch/mips/include/asm/cpu-type.h
@@ -163,6 +163,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
+ case CPU_CAVIUM_OCTEON3:
#endif
#if defined(CONFIG_SYS_HAS_CPU_BMIPS32_3300) || \
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 09/13] MIPS: Add functions for hypervisor call
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (7 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 08/13] MIPS: OCTEON: Add OCTEON3 to __get_cpu_type Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-06-03 8:30 ` Ralf Baechle
2014-05-28 21:52 ` [PATCH v2 10/13] MIPS: Add code for new system 'paravirt' Andreas Herrmann
` (3 subsequent siblings)
12 siblings, 1 reply; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
Introduce kvm_hypercall[0-3].
Define three new hypercalls for MIPS: GET_CLOCK_FREQ, EXIT_VM, and
CONSOLE_OUTPUT.
[andreas.herrmann:
* Properly define hypercalls and HC numbers for MIPS
in kvm_para.h header files]
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/include/asm/kvm_para.h | 91 +++++++++++++++++++++++++++++++++
arch/mips/include/uapi/asm/kvm_para.h | 6 ++-
include/uapi/linux/kvm_para.h | 3 ++
3 files changed, 99 insertions(+), 1 deletion(-)
create mode 100644 arch/mips/include/asm/kvm_para.h
diff --git a/arch/mips/include/asm/kvm_para.h b/arch/mips/include/asm/kvm_para.h
new file mode 100644
index 0000000..e559812
--- /dev/null
+++ b/arch/mips/include/asm/kvm_para.h
@@ -0,0 +1,91 @@
+#ifndef _ASM_MIPS_KVM_PARA_H
+#define _ASM_MIPS_KVM_PARA_H
+
+#include <uapi/asm/kvm_para.h>
+
+#define KVM_HYPERCALL ".word 0x42000028"
+
+/*
+ * Hypercalls for KVM.
+ *
+ * Hypercall number is passed in v0.
+ * Return value will be placed in v0.
+ * Up to 3 arguments are passed in a0, a1, and a2.
+ */
+static inline unsigned long kvm_hypercall0(unsigned long num)
+{
+ register unsigned long n asm("v0");
+ register unsigned long r asm("v0");
+
+ n = num;
+ __asm__ __volatile__(
+ KVM_HYPERCALL
+ : "=r" (r) : "r" (n) : "memory"
+ );
+
+ return r;
+}
+
+static inline unsigned long kvm_hypercall1(unsigned long num,
+ unsigned long arg0)
+{
+ register unsigned long n asm("v0");
+ register unsigned long r asm("v0");
+ register unsigned long a0 asm("a0");
+
+ n = num;
+ a0 = arg0;
+ __asm__ __volatile__(
+ KVM_HYPERCALL
+ : "=r" (r) : "r" (n), "r" (a0) : "memory"
+ );
+
+ return r;
+}
+
+static inline unsigned long kvm_hypercall2(unsigned long num,
+ unsigned long arg0, unsigned long arg1)
+{
+ register unsigned long n asm("v0");
+ register unsigned long r asm("v0");
+ register unsigned long a0 asm("a0");
+ register unsigned long a1 asm("a1");
+
+ n = num;
+ a0 = arg0;
+ a1 = arg1;
+ __asm__ __volatile__(
+ KVM_HYPERCALL
+ : "=r" (r) : "r" (n), "r" (a0), "r" (a1) : "memory"
+ );
+
+ return r;
+}
+
+static inline unsigned long kvm_hypercall3(unsigned long num,
+ unsigned long arg0, unsigned long arg1, unsigned long arg2)
+{
+ register unsigned long n asm("v0");
+ register unsigned long r asm("v0");
+ register unsigned long a0 asm("a0");
+ register unsigned long a1 asm("a1");
+ register unsigned long a2 asm("a2");
+
+ n = num;
+ a0 = arg0;
+ a1 = arg1;
+ a2 = arg2;
+ __asm__ __volatile__(
+ KVM_HYPERCALL
+ : "=r" (r) : "r" (n), "r" (a0), "r" (a1), "r" (a2) : "memory"
+ );
+
+ return r;
+}
+
+static inline unsigned int kvm_arch_para_features(void)
+{
+ return 0;
+}
+
+#endif /* _ASM_MIPS_KVM_PARA_H */
diff --git a/arch/mips/include/uapi/asm/kvm_para.h b/arch/mips/include/uapi/asm/kvm_para.h
index 14fab8f..7e16d7c 100644
--- a/arch/mips/include/uapi/asm/kvm_para.h
+++ b/arch/mips/include/uapi/asm/kvm_para.h
@@ -1 +1,5 @@
-#include <asm-generic/kvm_para.h>
+#ifndef _UAPI_ASM_MIPS_KVM_PARA_H
+#define _UAPI_ASM_MIPS_KVM_PARA_H
+
+
+#endif /* _UAPI_ASM_MIPS_KVM_PARA_H */
diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h
index 2841f86..bf6cd7d 100644
--- a/include/uapi/linux/kvm_para.h
+++ b/include/uapi/linux/kvm_para.h
@@ -20,6 +20,9 @@
#define KVM_HC_FEATURES 3
#define KVM_HC_PPC_MAP_MAGIC_PAGE 4
#define KVM_HC_KICK_CPU 5
+#define KVM_HC_MIPS_GET_CLOCK_FREQ 6
+#define KVM_HC_MIPS_EXIT_VM 7
+#define KVM_HC_MIPS_CONSOLE_OUTPUT 8
/*
* hypercalls use architecture specific
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 10/13] MIPS: Add code for new system 'paravirt'
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (8 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 09/13] MIPS: Add functions for hypervisor call Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 11/13] MIPS: paravirt: Add pci controller for virtio Andreas Herrmann
` (2 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
For para-virtualized guests running under KVM or other equivalent
hypervisor.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
.../asm/mach-paravirt/cpu-feature-overrides.h | 36 ++
arch/mips/include/asm/mach-paravirt/irq.h | 19 +
.../include/asm/mach-paravirt/kernel-entry-init.h | 50 +++
arch/mips/include/asm/mach-paravirt/war.h | 25 ++
arch/mips/mm/tlbex.c | 8 +-
arch/mips/paravirt/Makefile | 14 +
arch/mips/paravirt/Platform | 9 +
arch/mips/paravirt/paravirt-irq.c | 369 ++++++++++++++++++++
arch/mips/paravirt/paravirt-smp.c | 148 ++++++++
arch/mips/paravirt/serial.c | 40 +++
arch/mips/paravirt/setup.c | 67 ++++
11 files changed, 779 insertions(+), 6 deletions(-)
create mode 100644 arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h
create mode 100644 arch/mips/include/asm/mach-paravirt/irq.h
create mode 100644 arch/mips/include/asm/mach-paravirt/kernel-entry-init.h
create mode 100644 arch/mips/include/asm/mach-paravirt/war.h
create mode 100644 arch/mips/paravirt/Makefile
create mode 100644 arch/mips/paravirt/Platform
create mode 100644 arch/mips/paravirt/paravirt-irq.c
create mode 100644 arch/mips/paravirt/paravirt-smp.c
create mode 100644 arch/mips/paravirt/serial.c
create mode 100644 arch/mips/paravirt/setup.c
[andreas.herrmann:
* Adaptions after renaming of mips_cpunum to get_ebase_cpunum
* Provide _machine_halt function to exit VM on shutdown of guest
* Adapt serial.c and setup.c to use new hypercalls and HC numbers
* Fix barriers when booting secondary CPUs
* Replace check for 64-bit kernel by common macro
* Remove call to irq_reserve_irq from irq_init_core
The function was removed (linux-next) see
- commit 1d008353ba088fdec0b2a944e140ff9154a5fb20
(genirq: Remove irq_reserve_irq[s])
- commit f63b6a05f2b11537612266a8b27a61f412344a1d
(genirq: Replace reserve_irqs in core code)
- commit be4034016c11f8913d38fccf692007fab1c50be1
(s390: Avoid call to irq_reserve_irqs())
Not reserving unused irqs shouldn't hurt.
* Use on_each_cpu unconditionally in irq_core_bus_sync_unlock]
* Misc other minor changes after review of v1]
diff --git a/arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h b/arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h
new file mode 100644
index 0000000..725e1ed
--- /dev/null
+++ b/arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ */
+#ifndef __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_tx39_cache 0
+#define cpu_has_counter 1
+#define cpu_has_llsc 1
+/*
+ * We Disable LL/SC on non SMP systems as it is faster to disable
+ * interrupts for atomic access than a LL/SC.
+ */
+#ifdef CONFIG_SMP
+# define kernel_uses_llsc 1
+#else
+# define kernel_uses_llsc 0
+#endif
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define cpu_dcache_line_size() 128
+#define cpu_icache_line_size() 128
+#define cpu_has_octeon_cache 1
+#define cpu_has_4k_cache 0
+#else
+#define cpu_has_octeon_cache 0
+#define cpu_has_4k_cache 1
+#endif
+
+#endif /* __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-paravirt/irq.h b/arch/mips/include/asm/mach-paravirt/irq.h
new file mode 100644
index 0000000..9b4d35e
--- /dev/null
+++ b/arch/mips/include/asm/mach-paravirt/irq.h
@@ -0,0 +1,19 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ */
+#ifndef __ASM_MACH_PARAVIRT_IRQ_H__
+#define __ASM_MACH_PARAVIRT_IRQ_H__
+
+#define NR_IRQS 64
+#define MIPS_CPU_IRQ_BASE 1
+
+#define MIPS_IRQ_PCIA (MIPS_CPU_IRQ_BASE + 8)
+
+#define MIPS_IRQ_MBOX0 (MIPS_CPU_IRQ_BASE + 32)
+#define MIPS_IRQ_MBOX1 (MIPS_CPU_IRQ_BASE + 33)
+
+#endif /* __ASM_MACH_PARAVIRT_IRQ_H__ */
diff --git a/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h b/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h
new file mode 100644
index 0000000..2f82bfa
--- /dev/null
+++ b/arch/mips/include/asm/mach-paravirt/kernel-entry-init.h
@@ -0,0 +1,50 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Cavium, Inc
+ */
+#ifndef __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H
+#define __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H
+
+#define CP0_EBASE $15, 1
+
+ .macro kernel_entry_setup
+ mfc0 t0, CP0_EBASE
+ andi t0, t0, 0x3ff # CPUNum
+ beqz t0, 1f
+ # CPUs other than zero goto smp_bootstrap
+ j smp_bootstrap
+
+1:
+ .endm
+
+/*
+ * Do SMP slave processor setup necessary before we can safely execute
+ * C code.
+ */
+ .macro smp_slave_setup
+ mfc0 t0, CP0_EBASE
+ andi t0, t0, 0x3ff # CPUNum
+ slti t1, t0, NR_CPUS
+ bnez t1, 1f
+2:
+ di
+ wait
+ b 2b # Unknown CPU, loop forever.
+1:
+ PTR_LA t1, paravirt_smp_sp
+ PTR_SLL t0, PTR_SCALESHIFT
+ PTR_ADDU t1, t1, t0
+3:
+ PTR_L sp, 0(t1)
+ beqz sp, 3b # Spin until told to proceed.
+
+ PTR_LA t1, paravirt_smp_gp
+ PTR_ADDU t1, t1, t0
+ sync
+ PTR_L gp, 0(t1)
+ .endm
+
+#endif /* __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-paravirt/war.h b/arch/mips/include/asm/mach-paravirt/war.h
new file mode 100644
index 0000000..36d3afb
--- /dev/null
+++ b/arch/mips/include/asm/mach-paravirt/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2013 Cavium Networks <support@caviumnetworks.com>
+ */
+#ifndef __ASM_MIPS_MACH_PARAVIRT_WAR_H
+#define __ASM_MIPS_MACH_PARAVIRT_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_PARAVIRT_WAR_H */
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index af91f3e..e80e10b 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -1250,17 +1250,13 @@ static void build_r4000_tlb_refill_handler(void)
unsigned int final_len;
struct mips_huge_tlb_info htlb_info __maybe_unused;
enum vmalloc64_mode vmalloc_mode __maybe_unused;
-#ifdef CONFIG_64BIT
- bool is64bit = true;
-#else
- bool is64bit = false;
-#endif
+
memset(tlb_handler, 0, sizeof(tlb_handler));
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
memset(final_handler, 0, sizeof(final_handler));
- if (is64bit && (scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
+ if (IS_ENABLED(CONFIG_64BIT) && (scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
scratch_reg);
vmalloc_mode = refill_scratch;
diff --git a/arch/mips/paravirt/Makefile b/arch/mips/paravirt/Makefile
new file mode 100644
index 0000000..5023af7
--- /dev/null
+++ b/arch/mips/paravirt/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for MIPS para-virtualized specific kernel interface routines
+# under Linux.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2013 Cavium, Inc.
+#
+
+obj-y := setup.o serial.o paravirt-irq.o
+
+obj-$(CONFIG_SMP) += paravirt-smp.o
diff --git a/arch/mips/paravirt/Platform b/arch/mips/paravirt/Platform
new file mode 100644
index 0000000..c3901fa
--- /dev/null
+++ b/arch/mips/paravirt/Platform
@@ -0,0 +1,9 @@
+#
+# Generic para-virtualized guest.
+#
+platform-$(CONFIG_MIPS_PARAVIRT) += paravirt/
+cflags-$(CONFIG_MIPS_PARAVIRT) += \
+ -I$(srctree)/arch/mips/include/asm/mach-paravirt
+
+load-$(CONFIG_MIPS_PARAVIRT) = 0xffffffff80010000
+
diff --git a/arch/mips/paravirt/paravirt-irq.c b/arch/mips/paravirt/paravirt-irq.c
new file mode 100644
index 0000000..f4d3247
--- /dev/null
+++ b/arch/mips/paravirt/paravirt-irq.c
@@ -0,0 +1,369 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/cpumask.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+
+#include <asm/io.h>
+
+#define MBOX_BITS_PER_CPU 2
+
+static int cpunum_for_cpu(int cpu)
+{
+#ifdef CONFIG_SMP
+ return cpu_logical_map(cpu);
+#else
+ return get_ebase_cpunum();
+#endif
+}
+
+struct core_chip_data {
+ struct mutex core_irq_mutex;
+ bool current_en;
+ bool desired_en;
+ u8 bit;
+};
+
+static struct core_chip_data irq_core_chip_data[8];
+
+static void irq_core_ack(struct irq_data *data)
+{
+ struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ unsigned int bit = cd->bit;
+
+ /*
+ * We don't need to disable IRQs to make these atomic since
+ * they are already disabled earlier in the low level
+ * interrupt code.
+ */
+ clear_c0_status(0x100 << bit);
+ /* The two user interrupts must be cleared manually. */
+ if (bit < 2)
+ clear_c0_cause(0x100 << bit);
+}
+
+static void irq_core_eoi(struct irq_data *data)
+{
+ struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
+
+ /*
+ * We don't need to disable IRQs to make these atomic since
+ * they are already disabled earlier in the low level
+ * interrupt code.
+ */
+ set_c0_status(0x100 << cd->bit);
+}
+
+static void irq_core_set_enable_local(void *arg)
+{
+ struct irq_data *data = arg;
+ struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ unsigned int mask = 0x100 << cd->bit;
+
+ /*
+ * Interrupts are already disabled, so these are atomic.
+ */
+ if (cd->desired_en)
+ set_c0_status(mask);
+ else
+ clear_c0_status(mask);
+
+}
+
+static void irq_core_disable(struct irq_data *data)
+{
+ struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ cd->desired_en = false;
+}
+
+static void irq_core_enable(struct irq_data *data)
+{
+ struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ cd->desired_en = true;
+}
+
+static void irq_core_bus_lock(struct irq_data *data)
+{
+ struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&cd->core_irq_mutex);
+}
+
+static void irq_core_bus_sync_unlock(struct irq_data *data)
+{
+ struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
+
+ if (cd->desired_en != cd->current_en) {
+ on_each_cpu(irq_core_set_enable_local, data, 1);
+ cd->current_en = cd->desired_en;
+ }
+
+ mutex_unlock(&cd->core_irq_mutex);
+}
+
+static struct irq_chip irq_chip_core = {
+ .name = "Core",
+ .irq_enable = irq_core_enable,
+ .irq_disable = irq_core_disable,
+ .irq_ack = irq_core_ack,
+ .irq_eoi = irq_core_eoi,
+ .irq_bus_lock = irq_core_bus_lock,
+ .irq_bus_sync_unlock = irq_core_bus_sync_unlock,
+
+ .irq_cpu_online = irq_core_eoi,
+ .irq_cpu_offline = irq_core_ack,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
+
+static void __init irq_init_core(void)
+{
+ int i;
+ int irq;
+ struct core_chip_data *cd;
+
+ /* Start with a clean slate */
+ clear_c0_status(ST0_IM);
+ clear_c0_cause(CAUSEF_IP0 | CAUSEF_IP1);
+
+ for (i = 0; i < ARRAY_SIZE(irq_core_chip_data); i++) {
+ cd = irq_core_chip_data + i;
+ cd->current_en = false;
+ cd->desired_en = false;
+ cd->bit = i;
+ mutex_init(&cd->core_irq_mutex);
+
+ irq = MIPS_CPU_IRQ_BASE + i;
+
+ switch (i) {
+ case 0: /* SW0 */
+ case 1: /* SW1 */
+ case 5: /* IP5 */
+ case 6: /* IP6 */
+ case 7: /* IP7 */
+ irq_set_chip_data(irq, cd);
+ irq_set_chip_and_handler(irq, &irq_chip_core,
+ handle_percpu_irq);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void __iomem *mips_irq_chip;
+#define MIPS_IRQ_CHIP_NUM_BITS 0
+#define MIPS_IRQ_CHIP_REGS 8
+
+static int mips_irq_cpu_stride;
+static int mips_irq_chip_reg_raw;
+static int mips_irq_chip_reg_src;
+static int mips_irq_chip_reg_en;
+static int mips_irq_chip_reg_raw_w1s;
+static int mips_irq_chip_reg_raw_w1c;
+static int mips_irq_chip_reg_en_w1s;
+static int mips_irq_chip_reg_en_w1c;
+
+static void irq_pci_enable(struct irq_data *data)
+{
+ u32 mask = 1u << data->irq;
+
+ __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_en_w1s);
+}
+
+static void irq_pci_disable(struct irq_data *data)
+{
+ u32 mask = 1u << data->irq;
+
+ __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_en_w1c);
+}
+
+static void irq_pci_ack(struct irq_data *data)
+{
+}
+
+static void irq_pci_mask(struct irq_data *data)
+{
+ u32 mask = 1u << data->irq;
+
+ __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_en_w1c);
+}
+
+static void irq_pci_unmask(struct irq_data *data)
+{
+ u32 mask = 1u << data->irq;
+
+ __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_en_w1s);
+}
+
+static struct irq_chip irq_chip_pci = {
+ .name = "PCI",
+ .irq_enable = irq_pci_enable,
+ .irq_disable = irq_pci_disable,
+ .irq_ack = irq_pci_ack,
+ .irq_mask = irq_pci_mask,
+ .irq_unmask = irq_pci_unmask,
+};
+
+static void irq_mbox_all(struct irq_data *data, void __iomem *base)
+{
+ int cpu;
+ unsigned int mbox = data->irq - MIPS_IRQ_MBOX0;
+ u32 mask;
+
+ WARN_ON(mbox >= MBOX_BITS_PER_CPU);
+
+ for_each_online_cpu(cpu) {
+ unsigned int cpuid = cpunum_for_cpu(cpu);
+ mask = 1 << (cpuid * MBOX_BITS_PER_CPU + mbox);
+ __raw_writel(mask, base + (cpuid * mips_irq_cpu_stride));
+ }
+}
+
+static void irq_mbox_enable(struct irq_data *data)
+{
+ irq_mbox_all(data, mips_irq_chip + mips_irq_chip_reg_en_w1s + sizeof(u32));
+}
+
+static void irq_mbox_disable(struct irq_data *data)
+{
+ irq_mbox_all(data, mips_irq_chip + mips_irq_chip_reg_en_w1c + sizeof(u32));
+}
+
+static void irq_mbox_ack(struct irq_data *data)
+{
+ u32 mask;
+ unsigned int mbox = data->irq - MIPS_IRQ_MBOX0;
+
+ WARN_ON(mbox >= MBOX_BITS_PER_CPU);
+
+ mask = 1 << (get_ebase_cpunum() * MBOX_BITS_PER_CPU + mbox);
+ __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_raw_w1c + sizeof(u32));
+}
+
+void irq_mbox_ipi(int cpu, unsigned int actions)
+{
+ unsigned int cpuid = cpunum_for_cpu(cpu);
+ u32 mask;
+
+ WARN_ON(actions >= (1 << MBOX_BITS_PER_CPU));
+
+ mask = actions << (cpuid * MBOX_BITS_PER_CPU);
+ __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_raw_w1s + sizeof(u32));
+}
+
+static void irq_mbox_cpu_onoffline(struct irq_data *data, void __iomem *base)
+{
+ unsigned int mbox = data->irq - MIPS_IRQ_MBOX0;
+ unsigned int cpuid = get_ebase_cpunum();
+ u32 mask;
+
+ WARN_ON(mbox >= MBOX_BITS_PER_CPU);
+
+ mask = 1 << (cpuid * MBOX_BITS_PER_CPU + mbox);
+ __raw_writel(mask, base + (cpuid * mips_irq_cpu_stride));
+
+}
+
+static void irq_mbox_cpu_online(struct irq_data *data)
+{
+ irq_mbox_cpu_onoffline(data, mips_irq_chip + mips_irq_chip_reg_en_w1s + sizeof(u32));
+}
+
+static void irq_mbox_cpu_offline(struct irq_data *data)
+{
+ irq_mbox_cpu_onoffline(data, mips_irq_chip + mips_irq_chip_reg_en_w1c + sizeof(u32));
+}
+
+static struct irq_chip irq_chip_mbox = {
+ .name = "MBOX",
+ .irq_enable = irq_mbox_enable,
+ .irq_disable = irq_mbox_disable,
+ .irq_ack = irq_mbox_ack,
+ .irq_cpu_online = irq_mbox_cpu_online,
+ .irq_cpu_offline = irq_mbox_cpu_offline,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
+
+static void __init irq_pci_init(void)
+{
+ int i, stride;
+ u32 num_bits;
+
+ mips_irq_chip = ioremap(0x1e010000, 4096);
+
+ num_bits = __raw_readl(mips_irq_chip + MIPS_IRQ_CHIP_NUM_BITS);
+ stride = 8 * (1 + ((num_bits - 1) / 64));
+
+
+ pr_notice("mips_irq_chip: %u bits, reg stride: %d\n", num_bits, stride);
+ mips_irq_chip_reg_raw = MIPS_IRQ_CHIP_REGS + 0 * stride;
+ mips_irq_chip_reg_raw_w1s = MIPS_IRQ_CHIP_REGS + 1 * stride;
+ mips_irq_chip_reg_raw_w1c = MIPS_IRQ_CHIP_REGS + 2 * stride;
+ mips_irq_chip_reg_src = MIPS_IRQ_CHIP_REGS + 3 * stride;
+ mips_irq_chip_reg_en = MIPS_IRQ_CHIP_REGS + 4 * stride;
+ mips_irq_chip_reg_en_w1s = MIPS_IRQ_CHIP_REGS + 5 * stride;
+ mips_irq_chip_reg_en_w1c = MIPS_IRQ_CHIP_REGS + 6 * stride;
+ mips_irq_cpu_stride = stride * 4;
+
+ for (i = 0; i < 4; i++)
+ irq_set_chip_and_handler(i + MIPS_IRQ_PCIA, &irq_chip_pci, handle_level_irq);
+
+ for (i = 0; i < 2; i++)
+ irq_set_chip_and_handler(i + MIPS_IRQ_MBOX0, &irq_chip_mbox, handle_percpu_irq);
+
+
+ set_c0_status(STATUSF_IP2);
+}
+
+static void irq_pci_dispatch(void)
+{
+ unsigned int cpuid = get_ebase_cpunum();
+ u32 en;
+
+ en = __raw_readl(mips_irq_chip + mips_irq_chip_reg_src +
+ (cpuid * mips_irq_cpu_stride));
+
+ if (!en) {
+ en = __raw_readl(mips_irq_chip + mips_irq_chip_reg_src + (cpuid * mips_irq_cpu_stride) + sizeof(u32));
+ en = (en >> (2 * cpuid)) & 3;
+
+ if (!en)
+ spurious_interrupt();
+ else
+ do_IRQ(__ffs(en) + MIPS_IRQ_MBOX0); /* MBOX type */
+ } else {
+ do_IRQ(__ffs(en));
+ }
+}
+
+
+void __init arch_init_irq(void)
+{
+ irq_init_core();
+ irq_pci_init();
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+ int ip;
+
+ if (unlikely(!pending)) {
+ spurious_interrupt();
+ return;
+ }
+
+ ip = ffs(pending) - 1 - STATUSB_IP0;
+ if (ip == 2)
+ irq_pci_dispatch();
+ else
+ do_IRQ(MIPS_CPU_IRQ_BASE + ip);
+}
+
diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c
new file mode 100644
index 0000000..73a123e
--- /dev/null
+++ b/arch/mips/paravirt/paravirt-smp.c
@@ -0,0 +1,148 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/cpumask.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/mipsregs.h>
+#include <asm/setup.h>
+#include <asm/time.h>
+#include <asm/smp.h>
+
+/*
+ * Writing the sp releases the CPU, so writes must be ordered, gp
+ * first, then sp.
+ */
+unsigned long paravirt_smp_sp[NR_CPUS];
+unsigned long paravirt_smp_gp[NR_CPUS];
+
+static int numcpus = 1;
+
+static int __init set_numcpus(char *str)
+{
+ int newval;
+
+ if (get_option(&str, &newval)) {
+ if (newval < 1 || newval >= NR_CPUS)
+ goto bad;
+ numcpus = newval;
+ return 0;
+ }
+bad:
+ return -EINVAL;
+}
+early_param("numcpus", set_numcpus);
+
+
+static void paravirt_smp_setup(void)
+{
+ int id;
+ unsigned int cpunum = get_ebase_cpunum();
+
+ if (WARN_ON(cpunum >= NR_CPUS))
+ return;
+
+ /* The present CPUs are initially just the boot cpu (CPU 0). */
+ for (id = 0; id < NR_CPUS; id++) {
+ set_cpu_possible(id, id == 0);
+ set_cpu_present(id, id == 0);
+ }
+ __cpu_number_map[cpunum] = 0;
+ __cpu_logical_map[0] = cpunum;
+
+ for (id = 0; id < numcpus; id++) {
+ set_cpu_possible(id, true);
+ set_cpu_present(id, true);
+ __cpu_number_map[id] = id;
+ __cpu_logical_map[id] = id;
+ }
+}
+
+void irq_mbox_ipi(int cpu, unsigned int actions);
+static void paravirt_send_ipi_single(int cpu, unsigned int action)
+{
+ irq_mbox_ipi(cpu, action);
+}
+
+static void paravirt_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ unsigned int cpu;
+
+ for_each_cpu_mask(cpu, *mask)
+ paravirt_send_ipi_single(cpu, action);
+}
+
+static void paravirt_init_secondary(void)
+{
+ unsigned int sr;
+
+ sr = set_c0_status(ST0_BEV);
+ write_c0_ebase((u32)ebase);
+
+ sr |= STATUSF_IP2; /* Interrupt controller on IP2 */
+ write_c0_status(sr);
+
+ irq_cpu_online();
+}
+
+static void paravirt_smp_finish(void)
+{
+ /* to generate the first CPU timer interrupt */
+ write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
+ local_irq_enable();
+}
+
+static void paravirt_cpus_done(void)
+{
+}
+
+static void paravirt_boot_secondary(int cpu, struct task_struct *idle)
+{
+ paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle);
+ smp_wmb();
+ paravirt_smp_sp[cpu] = __KSTK_TOS(idle);
+}
+
+static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id)
+{
+ scheduler_ipi();
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t paravirt_function_interrupt(int irq, void *dev_id)
+{
+ smp_call_function_interrupt();
+ return IRQ_HANDLED;
+}
+
+static void paravirt_prepare_cpus(unsigned int max_cpus)
+{
+ if (request_irq(MIPS_IRQ_MBOX0, paravirt_reched_interrupt,
+ IRQF_PERCPU | IRQF_NO_THREAD, "Scheduler",
+ paravirt_reched_interrupt)) {
+ panic("Cannot request_irq for SchedulerIPI");
+ }
+ if (request_irq(MIPS_IRQ_MBOX1, paravirt_function_interrupt,
+ IRQF_PERCPU | IRQF_NO_THREAD, "SMP-Call",
+ paravirt_function_interrupt)) {
+ panic("Cannot request_irq for SMP-Call");
+ }
+}
+
+struct plat_smp_ops paravirt_smp_ops = {
+ .send_ipi_single = paravirt_send_ipi_single,
+ .send_ipi_mask = paravirt_send_ipi_mask,
+ .init_secondary = paravirt_init_secondary,
+ .smp_finish = paravirt_smp_finish,
+ .cpus_done = paravirt_cpus_done,
+ .boot_secondary = paravirt_boot_secondary,
+ .smp_setup = paravirt_smp_setup,
+ .prepare_cpus = paravirt_prepare_cpus,
+};
diff --git a/arch/mips/paravirt/serial.c b/arch/mips/paravirt/serial.c
new file mode 100644
index 0000000..02b665c
--- /dev/null
+++ b/arch/mips/paravirt/serial.c
@@ -0,0 +1,40 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/virtio_console.h>
+#include <linux/kvm_para.h>
+
+/*
+ * Emit one character to the boot console.
+ */
+int prom_putchar(char c)
+{
+ kvm_hypercall3(KVM_HC_MIPS_CONSOLE_OUTPUT, 0 /* port 0 */,
+ (unsigned long)&c, 1 /* len == 1 */);
+
+ return 1;
+}
+
+#ifdef CONFIG_VIRTIO_CONSOLE
+static int paravirt_put_chars(u32 vtermno, const char *buf, int count)
+{
+ kvm_hypercall3(KVM_HC_MIPS_CONSOLE_OUTPUT, vtermno,
+ (unsigned long)buf, count);
+
+ return count;
+}
+
+static int __init paravirt_cons_init(void)
+{
+ virtio_cons_early_init(paravirt_put_chars);
+ return 0;
+}
+core_initcall(paravirt_cons_init);
+
+#endif
diff --git a/arch/mips/paravirt/setup.c b/arch/mips/paravirt/setup.c
new file mode 100644
index 0000000..cb8448b
--- /dev/null
+++ b/arch/mips/paravirt/setup.c
@@ -0,0 +1,67 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kvm_para.h>
+
+#include <asm/reboot.h>
+#include <asm/bootinfo.h>
+#include <asm/smp-ops.h>
+#include <asm/time.h>
+
+extern struct plat_smp_ops paravirt_smp_ops;
+
+const char *get_system_type(void)
+{
+ return "MIPS Para-Virtualized Guest";
+}
+
+void __init plat_time_init(void)
+{
+ mips_hpt_frequency = kvm_hypercall0(KVM_HC_MIPS_GET_CLOCK_FREQ);
+
+ preset_lpj = mips_hpt_frequency / (2 * HZ);
+}
+
+static void pv_machine_halt(void)
+{
+ kvm_hypercall0(KVM_HC_MIPS_EXIT_VM);
+}
+
+/*
+ * Early entry point for arch setup
+ */
+void __init prom_init(void)
+{
+ int i;
+ int argc = fw_arg0;
+ char **argv = (char **)fw_arg1;
+
+#ifdef CONFIG_32BIT
+ set_io_port_base(KSEG1ADDR(0x1e000000));
+#else /* CONFIG_64BIT */
+ set_io_port_base(PHYS_TO_XKSEG_UNCACHED(0x1e000000));
+#endif
+
+ for (i = 0; i < argc; i++) {
+ strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE);
+ if (i < argc - 1)
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+ }
+ _machine_halt = pv_machine_halt;
+ register_smp_ops(¶virt_smp_ops);
+}
+
+void __init plat_mem_setup(void)
+{
+ /* Do nothing, the "mem=???" parser handles our memory. */
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 11/13] MIPS: paravirt: Add pci controller for virtio
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (9 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 10/13] MIPS: Add code for new system 'paravirt' Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 12/13] MIPS: Enable build for new system 'paravirt' Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 13/13] MIPS: Add minimal defconfig for mips_paravirt Andreas Herrmann
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/Kconfig | 1 +
arch/mips/paravirt/Kconfig | 6 ++
arch/mips/pci/Makefile | 2 +-
arch/mips/pci/pci-virtio-guest.c | 131 ++++++++++++++++++++++++++++++++++++++
4 files changed, 139 insertions(+), 1 deletion(-)
create mode 100644 arch/mips/paravirt/Kconfig
create mode 100644 arch/mips/pci/pci-virtio-guest.c
[andreas.herrmann:
* Make use of __BITFIELD_FIELD macro
* Calculate IO address for in[lwb] and out[lwb] depending on size]
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d540945..1f836d8 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -823,6 +823,7 @@ source "arch/mips/cavium-octeon/Kconfig"
source "arch/mips/loongson/Kconfig"
source "arch/mips/loongson1/Kconfig"
source "arch/mips/netlogic/Kconfig"
+source "arch/mips/paravirt/Kconfig"
endmenu
diff --git a/arch/mips/paravirt/Kconfig b/arch/mips/paravirt/Kconfig
new file mode 100644
index 0000000..ecae586
--- /dev/null
+++ b/arch/mips/paravirt/Kconfig
@@ -0,0 +1,6 @@
+if MIPS_PARAVIRT
+
+config MIPS_PCI_VIRTIO
+ def_bool y
+
+endif # MIPS_PARAVIRT
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index d61138a..ff8a553 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
-
+obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
#
# These are still pretty much in the old state, watch, go blind.
#
diff --git a/arch/mips/pci/pci-virtio-guest.c b/arch/mips/pci/pci-virtio-guest.c
new file mode 100644
index 0000000..40a078b
--- /dev/null
+++ b/arch/mips/pci/pci-virtio-guest.c
@@ -0,0 +1,131 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+
+#include <uapi/asm/bitfield.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+
+#define PCI_CONFIG_ADDRESS 0xcf8
+#define PCI_CONFIG_DATA 0xcfc
+
+union pci_config_address {
+ struct {
+ __BITFIELD_FIELD(unsigned enable_bit : 1, /* 31 */
+ __BITFIELD_FIELD(unsigned reserved : 7, /* 30 .. 24 */
+ __BITFIELD_FIELD(unsigned bus_number : 8, /* 23 .. 16 */
+ __BITFIELD_FIELD(unsigned devfn_number : 8, /* 15 .. 8 */
+ __BITFIELD_FIELD(unsigned register_number : 8, /* 7 .. 0 */
+ )))));
+ };
+ u32 w;
+};
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return ((pin + slot) % 4)+ MIPS_IRQ_PCIA;
+}
+
+static void pci_virtio_guest_write_config_addr(struct pci_bus *bus,
+ unsigned int devfn, int reg)
+{
+ union pci_config_address pca = { .w = 0 };
+
+ pca.register_number = reg;
+ pca.devfn_number = devfn;
+ pca.bus_number = bus->number;
+ pca.enable_bit = 1;
+
+ outl(pca.w, PCI_CONFIG_ADDRESS);
+}
+
+static int pci_virtio_guest_write_config(struct pci_bus *bus,
+ unsigned int devfn, int reg, int size, u32 val)
+{
+ pci_virtio_guest_write_config_addr(bus, devfn, reg);
+
+ switch (size) {
+ case 1:
+ outb(val, PCI_CONFIG_DATA + (reg & 3));
+ break;
+ case 2:
+ outw(val, PCI_CONFIG_DATA + (reg & 2));
+ break;
+ case 4:
+ outl(val, PCI_CONFIG_DATA);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_virtio_guest_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ pci_virtio_guest_write_config_addr(bus, devfn, reg);
+
+ switch (size) {
+ case 1:
+ *val = inb(PCI_CONFIG_DATA + (reg & 3));
+ break;
+ case 2:
+ *val = inw(PCI_CONFIG_DATA + (reg & 2));
+ break;
+ case 4:
+ *val = inl(PCI_CONFIG_DATA);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_virtio_guest_ops = {
+ .read = pci_virtio_guest_read_config,
+ .write = pci_virtio_guest_write_config,
+};
+
+static struct resource pci_virtio_guest_mem_resource = {
+ .name = "Virtio MEM",
+ .flags = IORESOURCE_MEM,
+ .start = 0x10000000,
+ .end = 0x1dffffff
+};
+
+static struct resource pci_virtio_guest_io_resource = {
+ .name = "Virtio IO",
+ .flags = IORESOURCE_IO,
+ .start = 0,
+ .end = 0xffff
+};
+
+static struct pci_controller pci_virtio_guest_controller = {
+ .pci_ops = &pci_virtio_guest_ops,
+ .mem_resource = &pci_virtio_guest_mem_resource,
+ .io_resource = &pci_virtio_guest_io_resource,
+};
+
+static int __init pci_virtio_guest_setup(void)
+{
+ pr_err("pci_virtio_guest_setup\n");
+
+ /* Virtio comes pre-assigned */
+ pci_set_flags(PCI_PROBE_ONLY);
+
+ pci_virtio_guest_controller.io_map_base = mips_io_port_base;
+ register_pci_controller(&pci_virtio_guest_controller);
+ return 0;
+}
+arch_initcall(pci_virtio_guest_setup);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 12/13] MIPS: Enable build for new system 'paravirt'
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (10 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 11/13] MIPS: paravirt: Add pci controller for virtio Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 13/13] MIPS: Add minimal defconfig for mips_paravirt Andreas Herrmann
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm, David Daney
From: David Daney <david.daney@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/Kbuild.platforms | 1 +
arch/mips/Kconfig | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 6e23912..f5e18bf 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -18,6 +18,7 @@ platforms += loongson1
platforms += mti-malta
platforms += mti-sead3
platforms += netlogic
+platforms += paravirt
platforms += pmcs-msp71xx
platforms += pnx833x
platforms += ralink
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 1f836d8..df16e1e 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -803,6 +803,25 @@ config NLM_XLP_BOARD
This board is based on Netlogic XLP Processor.
Say Y here if you have a XLP based board.
+config MIPS_PARAVIRT
+ bool "Para-Virtualized guest system"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_COHERENT
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_SMP
+ select NR_CPUS_DEFAULT_4
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R2
+ select SYS_HAS_CPU_CAVIUM_OCTEON
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ help
+ This option supports guest running under ????
+
endchoice
source "arch/mips/alchemy/Kconfig"
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 13/13] MIPS: Add minimal defconfig for mips_paravirt
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
` (11 preceding siblings ...)
2014-05-28 21:52 ` [PATCH v2 12/13] MIPS: Enable build for new system 'paravirt' Andreas Herrmann
@ 2014-05-28 21:52 ` Andreas Herrmann
12 siblings, 0 replies; 18+ messages in thread
From: Andreas Herrmann @ 2014-05-28 21:52 UTC (permalink / raw)
To: linux-mips; +Cc: David Daney, Andreas Herrmann, James Hogan, kvm
Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
---
arch/mips/configs/mips_paravirt_defconfig | 103 +++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 arch/mips/configs/mips_paravirt_defconfig
diff --git a/arch/mips/configs/mips_paravirt_defconfig b/arch/mips/configs/mips_paravirt_defconfig
new file mode 100644
index 0000000..84cfcb4
--- /dev/null
+++ b/arch/mips/configs/mips_paravirt_defconfig
@@ -0,0 +1,103 @@
+CONFIG_MIPS_PARAVIRT=y
+CONFIG_CPU_MIPS64_R2=y
+CONFIG_64BIT=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_SMP=y
+CONFIG_HZ_1000=y
+CONFIG_PREEMPT=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_VIRTIO_NET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+CONFIG_MARVELL_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_BCM87XX_PHY=y
+# CONFIG_WLAN is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_VIRTIO_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 09/13] MIPS: Add functions for hypervisor call
2014-05-28 21:52 ` [PATCH v2 09/13] MIPS: Add functions for hypervisor call Andreas Herrmann
@ 2014-06-03 8:30 ` Ralf Baechle
2014-06-03 15:03 ` Andreas Herrmann
0 siblings, 1 reply; 18+ messages in thread
From: Ralf Baechle @ 2014-06-03 8:30 UTC (permalink / raw)
To: Andreas Herrmann; +Cc: linux-mips, David Daney, James Hogan, kvm, David Daney
On Wed, May 28, 2014 at 11:52:12PM +0200, Andreas Herrmann wrote:
> +/*
> + * Hypercalls for KVM.
> + *
> + * Hypercall number is passed in v0.
> + * Return value will be placed in v0.
> + * Up to 3 arguments are passed in a0, a1, and a2.
> + */
> +static inline unsigned long kvm_hypercall0(unsigned long num)
> +{
> + register unsigned long n asm("v0");
> + register unsigned long r asm("v0");
Btw, is it safe to put two variables in the same register?
The syscall wrappers that used to be in <asm/unistd.h> were occasionally
hitting problems which eventually forced me to stop forcing variables
into particular registers instead using a MOVE instruction to shove
each variable into the right place.
Of course they were being used from non-PIC and PIC code, kernel and userland
so GCC had a much better chance to do evil than in the hypercall wrapper
case - but it made me paranoid ...
Ralf
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 09/13] MIPS: Add functions for hypervisor call
2014-06-03 8:30 ` Ralf Baechle
@ 2014-06-03 15:03 ` Andreas Herrmann
2014-06-03 16:40 ` David Daney
0 siblings, 1 reply; 18+ messages in thread
From: Andreas Herrmann @ 2014-06-03 15:03 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips, David Daney, James Hogan, kvm, David Daney
On Tue, Jun 03, 2014 at 10:30:31AM +0200, Ralf Baechle wrote:
> On Wed, May 28, 2014 at 11:52:12PM +0200, Andreas Herrmann wrote:
>
> > +/*
> > + * Hypercalls for KVM.
> > + *
> > + * Hypercall number is passed in v0.
> > + * Return value will be placed in v0.
> > + * Up to 3 arguments are passed in a0, a1, and a2.
> > + */
> > +static inline unsigned long kvm_hypercall0(unsigned long num)
> > +{
> > + register unsigned long n asm("v0");
> > + register unsigned long r asm("v0");
>
> Btw, is it safe to put two variables in the same register?
I think it's safe.
If we would have a matching constraint letter (say "v" for register v0) the
asm should translate to
__asm__ __volatile__(
KVM_HYPERCALL
: "=v" (n) : "v" (r) : "memory"
);
which isn't unusual on other archs. (Or maybe I am just biased from
x86 ... or missed something else.)
> The syscall wrappers that used to be in <asm/unistd.h> were occasionally
> hitting problems which eventually forced me to stop forcing variables
> into particular registers instead using a MOVE instruction to shove
> each variable into the right place.
>
> Of course they were being used from non-PIC and PIC code, kernel and userland
> so GCC had a much better chance to do evil than in the hypercall wrapper
> case - but it made me paranoid ...
Andreas
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 09/13] MIPS: Add functions for hypervisor call
2014-06-03 15:03 ` Andreas Herrmann
@ 2014-06-03 16:40 ` David Daney
2014-06-03 16:45 ` Pinski, Andrew
0 siblings, 1 reply; 18+ messages in thread
From: David Daney @ 2014-06-03 16:40 UTC (permalink / raw)
To: Andreas Herrmann, Ralf Baechle, Pinski, Andrew
Cc: linux-mips, David Daney, James Hogan, kvm, David Daney
In cases like this, I always wonder WWPD (What Would Pinski Do)...
Let's get him to opine.
Andrew, the patch in question is:
http://www.linux-mips.org/archives/linux-mips/2014-05/msg00309.html
Thanks,
David Daney
On 06/03/2014 08:03 AM, Andreas Herrmann wrote:
> On Tue, Jun 03, 2014 at 10:30:31AM +0200, Ralf Baechle wrote:
>> On Wed, May 28, 2014 at 11:52:12PM +0200, Andreas Herrmann wrote:
>>
>>> +/*
>>> + * Hypercalls for KVM.
>>> + *
>>> + * Hypercall number is passed in v0.
>>> + * Return value will be placed in v0.
>>> + * Up to 3 arguments are passed in a0, a1, and a2.
>>> + */
>>> +static inline unsigned long kvm_hypercall0(unsigned long num)
>>> +{
>>> + register unsigned long n asm("v0");
>>> + register unsigned long r asm("v0");
>>
>> Btw, is it safe to put two variables in the same register?
>
> I think it's safe.
>
> If we would have a matching constraint letter (say "v" for register v0) the
> asm should translate to
>
> __asm__ __volatile__(
> KVM_HYPERCALL
> : "=v" (n) : "v" (r) : "memory"
> );
>
> which isn't unusual on other archs. (Or maybe I am just biased from
> x86 ... or missed something else.)
>
>> The syscall wrappers that used to be in <asm/unistd.h> were occasionally
>> hitting problems which eventually forced me to stop forcing variables
>> into particular registers instead using a MOVE instruction to shove
>> each variable into the right place.
>>
>> Of course they were being used from non-PIC and PIC code, kernel and userland
>> so GCC had a much better chance to do evil than in the hypercall wrapper
>> case - but it made me paranoid ...
>
>
>
> Andreas
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 09/13] MIPS: Add functions for hypervisor call
2014-06-03 16:40 ` David Daney
@ 2014-06-03 16:45 ` Pinski, Andrew
0 siblings, 0 replies; 18+ messages in thread
From: Pinski, Andrew @ 2014-06-03 16:45 UTC (permalink / raw)
To: Daney, David
Cc: Herrmann, Andreas, Ralf Baechle, Pinski, Andrew,
linux-mips@linux-mips.org, David Daney, James Hogan,
kvm@vger.kernel.org, David Daney
> On Jun 3, 2014, at 9:40 AM, "Daney, David" <David.Daney@caviumnetworks.com> wrote:
>
> In cases like this, I always wonder WWPD (What Would Pinski Do)...
>
> Let's get him to opine.
>
> Andrew, the patch in question is:
>
> http://www.linux-mips.org/archives/linux-mips/2014-05/msg00309.html
Yes having two variables with the same register is safe as long as the only time the live ranges of them overlap is the inline-asm where they are used.
Thanks,
Andrew
>
> Thanks,
> David Daney
>
>> On 06/03/2014 08:03 AM, Andreas Herrmann wrote:
>>> On Tue, Jun 03, 2014 at 10:30:31AM +0200, Ralf Baechle wrote:
>>>> On Wed, May 28, 2014 at 11:52:12PM +0200, Andreas Herrmann wrote:
>>>>
>>>> +/*
>>>> + * Hypercalls for KVM.
>>>> + *
>>>> + * Hypercall number is passed in v0.
>>>> + * Return value will be placed in v0.
>>>> + * Up to 3 arguments are passed in a0, a1, and a2.
>>>> + */
>>>> +static inline unsigned long kvm_hypercall0(unsigned long num)
>>>> +{
>>>> + register unsigned long n asm("v0");
>>>> + register unsigned long r asm("v0");
>>>
>>> Btw, is it safe to put two variables in the same register?
>>
>> I think it's safe.
>>
>> If we would have a matching constraint letter (say "v" for register v0) the
>> asm should translate to
>>
>> __asm__ __volatile__(
>> KVM_HYPERCALL
>> : "=v" (n) : "v" (r) : "memory"
>> );
>>
>> which isn't unusual on other archs. (Or maybe I am just biased from
>> x86 ... or missed something else.)
>>
>>> The syscall wrappers that used to be in <asm/unistd.h> were occasionally
>>> hitting problems which eventually forced me to stop forcing variables
>>> into particular registers instead using a MOVE instruction to shove
>>> each variable into the right place.
>>>
>>> Of course they were being used from non-PIC and PIC code, kernel and userland
>>> so GCC had a much better chance to do evil than in the hypercall wrapper
>>> case - but it made me paranoid ...
>>
>>
>>
>> Andreas
>>
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2014-06-03 16:45 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-28 21:52 [PATCH v2 00/13] MIPS: Add mips_paravirt Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 01/13] MIPS: OCTEON: Enable use of FPU Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 02/13] MIPS: Move system level config items from CPU_CAVIUM_OCTEON to CAVIUM_OCTEON_SOC Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 03/13] MIPS: OCTEON: Move CAVIUM_OCTEON_CVMSEG_SIZE to CPU_CAVIUM_OCTEON Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 04/13] MIPS: Don't use RI/XI with 32-bit kernels on 64-bit CPUs Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 05/13] MIPS: Don't build fast TLB refill handler with 32-bit kernels Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 06/13] MIPS: Add minimal support for OCTEON3 to c-r4k.c Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 07/13] MIPS: Add function get_ebase_cpunum Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 08/13] MIPS: OCTEON: Add OCTEON3 to __get_cpu_type Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 09/13] MIPS: Add functions for hypervisor call Andreas Herrmann
2014-06-03 8:30 ` Ralf Baechle
2014-06-03 15:03 ` Andreas Herrmann
2014-06-03 16:40 ` David Daney
2014-06-03 16:45 ` Pinski, Andrew
2014-05-28 21:52 ` [PATCH v2 10/13] MIPS: Add code for new system 'paravirt' Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 11/13] MIPS: paravirt: Add pci controller for virtio Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 12/13] MIPS: Enable build for new system 'paravirt' Andreas Herrmann
2014-05-28 21:52 ` [PATCH v2 13/13] MIPS: Add minimal defconfig for mips_paravirt Andreas Herrmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox