* [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors
@ 2014-06-17 22:10 James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 01/12] target-mips: Reset CPU timer consistently James Hogan
` (13 more replies)
0 siblings, 14 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
The patchset depends on v4 of "target-mips: implement UserLocal
Register". I'm aiming for QEMU 2.1, hopefully it isn't too late to get
some final review.
Thanks to everybody who has already taken part in review.
This patchset implements KVM support for MIPS32 processors, using Trap &
Emulation.
In KVM mode, CPU virtualization is handled via the kvm kernel module,
while system and I/O virtualization leverage the Malta model already
present in QEMU.
Both Guest kernel and Guest Userspace execute in UM. The Guest address
space is as folows:
Guest User address space: 0x00000000 -> 0x40000000
Guest Kernel Unmapped: 0x40000000 -> 0x60000000
Guest Kernel Mapped: 0x60000000 -> 0x80000000
As a result, Guest Usermode virtual memory is limited to 1GB.
KVM support (by trap and emulate) was added to the Linux kernel in
v3.10. This patchset partly depends on MIPS KVM work which will land in
v3.16 (for example to save/restore the state of various registers and
the KVM Count/Compare timer).
Changes in v5:
Changes addressing review comments from v4 patchset, and to use the MIPS
KVM timer API added in v3.16.
A git tag for this version of the patchset can also be found on github:
https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v5
- Rebase on master + v4 of "target-mips: implement UserLocal Register".
- New patch ([01/12] target-mips: Reset CPU timer consistently) to
address timer reset behaviour (reported by Paolo Bonzini).
- New patch ([08/12] target-mips: Call kvm_mips_reset_vcpu() from
mips_cpu_reset()) and rename kvm_arch_reset_vcpu to
kvm_mips_reset_vcpu, based on commit 50a2c6e55fa2 (kvm: reset state
from the CPU's reset method).
- KSEG0 doesn't actually change size, so fix mask in
cpu_mips_kseg0_to_phys() (patch 3) and use that instead of having the
KVM specific cpu_mips_kvm_um_kseg0_to_phys() (patch 10).
- Fix typo in patch 9 subject (s/interupts/interrupts/).
- Rename kvm_mips_te_{put,get}_cp0_registers() functions to drop the
"te_" since they're not really specific to T&E.
- Pass level through from kvm_arch_put_registers() to
kvm_mips_put_cp0_registers() rather than hard coding it to
KVM_PUT_FULL_STATE.
- Fix KVM_REG_MIPS_CP0_* definitions to set KVM_REG_MIPS and
KVM_REG_SIZE_U32/KVM_REG_SIZE_U64 (using a macro).
- Remove unused KVM_REG_MIPS_CP0_* definitions for now.
- Correct type of kvm_mips_{get,put}_one_{,ul}reg() reg_id argument to
uint64_t. Various high bits must be set to disambiguate the
architecture and register size.
- Simplify register access functions slightly.
- Add register accessors for always-64-bit registers (rather than ulong
registers). These are needed for virtual KVM registers for
controlling the KVM Compare/Count timer.
- Save and restore KVM timer state with the rest of the state, and also
when VM clock is started or stopped. When the KVM timer state is
restored (or VM clock restarted) it is resumed with the stored count
at the monotonic time when the VM clock was last stopped. If the VM
clock hasn't been stopped it resumes from the monotonic time when the
state was saved (i.e. as if the timer was never stopped).
Changes since RFC patch on kernel KVM thread "[PATCH v2 00/23] MIPS:
KVM: Fixes and guest timer rewrite"):
- Simplified, removing extra state for storing VM time of
save/restore, at the cost of losing/gaining time when VM gets
stopped and started (Paolo Bonzini).
- Save and restore the UserLocal and HWREna CP0 registers.
- Improve get/put KVM register error handling with DPRINTFs and fall
through so that getting/putting of all the registers is attempted
even if one of them fails due to being unimplemented in the kernel.
Changes in v4:
Changes mostly addressing a few review comments from v3 patchset.
A git tag for this version of the patchset can also be found on github:
https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v4
- Rebase on v2.0.0-rc0.
- Use int32_t instead of int32 (which is for softfloat) in kvm register
accessors (Andreas Färber).
- Use uint64_t instead of __u64 (which is really just for kernel
headers) in the kvm register accessors (Andreas Färber).
- Cast pointer to uintptr_t rather than target_ulong in kvm register
accessors.
- Remove some redundant casts in kvm register accessors.
- Add MAINTAINERS entry for MIPS KVM.
Changes in v3:
Changes mostly addressing review comments from v2 patchset.
A git tag for this version of the patchset can also be found on github:
https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v3
- Remove "target-mips: Set target page size to 16K in KVM mode". It
should actually work fine with 4k TARGET_PAGE_SIZE as long as there
is no cache aliasing or both host and guest kernels are configured to
a sufficient page size to avoid aliasing (which the kernel
arch/mips/kvm/00README.txt alludes to anyway).
- Rewrote kvm sigmask patch to allow sigmask length to be set by
kvm_arch_init(), so that MIPS can set it to 16 as it has 128 signals.
This is better than cluttering kvm-all.c with TARGET_* ifdefs (Peter
Maydell).
- Set sigmask length to 16 from kvm_arch_init() since MIPS Linux has
128 signals. This is better than cluttering kvm_all.c with TARGET_*
ifdefs (Peter Maydell).
- s/dprintf/DPRINTF/ (Andreas Färber).
- Use "cs" rather than "cpu" or "env" for CPUState variable names
(Andreas Färber).
- Use CPUMIPSState rather than CPUArchState (Andreas Färber).
- Pass MIPSCPU to cpu_mips_io_interrupts_pending() rather than
CPUMIPSState (Andreas Färber).
- Remove spurious parentheses around cpu_mips_io_interrupts_pending()
call (Andreas Färber).
- Pass MIPSCPU to kvm_mips_set_[ipi_]interrupt (Andreas Färber).
- Make use of error_report (Andreas Färber) and clean up error messages
a little to include __func__.
- Remove inline kvm_mips_{put,get}_one_[ul]reg() declarations from
kvm_mips.h. They're only used in target-mips/kvm.c anyway.
- Make kvm_arch_{put,get}_registers static within target-mips/kvm.c and
remove from kvm_mips.h.
- Remove unnecessary includes from Malta patch, especially linux/kvm.h
which isn't a good idea on non-Linux (Peter Maydell).
Changes in v2:
This patchset is based on Sanjay Lal's V1 patchset from 2nd March 2013:
https://patchwork.kernel.org/project/kvm/list/?submitter=51991&state=*&q=qemu-devel
I think I've addressed all the V1 feedback. The other main change is the
removal of the boot-CPS ROM code binary blob and GIC/SMP support since
it's all slightly orthogonal to KVM support. Instead the existing
minimal bootloader code for Malta has been updated to work with KVM T&E.
A git tag for this version of the patchset can also be found on github:
https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v2
- Expand commit messages
- Rebase on v1.7.0
- Misc checkpatch and other cleanups
- Some interrupt bug fixes from Yann Le Du <ledu@kymasys.com>
- Add get/set register functionality from Yann Le Du <ledu@kymasys.com>
- Use new 64 bit compatible ABI from Cavium from Sanjay Lal
<sanjayl@kymasys.com>
- Add dummy kvm_arch_init_irq_routing()
The common KVM code insists on calling kvm_arch_init_irq_routing() as
soon as it sees kernel header support for it (regardless of whether
QEMU supports it). Provide a dummy function to satisfy this.
- Remove request_interrupt_window code (Peter Maydell)
- Remove #ifdef CONFIG_KVM where guarded by kvm_enabled() already
- Removal of cps / GIC / SMP support
- Minimal bootloader modified to execute safely from RAM
- Create asm-mips symlink using generic code and move above default
case (Peter Maydell)
- Remove redundant check of target_name = cpu = mips
- Remove mipsel cross compilation fix, which is now fixed by commit
61cc919f73ea (configure: detect endian via compile test)
- Add translation of guest kernel segments to allow an attached gdb to
see kernel memory correctly
James Hogan (7):
target-mips: Reset CPU timer consistently
target-mips: get_physical_address: Add defines for segment bases
target-mips: get_physical_address: Add KVM awareness
kvm: Allow arch to set sigmask length
target-mips: Call kvm_mips_reset_vcpu() from mips_cpu_reset()
hw/mips: malta: Add KVM support
MAINTAINERS: Add entry for MIPS KVM
Sanjay Lal (5):
hw/mips/cputimer: Don't start periodic timer in KVM mode
hw/mips: Add API to convert KVM guest KSEG0 <-> GPA
target-mips: kvm: Add main KVM support for MIPS
hw/mips: In KVM mode, inject IRQ2 (I/O) interrupts via ioctls
target-mips: Enable KVM support in build system
MAINTAINERS | 5 +
configure | 6 +-
hw/mips/addr.c | 7 +-
hw/mips/cputimer.c | 18 +-
hw/mips/mips_int.c | 11 +
hw/mips/mips_malta.c | 73 +++--
include/hw/mips/cpudevs.h | 2 +
include/sysemu/kvm.h | 2 +
kvm-all.c | 11 +-
target-mips/Makefile.objs | 1 +
target-mips/cpu.c | 8 +
target-mips/helper.c | 51 +++-
target-mips/kvm.c | 683 ++++++++++++++++++++++++++++++++++++++++++++++
target-mips/kvm_mips.h | 26 ++
target-mips/translate.c | 2 +
15 files changed, 866 insertions(+), 40 deletions(-)
create mode 100644 target-mips/kvm.c
create mode 100644 target-mips/kvm_mips.h
--
1.9.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 01/12] target-mips: Reset CPU timer consistently
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 02/12] hw/mips/cputimer: Don't start periodic timer in KVM mode James Hogan
` (12 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
The MIPS CPU timer (CP0 Count/Compare registers & QEMU timer) is
reset at machine initialisation, including starting the timeout. Both
registers however are placed before mvp in CPUMIPSState so they will
both be zeroed on reset by the memset in mips_cpu_reset() including soon
after init. This doesn't take into account that the timer may be
running, in which case env->CP0_Count will represent the delta against
the VM clock and the timeout will need updating.
At init time (cpu_mips_clock_init()), lets only create the timer.
Setting Count = 1 and starting the timer (cpu_mips_store_count()) can be
done at reset time from cpu_state_reset(), which is after the memset.
There is also no need to set CP0_Compare = 0 as that is already handled
by the memset.
Note that a reset occurs from mips_cpu_realizefn() which is before the
machine init callback has had a chance to set up the CPU interrupts and
the CPU timer, so env->timer will be NULL. This case is handled
explicitly in cpu_mips_store_count(), treating the timer as disabled
(which will also be the right thing to do when KVM support is added).
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v5:
- New patch (Paolo Bonzini).
---
hw/mips/cputimer.c | 9 ++++++---
target-mips/translate.c | 2 ++
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/hw/mips/cputimer.c b/hw/mips/cputimer.c
index c8b4b000cd0e..6900a745c60c 100644
--- a/hw/mips/cputimer.c
+++ b/hw/mips/cputimer.c
@@ -85,7 +85,12 @@ uint32_t cpu_mips_get_count (CPUMIPSState *env)
void cpu_mips_store_count (CPUMIPSState *env, uint32_t count)
{
- if (env->CP0_Cause & (1 << CP0Ca_DC))
+ /*
+ * This gets called from cpu_state_reset(), potentially before timer init.
+ * So env->timer may be NULL, which is also the case with KVM enabled so
+ * treat timer as disabled in that case.
+ */
+ if (env->CP0_Cause & (1 << CP0Ca_DC) || !env->timer)
env->CP0_Count = count;
else {
/* Store new count register */
@@ -142,6 +147,4 @@ static void mips_timer_cb (void *opaque)
void cpu_mips_clock_init (CPUMIPSState *env)
{
env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env);
- env->CP0_Compare = 0;
- cpu_mips_store_count(env, 1);
}
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 2c4c80103d14..b63f30fc3a76 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -16091,6 +16091,8 @@ void cpu_state_reset(CPUMIPSState *env)
/* Count register increments in debug mode, EJTAG version 1 */
env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
+ cpu_mips_store_count(env, 1);
+
if (env->CP0_Config3 & (1 << CP0C3_MT)) {
int i;
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 02/12] hw/mips/cputimer: Don't start periodic timer in KVM mode
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 01/12] target-mips: Reset CPU timer consistently James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 03/12] hw/mips: Add API to convert KVM guest KSEG0 <-> GPA James Hogan
` (11 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
From: Sanjay Lal <sanjayl@kymasys.com>
Compare/Count timer interrupts are handled in-kernel for KVM. Therefore
don't bother creating the timer at init time if KVM is enabled. This
will conveniently avoid attempts to set the timeout when
cpu_mips_store_count() is called at reset with KVM enabled, treating the
timer as stopped so that CP0_Count is modified directly.
Signed-off-by: Sanjay Lal <sanjayl@kymasys.com>
[james.hogan@imgtec.com: Update after "target-mips: Reset CPU timer
consistently" which moves timer start to reset time]
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
Changes in v5:
- Update commit message and comment in cpu_mips_clock_init() after the
patch "target-mips: Reset CPU timer consistently") (Paolo Bonzini).
Changes in v2:
- Expand commit message
- Rebase on v1.7.0
- Wrap comment
---
hw/mips/cputimer.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/hw/mips/cputimer.c b/hw/mips/cputimer.c
index 6900a745c60c..577c9aeab877 100644
--- a/hw/mips/cputimer.c
+++ b/hw/mips/cputimer.c
@@ -23,6 +23,7 @@
#include "hw/hw.h"
#include "hw/mips/cpudevs.h"
#include "qemu/timer.h"
+#include "sysemu/kvm.h"
#define TIMER_FREQ 100 * 1000 * 1000
@@ -146,5 +147,11 @@ static void mips_timer_cb (void *opaque)
void cpu_mips_clock_init (CPUMIPSState *env)
{
- env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env);
+ /*
+ * If we're in KVM mode, don't create the periodic timer, that is handled in
+ * kernel.
+ */
+ if (!kvm_enabled()) {
+ env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env);
+ }
}
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 03/12] hw/mips: Add API to convert KVM guest KSEG0 <-> GPA
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 01/12] target-mips: Reset CPU timer consistently James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 02/12] hw/mips/cputimer: Don't start periodic timer in KVM mode James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 04/12] target-mips: get_physical_address: Add defines for segment bases James Hogan
` (10 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
From: Sanjay Lal <sanjayl@kymasys.com>
Add API for converting physical addresses to KVM guest KSEG0 addresses,
and fix the existing API for converting KSEG0 addresses to physical
addresses to work in the KVM case. Both have the same sized KSEG0, so
it's just a case of fixing the mask.
In KVM trap and emulate mode both the guest kernel and guest userspace
execute in useg:
Guest User address space: 0x00000000..0x3fffffff
Guest Kernel Unmapped: 0x40000000..0x5fffffff
Guest Kernel Mapped: 0x60000000..0x7fffffff
Signed-off-by: Sanjay Lal <sanjayl@kymasys.com>
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v5:
- KSEG0 doesn't actually change size, so fix mask in
cpu_mips_kseg0_to_phys() instead of having the KVM specific
cpu_mips_kvm_um_kseg0_to_phys().
Changes in v2:
- Expand commit message
- Remove unnecessary include
---
hw/mips/addr.c | 7 ++++++-
include/hw/mips/cpudevs.h | 2 ++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/hw/mips/addr.c b/hw/mips/addr.c
index 99488f1d2a6f..ff3b952600bb 100644
--- a/hw/mips/addr.c
+++ b/hw/mips/addr.c
@@ -25,10 +25,15 @@
uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr)
{
- return addr & 0x7fffffffll;
+ return addr & 0x1fffffffll;
}
uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr)
{
return addr | ~0x7fffffffll;
}
+
+uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr)
+{
+ return addr | 0x40000000ll;
+}
diff --git a/include/hw/mips/cpudevs.h b/include/hw/mips/cpudevs.h
index 6bea24bf102d..b2626f2922f4 100644
--- a/include/hw/mips/cpudevs.h
+++ b/include/hw/mips/cpudevs.h
@@ -5,6 +5,8 @@
/* mips_addr.c */
uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr);
uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr);
+uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr);
+
/* mips_int.c */
void cpu_mips_irq_init_cpu(CPUMIPSState *env);
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 04/12] target-mips: get_physical_address: Add defines for segment bases
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (2 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 03/12] hw/mips: Add API to convert KVM guest KSEG0 <-> GPA James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 05/12] target-mips: get_physical_address: Add KVM awareness James Hogan
` (9 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
Add preprocessor definitions for 32bit segment bases for use in
get_physical_address(). These will also be taken advantage of in the
next patch which adds KVM awareness.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
---
target-mips/helper.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 064622cc31ba..caacd762fd90 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -118,7 +118,13 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
qemu_log("user mode %d h %08x\n", user_mode, env->hflags);
#endif
- if (address <= (int32_t)0x7FFFFFFFUL) {
+#define USEG_LIMIT 0x7FFFFFFFUL
+#define KSEG0_BASE 0x80000000UL
+#define KSEG1_BASE 0xA0000000UL
+#define KSEG2_BASE 0xC0000000UL
+#define KSEG3_BASE 0xE0000000UL
+
+ if (address <= USEG_LIMIT) {
/* useg */
if (env->CP0_Status & (1 << CP0St_ERL)) {
*physical = address & 0xFFFFFFFF;
@@ -160,23 +166,23 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
ret = TLBRET_BADADDR;
}
#endif
- } else if (address < (int32_t)0xA0000000UL) {
+ } else if (address < (int32_t)KSEG1_BASE) {
/* kseg0 */
if (kernel_mode) {
- *physical = address - (int32_t)0x80000000UL;
+ *physical = address - (int32_t)KSEG0_BASE;
*prot = PAGE_READ | PAGE_WRITE;
} else {
ret = TLBRET_BADADDR;
}
- } else if (address < (int32_t)0xC0000000UL) {
+ } else if (address < (int32_t)KSEG2_BASE) {
/* kseg1 */
if (kernel_mode) {
- *physical = address - (int32_t)0xA0000000UL;
+ *physical = address - (int32_t)KSEG1_BASE;
*prot = PAGE_READ | PAGE_WRITE;
} else {
ret = TLBRET_BADADDR;
}
- } else if (address < (int32_t)0xE0000000UL) {
+ } else if (address < (int32_t)KSEG3_BASE) {
/* sseg (kseg2) */
if (supervisor_mode || kernel_mode) {
ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 05/12] target-mips: get_physical_address: Add KVM awareness
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (3 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 04/12] target-mips: get_physical_address: Add defines for segment bases James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 06/12] kvm: Allow arch to set sigmask length James Hogan
` (8 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
MIPS KVM trap & emulate mode (which is currently the only supported
mode) has to add an extra kseg0/kseg1 at 0x40000000 and an extra
kseg2/kseg3 at 0x60000000. Take this into account in
get_physical_address() so that debug memory access works.
This is done by translating the address to a standard kseg0 or kseg2
address before doing the normal address translation. The real virtual
address is still used for TLB lookups.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
target-mips/helper.c | 33 ++++++++++++++++++++++++++-------
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/target-mips/helper.c b/target-mips/helper.c
index caacd762fd90..8a997e44e5ac 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -24,6 +24,7 @@
#include <signal.h>
#include "cpu.h"
+#include "sysemu/kvm.h"
enum {
TLBRET_DIRTY = -4,
@@ -100,7 +101,7 @@ int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
}
static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
- int *prot, target_ulong address,
+ int *prot, target_ulong real_address,
int rw, int access_type)
{
/* User mode can only access useg/xuseg */
@@ -113,6 +114,8 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
#endif
int ret = TLBRET_MATCH;
+ /* effective address (modified for KVM T&E kernel segments) */
+ target_ulong address = real_address;
#if 0
qemu_log("user mode %d h %08x\n", user_mode, env->hflags);
@@ -124,19 +127,35 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
#define KSEG2_BASE 0xC0000000UL
#define KSEG3_BASE 0xE0000000UL
+#define KVM_KSEG0_BASE 0x40000000UL
+#define KVM_KSEG2_BASE 0x60000000UL
+
+ if (kvm_enabled()) {
+ /* KVM T&E adds guest kernel segments in useg */
+ if (real_address >= KVM_KSEG0_BASE) {
+ if (real_address < KVM_KSEG2_BASE) {
+ /* kseg0 */
+ address += KSEG0_BASE - KVM_KSEG0_BASE;
+ } else if (real_address <= USEG_LIMIT) {
+ /* kseg2/3 */
+ address += KSEG2_BASE - KVM_KSEG2_BASE;
+ }
+ }
+ }
+
if (address <= USEG_LIMIT) {
/* useg */
if (env->CP0_Status & (1 << CP0St_ERL)) {
*physical = address & 0xFFFFFFFF;
*prot = PAGE_READ | PAGE_WRITE;
} else {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
}
#if defined(TARGET_MIPS64)
} else if (address < 0x4000000000000000ULL) {
/* xuseg */
if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -144,7 +163,7 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
/* xsseg */
if ((supervisor_mode || kernel_mode) &&
SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -161,7 +180,7 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
/* xkseg */
if (kernel_mode && KX &&
address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -185,7 +204,7 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
} else if (address < (int32_t)KSEG3_BASE) {
/* sseg (kseg2) */
if (supervisor_mode || kernel_mode) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -193,7 +212,7 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
/* kseg3 */
/* XXX: debug segment is not emulated */
if (kernel_mode) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
} else {
ret = TLBRET_BADADDR;
}
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 06/12] kvm: Allow arch to set sigmask length
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (4 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 05/12] target-mips: get_physical_address: Add KVM awareness James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 07/12] target-mips: kvm: Add main KVM support for MIPS James Hogan
` (7 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, Sanjay Lal,
Paolo Bonzini, Aurelien Jarno
MIPS/Linux is unusual in having 128 signals rather than just 64 like
most other architectures. This means its sigmask is 16 bytes instead of
8, so allow arches to override the sigmask->len value passed to the
KVM_SET_SIGNAL_MASK ioctl in kvm_set_signal_mask() by calling
kvm_set_sigmask_len() from kvm_arch_init(). Otherwise default to 8
bytes.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Sanjay Lal <sanjayl@kymasys.com>
Cc: Gleb Natapov <gleb@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
---
Changes in v3:
- Rewrote to allow sigmask length to be set by kvm_arch_init(), so that
MIPS can set it to 16 as it has 128 signals. This is better than
cluttering kvm-all.c with TARGET_* ifdefs (Peter Maydell).
Changes in v2:
- Expand commit message
- Reword comment
---
include/sysemu/kvm.h | 2 ++
kvm-all.c | 11 ++++++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index e79e92c50e3f..de4bdaa40e56 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -325,6 +325,8 @@ int kvm_check_extension(KVMState *s, unsigned int extension);
uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
uint32_t index, int reg);
+void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
+
#if !defined(CONFIG_USER_ONLY)
int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
hwaddr *phys_addr);
diff --git a/kvm-all.c b/kvm-all.c
index 4e19eff0efee..0d485b644539 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -99,6 +99,7 @@ struct KVMState
* they're not. Linux, glibc and *BSD all treat ioctl numbers as
* unsigned, and treating them as signed here can break things */
unsigned irq_set_ioctl;
+ unsigned int sigmask_len;
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing *irq_routes;
int nr_allocated_irq_routes;
@@ -1397,6 +1398,8 @@ int kvm_init(MachineClass *mc)
assert(TARGET_PAGE_SIZE <= getpagesize());
page_size_init();
+ s->sigmask_len = 8;
+
#ifdef KVM_CAP_SET_GUEST_DEBUG
QTAILQ_INIT(&s->kvm_sw_breakpoints);
#endif
@@ -1575,6 +1578,11 @@ err:
return ret;
}
+void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len)
+{
+ s->sigmask_len = sigmask_len;
+}
+
static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
uint32_t count)
{
@@ -2095,6 +2103,7 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
{
+ KVMState *s = kvm_state;
struct kvm_signal_mask *sigmask;
int r;
@@ -2104,7 +2113,7 @@ int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
sigmask = g_malloc(sizeof(*sigmask) + sizeof(*sigset));
- sigmask->len = 8;
+ sigmask->len = s->sigmask_len;
memcpy(sigmask->sigset, sigset, sizeof(*sigset));
r = kvm_vcpu_ioctl(cpu, KVM_SET_SIGNAL_MASK, sigmask);
g_free(sigmask);
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 07/12] target-mips: kvm: Add main KVM support for MIPS
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (5 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 06/12] kvm: Allow arch to set sigmask length James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 08/12] target-mips: Call kvm_mips_reset_vcpu() from mips_cpu_reset() James Hogan
` (6 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, Sanjay Lal,
Paolo Bonzini, Andreas Färber, Aurelien Jarno
From: Sanjay Lal <sanjayl@kymasys.com>
Implement the main KVM arch API for MIPS.
Signed-off-by: Sanjay Lal <sanjayl@kymasys.com>
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Gleb Natapov <gleb@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Andreas Färber <afaerber@suse.de>
Cc: Peter Maydell <peter.maydell@linaro.org>
---
Changes in v5:
- Rename kvm_arch_reset_vcpu to kvm_mips_reset_vcpu based on commit
50a2c6e55fa2 (kvm: reset state from the CPU's reset method).
- Rename kvm_mips_te_{put,get}_cp0_registers() functions to drop the
"te_" since they're not really specific to T&E.
- Pass level through from kvm_arch_put_registers() to
kvm_mips_put_cp0_registers() rather than hard coding it to
KVM_PUT_FULL_STATE.
- Fix KVM_REG_MIPS_CP0_* definitions to set KVM_REG_MIPS and
KVM_REG_SIZE_U32/KVM_REG_SIZE_U64 (using a macro).
- Remove unused KVM_REG_MIPS_CP0_* definitions for now.
- Correct type of kvm_mips_{get,put}_one_{,ul}reg() reg_id argument to
uint64_t. Various high bits must be set to disambiguate the
architecture and register size.
- Add register accessors for always-64-bit registers (rather than ulong
registers). These are needed for virtual KVM registers for
controlling the KVM Compare/Count timer.
- Simplify register access functions slightly.
- Save and restore KVM timer state with the rest of the state, and also
when VM clock is started or stopped. When the KVM timer state is
restored (or VM clock restarted) it is resumed with the stored count
at the monotonic time when the VM clock was last stopped. If the VM
clock hasn't been stopped it resumes from the monotonic time when the
state was saved (i.e. as if the timer was never stopped).
Changes since RFC patch on kernel KVM thread "[PATCH v2 00/23] MIPS:
KVM: Fixes and guest timer rewrite"):
- Simplified, removing extra state for storing VM time of
save/restore, at the cost of losing/gaining time when VM gets
stopped and started (Paolo Bonzini).
- Save and restore the UserLocal and HWREna CP0 registers.
- Improve get/put KVM register error handling with DPRINTFs and fall
through so that getting/putting of all the registers is attempted
even if one of them fails due to being unimplemented in the kernel.
Changes in v4:
(No functional changes, assembly output unchanged)
- Use int32_t instead of int32 (which is for softfloat) in kvm register
accessors (Andreas Färber).
- Use uint64_t instead of __u64 (which is really just for kernel
headers) in the kvm register accessors (Andreas Färber).
- Cast pointer to uintptr_t rather than target_ulong in kvm register
accessors.
- Remove some redundant casts in kvm register accessors.
Changes in v3:
- s/dprintf/DPRINTF/ (Andreas Färber).
- Use "cs" rather than "cpu" or "env" for CPUState variable names
(Andreas Färber).
- Use CPUMIPSState rather than CPUArchState (Andreas Färber).
- Pass MIPSCPU to cpu_mips_io_interrupts_pending() rather than
CPUMIPSState (Andreas Färber).
- Remove spurious parentheses around cpu_mips_io_interrupts_pending()
call (Andreas Färber).
- Pass MIPSCPU to kvm_mips_set_[ipi_]interrupt (Andreas Färber).
- Make use of error_report (Andreas Färber) and clean up error messages
a little to include __func__.
- Remove inline kvm_mips_{put,get}_one_[ul]reg() declarations from
kvm_mips.h. They're only used in target-mips/kvm.c anyway.
- Make kvm_arch_{put,get}_registers static within target-mips/kvm.c and
remove from kvm_mips.h.
- Set sigmask length to 16 from kvm_arch_init() since MIPS Linux has
128 signals. This is better than cluttering kvm_all.c with TARGET_*
ifdefs (Peter Maydell).
Changes in v2:
- Expand commit message
- Checkpatch cleanups.
- Some interrupt bug fixes from Yann Le Du <ledu@kymasys.com>
- Add get/set register functionality from Yann Le Du <ledu@kymasys.com>
- Use new 64 bit compatible ABI from Cavium from Sanjay Lal
<sanjayl@kymasys.com>
- Add dummy kvm_arch_init_irq_routing()
The common KVM code insists on calling kvm_arch_init_irq_routing() as
soon as it sees kernel header support for it (regardless of whether
QEMU supports it). Provide a dummy function to satisfy this.
- Remove request_interrupt_window code (Peter Maydell)
---
target-mips/kvm.c | 683 +++++++++++++++++++++++++++++++++++++++++++++++++
target-mips/kvm_mips.h | 26 ++
2 files changed, 709 insertions(+)
create mode 100644 target-mips/kvm.c
create mode 100644 target-mips/kvm_mips.h
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
new file mode 100644
index 000000000000..844e5bbe5f92
--- /dev/null
+++ b/target-mips/kvm.c
@@ -0,0 +1,683 @@
+/*
+ * 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.
+ *
+ * KVM/MIPS: MIPS specific KVM APIs
+ *
+ * Copyright (C) 2012-2014 Imagination Technologies Ltd.
+ * Authors: Sanjay Lal <sanjayl@kymasys.com>
+*/
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <linux/kvm.h>
+
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
+#include "cpu.h"
+#include "sysemu/cpus.h"
+#include "kvm_mips.h"
+
+#define DEBUG_KVM 0
+
+#define DPRINTF(fmt, ...) \
+ do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0)
+
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+ KVM_CAP_LAST_INFO
+};
+
+static void kvm_mips_update_state(void *opaque, int running, RunState state);
+
+unsigned long kvm_arch_vcpu_id(CPUState *cs)
+{
+ return cs->cpu_index;
+}
+
+int kvm_arch_init(KVMState *s)
+{
+ /* MIPS has 128 signals */
+ kvm_set_sigmask_len(s, 16);
+
+ DPRINTF("%s\n", __func__);
+ return 0;
+}
+
+int kvm_arch_init_vcpu(CPUState *cs)
+{
+ int ret = 0;
+
+ qemu_add_vm_change_state_handler(kvm_mips_update_state, cs);
+
+ DPRINTF("%s\n", __func__);
+ return ret;
+}
+
+void kvm_mips_reset_vcpu(MIPSCPU *cpu)
+{
+ DPRINTF("%s\n", __func__);
+}
+
+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
+{
+ DPRINTF("%s\n", __func__);
+ return 0;
+}
+
+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
+{
+ DPRINTF("%s\n", __func__);
+ return 0;
+}
+
+static inline int cpu_mips_io_interrupts_pending(MIPSCPU *cpu)
+{
+ CPUMIPSState *env = &cpu->env;
+
+ DPRINTF("%s: %#x\n", __func__, env->CP0_Cause & (1 << (2 + CP0Ca_IP)));
+ return env->CP0_Cause & (0x1 << (2 + CP0Ca_IP));
+}
+
+
+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ int r;
+ struct kvm_mips_interrupt intr;
+
+ if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
+ cpu_mips_io_interrupts_pending(cpu)) {
+ intr.cpu = -1;
+ intr.irq = 2;
+ r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
+ if (r < 0) {
+ error_report("%s: cpu %d: failed to inject IRQ %x",
+ __func__, cs->cpu_index, intr.irq);
+ }
+ }
+}
+
+void kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
+{
+ DPRINTF("%s\n", __func__);
+}
+
+int kvm_arch_process_async_events(CPUState *cs)
+{
+ return cs->halted;
+}
+
+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
+{
+ int ret;
+
+ DPRINTF("%s\n", __func__);
+ switch (run->exit_reason) {
+ default:
+ error_report("%s: unknown exit reason %d",
+ __func__, run->exit_reason);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+bool kvm_arch_stop_on_emulation_error(CPUState *cs)
+{
+ DPRINTF("%s\n", __func__);
+ return true;
+}
+
+int kvm_arch_on_sigbus_vcpu(CPUState *cs, int code, void *addr)
+{
+ DPRINTF("%s\n", __func__);
+ return 1;
+}
+
+int kvm_arch_on_sigbus(int code, void *addr)
+{
+ DPRINTF("%s\n", __func__);
+ return 1;
+}
+
+void kvm_arch_init_irq_routing(KVMState *s)
+{
+}
+
+int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level)
+{
+ CPUState *cs = CPU(cpu);
+ struct kvm_mips_interrupt intr;
+
+ if (!kvm_enabled()) {
+ return 0;
+ }
+
+ intr.cpu = -1;
+
+ if (level) {
+ intr.irq = irq;
+ } else {
+ intr.irq = -irq;
+ }
+
+ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
+
+ return 0;
+}
+
+int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level)
+{
+ CPUState *cs = current_cpu;
+ CPUState *dest_cs = CPU(cpu);
+ struct kvm_mips_interrupt intr;
+
+ if (!kvm_enabled()) {
+ return 0;
+ }
+
+ intr.cpu = dest_cs->cpu_index;
+
+ if (level) {
+ intr.irq = irq;
+ } else {
+ intr.irq = -irq;
+ }
+
+ DPRINTF("%s: CPU %d, IRQ: %d\n", __func__, intr.cpu, intr.irq);
+
+ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
+
+ return 0;
+}
+
+#define MIPS_CP0_32(_R, _S) \
+ (KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x10000 | (8 * (_R) + (_S)))
+
+#define MIPS_CP0_64(_R, _S) \
+ (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x10000 | (8 * (_R) + (_S)))
+
+#define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0)
+#define KVM_REG_MIPS_CP0_CONTEXT MIPS_CP0_64(4, 0)
+#define KVM_REG_MIPS_CP0_USERLOCAL MIPS_CP0_64(4, 2)
+#define KVM_REG_MIPS_CP0_PAGEMASK MIPS_CP0_32(5, 0)
+#define KVM_REG_MIPS_CP0_WIRED MIPS_CP0_32(6, 0)
+#define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0)
+#define KVM_REG_MIPS_CP0_BADVADDR MIPS_CP0_64(8, 0)
+#define KVM_REG_MIPS_CP0_COUNT MIPS_CP0_32(9, 0)
+#define KVM_REG_MIPS_CP0_ENTRYHI MIPS_CP0_64(10, 0)
+#define KVM_REG_MIPS_CP0_COMPARE MIPS_CP0_32(11, 0)
+#define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0)
+#define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0)
+#define KVM_REG_MIPS_CP0_EPC MIPS_CP0_64(14, 0)
+#define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0)
+
+/* CP0_Count control */
+#define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
+ 0x20000 | 0)
+#define KVM_REG_MIPS_COUNT_CTL_DC 0x00000001 /* master disable */
+/* CP0_Count resume monotonic nanoseconds */
+#define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
+ 0x20000 | 1)
+/* CP0_Count rate in Hz */
+#define KVM_REG_MIPS_COUNT_HZ (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
+ 0x20000 | 2)
+
+static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
+ int32_t *addr)
+{
+ uint64_t val64 = *addr;
+ struct kvm_one_reg cp0reg = {
+ .id = reg_id,
+ .addr = (uintptr_t)&val64
+ };
+
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_put_one_ulreg(CPUState *cs, uint64_t reg_id,
+ target_ulong *addr)
+{
+ uint64_t val64 = *addr;
+ struct kvm_one_reg cp0reg = {
+ .id = reg_id,
+ .addr = (uintptr_t)&val64
+ };
+
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_put_one_reg64(CPUState *cs, uint64_t reg_id,
+ uint64_t *addr)
+{
+ struct kvm_one_reg cp0reg = {
+ .id = reg_id,
+ .addr = (uintptr_t)addr
+ };
+
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_get_one_reg(CPUState *cs, uint64_t reg_id,
+ int32_t *addr)
+{
+ int ret;
+ uint64_t val64 = 0;
+ struct kvm_one_reg cp0reg = {
+ .id = reg_id,
+ .addr = (uintptr_t)&val64
+ };
+
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+ if (ret >= 0) {
+ *addr = val64;
+ }
+ return ret;
+}
+
+static inline int kvm_mips_get_one_ulreg(CPUState *cs, uint64 reg_id,
+ target_ulong *addr)
+{
+ int ret;
+ uint64_t val64 = 0;
+ struct kvm_one_reg cp0reg = {
+ .id = reg_id,
+ .addr = (uintptr_t)&val64
+ };
+
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+ if (ret >= 0) {
+ *addr = val64;
+ }
+ return ret;
+}
+
+static inline int kvm_mips_get_one_reg64(CPUState *cs, uint64 reg_id,
+ uint64_t *addr)
+{
+ struct kvm_one_reg cp0reg = {
+ .id = reg_id,
+ .addr = (uintptr_t)addr
+ };
+
+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+}
+
+/*
+ * We freeze the KVM timer when either the VM clock is stopped or the state is
+ * saved (the state is dirty).
+ */
+
+/*
+ * Save the state of the KVM timer when VM clock is stopped or state is synced
+ * to QEMU.
+ */
+static int kvm_mips_save_count(CPUState *cs)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ CPUMIPSState *env = &cpu->env;
+ uint64_t count_ctl;
+ int err, ret = 0;
+
+ /* freeze KVM timer */
+ err = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err);
+ ret = err;
+ } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
+ count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
+ err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+ if (err < 0) {
+ DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
+ ret = err;
+ }
+ }
+
+ /* read CP0_Cause */
+ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CAUSE, &env->CP0_Cause);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_CAUSE (%d)\n", __func__, err);
+ ret = err;
+ }
+
+ /* read CP0_Count */
+ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_COUNT, &env->CP0_Count);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_COUNT (%d)\n", __func__, err);
+ ret = err;
+ }
+
+ return ret;
+}
+
+/*
+ * Restore the state of the KVM timer when VM clock is restarted or state is
+ * synced to KVM.
+ */
+static int kvm_mips_restore_count(CPUState *cs)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ CPUMIPSState *env = &cpu->env;
+ uint64_t count_ctl;
+ int err_dc, err, ret = 0;
+
+ /* check the timer is frozen */
+ err_dc = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+ if (err_dc < 0) {
+ DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err_dc);
+ ret = err_dc;
+ } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
+ /* freeze timer (sets COUNT_RESUME for us) */
+ count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
+ err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+ if (err < 0) {
+ DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
+ ret = err;
+ }
+ }
+
+ /* load CP0_Cause */
+ err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_CAUSE, &env->CP0_Cause);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_CAUSE (%d)\n", __func__, err);
+ ret = err;
+ }
+
+ /* load CP0_Count */
+ err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_COUNT, &env->CP0_Count);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_COUNT (%d)\n", __func__, err);
+ ret = err;
+ }
+
+ /* resume KVM timer */
+ if (err_dc >= 0) {
+ count_ctl &= ~KVM_REG_MIPS_COUNT_CTL_DC;
+ err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+ if (err < 0) {
+ DPRINTF("%s: Failed to set COUNT_CTL.DC=0 (%d)\n", __func__, err);
+ ret = err;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Handle the VM clock being started or stopped
+ */
+static void kvm_mips_update_state(void *opaque, int running, RunState state)
+{
+ CPUState *cs = opaque;
+ int ret;
+ uint64_t count_resume;
+
+ /*
+ * If state is already dirty (synced to QEMU) then the KVM timer state is
+ * already saved and can be restored when it is synced back to KVM.
+ */
+ if (!running) {
+ if (!cs->kvm_vcpu_dirty) {
+ ret = kvm_mips_save_count(cs);
+ if (ret < 0) {
+ fprintf(stderr, "Failed saving count\n");
+ }
+ }
+ } else {
+ /* Set clock restore time to now */
+ count_resume = get_clock();
+ ret = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_RESUME,
+ &count_resume);
+ if (ret < 0) {
+ fprintf(stderr, "Failed setting COUNT_RESUME\n");
+ return;
+ }
+
+ if (!cs->kvm_vcpu_dirty) {
+ ret = kvm_mips_restore_count(cs);
+ if (ret < 0) {
+ fprintf(stderr, "Failed restoring count\n");
+ }
+ }
+ }
+}
+
+static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ CPUMIPSState *env = &cpu->env;
+ int err, ret = 0;
+
+ (void)level;
+
+ err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_INDEX, &env->CP0_Index);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_INDEX (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
+ &env->CP0_Context);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_CONTEXT (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_USERLOCAL,
+ &env->active_tc.CP0_UserLocal);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_USERLOCAL (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PAGEMASK,
+ &env->CP0_PageMask);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_PAGEMASK (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_WIRED (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_HWRENA (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_BADVADDR,
+ &env->CP0_BadVAddr);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_BADVADDR (%d)\n", __func__, err);
+ ret = err;
+ }
+
+ /* If VM clock stopped then state will be restored when it is restarted */
+ if (runstate_is_running()) {
+ err = kvm_mips_restore_count(cs);
+ if (err < 0) {
+ ret = err;
+ }
+ }
+
+ err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ENTRYHI,
+ &env->CP0_EntryHi);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_ENTRYHI (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_COMPARE,
+ &env->CP0_Compare);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_COMPARE (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_STATUS, &env->CP0_Status);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_STATUS (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_EPC, &env->CP0_EPC);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_EPC (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
+ &env->CP0_ErrorEPC);
+ if (err < 0) {
+ DPRINTF("%s: Failed to put CP0_ERROREPC (%d)\n", __func__, err);
+ ret = err;
+ }
+
+ return ret;
+}
+
+static int kvm_mips_get_cp0_registers(CPUState *cs)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ CPUMIPSState *env = &cpu->env;
+ int err, ret = 0;
+
+ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_INDEX, &env->CP0_Index);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_INDEX (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
+ &env->CP0_Context);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_CONTEXT (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_USERLOCAL,
+ &env->active_tc.CP0_UserLocal);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_USERLOCAL (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PAGEMASK,
+ &env->CP0_PageMask);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_PAGEMASK (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_WIRED (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_HWRENA (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_BADVADDR,
+ &env->CP0_BadVAddr);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_BADVADDR (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ENTRYHI,
+ &env->CP0_EntryHi);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_ENTRYHI (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_COMPARE,
+ &env->CP0_Compare);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_COMPARE (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_STATUS, &env->CP0_Status);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_STATUS (%d)\n", __func__, err);
+ ret = err;
+ }
+
+ /* If VM clock stopped then state was already saved when it was stopped */
+ if (runstate_is_running()) {
+ err = kvm_mips_save_count(cs);
+ if (err < 0) {
+ ret = err;
+ }
+ }
+
+ err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_EPC, &env->CP0_EPC);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_EPC (%d)\n", __func__, err);
+ ret = err;
+ }
+ err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
+ &env->CP0_ErrorEPC);
+ if (err < 0) {
+ DPRINTF("%s: Failed to get CP0_ERROREPC (%d)\n", __func__, err);
+ ret = err;
+ }
+
+ return ret;
+}
+
+int kvm_arch_put_registers(CPUState *cs, int level)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ CPUMIPSState *env = &cpu->env;
+ struct kvm_regs regs;
+ int ret;
+ int i;
+
+ /* Set the registers based on QEMU's view of things */
+ for (i = 0; i < 32; i++) {
+ regs.gpr[i] = env->active_tc.gpr[i];
+ }
+
+ regs.hi = env->active_tc.HI[0];
+ regs.lo = env->active_tc.LO[0];
+ regs.pc = env->active_tc.PC;
+
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = kvm_mips_put_cp0_registers(cs, level);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return ret;
+}
+
+int kvm_arch_get_registers(CPUState *cs)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ CPUMIPSState *env = &cpu->env;
+ int ret = 0;
+ struct kvm_regs regs;
+ int i;
+
+ /* Get the current register set as KVM seems it */
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s);
+
+ if (ret < 0) {
+ return ret;
+ }
+
+ for (i = 0; i < 32; i++) {
+ env->active_tc.gpr[i] = regs.gpr[i];
+ }
+
+ env->active_tc.HI[0] = regs.hi;
+ env->active_tc.LO[0] = regs.lo;
+ env->active_tc.PC = regs.pc;
+
+ kvm_mips_get_cp0_registers(cs);
+
+ return ret;
+}
diff --git a/target-mips/kvm_mips.h b/target-mips/kvm_mips.h
new file mode 100644
index 000000000000..54f59656efb3
--- /dev/null
+++ b/target-mips/kvm_mips.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ *
+ * KVM/MIPS: MIPS specific KVM APIs
+ *
+ * Copyright (C) 2012-2014 Imagination Technologies Ltd.
+ * Authors: Sanjay Lal <sanjayl@kymasys.com>
+*/
+
+#ifndef __KVM_MIPS_H__
+#define __KVM_MIPS_H__
+
+/**
+ * kvm_mips_reset_vcpu:
+ * @cpu: MIPSCPU
+ *
+ * Called at reset time to set kernel registers to their initial values.
+ */
+void kvm_mips_reset_vcpu(MIPSCPU *cpu);
+
+int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level);
+int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level);
+
+#endif /* __KVM_MIPS_H__ */
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 08/12] target-mips: Call kvm_mips_reset_vcpu() from mips_cpu_reset()
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (6 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 07/12] target-mips: kvm: Add main KVM support for MIPS James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 09/12] hw/mips: In KVM mode, inject IRQ2 (I/O) interrupts via ioctls James Hogan
` (5 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
When KVM is enabled call kvm_mips_reset_vcpu() from mips_cpu_reset() as
done for other targets since commit 50a2c6e55fa2 (kvm: reset state from
the CPU's reset method).
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
---
Changes in v5:
- New patch, based on commit 50a2c6e55fa2 (kvm: reset state from the
CPU's reset method).
---
target-mips/cpu.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index dd954fc55a10..b3e0e6cce7b6 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -19,7 +19,9 @@
*/
#include "cpu.h"
+#include "kvm_mips.h"
#include "qemu-common.h"
+#include "sysemu/kvm.h"
static void mips_cpu_set_pc(CPUState *cs, vaddr value)
@@ -87,6 +89,12 @@ static void mips_cpu_reset(CPUState *s)
tlb_flush(s, 1);
cpu_state_reset(env);
+
+#ifndef CONFIG_USER_ONLY
+ if (kvm_enabled()) {
+ kvm_mips_reset_vcpu(cpu);
+ }
+#endif
}
static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 09/12] hw/mips: In KVM mode, inject IRQ2 (I/O) interrupts via ioctls
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (7 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 08/12] target-mips: Call kvm_mips_reset_vcpu() from mips_cpu_reset() James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support James Hogan
` (4 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
From: Sanjay Lal <sanjayl@kymasys.com>
COP0 emulation is in-kernel for KVM, so inject IRQ2 (I/O) interrupts via
ioctls.
Signed-off-by: Sanjay Lal <sanjayl@kymasys.com>
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Andreas Färber <afaerber@suse.de>
---
Changes in v5:
- Fix typo in subject (s/interupts/interrupts/)
Changes in v3:
- Pass MIPSCPU to kvm_mips_set_[ipi_]interrupt (Andreas Färber).
Changes in v2:
- Expand commit message
- Remove #ifdef CONFIG_KVM since it's guarded by kvm_enabled() already
---
hw/mips/mips_int.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
index 7dbd24d3d6e5..d740046ba151 100644
--- a/hw/mips/mips_int.c
+++ b/hw/mips/mips_int.c
@@ -23,6 +23,8 @@
#include "hw/hw.h"
#include "hw/mips/cpudevs.h"
#include "cpu.h"
+#include "sysemu/kvm.h"
+#include "kvm_mips.h"
static void cpu_mips_irq_request(void *opaque, int irq, int level)
{
@@ -35,8 +37,17 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level)
if (level) {
env->CP0_Cause |= 1 << (irq + CP0Ca_IP);
+
+ if (kvm_enabled() && irq == 2) {
+ kvm_mips_set_interrupt(cpu, irq, level);
+ }
+
} else {
env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
+
+ if (kvm_enabled() && irq == 2) {
+ kvm_mips_set_interrupt(cpu, irq, level);
+ }
}
if (env->CP0_Cause & CP0Ca_IP_mask) {
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (8 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 09/12] hw/mips: In KVM mode, inject IRQ2 (I/O) interrupts via ioctls James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-19 16:27 ` Aurelien Jarno
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 11/12] target-mips: Enable KVM support in build system James Hogan
` (3 subsequent siblings)
13 siblings, 1 reply; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, Sanjay Lal,
Paolo Bonzini, Aurelien Jarno
In KVM mode the bootrom is loaded and executed from the last 1MB of
DRAM.
Based on "[PATCH 12/12] KVM/MIPS: General KVM support and support for
SMP Guests" by Sanjay Lal <sanjayl@kymasys.com>.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Sanjay Lal <sanjayl@kymasys.com>
---
Changes in v5:
- Kseg0 doesn't actually change size, so use cpu_mips_kseg0_to_phys()
rather than having the KVM specific cpu_mips_kvm_um_kseg0_to_phys().
Changes in v3:
- Remove unnecessary includes, especially linux/kvm.h which isn't a
good idea on non-Linux (Peter Maydell).
Changes in v2:
- Removal of cps / GIC / SMP support
- Minimal bootloader modified to execute safely from RAM
- Remove "Writing bootloader to final 1MB of RAM" printf
---
hw/mips/mips_malta.c | 73 ++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 53 insertions(+), 20 deletions(-)
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index f4a7d4712952..8bc5392b4223 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -51,6 +51,7 @@
#include "sysemu/qtest.h"
#include "qemu/error-report.h"
#include "hw/empty_slot.h"
+#include "sysemu/kvm.h"
//#define DEBUG_BOARD_INIT
@@ -603,29 +604,31 @@ static void network_init(PCIBus *pci_bus)
*/
static void write_bootloader (CPUMIPSState *env, uint8_t *base,
- int64_t kernel_entry)
+ int64_t run_addr, int64_t kernel_entry)
{
uint32_t *p;
/* Small bootloader */
p = (uint32_t *)base;
- stl_p(p++, 0x0bf00160); /* j 0x1fc00580 */
+
+ stl_p(p++, 0x08000000 | /* j 0x1fc00580 */
+ ((run_addr + 0x580) & 0x0fffffff) >> 2);
stl_p(p++, 0x00000000); /* nop */
/* YAMON service vector */
- stl_p(base + 0x500, 0xbfc00580); /* start: */
- stl_p(base + 0x504, 0xbfc0083c); /* print_count: */
- stl_p(base + 0x520, 0xbfc00580); /* start: */
- stl_p(base + 0x52c, 0xbfc00800); /* flush_cache: */
- stl_p(base + 0x534, 0xbfc00808); /* print: */
- stl_p(base + 0x538, 0xbfc00800); /* reg_cpu_isr: */
- stl_p(base + 0x53c, 0xbfc00800); /* unred_cpu_isr: */
- stl_p(base + 0x540, 0xbfc00800); /* reg_ic_isr: */
- stl_p(base + 0x544, 0xbfc00800); /* unred_ic_isr: */
- stl_p(base + 0x548, 0xbfc00800); /* reg_esr: */
- stl_p(base + 0x54c, 0xbfc00800); /* unreg_esr: */
- stl_p(base + 0x550, 0xbfc00800); /* getchar: */
- stl_p(base + 0x554, 0xbfc00800); /* syscon_read: */
+ stl_p(base + 0x500, run_addr + 0x0580); /* start: */
+ stl_p(base + 0x504, run_addr + 0x083c); /* print_count: */
+ stl_p(base + 0x520, run_addr + 0x0580); /* start: */
+ stl_p(base + 0x52c, run_addr + 0x0800); /* flush_cache: */
+ stl_p(base + 0x534, run_addr + 0x0808); /* print: */
+ stl_p(base + 0x538, run_addr + 0x0800); /* reg_cpu_isr: */
+ stl_p(base + 0x53c, run_addr + 0x0800); /* unred_cpu_isr: */
+ stl_p(base + 0x540, run_addr + 0x0800); /* reg_ic_isr: */
+ stl_p(base + 0x544, run_addr + 0x0800); /* unred_ic_isr: */
+ stl_p(base + 0x548, run_addr + 0x0800); /* reg_esr: */
+ stl_p(base + 0x54c, run_addr + 0x0800); /* unreg_esr: */
+ stl_p(base + 0x550, run_addr + 0x0800); /* getchar: */
+ stl_p(base + 0x554, run_addr + 0x0800); /* syscon_read: */
/* Second part of the bootloader */
@@ -701,7 +704,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
p = (uint32_t *) (base + 0x800);
stl_p(p++, 0x03e00008); /* jr ra */
stl_p(p++, 0x24020000); /* li v0,0 */
- /* 808 YAMON print */
+ /* 808 YAMON print */
stl_p(p++, 0x03e06821); /* move t5,ra */
stl_p(p++, 0x00805821); /* move t3,a0 */
stl_p(p++, 0x00a05021); /* move t2,a1 */
@@ -774,6 +777,7 @@ static int64_t load_kernel (void)
uint32_t *prom_buf;
long prom_size;
int prom_index = 0;
+ uint64_t (*xlate_to_kseg0) (void *opaque, uint64_t addr);
#ifdef TARGET_WORDS_BIGENDIAN
big_endian = 1;
@@ -788,6 +792,11 @@ static int64_t load_kernel (void)
loaderparams.kernel_filename);
exit(1);
}
+ if (kvm_enabled()) {
+ xlate_to_kseg0 = cpu_mips_kvm_um_phys_to_kseg0;
+ } else {
+ xlate_to_kseg0 = cpu_mips_phys_to_kseg0;
+ }
/* load initrd */
initrd_size = 0;
@@ -820,7 +829,7 @@ static int64_t load_kernel (void)
prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
if (initrd_size > 0) {
prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
- cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
+ xlate_to_kseg0(NULL, initrd_offset), initrd_size,
loaderparams.kernel_cmdline);
} else {
prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
@@ -829,6 +838,7 @@ static int64_t load_kernel (void)
prom_set(prom_buf, prom_index++, "memsize");
prom_set(prom_buf, prom_index++, "%i",
MIN(loaderparams.ram_size, 256 << 20));
+
prom_set(prom_buf, prom_index++, "modetty0");
prom_set(prom_buf, prom_index++, "38400n8r");
prom_set(prom_buf, prom_index++, NULL);
@@ -863,6 +873,11 @@ static void main_cpu_reset(void *opaque)
}
malta_mips_config(cpu);
+
+ if (kvm_enabled()) {
+ /* Start running from the bootloader we wrote to end of RAM */
+ env->active_tc.PC = 0x40000000 + loaderparams.ram_size;
+ }
}
static void cpu_request_exit(void *opaque, int irq, int level)
@@ -878,6 +893,7 @@ static
void mips_malta_init(MachineState *machine)
{
ram_addr_t ram_size = machine->ram_size;
+ ram_addr_t ram_low_size;
const char *cpu_model = machine->cpu_model;
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
@@ -892,7 +908,7 @@ void mips_malta_init(MachineState *machine)
target_long bios_size = FLASH_SIZE;
const size_t smbus_eeprom_size = 8 * 256;
uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
- int64_t kernel_entry;
+ int64_t kernel_entry, bootloader_run_addr;
PCIBus *pci_bus;
ISABus *isa_bus;
MIPSCPU *cpu;
@@ -1011,13 +1027,30 @@ void mips_malta_init(MachineState *machine)
bios = pflash_cfi01_get_memory(fl);
fl_idx++;
if (kernel_filename) {
+ ram_low_size = MIN(ram_size, 256 << 20);
+ /* For KVM T&E we reserve 1MB of RAM for running bootloader */
+ if (kvm_enabled()) {
+ ram_low_size -= 0x100000;
+ bootloader_run_addr = 0x40000000 + ram_low_size;
+ } else {
+ bootloader_run_addr = 0xbfc00000;
+ }
+
/* Write a small bootloader to the flash location. */
- loaderparams.ram_size = MIN(ram_size, 256 << 20);
+ loaderparams.ram_size = ram_low_size;
loaderparams.kernel_filename = kernel_filename;
loaderparams.kernel_cmdline = kernel_cmdline;
loaderparams.initrd_filename = initrd_filename;
kernel_entry = load_kernel();
- write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
+
+ write_bootloader(env, memory_region_get_ram_ptr(bios),
+ bootloader_run_addr, kernel_entry);
+ if (kvm_enabled()) {
+ /* Write the bootloader code @ the end of RAM, 1MB reserved */
+ write_bootloader(env, memory_region_get_ram_ptr(ram_low_preio) +
+ ram_low_size,
+ bootloader_run_addr, kernel_entry);
+ }
} else {
/* Load firmware from flash. */
if (!dinfo) {
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 11/12] target-mips: Enable KVM support in build system
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (9 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 12/12] MAINTAINERS: Add entry for MIPS KVM James Hogan
` (2 subsequent siblings)
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
From: Sanjay Lal <sanjayl@kymasys.com>
Enable KVM support for MIPS in the build system.
Signed-off-by: Sanjay Lal <sanjayl@kymasys.com>
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Expand commit message
- Remove GIC code
- Create asm-mips symlink using generic code and move above default
case (Peter Maydell)
- Remove redundant check of target_name = cpu = mips
- Remove mipsel cross compilation fix, which is now fixed by
commit 61cc919f73ea (configure: detect endian via compile test)
---
configure | 6 +++++-
target-mips/Makefile.objs | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index 27d84d9fdbe4..a32e651aa421 100755
--- a/configure
+++ b/configure
@@ -4830,6 +4830,9 @@ if test "$linux" = "yes" ; then
aarch64)
linux_arch=arm64
;;
+ mips64)
+ linux_arch=mips
+ ;;
*)
# For most CPUs the kernel architecture name and QEMU CPU name match.
linux_arch="$cpu"
@@ -5028,7 +5031,7 @@ case "$target_name" in
*)
esac
case "$target_name" in
- aarch64|arm|i386|x86_64|ppcemb|ppc|ppc64|s390x)
+ aarch64|arm|i386|x86_64|ppcemb|ppc|ppc64|s390x|mipsel|mips)
# Make sure the target and host cpus are compatible
if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
\( "$target_name" = "$cpu" -o \
@@ -5036,6 +5039,7 @@ case "$target_name" in
\( "$target_name" = "ppc64" -a "$cpu" = "ppc" \) -o \
\( "$target_name" = "ppc" -a "$cpu" = "ppc64" \) -o \
\( "$target_name" = "ppcemb" -a "$cpu" = "ppc64" \) -o \
+ \( "$target_name" = "mipsel" -a "$cpu" = "mips" \) -o \
\( "$target_name" = "x86_64" -a "$cpu" = "i386" \) -o \
\( "$target_name" = "i386" -a "$cpu" = "x86_64" \) \) ; then
echo "CONFIG_KVM=y" >> $config_target_mak
diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs
index 0277d56e8252..716244f3d5f3 100644
--- a/target-mips/Makefile.objs
+++ b/target-mips/Makefile.objs
@@ -1,3 +1,4 @@
obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
obj-y += gdbstub.o
obj-$(CONFIG_SOFTMMU) += machine.o
+obj-$(CONFIG_KVM) += kvm.o
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH v5 12/12] MAINTAINERS: Add entry for MIPS KVM
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (10 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 11/12] target-mips: Enable KVM support in build system James Hogan
@ 2014-06-17 22:10 ` James Hogan
2014-06-18 15:00 ` [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors Paolo Bonzini
2014-07-10 12:17 ` Peter Maydell
13 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-17 22:10 UTC (permalink / raw)
To: qemu-devel
Cc: James Hogan, kvm, Gleb Natapov, Sanjay Lal, Paolo Bonzini,
Aurelien Jarno
Add MAINTAINERS entry for MIPS KVM.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
---
Changes in v4:
- Add MAINTAINERS entry for MIPS KVM.
---
MAINTAINERS | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 51a6f51842be..0a637c90c679 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -176,6 +176,11 @@ M: Peter Maydell <peter.maydell@linaro.org>
S: Maintained
F: target-arm/kvm.c
+MIPS
+M: James Hogan <james.hogan@imgtec.com>
+S: Maintained
+F: target-mips/kvm.c
+
PPC
M: Alexander Graf <agraf@suse.de>
S: Maintained
--
1.9.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (11 preceding siblings ...)
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 12/12] MAINTAINERS: Add entry for MIPS KVM James Hogan
@ 2014-06-18 15:00 ` Paolo Bonzini
2014-06-19 16:29 ` Aurelien Jarno
2014-07-10 12:17 ` Peter Maydell
13 siblings, 1 reply; 32+ messages in thread
From: Paolo Bonzini @ 2014-06-18 15:00 UTC (permalink / raw)
To: James Hogan, qemu-devel; +Cc: Sanjay Lal, Gleb Natapov, Aurelien Jarno, kvm
Il 18/06/2014 00:10, James Hogan ha scritto:
> The patchset depends on v4 of "target-mips: implement UserLocal
> Register". I'm aiming for QEMU 2.1, hopefully it isn't too late to get
> some final review.
>
> Thanks to everybody who has already taken part in review.
>
> This patchset implements KVM support for MIPS32 processors, using Trap &
> Emulation.
>
> In KVM mode, CPU virtualization is handled via the kvm kernel module,
> while system and I/O virtualization leverage the Malta model already
> present in QEMU.
>
> Both Guest kernel and Guest Userspace execute in UM. The Guest address
> space is as folows:
> Guest User address space: 0x00000000 -> 0x40000000
> Guest Kernel Unmapped: 0x40000000 -> 0x60000000
> Guest Kernel Mapped: 0x60000000 -> 0x80000000
>
> As a result, Guest Usermode virtual memory is limited to 1GB.
>
> KVM support (by trap and emulate) was added to the Linux kernel in
> v3.10. This patchset partly depends on MIPS KVM work which will land in
> v3.16 (for example to save/restore the state of various registers and
> the KVM Count/Compare timer).
>
> Changes in v5:
>
> Changes addressing review comments from v4 patchset, and to use the MIPS
> KVM timer API added in v3.16.
>
> A git tag for this version of the patchset can also be found on github:
> https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v5
>
> - Rebase on master + v4 of "target-mips: implement UserLocal Register".
> - New patch ([01/12] target-mips: Reset CPU timer consistently) to
> address timer reset behaviour (reported by Paolo Bonzini).
> - New patch ([08/12] target-mips: Call kvm_mips_reset_vcpu() from
> mips_cpu_reset()) and rename kvm_arch_reset_vcpu to
> kvm_mips_reset_vcpu, based on commit 50a2c6e55fa2 (kvm: reset state
> from the CPU's reset method).
> - KSEG0 doesn't actually change size, so fix mask in
> cpu_mips_kseg0_to_phys() (patch 3) and use that instead of having the
> KVM specific cpu_mips_kvm_um_kseg0_to_phys() (patch 10).
> - Fix typo in patch 9 subject (s/interupts/interrupts/).
> - Rename kvm_mips_te_{put,get}_cp0_registers() functions to drop the
> "te_" since they're not really specific to T&E.
> - Pass level through from kvm_arch_put_registers() to
> kvm_mips_put_cp0_registers() rather than hard coding it to
> KVM_PUT_FULL_STATE.
> - Fix KVM_REG_MIPS_CP0_* definitions to set KVM_REG_MIPS and
> KVM_REG_SIZE_U32/KVM_REG_SIZE_U64 (using a macro).
> - Remove unused KVM_REG_MIPS_CP0_* definitions for now.
> - Correct type of kvm_mips_{get,put}_one_{,ul}reg() reg_id argument to
> uint64_t. Various high bits must be set to disambiguate the
> architecture and register size.
> - Simplify register access functions slightly.
> - Add register accessors for always-64-bit registers (rather than ulong
> registers). These are needed for virtual KVM registers for
> controlling the KVM Compare/Count timer.
> - Save and restore KVM timer state with the rest of the state, and also
> when VM clock is started or stopped. When the KVM timer state is
> restored (or VM clock restarted) it is resumed with the stored count
> at the monotonic time when the VM clock was last stopped. If the VM
> clock hasn't been stopped it resumes from the monotonic time when the
> state was saved (i.e. as if the timer was never stopped).
> Changes since RFC patch on kernel KVM thread "[PATCH v2 00/23] MIPS:
> KVM: Fixes and guest timer rewrite"):
> - Simplified, removing extra state for storing VM time of
> save/restore, at the cost of losing/gaining time when VM gets
> stopped and started (Paolo Bonzini).
> - Save and restore the UserLocal and HWREna CP0 registers.
> - Improve get/put KVM register error handling with DPRINTFs and fall
> through so that getting/putting of all the registers is attempted
> even if one of them fails due to being unimplemented in the kernel.
>
> Changes in v4:
>
> Changes mostly addressing a few review comments from v3 patchset.
>
> A git tag for this version of the patchset can also be found on github:
> https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v4
>
> - Rebase on v2.0.0-rc0.
> - Use int32_t instead of int32 (which is for softfloat) in kvm register
> accessors (Andreas Färber).
> - Use uint64_t instead of __u64 (which is really just for kernel
> headers) in the kvm register accessors (Andreas Färber).
> - Cast pointer to uintptr_t rather than target_ulong in kvm register
> accessors.
> - Remove some redundant casts in kvm register accessors.
> - Add MAINTAINERS entry for MIPS KVM.
>
> Changes in v3:
>
> Changes mostly addressing review comments from v2 patchset.
>
> A git tag for this version of the patchset can also be found on github:
> https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v3
>
> - Remove "target-mips: Set target page size to 16K in KVM mode". It
> should actually work fine with 4k TARGET_PAGE_SIZE as long as there
> is no cache aliasing or both host and guest kernels are configured to
> a sufficient page size to avoid aliasing (which the kernel
> arch/mips/kvm/00README.txt alludes to anyway).
> - Rewrote kvm sigmask patch to allow sigmask length to be set by
> kvm_arch_init(), so that MIPS can set it to 16 as it has 128 signals.
> This is better than cluttering kvm-all.c with TARGET_* ifdefs (Peter
> Maydell).
> - Set sigmask length to 16 from kvm_arch_init() since MIPS Linux has
> 128 signals. This is better than cluttering kvm_all.c with TARGET_*
> ifdefs (Peter Maydell).
> - s/dprintf/DPRINTF/ (Andreas Färber).
> - Use "cs" rather than "cpu" or "env" for CPUState variable names
> (Andreas Färber).
> - Use CPUMIPSState rather than CPUArchState (Andreas Färber).
> - Pass MIPSCPU to cpu_mips_io_interrupts_pending() rather than
> CPUMIPSState (Andreas Färber).
> - Remove spurious parentheses around cpu_mips_io_interrupts_pending()
> call (Andreas Färber).
> - Pass MIPSCPU to kvm_mips_set_[ipi_]interrupt (Andreas Färber).
> - Make use of error_report (Andreas Färber) and clean up error messages
> a little to include __func__.
> - Remove inline kvm_mips_{put,get}_one_[ul]reg() declarations from
> kvm_mips.h. They're only used in target-mips/kvm.c anyway.
> - Make kvm_arch_{put,get}_registers static within target-mips/kvm.c and
> remove from kvm_mips.h.
> - Remove unnecessary includes from Malta patch, especially linux/kvm.h
> which isn't a good idea on non-Linux (Peter Maydell).
>
> Changes in v2:
>
> This patchset is based on Sanjay Lal's V1 patchset from 2nd March 2013:
> https://patchwork.kernel.org/project/kvm/list/?submitter=51991&state=*&q=qemu-devel
>
> I think I've addressed all the V1 feedback. The other main change is the
> removal of the boot-CPS ROM code binary blob and GIC/SMP support since
> it's all slightly orthogonal to KVM support. Instead the existing
> minimal bootloader code for Malta has been updated to work with KVM T&E.
>
> A git tag for this version of the patchset can also be found on github:
> https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v2
>
> - Expand commit messages
> - Rebase on v1.7.0
> - Misc checkpatch and other cleanups
> - Some interrupt bug fixes from Yann Le Du <ledu@kymasys.com>
> - Add get/set register functionality from Yann Le Du <ledu@kymasys.com>
> - Use new 64 bit compatible ABI from Cavium from Sanjay Lal
> <sanjayl@kymasys.com>
> - Add dummy kvm_arch_init_irq_routing()
> The common KVM code insists on calling kvm_arch_init_irq_routing() as
> soon as it sees kernel header support for it (regardless of whether
> QEMU supports it). Provide a dummy function to satisfy this.
> - Remove request_interrupt_window code (Peter Maydell)
> - Remove #ifdef CONFIG_KVM where guarded by kvm_enabled() already
> - Removal of cps / GIC / SMP support
> - Minimal bootloader modified to execute safely from RAM
> - Create asm-mips symlink using generic code and move above default
> case (Peter Maydell)
> - Remove redundant check of target_name = cpu = mips
> - Remove mipsel cross compilation fix, which is now fixed by commit
> 61cc919f73ea (configure: detect endian via compile test)
> - Add translation of guest kernel segments to allow an attached gdb to
> see kernel memory correctly
>
> James Hogan (7):
> target-mips: Reset CPU timer consistently
> target-mips: get_physical_address: Add defines for segment bases
> target-mips: get_physical_address: Add KVM awareness
> kvm: Allow arch to set sigmask length
> target-mips: Call kvm_mips_reset_vcpu() from mips_cpu_reset()
> hw/mips: malta: Add KVM support
> MAINTAINERS: Add entry for MIPS KVM
>
> Sanjay Lal (5):
> hw/mips/cputimer: Don't start periodic timer in KVM mode
> hw/mips: Add API to convert KVM guest KSEG0 <-> GPA
> target-mips: kvm: Add main KVM support for MIPS
> hw/mips: In KVM mode, inject IRQ2 (I/O) interrupts via ioctls
> target-mips: Enable KVM support in build system
>
> MAINTAINERS | 5 +
> configure | 6 +-
> hw/mips/addr.c | 7 +-
> hw/mips/cputimer.c | 18 +-
> hw/mips/mips_int.c | 11 +
> hw/mips/mips_malta.c | 73 +++--
> include/hw/mips/cpudevs.h | 2 +
> include/sysemu/kvm.h | 2 +
> kvm-all.c | 11 +-
> target-mips/Makefile.objs | 1 +
> target-mips/cpu.c | 8 +
> target-mips/helper.c | 51 +++-
> target-mips/kvm.c | 683 ++++++++++++++++++++++++++++++++++++++++++++++
> target-mips/kvm_mips.h | 26 ++
> target-mips/translate.c | 2 +
> 15 files changed, 866 insertions(+), 40 deletions(-)
> create mode 100644 target-mips/kvm.c
> create mode 100644 target-mips/kvm_mips.h
>
Thanks, it's a very clean patch set. I'll leave a few days for Aurelien
to comment, and then apply to uq/master.
Paolo
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support James Hogan
@ 2014-06-19 16:27 ` Aurelien Jarno
2014-06-19 19:34 ` Sanjay Lal
0 siblings, 1 reply; 32+ messages in thread
From: Aurelien Jarno @ 2014-06-19 16:27 UTC (permalink / raw)
To: James Hogan
Cc: Peter Maydell, kvm, Gleb Natapov, qemu-devel, Sanjay Lal,
Paolo Bonzini
On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
> In KVM mode the bootrom is loaded and executed from the last 1MB of
> DRAM.
What is the reason for that? I am not opposed to that, but if it is
really needed, it means that loading a bootloader into the flash area
(for example YAMON) won't work and that this should be forbidden to the
user.
> Based on "[PATCH 12/12] KVM/MIPS: General KVM support and support for
> SMP Guests" by Sanjay Lal <sanjayl@kymasys.com>.
>
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Cc: Sanjay Lal <sanjayl@kymasys.com>
> ---
> Changes in v5:
> - Kseg0 doesn't actually change size, so use cpu_mips_kseg0_to_phys()
> rather than having the KVM specific cpu_mips_kvm_um_kseg0_to_phys().
>
> Changes in v3:
> - Remove unnecessary includes, especially linux/kvm.h which isn't a
> good idea on non-Linux (Peter Maydell).
>
> Changes in v2:
> - Removal of cps / GIC / SMP support
> - Minimal bootloader modified to execute safely from RAM
> - Remove "Writing bootloader to final 1MB of RAM" printf
> ---
> hw/mips/mips_malta.c | 73 ++++++++++++++++++++++++++++++++++++++--------------
> 1 file changed, 53 insertions(+), 20 deletions(-)
>
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index f4a7d4712952..8bc5392b4223 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -51,6 +51,7 @@
> #include "sysemu/qtest.h"
> #include "qemu/error-report.h"
> #include "hw/empty_slot.h"
> +#include "sysemu/kvm.h"
>
> //#define DEBUG_BOARD_INIT
>
> @@ -603,29 +604,31 @@ static void network_init(PCIBus *pci_bus)
> */
>
> static void write_bootloader (CPUMIPSState *env, uint8_t *base,
> - int64_t kernel_entry)
> + int64_t run_addr, int64_t kernel_entry)
> {
> uint32_t *p;
>
> /* Small bootloader */
> p = (uint32_t *)base;
> - stl_p(p++, 0x0bf00160); /* j 0x1fc00580 */
> +
> + stl_p(p++, 0x08000000 | /* j 0x1fc00580 */
> + ((run_addr + 0x580) & 0x0fffffff) >> 2);
> stl_p(p++, 0x00000000); /* nop */
>
> /* YAMON service vector */
> - stl_p(base + 0x500, 0xbfc00580); /* start: */
> - stl_p(base + 0x504, 0xbfc0083c); /* print_count: */
> - stl_p(base + 0x520, 0xbfc00580); /* start: */
> - stl_p(base + 0x52c, 0xbfc00800); /* flush_cache: */
> - stl_p(base + 0x534, 0xbfc00808); /* print: */
> - stl_p(base + 0x538, 0xbfc00800); /* reg_cpu_isr: */
> - stl_p(base + 0x53c, 0xbfc00800); /* unred_cpu_isr: */
> - stl_p(base + 0x540, 0xbfc00800); /* reg_ic_isr: */
> - stl_p(base + 0x544, 0xbfc00800); /* unred_ic_isr: */
> - stl_p(base + 0x548, 0xbfc00800); /* reg_esr: */
> - stl_p(base + 0x54c, 0xbfc00800); /* unreg_esr: */
> - stl_p(base + 0x550, 0xbfc00800); /* getchar: */
> - stl_p(base + 0x554, 0xbfc00800); /* syscon_read: */
> + stl_p(base + 0x500, run_addr + 0x0580); /* start: */
> + stl_p(base + 0x504, run_addr + 0x083c); /* print_count: */
> + stl_p(base + 0x520, run_addr + 0x0580); /* start: */
> + stl_p(base + 0x52c, run_addr + 0x0800); /* flush_cache: */
> + stl_p(base + 0x534, run_addr + 0x0808); /* print: */
> + stl_p(base + 0x538, run_addr + 0x0800); /* reg_cpu_isr: */
> + stl_p(base + 0x53c, run_addr + 0x0800); /* unred_cpu_isr: */
> + stl_p(base + 0x540, run_addr + 0x0800); /* reg_ic_isr: */
> + stl_p(base + 0x544, run_addr + 0x0800); /* unred_ic_isr: */
> + stl_p(base + 0x548, run_addr + 0x0800); /* reg_esr: */
> + stl_p(base + 0x54c, run_addr + 0x0800); /* unreg_esr: */
> + stl_p(base + 0x550, run_addr + 0x0800); /* getchar: */
> + stl_p(base + 0x554, run_addr + 0x0800); /* syscon_read: */
>
>
> /* Second part of the bootloader */
> @@ -701,7 +704,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
> p = (uint32_t *) (base + 0x800);
> stl_p(p++, 0x03e00008); /* jr ra */
> stl_p(p++, 0x24020000); /* li v0,0 */
> - /* 808 YAMON print */
> + /* 808 YAMON print */
> stl_p(p++, 0x03e06821); /* move t5,ra */
> stl_p(p++, 0x00805821); /* move t3,a0 */
> stl_p(p++, 0x00a05021); /* move t2,a1 */
> @@ -774,6 +777,7 @@ static int64_t load_kernel (void)
> uint32_t *prom_buf;
> long prom_size;
> int prom_index = 0;
> + uint64_t (*xlate_to_kseg0) (void *opaque, uint64_t addr);
>
> #ifdef TARGET_WORDS_BIGENDIAN
> big_endian = 1;
> @@ -788,6 +792,11 @@ static int64_t load_kernel (void)
> loaderparams.kernel_filename);
> exit(1);
> }
> + if (kvm_enabled()) {
> + xlate_to_kseg0 = cpu_mips_kvm_um_phys_to_kseg0;
> + } else {
> + xlate_to_kseg0 = cpu_mips_phys_to_kseg0;
> + }
>
> /* load initrd */
> initrd_size = 0;
> @@ -820,7 +829,7 @@ static int64_t load_kernel (void)
> prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
> if (initrd_size > 0) {
> prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
> - cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
> + xlate_to_kseg0(NULL, initrd_offset), initrd_size,
> loaderparams.kernel_cmdline);
> } else {
> prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
> @@ -829,6 +838,7 @@ static int64_t load_kernel (void)
> prom_set(prom_buf, prom_index++, "memsize");
> prom_set(prom_buf, prom_index++, "%i",
> MIN(loaderparams.ram_size, 256 << 20));
> +
> prom_set(prom_buf, prom_index++, "modetty0");
> prom_set(prom_buf, prom_index++, "38400n8r");
> prom_set(prom_buf, prom_index++, NULL);
> @@ -863,6 +873,11 @@ static void main_cpu_reset(void *opaque)
> }
>
> malta_mips_config(cpu);
> +
> + if (kvm_enabled()) {
> + /* Start running from the bootloader we wrote to end of RAM */
> + env->active_tc.PC = 0x40000000 + loaderparams.ram_size;
> + }
> }
>
> static void cpu_request_exit(void *opaque, int irq, int level)
> @@ -878,6 +893,7 @@ static
> void mips_malta_init(MachineState *machine)
> {
> ram_addr_t ram_size = machine->ram_size;
> + ram_addr_t ram_low_size;
> const char *cpu_model = machine->cpu_model;
> const char *kernel_filename = machine->kernel_filename;
> const char *kernel_cmdline = machine->kernel_cmdline;
> @@ -892,7 +908,7 @@ void mips_malta_init(MachineState *machine)
> target_long bios_size = FLASH_SIZE;
> const size_t smbus_eeprom_size = 8 * 256;
> uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
> - int64_t kernel_entry;
> + int64_t kernel_entry, bootloader_run_addr;
> PCIBus *pci_bus;
> ISABus *isa_bus;
> MIPSCPU *cpu;
> @@ -1011,13 +1027,30 @@ void mips_malta_init(MachineState *machine)
> bios = pflash_cfi01_get_memory(fl);
> fl_idx++;
> if (kernel_filename) {
> + ram_low_size = MIN(ram_size, 256 << 20);
> + /* For KVM T&E we reserve 1MB of RAM for running bootloader */
> + if (kvm_enabled()) {
> + ram_low_size -= 0x100000;
> + bootloader_run_addr = 0x40000000 + ram_low_size;
> + } else {
> + bootloader_run_addr = 0xbfc00000;
> + }
> +
> /* Write a small bootloader to the flash location. */
> - loaderparams.ram_size = MIN(ram_size, 256 << 20);
> + loaderparams.ram_size = ram_low_size;
> loaderparams.kernel_filename = kernel_filename;
> loaderparams.kernel_cmdline = kernel_cmdline;
> loaderparams.initrd_filename = initrd_filename;
> kernel_entry = load_kernel();
> - write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
> +
> + write_bootloader(env, memory_region_get_ram_ptr(bios),
> + bootloader_run_addr, kernel_entry);
> + if (kvm_enabled()) {
> + /* Write the bootloader code @ the end of RAM, 1MB reserved */
> + write_bootloader(env, memory_region_get_ram_ptr(ram_low_preio) +
> + ram_low_size,
> + bootloader_run_addr, kernel_entry);
> + }
> } else {
> /* Load firmware from flash. */
> if (!dinfo) {
> --
> 1.9.3
>
>
>
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors
2014-06-18 15:00 ` [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors Paolo Bonzini
@ 2014-06-19 16:29 ` Aurelien Jarno
0 siblings, 0 replies; 32+ messages in thread
From: Aurelien Jarno @ 2014-06-19 16:29 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Sanjay Lal, Gleb Natapov, James Hogan, qemu-devel, kvm
On Wed, Jun 18, 2014 at 05:00:47PM +0200, Paolo Bonzini wrote:
> Il 18/06/2014 00:10, James Hogan ha scritto:
> >The patchset depends on v4 of "target-mips: implement UserLocal
> >Register". I'm aiming for QEMU 2.1, hopefully it isn't too late to get
> >some final review.
> >
> >Thanks to everybody who has already taken part in review.
> >
> >This patchset implements KVM support for MIPS32 processors, using Trap &
> >Emulation.
> >
> >In KVM mode, CPU virtualization is handled via the kvm kernel module,
> >while system and I/O virtualization leverage the Malta model already
> >present in QEMU.
> >
> >Both Guest kernel and Guest Userspace execute in UM. The Guest address
> >space is as folows:
> >Guest User address space: 0x00000000 -> 0x40000000
> >Guest Kernel Unmapped: 0x40000000 -> 0x60000000
> >Guest Kernel Mapped: 0x60000000 -> 0x80000000
> >
> >As a result, Guest Usermode virtual memory is limited to 1GB.
> >
> >KVM support (by trap and emulate) was added to the Linux kernel in
> >v3.10. This patchset partly depends on MIPS KVM work which will land in
> >v3.16 (for example to save/restore the state of various registers and
> >the KVM Count/Compare timer).
> >
> >Changes in v5:
> >
> >Changes addressing review comments from v4 patchset, and to use the MIPS
> >KVM timer API added in v3.16.
> >
> >A git tag for this version of the patchset can also be found on github:
> >https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v5
> >
> > - Rebase on master + v4 of "target-mips: implement UserLocal Register".
> > - New patch ([01/12] target-mips: Reset CPU timer consistently) to
> > address timer reset behaviour (reported by Paolo Bonzini).
> > - New patch ([08/12] target-mips: Call kvm_mips_reset_vcpu() from
> > mips_cpu_reset()) and rename kvm_arch_reset_vcpu to
> > kvm_mips_reset_vcpu, based on commit 50a2c6e55fa2 (kvm: reset state
> > from the CPU's reset method).
> > - KSEG0 doesn't actually change size, so fix mask in
> > cpu_mips_kseg0_to_phys() (patch 3) and use that instead of having the
> > KVM specific cpu_mips_kvm_um_kseg0_to_phys() (patch 10).
> > - Fix typo in patch 9 subject (s/interupts/interrupts/).
> > - Rename kvm_mips_te_{put,get}_cp0_registers() functions to drop the
> > "te_" since they're not really specific to T&E.
> > - Pass level through from kvm_arch_put_registers() to
> > kvm_mips_put_cp0_registers() rather than hard coding it to
> > KVM_PUT_FULL_STATE.
> > - Fix KVM_REG_MIPS_CP0_* definitions to set KVM_REG_MIPS and
> > KVM_REG_SIZE_U32/KVM_REG_SIZE_U64 (using a macro).
> > - Remove unused KVM_REG_MIPS_CP0_* definitions for now.
> > - Correct type of kvm_mips_{get,put}_one_{,ul}reg() reg_id argument to
> > uint64_t. Various high bits must be set to disambiguate the
> > architecture and register size.
> > - Simplify register access functions slightly.
> > - Add register accessors for always-64-bit registers (rather than ulong
> > registers). These are needed for virtual KVM registers for
> > controlling the KVM Compare/Count timer.
> > - Save and restore KVM timer state with the rest of the state, and also
> > when VM clock is started or stopped. When the KVM timer state is
> > restored (or VM clock restarted) it is resumed with the stored count
> > at the monotonic time when the VM clock was last stopped. If the VM
> > clock hasn't been stopped it resumes from the monotonic time when the
> > state was saved (i.e. as if the timer was never stopped).
> > Changes since RFC patch on kernel KVM thread "[PATCH v2 00/23] MIPS:
> > KVM: Fixes and guest timer rewrite"):
> > - Simplified, removing extra state for storing VM time of
> > save/restore, at the cost of losing/gaining time when VM gets
> > stopped and started (Paolo Bonzini).
> > - Save and restore the UserLocal and HWREna CP0 registers.
> > - Improve get/put KVM register error handling with DPRINTFs and fall
> > through so that getting/putting of all the registers is attempted
> > even if one of them fails due to being unimplemented in the kernel.
> >
> >Changes in v4:
> >
> >Changes mostly addressing a few review comments from v3 patchset.
> >
> >A git tag for this version of the patchset can also be found on github:
> >https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v4
> >
> > - Rebase on v2.0.0-rc0.
> > - Use int32_t instead of int32 (which is for softfloat) in kvm register
> > accessors (Andreas Färber).
> > - Use uint64_t instead of __u64 (which is really just for kernel
> > headers) in the kvm register accessors (Andreas Färber).
> > - Cast pointer to uintptr_t rather than target_ulong in kvm register
> > accessors.
> > - Remove some redundant casts in kvm register accessors.
> > - Add MAINTAINERS entry for MIPS KVM.
> >
> >Changes in v3:
> >
> >Changes mostly addressing review comments from v2 patchset.
> >
> >A git tag for this version of the patchset can also be found on github:
> >https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v3
> >
> > - Remove "target-mips: Set target page size to 16K in KVM mode". It
> > should actually work fine with 4k TARGET_PAGE_SIZE as long as there
> > is no cache aliasing or both host and guest kernels are configured to
> > a sufficient page size to avoid aliasing (which the kernel
> > arch/mips/kvm/00README.txt alludes to anyway).
> > - Rewrote kvm sigmask patch to allow sigmask length to be set by
> > kvm_arch_init(), so that MIPS can set it to 16 as it has 128 signals.
> > This is better than cluttering kvm-all.c with TARGET_* ifdefs (Peter
> > Maydell).
> > - Set sigmask length to 16 from kvm_arch_init() since MIPS Linux has
> > 128 signals. This is better than cluttering kvm_all.c with TARGET_*
> > ifdefs (Peter Maydell).
> > - s/dprintf/DPRINTF/ (Andreas Färber).
> > - Use "cs" rather than "cpu" or "env" for CPUState variable names
> > (Andreas Färber).
> > - Use CPUMIPSState rather than CPUArchState (Andreas Färber).
> > - Pass MIPSCPU to cpu_mips_io_interrupts_pending() rather than
> > CPUMIPSState (Andreas Färber).
> > - Remove spurious parentheses around cpu_mips_io_interrupts_pending()
> > call (Andreas Färber).
> > - Pass MIPSCPU to kvm_mips_set_[ipi_]interrupt (Andreas Färber).
> > - Make use of error_report (Andreas Färber) and clean up error messages
> > a little to include __func__.
> > - Remove inline kvm_mips_{put,get}_one_[ul]reg() declarations from
> > kvm_mips.h. They're only used in target-mips/kvm.c anyway.
> > - Make kvm_arch_{put,get}_registers static within target-mips/kvm.c and
> > remove from kvm_mips.h.
> > - Remove unnecessary includes from Malta patch, especially linux/kvm.h
> > which isn't a good idea on non-Linux (Peter Maydell).
> >
> >Changes in v2:
> >
> >This patchset is based on Sanjay Lal's V1 patchset from 2nd March 2013:
> >https://patchwork.kernel.org/project/kvm/list/?submitter=51991&state=*&q=qemu-devel
> >
> >I think I've addressed all the V1 feedback. The other main change is the
> >removal of the boot-CPS ROM code binary blob and GIC/SMP support since
> >it's all slightly orthogonal to KVM support. Instead the existing
> >minimal bootloader code for Malta has been updated to work with KVM T&E.
> >
> >A git tag for this version of the patchset can also be found on github:
> >https://github.com/jahogan/qemu-kvm-mips.git kvm-mips-v2
> >
> > - Expand commit messages
> > - Rebase on v1.7.0
> > - Misc checkpatch and other cleanups
> > - Some interrupt bug fixes from Yann Le Du <ledu@kymasys.com>
> > - Add get/set register functionality from Yann Le Du <ledu@kymasys.com>
> > - Use new 64 bit compatible ABI from Cavium from Sanjay Lal
> > <sanjayl@kymasys.com>
> > - Add dummy kvm_arch_init_irq_routing()
> > The common KVM code insists on calling kvm_arch_init_irq_routing() as
> > soon as it sees kernel header support for it (regardless of whether
> > QEMU supports it). Provide a dummy function to satisfy this.
> > - Remove request_interrupt_window code (Peter Maydell)
> > - Remove #ifdef CONFIG_KVM where guarded by kvm_enabled() already
> > - Removal of cps / GIC / SMP support
> > - Minimal bootloader modified to execute safely from RAM
> > - Create asm-mips symlink using generic code and move above default
> > case (Peter Maydell)
> > - Remove redundant check of target_name = cpu = mips
> > - Remove mipsel cross compilation fix, which is now fixed by commit
> > 61cc919f73ea (configure: detect endian via compile test)
> > - Add translation of guest kernel segments to allow an attached gdb to
> > see kernel memory correctly
> >
> >James Hogan (7):
> > target-mips: Reset CPU timer consistently
> > target-mips: get_physical_address: Add defines for segment bases
> > target-mips: get_physical_address: Add KVM awareness
> > kvm: Allow arch to set sigmask length
> > target-mips: Call kvm_mips_reset_vcpu() from mips_cpu_reset()
> > hw/mips: malta: Add KVM support
> > MAINTAINERS: Add entry for MIPS KVM
> >
> >Sanjay Lal (5):
> > hw/mips/cputimer: Don't start periodic timer in KVM mode
> > hw/mips: Add API to convert KVM guest KSEG0 <-> GPA
> > target-mips: kvm: Add main KVM support for MIPS
> > hw/mips: In KVM mode, inject IRQ2 (I/O) interrupts via ioctls
> > target-mips: Enable KVM support in build system
> >
> > MAINTAINERS | 5 +
> > configure | 6 +-
> > hw/mips/addr.c | 7 +-
> > hw/mips/cputimer.c | 18 +-
> > hw/mips/mips_int.c | 11 +
> > hw/mips/mips_malta.c | 73 +++--
> > include/hw/mips/cpudevs.h | 2 +
> > include/sysemu/kvm.h | 2 +
> > kvm-all.c | 11 +-
> > target-mips/Makefile.objs | 1 +
> > target-mips/cpu.c | 8 +
> > target-mips/helper.c | 51 +++-
> > target-mips/kvm.c | 683 ++++++++++++++++++++++++++++++++++++++++++++++
> > target-mips/kvm_mips.h | 26 ++
> > target-mips/translate.c | 2 +
> > 15 files changed, 866 insertions(+), 40 deletions(-)
> > create mode 100644 target-mips/kvm.c
> > create mode 100644 target-mips/kvm_mips.h
> >
>
> Thanks, it's a very clean patch set. I'll leave a few days for
> Aurelien to comment, and then apply to uq/master.
Except the minor comment on patch 10 it looks fine to me. That said I
haven't reviewed the KVM interface part very deeply, I trust you for
that part.
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-19 16:27 ` Aurelien Jarno
@ 2014-06-19 19:34 ` Sanjay Lal
2014-06-19 21:47 ` Aurelien Jarno
0 siblings, 1 reply; 32+ messages in thread
From: Sanjay Lal @ 2014-06-19 19:34 UTC (permalink / raw)
To: Aurelien Jarno
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, qemu-devel,
Paolo Bonzini
[-- Attachment #1: Type: text/plain, Size: 909 bytes --]
On Jun 19, 2014, at 9:27 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
>> In KVM mode the bootrom is loaded and executed from the last 1MB of
>> DRAM.
>
> What is the reason for that? I am not opposed to that, but if it is
> really needed, it means that loading a bootloader into the flash area
> (for example YAMON) won't work and that this should be forbidden to the
> user.
>
In trap and emulate mode, both the kernel and userland run in user mode on the processor. Virtual addresses >= 0x80000000 are only accessible in kernel mode, and the default flash area (VA: 0xbfc00000/PA: 0x1fc00000) falls in this range.
We therefore decided to relocate the bootloader to the last 1MB of RAM. This area is excluded from the RAM ranges supplied to the kernel, so it should not be accessible to the user.
Regards
Sanjay
[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 841 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-19 19:34 ` Sanjay Lal
@ 2014-06-19 21:47 ` Aurelien Jarno
2014-06-20 6:07 ` Paolo Bonzini
2014-06-20 9:25 ` James Hogan
0 siblings, 2 replies; 32+ messages in thread
From: Aurelien Jarno @ 2014-06-19 21:47 UTC (permalink / raw)
To: Sanjay Lal
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, qemu-devel,
Paolo Bonzini
On Thu, Jun 19, 2014 at 12:34:24PM -0700, Sanjay Lal wrote:
>
> On Jun 19, 2014, at 9:27 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
>
> > On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
> >> In KVM mode the bootrom is loaded and executed from the last 1MB of
> >> DRAM.
> >
> > What is the reason for that? I am not opposed to that, but if it is
> > really needed, it means that loading a bootloader into the flash area
> > (for example YAMON) won't work and that this should be forbidden to the
> > user.
> >
>
> In trap and emulate mode, both the kernel and userland run in user mode on the processor. Virtual addresses >= 0x80000000 are only accessible in kernel mode, and the default flash area (VA: 0xbfc00000/PA: 0x1fc00000) falls in this range.
>
> We therefore decided to relocate the bootloader to the last 1MB of RAM. This area is excluded from the RAM ranges supplied to the kernel, so it should not be accessible to the user.
>
Thanks for the explanation. It means we should disable the support for
booting from the flash (using -pflash) in KVM mode, as it would simply
not work.
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-19 21:47 ` Aurelien Jarno
@ 2014-06-20 6:07 ` Paolo Bonzini
2014-06-20 8:46 ` James Hogan
2014-06-20 9:10 ` Aurelien Jarno
2014-06-20 9:25 ` James Hogan
1 sibling, 2 replies; 32+ messages in thread
From: Paolo Bonzini @ 2014-06-20 6:07 UTC (permalink / raw)
To: Aurelien Jarno
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, qemu-devel,
Sanjay Lal
----- Messaggio originale -----
> Da: "Aurelien Jarno" <aurelien@aurel32.net>
> A: "Sanjay Lal" <sanjayl@kymasys.com>
> Cc: "James Hogan" <james.hogan@imgtec.com>, qemu-devel@nongnu.org, "Peter Maydell" <peter.maydell@linaro.org>,
> kvm@vger.kernel.org, "Gleb Natapov" <gleb@redhat.com>, "Paolo Bonzini" <pbonzini@redhat.com>
> Inviato: Giovedì, 19 giugno 2014 23:47:34
> Oggetto: Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
>
> On Thu, Jun 19, 2014 at 12:34:24PM -0700, Sanjay Lal wrote:
> >
> > On Jun 19, 2014, at 9:27 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> >
> > > On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
> > >> In KVM mode the bootrom is loaded and executed from the last 1MB of
> > >> DRAM.
> > >
> > > What is the reason for that? I am not opposed to that, but if it is
> > > really needed, it means that loading a bootloader into the flash area
> > > (for example YAMON) won't work and that this should be forbidden to the
> > > user.
> > >
> >
> > In trap and emulate mode, both the kernel and userland run in user mode on
> > the processor. Virtual addresses >= 0x80000000 are only accessible in
> > kernel mode, and the default flash area (VA: 0xbfc00000/PA: 0x1fc00000)
> > falls in this range.
> >
> > We therefore decided to relocate the bootloader to the last 1MB of RAM.
> > This area is excluded from the RAM ranges supplied to the kernel, so it
> > should not be accessible to the user.
> >
>
> Thanks for the explanation. It means we should disable the support for
> booting from the flash (using -pflash) in KVM mode, as it would simply
> not work.
My idea was to add a machines-specific option umkernel=on, and require it
in order to run KVM. Later we can add umkernel=on support for TCG as well,
while umkernel=off with KVM requires virtualization extensions.
The same option can disable pflash boot.
What do you think?
Paolo
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-20 6:07 ` Paolo Bonzini
@ 2014-06-20 8:46 ` James Hogan
2014-06-20 9:10 ` Aurelien Jarno
1 sibling, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-20 8:46 UTC (permalink / raw)
To: Paolo Bonzini, Aurelien Jarno
Cc: Sanjay Lal, Gleb Natapov, qemu-devel, kvm, Peter Maydell
Hi,
On 20/06/14 07:07, Paolo Bonzini wrote:
> ----- Messaggio originale -----
>> Da: "Aurelien Jarno" <aurelien@aurel32.net>
>> A: "Sanjay Lal" <sanjayl@kymasys.com>
>> Cc: "James Hogan" <james.hogan@imgtec.com>, qemu-devel@nongnu.org, "Peter Maydell" <peter.maydell@linaro.org>,
>> kvm@vger.kernel.org, "Gleb Natapov" <gleb@redhat.com>, "Paolo Bonzini" <pbonzini@redhat.com>
>> Inviato: Giovedì, 19 giugno 2014 23:47:34
>> Oggetto: Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
>>
>> On Thu, Jun 19, 2014 at 12:34:24PM -0700, Sanjay Lal wrote:
>>>
>>> On Jun 19, 2014, at 9:27 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
>>>
>>>> On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
>>>>> In KVM mode the bootrom is loaded and executed from the last 1MB of
>>>>> DRAM.
>>>>
>>>> What is the reason for that? I am not opposed to that, but if it is
>>>> really needed, it means that loading a bootloader into the flash area
>>>> (for example YAMON) won't work and that this should be forbidden to the
>>>> user.
>>>>
>>>
>>> In trap and emulate mode, both the kernel and userland run in user mode on
>>> the processor. Virtual addresses >= 0x80000000 are only accessible in
>>> kernel mode, and the default flash area (VA: 0xbfc00000/PA: 0x1fc00000)
>>> falls in this range.
>>>
>>> We therefore decided to relocate the bootloader to the last 1MB of RAM.
>>> This area is excluded from the RAM ranges supplied to the kernel, so it
>>> should not be accessible to the user.
I did recently try relocating the bootloader to the reset address in the
T&E KSeg0 (i.e. PA=0x1fc00000, VA=0x5fc00000), but the current MIPS KVM
implementation in the kernel has some limitations when it comes to
memory regions. It allocates a linear guest_pmap array (for GPA->RPA
page mapping) based only on the first memory region committed, so if you
set e.g. mem=64MB then physical memory according to guest_pmap won't
reach the reset address and it fails to map it. The kernel needs fixing
to use a more flexible physical page table structure first really.
>> Thanks for the explanation. It means we should disable the support for
>> booting from the flash (using -pflash) in KVM mode, as it would simply
>> not work.
>
> My idea was to add a machines-specific option umkernel=on, and require it
> in order to run KVM. Later we can add umkernel=on support for TCG as well,
FYI I tried this and it was a fairly small change (fixing CP0_EBase
initialisation and switching a couple of kvm_enabled() checks to
something like mips_um_ksegs_enabled()). Needs more testing though.
> while umkernel=off with KVM requires virtualization extensions.
>
> The same option can disable pflash boot.
>
> What do you think?
I think with an executable flash region / reset address the pflash
option could be made to work, but of course you'd probably need a
relocated flash image too, which may make the option less useful (and it
presumably isn't like a kernel ELF where you can detect what address
it's linked).
For now disabling Malta non kernel loads in KVM mode makes sense I think.
Thanks
James
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-20 6:07 ` Paolo Bonzini
2014-06-20 8:46 ` James Hogan
@ 2014-06-20 9:10 ` Aurelien Jarno
2014-06-20 10:38 ` Paolo Bonzini
1 sibling, 1 reply; 32+ messages in thread
From: Aurelien Jarno @ 2014-06-20 9:10 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, qemu-devel,
Sanjay Lal
On Fri, Jun 20, 2014 at 02:07:05AM -0400, Paolo Bonzini wrote:
>
>
> ----- Messaggio originale -----
> > Da: "Aurelien Jarno" <aurelien@aurel32.net>
> > A: "Sanjay Lal" <sanjayl@kymasys.com>
> > Cc: "James Hogan" <james.hogan@imgtec.com>, qemu-devel@nongnu.org, "Peter Maydell" <peter.maydell@linaro.org>,
> > kvm@vger.kernel.org, "Gleb Natapov" <gleb@redhat.com>, "Paolo Bonzini" <pbonzini@redhat.com>
> > Inviato: Giovedì, 19 giugno 2014 23:47:34
> > Oggetto: Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
> >
> > On Thu, Jun 19, 2014 at 12:34:24PM -0700, Sanjay Lal wrote:
> > >
> > > On Jun 19, 2014, at 9:27 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > >
> > > > On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
> > > >> In KVM mode the bootrom is loaded and executed from the last 1MB of
> > > >> DRAM.
> > > >
> > > > What is the reason for that? I am not opposed to that, but if it is
> > > > really needed, it means that loading a bootloader into the flash area
> > > > (for example YAMON) won't work and that this should be forbidden to the
> > > > user.
> > > >
> > >
> > > In trap and emulate mode, both the kernel and userland run in user mode on
> > > the processor. Virtual addresses >= 0x80000000 are only accessible in
> > > kernel mode, and the default flash area (VA: 0xbfc00000/PA: 0x1fc00000)
> > > falls in this range.
> > >
> > > We therefore decided to relocate the bootloader to the last 1MB of RAM.
> > > This area is excluded from the RAM ranges supplied to the kernel, so it
> > > should not be accessible to the user.
> > >
> >
> > Thanks for the explanation. It means we should disable the support for
> > booting from the flash (using -pflash) in KVM mode, as it would simply
> > not work.
>
> My idea was to add a machines-specific option umkernel=on, and require it
> in order to run KVM. Later we can add umkernel=on support for TCG as well,
> while umkernel=off with KVM requires virtualization extensions.
>
> The same option can disable pflash boot.
>
> What do you think?
For what I understand the current KVM support in MIPS uses trap and
emulate and thus doesn't need hardware support, just a recent kernel
with the option enabled. That's why I do wonder if there is a real point
in supporting UM kernels in TCG mode.
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-19 21:47 ` Aurelien Jarno
2014-06-20 6:07 ` Paolo Bonzini
@ 2014-06-20 9:25 ` James Hogan
2014-06-20 11:11 ` Paolo Bonzini
2014-06-20 11:20 ` Aurelien Jarno
1 sibling, 2 replies; 32+ messages in thread
From: James Hogan @ 2014-06-20 9:25 UTC (permalink / raw)
To: Aurelien Jarno, Sanjay Lal
Cc: Peter Maydell, Gleb Natapov, qemu-devel, kvm, Paolo Bonzini
On 19/06/14 22:47, Aurelien Jarno wrote:
> On Thu, Jun 19, 2014 at 12:34:24PM -0700, Sanjay Lal wrote:
>>
>> On Jun 19, 2014, at 9:27 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
>>
>>> On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
>>>> In KVM mode the bootrom is loaded and executed from the last 1MB of
>>>> DRAM.
>>>
>>> What is the reason for that? I am not opposed to that, but if it is
>>> really needed, it means that loading a bootloader into the flash area
>>> (for example YAMON) won't work and that this should be forbidden to the
>>> user.
>>>
>>
>> In trap and emulate mode, both the kernel and userland run in user mode on the processor. Virtual addresses >= 0x80000000 are only accessible in kernel mode, and the default flash area (VA: 0xbfc00000/PA: 0x1fc00000) falls in this range.
>>
>> We therefore decided to relocate the bootloader to the last 1MB of RAM. This area is excluded from the RAM ranges supplied to the kernel, so it should not be accessible to the user.
>>
>
> Thanks for the explanation. It means we should disable the support for
> booting from the flash (using -pflash) in KVM mode, as it would simply
> not work.
>
Hi Aurelien,
Is this fixup to the malta patch the sort of thing you had in mind? If
so I'll generate a v6 patchset with it.
Cheers
James
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 8bc5392b4223..91b0ce566111 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1052,6 +1052,12 @@ void mips_malta_init(MachineState *machine)
bootloader_run_addr, kernel_entry);
}
} else {
+ /* The flash region isn't executable from a KVM T&E guest */
+ if (kvm_enabled()) {
+ error_report("KVM enabled but no -kernel argument was specified. "
+ "Booting from flash is not supported with KVM T&E.");
+ exit(1);
+ }
/* Load firmware from flash. */
if (!dinfo) {
/* Load a BIOS image. */
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-20 9:10 ` Aurelien Jarno
@ 2014-06-20 10:38 ` Paolo Bonzini
2014-06-20 11:19 ` Aurelien Jarno
0 siblings, 1 reply; 32+ messages in thread
From: Paolo Bonzini @ 2014-06-20 10:38 UTC (permalink / raw)
To: Aurelien Jarno
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, qemu-devel,
Sanjay Lal
Il 20/06/2014 11:10, Aurelien Jarno ha scritto:
> > My idea was to add a machines-specific option umkernel=on, and require it
> > in order to run KVM. Later we can add umkernel=on support for TCG as well,
> > while umkernel=off with KVM requires virtualization extensions.
> >
> > The same option can disable pflash boot.
> >
> > What do you think?
>
> For what I understand the current KVM support in MIPS uses trap and
> emulate and thus doesn't need hardware support, just a recent kernel
> with the option enabled.
Yes, but work to support virtualization extensions is underway. Patches
were posted a few months ago.
> That's why I do wonder if there is a real point
> in supporting UM kernels in TCG mode.
Debugging, mainly. It is sometimes useful to compare TCG with KVM on
x86, and I suppose it could be the same on MIPS.
Paolo
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-20 9:25 ` James Hogan
@ 2014-06-20 11:11 ` Paolo Bonzini
2014-06-20 11:20 ` Aurelien Jarno
1 sibling, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2014-06-20 11:11 UTC (permalink / raw)
To: James Hogan, Aurelien Jarno, Sanjay Lal
Cc: Peter Maydell, Gleb Natapov, qemu-devel, kvm
Il 20/06/2014 11:25, James Hogan ha scritto:
> On 19/06/14 22:47, Aurelien Jarno wrote:
>> On Thu, Jun 19, 2014 at 12:34:24PM -0700, Sanjay Lal wrote:
>>>
>>> On Jun 19, 2014, at 9:27 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
>>>
>>>> On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
>>>>> In KVM mode the bootrom is loaded and executed from the last 1MB of
>>>>> DRAM.
>>>>
>>>> What is the reason for that? I am not opposed to that, but if it is
>>>> really needed, it means that loading a bootloader into the flash area
>>>> (for example YAMON) won't work and that this should be forbidden to the
>>>> user.
>>>>
>>>
>>> In trap and emulate mode, both the kernel and userland run in user mode on the processor. Virtual addresses >= 0x80000000 are only accessible in kernel mode, and the default flash area (VA: 0xbfc00000/PA: 0x1fc00000) falls in this range.
>>>
>>> We therefore decided to relocate the bootloader to the last 1MB of RAM. This area is excluded from the RAM ranges supplied to the kernel, so it should not be accessible to the user.
>>>
>>
>> Thanks for the explanation. It means we should disable the support for
>> booting from the flash (using -pflash) in KVM mode, as it would simply
>> not work.
>>
>
> Hi Aurelien,
>
> Is this fixup to the malta patch the sort of thing you had in mind? If
> so I'll generate a v6 patchset with it.
It looks like this. No hurry, it can go in after the main series; just
git-send-email it so it gets noticed and has a proper commit message.
Paolo
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-20 10:38 ` Paolo Bonzini
@ 2014-06-20 11:19 ` Aurelien Jarno
2014-06-20 11:28 ` James Hogan
0 siblings, 1 reply; 32+ messages in thread
From: Aurelien Jarno @ 2014-06-20 11:19 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Peter Maydell, James Hogan, kvm, Gleb Natapov, qemu-devel,
Sanjay Lal
On Fri, Jun 20, 2014 at 12:38:30PM +0200, Paolo Bonzini wrote:
> Il 20/06/2014 11:10, Aurelien Jarno ha scritto:
> >> My idea was to add a machines-specific option umkernel=on, and require it
> >> in order to run KVM. Later we can add umkernel=on support for TCG as well,
> >> while umkernel=off with KVM requires virtualization extensions.
> >>
> >> The same option can disable pflash boot.
> >>
> >> What do you think?
> >
> >For what I understand the current KVM support in MIPS uses trap and
> >emulate and thus doesn't need hardware support, just a recent kernel
> >with the option enabled.
>
> Yes, but work to support virtualization extensions is underway.
> Patches were posted a few months ago.
>
> >That's why I do wonder if there is a real point
> >in supporting UM kernels in TCG mode.
>
> Debugging, mainly. It is sometimes useful to compare TCG with KVM
> on x86, and I suppose it could be the same on MIPS.
Ok, then we can indeed add a umkernel option, which is always enabled
with KVM, and which disable the flash (and why not other devices) in
that case.
At some point it might be a good idea to add a specific machine for
emulation/virtualization, like it is done on ARM, which do not have to
handle this kind of devices, and which does not have all the current
limitations of the Malta board.
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-20 9:25 ` James Hogan
2014-06-20 11:11 ` Paolo Bonzini
@ 2014-06-20 11:20 ` Aurelien Jarno
1 sibling, 0 replies; 32+ messages in thread
From: Aurelien Jarno @ 2014-06-20 11:20 UTC (permalink / raw)
To: James Hogan
Cc: Peter Maydell, kvm, Gleb Natapov, qemu-devel, Sanjay Lal,
Paolo Bonzini
On Fri, Jun 20, 2014 at 10:25:24AM +0100, James Hogan wrote:
> On 19/06/14 22:47, Aurelien Jarno wrote:
> > On Thu, Jun 19, 2014 at 12:34:24PM -0700, Sanjay Lal wrote:
> >>
> >> On Jun 19, 2014, at 9:27 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> >>
> >>> On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote:
> >>>> In KVM mode the bootrom is loaded and executed from the last 1MB of
> >>>> DRAM.
> >>>
> >>> What is the reason for that? I am not opposed to that, but if it is
> >>> really needed, it means that loading a bootloader into the flash area
> >>> (for example YAMON) won't work and that this should be forbidden to the
> >>> user.
> >>>
> >>
> >> In trap and emulate mode, both the kernel and userland run in user mode on the processor. Virtual addresses >= 0x80000000 are only accessible in kernel mode, and the default flash area (VA: 0xbfc00000/PA: 0x1fc00000) falls in this range.
> >>
> >> We therefore decided to relocate the bootloader to the last 1MB of RAM. This area is excluded from the RAM ranges supplied to the kernel, so it should not be accessible to the user.
> >>
> >
> > Thanks for the explanation. It means we should disable the support for
> > booting from the flash (using -pflash) in KVM mode, as it would simply
> > not work.
> >
>
> Hi Aurelien,
>
> Is this fixup to the malta patch the sort of thing you had in mind? If
> so I'll generate a v6 patchset with it.
>
> Cheers
> James
>
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 8bc5392b4223..91b0ce566111 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -1052,6 +1052,12 @@ void mips_malta_init(MachineState *machine)
> bootloader_run_addr, kernel_entry);
> }
> } else {
> + /* The flash region isn't executable from a KVM T&E guest */
> + if (kvm_enabled()) {
> + error_report("KVM enabled but no -kernel argument was specified. "
> + "Booting from flash is not supported with KVM T&E.");
> + exit(1);
> + }
> /* Load firmware from flash. */
> if (!dinfo) {
> /* Load a BIOS image. */
>
This looks fine to me.
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
2014-06-20 11:19 ` Aurelien Jarno
@ 2014-06-20 11:28 ` James Hogan
0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-06-20 11:28 UTC (permalink / raw)
To: Aurelien Jarno, Paolo Bonzini
Cc: Sanjay Lal, Gleb Natapov, qemu-devel, kvm, Peter Maydell
On 20/06/14 12:19, Aurelien Jarno wrote:
> On Fri, Jun 20, 2014 at 12:38:30PM +0200, Paolo Bonzini wrote:
>> Il 20/06/2014 11:10, Aurelien Jarno ha scritto:
>>>> My idea was to add a machines-specific option umkernel=on, and require it
>>>> in order to run KVM. Later we can add umkernel=on support for TCG as well,
>>>> while umkernel=off with KVM requires virtualization extensions.
>>>>
>>>> The same option can disable pflash boot.
>>>>
>>>> What do you think?
>>>
>>> For what I understand the current KVM support in MIPS uses trap and
>>> emulate and thus doesn't need hardware support, just a recent kernel
>>> with the option enabled.
>>
>> Yes, but work to support virtualization extensions is underway.
>> Patches were posted a few months ago.
>>
>>> That's why I do wonder if there is a real point
>>> in supporting UM kernels in TCG mode.
>>
>> Debugging, mainly. It is sometimes useful to compare TCG with KVM
>> on x86, and I suppose it could be the same on MIPS.
>
> Ok, then we can indeed add a umkernel option, which is always enabled
> with KVM, and which disable the flash (and why not other devices) in
> that case.
>
> At some point it might be a good idea to add a specific machine for
> emulation/virtualization, like it is done on ARM, which do not have to
> handle this kind of devices, and which does not have all the current
> limitations of the Malta board.
FYI Cavium have been working on a para-virtualised machine which they
use with their VZ KVM implementation. They're using lkvm, but I expect
it will make sense to port that to QEMU too.
lkvm patchset (applied):
https://www.mail-archive.com/kvm%40vger.kernel.org/msg102792.html
linux kernel patchset (merged in v3.16-rc1):
https://www.mail-archive.com/kvm%40vger.kernel.org/msg102806.html
Cheers
James
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
` (12 preceding siblings ...)
2014-06-18 15:00 ` [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors Paolo Bonzini
@ 2014-07-10 12:17 ` Peter Maydell
2014-07-10 12:47 ` Paolo Bonzini
2014-07-14 13:33 ` James Hogan
13 siblings, 2 replies; 32+ messages in thread
From: Peter Maydell @ 2014-07-10 12:17 UTC (permalink / raw)
To: James Hogan
Cc: kvm-devel, Gleb Natapov, QEMU Developers, Sanjay Lal,
Christoffer Dall, Paolo Bonzini, Aurelien Jarno
On 17 June 2014 23:10, James Hogan <james.hogan@imgtec.com> wrote:
> The patchset depends on v4 of "target-mips: implement UserLocal
> Register". I'm aiming for QEMU 2.1, hopefully it isn't too late to get
> some final review.
>
> Thanks to everybody who has already taken part in review.
>
> This patchset implements KVM support for MIPS32 processors, using Trap &
> Emulation.
I was looking at what happens for MMIO accesses to nonexistent
memory when we're running under KVM, and interestingly this
patchset means MIPS is now the only CPU which both (a) supports
KVM and (b) has an implementation of the do_unassigned_access()
CPU hook. Does the current code support a guest attempt to
access unassigned physical addresses? I had a look at the code
and it seems like mips_cpu_unassigned_access() will end up
calling cpu_restore_state() and cpu_loop_exit(), which I think
will probably crash if you call them when using KVM rather than
TCG...
More generally, there doesn't really seem to be provision in the
KVM KVM_EXIT_MMIO API for returning "this access failed".
I guess in theory userspace could do all the "figure out how
to adjust CPU state to do exception entry and then run VCPU",
but that seems like quite a lot of work which the kernel already
knows how to do; is there some way to provide a simpler API
that lets userspace just inform the kernel that it needs to
fault the access?
thanks
-- PMM
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors
2014-07-10 12:17 ` Peter Maydell
@ 2014-07-10 12:47 ` Paolo Bonzini
2014-07-14 13:33 ` James Hogan
1 sibling, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2014-07-10 12:47 UTC (permalink / raw)
To: Peter Maydell, James Hogan
Cc: kvm-devel, Gleb Natapov, QEMU Developers, Sanjay Lal,
Aurelien Jarno, Christoffer Dall
Il 10/07/2014 14:17, Peter Maydell ha scritto:
>
> More generally, there doesn't really seem to be provision in the
> KVM KVM_EXIT_MMIO API for returning "this access failed".
> I guess in theory userspace could do all the "figure out how
> to adjust CPU state to do exception entry and then run VCPU",
> but that seems like quite a lot of work which the kernel already
> knows how to do; is there some way to provide a simpler API
> that lets userspace just inform the kernel that it needs to
> fault the access?
There are 3 free padding bytes in struct kvm_run's mmio field. It's
possible to add a per-VM capability and have the kernel check one of
these bytes when the capability is set.
Paolo
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors
2014-07-10 12:17 ` Peter Maydell
2014-07-10 12:47 ` Paolo Bonzini
@ 2014-07-14 13:33 ` James Hogan
2014-07-14 14:35 ` Peter Maydell
1 sibling, 1 reply; 32+ messages in thread
From: James Hogan @ 2014-07-14 13:33 UTC (permalink / raw)
To: Peter Maydell
Cc: kvm-devel, Gleb Natapov, QEMU Developers, Sanjay Lal,
Christoffer Dall, Paolo Bonzini, Aurelien Jarno
Hi Peter,
On 10/07/14 13:17, Peter Maydell wrote:
> On 17 June 2014 23:10, James Hogan <james.hogan@imgtec.com> wrote:
>> The patchset depends on v4 of "target-mips: implement UserLocal
>> Register". I'm aiming for QEMU 2.1, hopefully it isn't too late to get
>> some final review.
>>
>> Thanks to everybody who has already taken part in review.
>>
>> This patchset implements KVM support for MIPS32 processors, using Trap &
>> Emulation.
>
> I was looking at what happens for MMIO accesses to nonexistent
> memory when we're running under KVM, and interestingly this
> patchset means MIPS is now the only CPU which both (a) supports
> KVM and (b) has an implementation of the do_unassigned_access()
> CPU hook. Does the current code support a guest attempt to
> access unassigned physical addresses? I had a look at the code
> and it seems like mips_cpu_unassigned_access() will end up
> calling cpu_restore_state() and cpu_loop_exit(), which I think
> will probably crash if you call them when using KVM rather than
> TCG...
Yes, I have observed this in the past when experimentally writing to the
Malta reset region from the guest (see the patch "mips/malta: allow
volatile writes to reset flash" which didn't get applied but worked
around the specific issue). That was because read only memory regions
were treated as unassigned from the point of view of writes (which tbh
seems wrong), but it could happen with any unassigned access >
0x80000000 from the guest AFAICT.
So yeh, until mips_cpu_unassigned_access does something more portable
for KVM, conditionally setting do_unassigned_access only if
!kvm_enabled() looks sensible. I'll see if I can reproduce it and submit
a patch.
> More generally, there doesn't really seem to be provision in the
> KVM KVM_EXIT_MMIO API for returning "this access failed".
> I guess in theory userspace could do all the "figure out how
> to adjust CPU state to do exception entry and then run VCPU",
> but that seems like quite a lot of work which the kernel already
> knows how to do; is there some way to provide a simpler API
> that lets userspace just inform the kernel that it needs to
> fault the access?
Indeed. Paolo's idea would work well I think. A data bus error exception
would likely be the only sensible error response required other than
ignoring writes or returning a garbage value for a read (which the
current KVM MMIO API already allows).
Cheers
James
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors
2014-07-14 13:33 ` James Hogan
@ 2014-07-14 14:35 ` Peter Maydell
2014-07-14 15:50 ` James Hogan
0 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2014-07-14 14:35 UTC (permalink / raw)
To: James Hogan
Cc: kvm-devel, Gleb Natapov, QEMU Developers, Sanjay Lal,
Christoffer Dall, Paolo Bonzini, Aurelien Jarno
On 14 July 2014 14:33, James Hogan <james.hogan@imgtec.com> wrote:
> On 10/07/14 13:17, Peter Maydell wrote:
>> More generally, there doesn't really seem to be provision in the
>> KVM KVM_EXIT_MMIO API for returning "this access failed".
>> I guess in theory userspace could do all the "figure out how
>> to adjust CPU state to do exception entry and then run VCPU",
>> but that seems like quite a lot of work which the kernel already
>> knows how to do; is there some way to provide a simpler API
>> that lets userspace just inform the kernel that it needs to
>> fault the access?
>
> Indeed. Paolo's idea would work well I think. A data bus error exception
> would likely be the only sensible error response required other than
> ignoring writes or returning a garbage value for a read (which the
> current KVM MMIO API already allows).
I think we should make the API at least permit returning an
(architecture-specific) error code to the kernel, rather than just
a single boolean "failed" response. For instance on ARM the
fault status registers include a single ExT bit for classifying
the type of an external abort. (The meaning of the bit is
IMPDEF; on the Cortex-A15 it can be used to distinguish
AXI bus DECERR ("decode error", ie the interconnect doesn't
have anything attached at that address) and SLVERR ("slave
error", ie there was a device at that address but it chose to
reject the transaction for some reason, eg unsupported
transfer size, timeout, write to read-only location, FIFO
overrun or just because the device was in a bad mood.)
thanks
-- PMM
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors
2014-07-14 14:35 ` Peter Maydell
@ 2014-07-14 15:50 ` James Hogan
0 siblings, 0 replies; 32+ messages in thread
From: James Hogan @ 2014-07-14 15:50 UTC (permalink / raw)
To: Peter Maydell
Cc: kvm-devel, Gleb Natapov, QEMU Developers, Sanjay Lal,
Christoffer Dall, Paolo Bonzini, Aurelien Jarno
On 14/07/14 15:35, Peter Maydell wrote:
> On 14 July 2014 14:33, James Hogan <james.hogan@imgtec.com> wrote:
>> On 10/07/14 13:17, Peter Maydell wrote:
>>> More generally, there doesn't really seem to be provision in the
>>> KVM KVM_EXIT_MMIO API for returning "this access failed".
>>> I guess in theory userspace could do all the "figure out how
>>> to adjust CPU state to do exception entry and then run VCPU",
>>> but that seems like quite a lot of work which the kernel already
>>> knows how to do; is there some way to provide a simpler API
>>> that lets userspace just inform the kernel that it needs to
>>> fault the access?
>>
>> Indeed. Paolo's idea would work well I think. A data bus error exception
>> would likely be the only sensible error response required other than
>> ignoring writes or returning a garbage value for a read (which the
>> current KVM MMIO API already allows).
>
> I think we should make the API at least permit returning an
> (architecture-specific) error code to the kernel, rather than just
> a single boolean "failed" response. For instance on ARM the
> fault status registers include a single ExT bit for classifying
> the type of an external abort. (The meaning of the bit is
> IMPDEF; on the Cortex-A15 it can be used to distinguish
> AXI bus DECERR ("decode error", ie the interconnect doesn't
> have anything attached at that address) and SLVERR ("slave
> error", ie there was a device at that address but it chose to
> reject the transaction for some reason, eg unsupported
> transfer size, timeout, write to read-only location, FIFO
> overrun or just because the device was in a bad mood.)
Agreed (I wasn't suggesting a bool, just thinking out loud about how
mips would use that arch specific value :-) ).
Cheers
James
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2014-07-14 15:50 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-17 22:10 [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 01/12] target-mips: Reset CPU timer consistently James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 02/12] hw/mips/cputimer: Don't start periodic timer in KVM mode James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 03/12] hw/mips: Add API to convert KVM guest KSEG0 <-> GPA James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 04/12] target-mips: get_physical_address: Add defines for segment bases James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 05/12] target-mips: get_physical_address: Add KVM awareness James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 06/12] kvm: Allow arch to set sigmask length James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 07/12] target-mips: kvm: Add main KVM support for MIPS James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 08/12] target-mips: Call kvm_mips_reset_vcpu() from mips_cpu_reset() James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 09/12] hw/mips: In KVM mode, inject IRQ2 (I/O) interrupts via ioctls James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support James Hogan
2014-06-19 16:27 ` Aurelien Jarno
2014-06-19 19:34 ` Sanjay Lal
2014-06-19 21:47 ` Aurelien Jarno
2014-06-20 6:07 ` Paolo Bonzini
2014-06-20 8:46 ` James Hogan
2014-06-20 9:10 ` Aurelien Jarno
2014-06-20 10:38 ` Paolo Bonzini
2014-06-20 11:19 ` Aurelien Jarno
2014-06-20 11:28 ` James Hogan
2014-06-20 9:25 ` James Hogan
2014-06-20 11:11 ` Paolo Bonzini
2014-06-20 11:20 ` Aurelien Jarno
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 11/12] target-mips: Enable KVM support in build system James Hogan
2014-06-17 22:10 ` [Qemu-devel] [PATCH v5 12/12] MAINTAINERS: Add entry for MIPS KVM James Hogan
2014-06-18 15:00 ` [Qemu-devel] [PATCH v5 00/12] KVM Support for MIPS32 Processors Paolo Bonzini
2014-06-19 16:29 ` Aurelien Jarno
2014-07-10 12:17 ` Peter Maydell
2014-07-10 12:47 ` Paolo Bonzini
2014-07-14 13:33 ` James Hogan
2014-07-14 14:35 ` Peter Maydell
2014-07-14 15:50 ` James Hogan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).