1
The following changes since commit bd2e12310b18b51aefbf834e6d54989fd175976f:
1
The following changes since commit b69801dd6b1eb4d107f7c2f643adf0a4e3ec9124:
2
2
3
Merge tag 'qga-pull-2024-01-30' of https://github.com/kostyanf14/qemu into staging (2024-01-30 15:53:46 +0000)
3
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2025-02-22 05:06:39 +0800)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240201
7
https://gitlab.com/bibo-mao/qemu.git tags/pull-loongarch-20250225
8
8
9
for you to fetch changes up to 27edd5040cae63bfa92c68f69883ba81aa3b6cda:
9
for you to fetch changes up to db369c11c90b35f3a6ab59ad78564aea5b30c3da:
10
10
11
target/loongarch: Fix qtest test-hmp error when KVM-only build (2024-02-01 15:29:40 +0800)
11
target/loongarch: Enable virtual extioi feature (2025-02-25 16:05:31 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
pull-loongarch-20240201
14
pull-loongarch-20250225 queue
15
15
16
----------------------------------------------------------------
16
----------------------------------------------------------------
17
Song Gao (1):
17
Bibo Mao (10):
18
target/loongarch: Fix qtest test-hmp error when KVM-only build
18
target/loongarch/gdbstub: Fix gdbstub incorrectly handling some registers
19
target/loongarch: Correct maximum physical address in KVM mode
20
target/loongarch: Add post init function for kvm mode
21
target/loongarch: Move kvm specified vCPU property to kvm directory
22
target/loongarch: Add vCPU property for paravirt ipi feature
23
target/loongarch: Add paravirt ipi feature detection
24
target/loongarch: Enable paravirt ipi feature
25
target/loongarch: Add vCPU property for kvm steal time feature
26
target/loongarch: Add kvm steal time feature detection
27
target/loongarch: Enable virtual extioi feature
19
28
20
target/loongarch/cpu.c | 2 -
29
Xianglai Li (1):
21
target/loongarch/cpu_helper.c | 231 ++++++++++++++++++++++++++++++++++++++
30
target/loongarch: fix vcpu reset command word issue
22
target/loongarch/internals.h | 20 +++-
31
23
target/loongarch/meson.build | 1 +
32
hw/loongarch/virt.c | 8 --
24
target/loongarch/tcg/tlb_helper.c | 230 -------------------------------------
33
include/hw/loongarch/virt.h | 9 ++
25
5 files changed, 250 insertions(+), 234 deletions(-)
34
target/loongarch/cpu.c | 52 ++--------
26
create mode 100644 target/loongarch/cpu_helper.c
35
target/loongarch/cpu.h | 13 +++
36
target/loongarch/gdbstub.c | 11 +-
37
target/loongarch/kvm/kvm.c | 186 +++++++++++++++++++++++++++++++++-
38
target/loongarch/loongarch-qmp-cmds.c | 2 +-
39
7 files changed, 224 insertions(+), 57 deletions(-)
diff view generated by jsdifflib
New patch
1
From: Xianglai Li <lixianglai@loongson.cn>
1
2
3
When the KVM_REG_LOONGARCH_VCPU_RESET command word
4
is sent to the kernel through the kvm_set_one_reg interface,
5
the parameter source needs to be a legal address,
6
otherwise the kernel will return an error and the command word
7
will fail to be sent.
8
9
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
12
---
13
target/loongarch/kvm/kvm.c | 9 ++++++++-
14
1 file changed, 8 insertions(+), 1 deletion(-)
15
16
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/loongarch/kvm/kvm.c
19
+++ b/target/loongarch/kvm/kvm.c
20
@@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_get_lbt(CPUState *cs)
21
void kvm_arch_reset_vcpu(CPUState *cs)
22
{
23
CPULoongArchState *env = cpu_env(cs);
24
+ int ret = 0;
25
+ uint64_t unused = 0;
26
27
env->mp_state = KVM_MP_STATE_RUNNABLE;
28
- kvm_set_one_reg(cs, KVM_REG_LOONGARCH_VCPU_RESET, 0);
29
+ ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_VCPU_RESET, &unused);
30
+ if (ret) {
31
+ error_report("Failed to set KVM_REG_LOONGARCH_VCPU_RESET: %s",
32
+ strerror(errno));
33
+ exit(EXIT_FAILURE);
34
+ }
35
}
36
37
static int kvm_loongarch_get_mpstate(CPUState *cs)
38
--
39
2.43.5
40
41
diff view generated by jsdifflib
New patch
1
Write operation with R32 (orig_a0) and R34 (CSR_BADV) is discarded on
2
gdbstub implementation for LoongArch system. And return value should
3
be register size rather than 0, since it is used to calculate offset of
4
next register such as R33 (PC) in function handle_write_all_regs().
1
5
6
Cc: qemu-stable@nongnu.org
7
Fixes: ca61e75071c6 ("target/loongarch: Add gdb support.")
8
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
9
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
10
---
11
target/loongarch/gdbstub.c | 11 ++++++-----
12
1 file changed, 6 insertions(+), 5 deletions(-)
13
14
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/loongarch/gdbstub.c
17
+++ b/target/loongarch/gdbstub.c
18
@@ -XXX,XX +XXX,XX @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
19
{
20
CPULoongArchState *env = cpu_env(cs);
21
target_ulong tmp;
22
- int read_length;
23
int length = 0;
24
25
+ if (n < 0 || n > 34) {
26
+ return 0;
27
+ }
28
+
29
if (is_la64(env)) {
30
tmp = ldq_le_p(mem_buf);
31
- read_length = 8;
32
+ length = 8;
33
} else {
34
tmp = ldl_le_p(mem_buf);
35
- read_length = 4;
36
+ length = 4;
37
}
38
39
if (0 <= n && n < 32) {
40
env->gpr[n] = tmp;
41
- length = read_length;
42
} else if (n == 33) {
43
set_pc(env, tmp);
44
- length = read_length;
45
}
46
return length;
47
}
48
--
49
2.43.5
diff view generated by jsdifflib
New patch
1
On 3A5000 system, the physical address space width for host is 48,
2
however 47 bit for KVM VM. For KVM VM, size of physical address space is
3
the same with that of virtual user space address.
1
4
5
Here modify physical address space width with 47 bit in KVM mode.
6
7
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
8
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
9
---
10
target/loongarch/cpu.c | 10 ++++++++--
11
1 file changed, 8 insertions(+), 2 deletions(-)
12
13
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/loongarch/cpu.c
16
+++ b/target/loongarch/cpu.c
17
@@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj)
18
{
19
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
20
CPULoongArchState *env = &cpu->env;
21
- uint32_t data = 0;
22
+ uint32_t data = 0, field;
23
int i;
24
25
for (i = 0; i < 21; i++) {
26
@@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj)
27
data = FIELD_DP32(data, CPUCFG1, ARCH, 2);
28
data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
29
data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
30
- data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f);
31
+ if (kvm_enabled()) {
32
+ /* GPA address width of VM is 47, field value is 47 - 1 */
33
+ field = 0x2e;
34
+ } else {
35
+ field = 0x2f; /* 48 bit - 1 */
36
+ }
37
+ data = FIELD_DP32(data, CPUCFG1, PALEN, field);
38
data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f);
39
data = FIELD_DP32(data, CPUCFG1, UAL, 1);
40
data = FIELD_DP32(data, CPUCFG1, RI, 1);
41
--
42
2.43.5
diff view generated by jsdifflib
New patch
1
Some features such as LBT and PMU are implemented in kvm mode,
2
With paravirt features in future, post init function is added
3
for kvm mode, so that property for these features will be created
4
in kvm post init function.
1
5
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
7
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
8
---
9
target/loongarch/cpu.c | 2 +-
10
target/loongarch/cpu.h | 8 ++++++++
11
target/loongarch/kvm/kvm.c | 4 ++++
12
3 files changed, 13 insertions(+), 1 deletion(-)
13
14
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/loongarch/cpu.c
17
+++ b/target/loongarch/cpu.c
18
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_post_init(Object *obj)
19
loongarch_set_pmu);
20
object_property_set_description(obj, "pmu",
21
"Set off to performance monitor unit.");
22
-
23
+ kvm_loongarch_cpu_post_init(cpu);
24
} else {
25
cpu->lbt = ON_OFF_AUTO_OFF;
26
cpu->pmu = ON_OFF_AUTO_OFF;
27
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/loongarch/cpu.h
30
+++ b/target/loongarch/cpu.h
31
@@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
32
33
void loongarch_cpu_post_init(Object *obj);
34
35
+#ifdef CONFIG_KVM
36
+void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu);
37
+#else
38
+static inline void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
39
+{
40
+}
41
+#endif
42
+
43
#endif /* LOONGARCH_CPU_H */
44
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/loongarch/kvm/kvm.c
47
+++ b/target/loongarch/kvm/kvm.c
48
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
49
return ret;
50
}
51
52
+void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
53
+{
54
+}
55
+
56
int kvm_arch_destroy_vcpu(CPUState *cs)
57
{
58
return 0;
59
--
60
2.43.5
diff view generated by jsdifflib
1
The cc->sysemu_ops->get_phys_page_debug() is NULL when
1
LBT and PMU feature is supported only in kvm mode, move property
2
KVM-only build. this patch fixes it.
2
about these two features to function kvm_loongarch_cpu_post_init().
3
3
4
Signed-off-by: Song Gao <gaosong@loongson.cn>
4
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
5
Tested-by: Bibo Mao <maobibo@loongson.cn>
5
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
6
Message-Id: <20240125061401.52526-1-gaosong@loongson.cn>
7
---
6
---
8
target/loongarch/cpu.c | 2 -
7
target/loongarch/cpu.c | 40 ++------------------------------------
9
target/loongarch/cpu_helper.c | 231 ++++++++++++++++++++++++++++++
8
target/loongarch/kvm/kvm.c | 35 +++++++++++++++++++++++++++++++++
10
target/loongarch/internals.h | 20 ++-
9
2 files changed, 37 insertions(+), 38 deletions(-)
11
target/loongarch/meson.build | 1 +
12
target/loongarch/tcg/tlb_helper.c | 230 -----------------------------
13
5 files changed, 250 insertions(+), 234 deletions(-)
14
create mode 100644 target/loongarch/cpu_helper.c
15
10
16
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
11
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/target/loongarch/cpu.c
13
--- a/target/loongarch/cpu.c
19
+++ b/target/loongarch/cpu.c
14
+++ b/target/loongarch/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static const TCGCPUOps loongarch_tcg_ops = {
15
@@ -XXX,XX +XXX,XX @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
21
#include "hw/core/sysemu-cpu-ops.h"
16
cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, value);
22
17
}
23
static const struct SysemuCPUOps loongarch_sysemu_ops = {
18
24
-#ifdef CONFIG_TCG
19
-static bool loongarch_get_lbt(Object *obj, Error **errp)
25
.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
20
-{
26
-#endif
21
- return LOONGARCH_CPU(obj)->lbt != ON_OFF_AUTO_OFF;
27
};
22
-}
28
23
-
29
static int64_t loongarch_cpu_get_arch_id(CPUState *cs)
24
-static void loongarch_set_lbt(Object *obj, bool value, Error **errp)
30
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
25
-{
31
new file mode 100644
26
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
32
index XXXXXXX..XXXXXXX
27
-
33
--- /dev/null
28
- cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
34
+++ b/target/loongarch/cpu_helper.c
29
-}
35
@@ -XXX,XX +XXX,XX @@
30
-
36
+/* SPDX-License-Identifier: GPL-2.0-or-later */
31
-static bool loongarch_get_pmu(Object *obj, Error **errp)
37
+/*
32
-{
38
+ * LoongArch CPU helpers for qemu
33
- return LOONGARCH_CPU(obj)->pmu != ON_OFF_AUTO_OFF;
39
+ *
34
-}
40
+ * Copyright (c) 2024 Loongson Technology Corporation Limited
35
-
41
+ *
36
-static void loongarch_set_pmu(Object *obj, bool value, Error **errp)
42
+ */
37
-{
43
+
38
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
44
+#include "qemu/osdep.h"
39
-
45
+#include "cpu.h"
40
- cpu->pmu = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
46
+#include "internals.h"
41
-}
47
+#include "cpu-csr.h"
42
-
48
+
43
void loongarch_cpu_post_init(Object *obj)
49
+static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
44
{
50
+ int *prot, target_ulong address,
45
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
51
+ int access_type, int index, int mmu_idx)
46
47
+ cpu->lbt = ON_OFF_AUTO_OFF;
48
+ cpu->pmu = ON_OFF_AUTO_OFF;
49
cpu->lsx = ON_OFF_AUTO_AUTO;
50
cpu->lasx = ON_OFF_AUTO_AUTO;
51
object_property_add_bool(obj, "lsx", loongarch_get_lsx,
52
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_post_init(Object *obj)
53
loongarch_set_lasx);
54
/* lbt is enabled only in kvm mode, not supported in tcg mode */
55
if (kvm_enabled()) {
56
- cpu->lbt = ON_OFF_AUTO_AUTO;
57
- object_property_add_bool(obj, "lbt", loongarch_get_lbt,
58
- loongarch_set_lbt);
59
- object_property_set_description(obj, "lbt",
60
- "Set off to disable Binary Tranlation.");
61
-
62
- cpu->pmu = ON_OFF_AUTO_AUTO;
63
- object_property_add_bool(obj, "pmu", loongarch_get_pmu,
64
- loongarch_set_pmu);
65
- object_property_set_description(obj, "pmu",
66
- "Set off to performance monitor unit.");
67
kvm_loongarch_cpu_post_init(cpu);
68
- } else {
69
- cpu->lbt = ON_OFF_AUTO_OFF;
70
- cpu->pmu = ON_OFF_AUTO_OFF;
71
}
72
}
73
74
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/loongarch/kvm/kvm.c
77
+++ b/target/loongarch/kvm/kvm.c
78
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
79
return ret;
80
}
81
82
+static bool loongarch_get_lbt(Object *obj, Error **errp)
52
+{
83
+{
53
+ LoongArchTLB *tlb = &env->tlb[index];
84
+ return LOONGARCH_CPU(obj)->lbt != ON_OFF_AUTO_OFF;
54
+ uint64_t plv = mmu_idx;
55
+ uint64_t tlb_entry, tlb_ppn;
56
+ uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
57
+
58
+ if (index >= LOONGARCH_STLB) {
59
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
60
+ } else {
61
+ tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
62
+ }
63
+ n = (address >> tlb_ps) & 0x1;/* Odd or even */
64
+
65
+ tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
66
+ tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
67
+ tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
68
+ tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
69
+ if (is_la64(env)) {
70
+ tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
71
+ tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
72
+ tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
73
+ tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
74
+ } else {
75
+ tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
76
+ tlb_nx = 0;
77
+ tlb_nr = 0;
78
+ tlb_rplv = 0;
79
+ }
80
+
81
+ /* Remove sw bit between bit12 -- bit PS*/
82
+ tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) -1));
83
+
84
+ /* Check access rights */
85
+ if (!tlb_v) {
86
+ return TLBRET_INVALID;
87
+ }
88
+
89
+ if (access_type == MMU_INST_FETCH && tlb_nx) {
90
+ return TLBRET_XI;
91
+ }
92
+
93
+ if (access_type == MMU_DATA_LOAD && tlb_nr) {
94
+ return TLBRET_RI;
95
+ }
96
+
97
+ if (((tlb_rplv == 0) && (plv > tlb_plv)) ||
98
+ ((tlb_rplv == 1) && (plv != tlb_plv))) {
99
+ return TLBRET_PE;
100
+ }
101
+
102
+ if ((access_type == MMU_DATA_STORE) && !tlb_d) {
103
+ return TLBRET_DIRTY;
104
+ }
105
+
106
+ *physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
107
+ (address & MAKE_64BIT_MASK(0, tlb_ps));
108
+ *prot = PAGE_READ;
109
+ if (tlb_d) {
110
+ *prot |= PAGE_WRITE;
111
+ }
112
+ if (!tlb_nx) {
113
+ *prot |= PAGE_EXEC;
114
+ }
115
+ return TLBRET_MATCH;
116
+}
85
+}
117
+
86
+
118
+/*
87
+static void loongarch_set_lbt(Object *obj, bool value, Error **errp)
119
+ * One tlb entry holds an adjacent odd/even pair, the vpn is the
120
+ * content of the virtual page number divided by 2. So the
121
+ * compare vpn is bit[47:15] for 16KiB page. while the vppn
122
+ * field in tlb entry contains bit[47:13], so need adjust.
123
+ * virt_vpn = vaddr[47:13]
124
+ */
125
+bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
126
+ int *index)
127
+{
88
+{
128
+ LoongArchTLB *tlb;
89
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
129
+ uint16_t csr_asid, tlb_asid, stlb_idx;
130
+ uint8_t tlb_e, tlb_ps, tlb_g, stlb_ps;
131
+ int i, compare_shift;
132
+ uint64_t vpn, tlb_vppn;
133
+
90
+
134
+ csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
91
+ cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
135
+ stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
136
+ vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1);
137
+ stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */
138
+ compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
139
+
140
+ /* Search STLB */
141
+ for (i = 0; i < 8; ++i) {
142
+ tlb = &env->tlb[i * 256 + stlb_idx];
143
+ tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
144
+ if (tlb_e) {
145
+ tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
146
+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
147
+ tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
148
+
149
+ if ((tlb_g == 1 || tlb_asid == csr_asid) &&
150
+ (vpn == (tlb_vppn >> compare_shift))) {
151
+ *index = i * 256 + stlb_idx;
152
+ return true;
153
+ }
154
+ }
155
+ }
156
+
157
+ /* Search MTLB */
158
+ for (i = LOONGARCH_STLB; i < LOONGARCH_TLB_MAX; ++i) {
159
+ tlb = &env->tlb[i];
160
+ tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
161
+ if (tlb_e) {
162
+ tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
163
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
164
+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
165
+ tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
166
+ compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
167
+ vpn = (vaddr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
168
+ if ((tlb_g == 1 || tlb_asid == csr_asid) &&
169
+ (vpn == (tlb_vppn >> compare_shift))) {
170
+ *index = i;
171
+ return true;
172
+ }
173
+ }
174
+ }
175
+ return false;
176
+}
92
+}
177
+
93
+
178
+static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
94
+static bool loongarch_get_pmu(Object *obj, Error **errp)
179
+ int *prot, target_ulong address,
180
+ MMUAccessType access_type, int mmu_idx)
181
+{
95
+{
182
+ int index, match;
96
+ return LOONGARCH_CPU(obj)->pmu != ON_OFF_AUTO_OFF;
183
+
184
+ match = loongarch_tlb_search(env, address, &index);
185
+ if (match) {
186
+ return loongarch_map_tlb_entry(env, physical, prot,
187
+ address, access_type, index, mmu_idx);
188
+ }
189
+
190
+ return TLBRET_NOMATCH;
191
+}
97
+}
192
+
98
+
193
+static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
99
+static void loongarch_set_pmu(Object *obj, bool value, Error **errp)
194
+ target_ulong dmw)
195
+{
100
+{
196
+ if (is_la64(env)) {
101
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
197
+ return va & TARGET_VIRT_MASK;
102
+
198
+ } else {
103
+ cpu->pmu = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
199
+ uint32_t pseg = FIELD_EX32(dmw, CSR_DMW_32, PSEG);
200
+ return (va & MAKE_64BIT_MASK(0, R_CSR_DMW_32_VSEG_SHIFT)) | \
201
+ (pseg << R_CSR_DMW_32_VSEG_SHIFT);
202
+ }
203
+}
104
+}
204
+
105
+
205
+int get_physical_address(CPULoongArchState *env, hwaddr *physical,
106
void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
206
+ int *prot, target_ulong address,
107
{
207
+ MMUAccessType access_type, int mmu_idx)
108
+ cpu->lbt = ON_OFF_AUTO_AUTO;
208
+{
109
+ object_property_add_bool(OBJECT(cpu), "lbt", loongarch_get_lbt,
209
+ int user_mode = mmu_idx == MMU_IDX_USER;
110
+ loongarch_set_lbt);
210
+ int kernel_mode = mmu_idx == MMU_IDX_KERNEL;
111
+ object_property_set_description(OBJECT(cpu), "lbt",
211
+ uint32_t plv, base_c, base_v;
112
+ "Set off to disable Binary Tranlation.");
212
+ int64_t addr_high;
213
+ uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
214
+ uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
215
+
113
+
216
+ /* Check PG and DA */
114
+ cpu->pmu = ON_OFF_AUTO_AUTO;
217
+ if (da & !pg) {
115
+ object_property_add_bool(OBJECT(cpu), "pmu", loongarch_get_pmu,
218
+ *physical = address & TARGET_PHYS_MASK;
116
+ loongarch_set_pmu);
219
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
117
+ object_property_set_description(OBJECT(cpu), "pmu",
220
+ return TLBRET_MATCH;
118
+ "Set off to disable performance monitor unit.");
221
+ }
119
}
222
+
120
223
+ plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT);
121
int kvm_arch_destroy_vcpu(CPUState *cs)
224
+ if (is_la64(env)) {
225
+ base_v = address >> R_CSR_DMW_64_VSEG_SHIFT;
226
+ } else {
227
+ base_v = address >> R_CSR_DMW_32_VSEG_SHIFT;
228
+ }
229
+ /* Check direct map window */
230
+ for (int i = 0; i < 4; i++) {
231
+ if (is_la64(env)) {
232
+ base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG);
233
+ } else {
234
+ base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG);
235
+ }
236
+ if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
237
+ *physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
238
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
239
+ return TLBRET_MATCH;
240
+ }
241
+ }
242
+
243
+ /* Check valid extension */
244
+ addr_high = sextract64(address, TARGET_VIRT_ADDR_SPACE_BITS, 16);
245
+ if (!(addr_high == 0 || addr_high == -1)) {
246
+ return TLBRET_BADADDR;
247
+ }
248
+
249
+ /* Mapped address */
250
+ return loongarch_map_address(env, physical, prot, address,
251
+ access_type, mmu_idx);
252
+}
253
+
254
+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
255
+{
256
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
257
+ CPULoongArchState *env = &cpu->env;
258
+ hwaddr phys_addr;
259
+ int prot;
260
+
261
+ if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
262
+ cpu_mmu_index(env, false)) != 0) {
263
+ return -1;
264
+ }
265
+ return phys_addr;
266
+}
267
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
268
index XXXXXXX..XXXXXXX 100644
269
--- a/target/loongarch/internals.h
270
+++ b/target/loongarch/internals.h
271
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env);
272
#endif
273
274
#ifndef CONFIG_USER_ONLY
275
+enum {
276
+ TLBRET_MATCH = 0,
277
+ TLBRET_BADADDR = 1,
278
+ TLBRET_NOMATCH = 2,
279
+ TLBRET_INVALID = 3,
280
+ TLBRET_DIRTY = 4,
281
+ TLBRET_RI = 5,
282
+ TLBRET_XI = 6,
283
+ TLBRET_PE = 7,
284
+};
285
+
286
extern const VMStateDescription vmstate_loongarch_cpu;
287
288
void loongarch_cpu_set_irq(void *opaque, int irq, int level);
289
@@ -XXX,XX +XXX,XX @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
290
uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
291
void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
292
uint64_t value);
293
+bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
294
+ int *index);
295
+int get_physical_address(CPULoongArchState *env, hwaddr *physical,
296
+ int *prot, target_ulong address,
297
+ MMUAccessType access_type, int mmu_idx);
298
+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
299
+
300
#ifdef CONFIG_TCG
301
bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
302
MMUAccessType access_type, int mmu_idx,
303
bool probe, uintptr_t retaddr);
304
-
305
-hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
306
#endif
307
#endif /* !CONFIG_USER_ONLY */
308
309
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
310
index XXXXXXX..XXXXXXX 100644
311
--- a/target/loongarch/meson.build
312
+++ b/target/loongarch/meson.build
313
@@ -XXX,XX +XXX,XX @@ loongarch_ss.add(files(
314
315
loongarch_system_ss = ss.source_set()
316
loongarch_system_ss.add(files(
317
+ 'cpu_helper.c',
318
'loongarch-qmp-cmds.c',
319
'machine.c',
320
))
321
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/target/loongarch/tcg/tlb_helper.c
324
+++ b/target/loongarch/tcg/tlb_helper.c
325
@@ -XXX,XX +XXX,XX @@
326
#include "exec/log.h"
327
#include "cpu-csr.h"
328
329
-enum {
330
- TLBRET_MATCH = 0,
331
- TLBRET_BADADDR = 1,
332
- TLBRET_NOMATCH = 2,
333
- TLBRET_INVALID = 3,
334
- TLBRET_DIRTY = 4,
335
- TLBRET_RI = 5,
336
- TLBRET_XI = 6,
337
- TLBRET_PE = 7,
338
-};
339
-
340
-static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
341
- int *prot, target_ulong address,
342
- int access_type, int index, int mmu_idx)
343
-{
344
- LoongArchTLB *tlb = &env->tlb[index];
345
- uint64_t plv = mmu_idx;
346
- uint64_t tlb_entry, tlb_ppn;
347
- uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
348
-
349
- if (index >= LOONGARCH_STLB) {
350
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
351
- } else {
352
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
353
- }
354
- n = (address >> tlb_ps) & 0x1;/* Odd or even */
355
-
356
- tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
357
- tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
358
- tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
359
- tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
360
- if (is_la64(env)) {
361
- tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
362
- tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
363
- tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
364
- tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
365
- } else {
366
- tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
367
- tlb_nx = 0;
368
- tlb_nr = 0;
369
- tlb_rplv = 0;
370
- }
371
-
372
- /* Remove sw bit between bit12 -- bit PS*/
373
- tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) -1));
374
-
375
- /* Check access rights */
376
- if (!tlb_v) {
377
- return TLBRET_INVALID;
378
- }
379
-
380
- if (access_type == MMU_INST_FETCH && tlb_nx) {
381
- return TLBRET_XI;
382
- }
383
-
384
- if (access_type == MMU_DATA_LOAD && tlb_nr) {
385
- return TLBRET_RI;
386
- }
387
-
388
- if (((tlb_rplv == 0) && (plv > tlb_plv)) ||
389
- ((tlb_rplv == 1) && (plv != tlb_plv))) {
390
- return TLBRET_PE;
391
- }
392
-
393
- if ((access_type == MMU_DATA_STORE) && !tlb_d) {
394
- return TLBRET_DIRTY;
395
- }
396
-
397
- *physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
398
- (address & MAKE_64BIT_MASK(0, tlb_ps));
399
- *prot = PAGE_READ;
400
- if (tlb_d) {
401
- *prot |= PAGE_WRITE;
402
- }
403
- if (!tlb_nx) {
404
- *prot |= PAGE_EXEC;
405
- }
406
- return TLBRET_MATCH;
407
-}
408
-
409
-/*
410
- * One tlb entry holds an adjacent odd/even pair, the vpn is the
411
- * content of the virtual page number divided by 2. So the
412
- * compare vpn is bit[47:15] for 16KiB page. while the vppn
413
- * field in tlb entry contains bit[47:13], so need adjust.
414
- * virt_vpn = vaddr[47:13]
415
- */
416
-static bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
417
- int *index)
418
-{
419
- LoongArchTLB *tlb;
420
- uint16_t csr_asid, tlb_asid, stlb_idx;
421
- uint8_t tlb_e, tlb_ps, tlb_g, stlb_ps;
422
- int i, compare_shift;
423
- uint64_t vpn, tlb_vppn;
424
-
425
- csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
426
- stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
427
- vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1);
428
- stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */
429
- compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
430
-
431
- /* Search STLB */
432
- for (i = 0; i < 8; ++i) {
433
- tlb = &env->tlb[i * 256 + stlb_idx];
434
- tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
435
- if (tlb_e) {
436
- tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
437
- tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
438
- tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
439
-
440
- if ((tlb_g == 1 || tlb_asid == csr_asid) &&
441
- (vpn == (tlb_vppn >> compare_shift))) {
442
- *index = i * 256 + stlb_idx;
443
- return true;
444
- }
445
- }
446
- }
447
-
448
- /* Search MTLB */
449
- for (i = LOONGARCH_STLB; i < LOONGARCH_TLB_MAX; ++i) {
450
- tlb = &env->tlb[i];
451
- tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
452
- if (tlb_e) {
453
- tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
454
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
455
- tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
456
- tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
457
- compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
458
- vpn = (vaddr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
459
- if ((tlb_g == 1 || tlb_asid == csr_asid) &&
460
- (vpn == (tlb_vppn >> compare_shift))) {
461
- *index = i;
462
- return true;
463
- }
464
- }
465
- }
466
- return false;
467
-}
468
-
469
-static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
470
- int *prot, target_ulong address,
471
- MMUAccessType access_type, int mmu_idx)
472
-{
473
- int index, match;
474
-
475
- match = loongarch_tlb_search(env, address, &index);
476
- if (match) {
477
- return loongarch_map_tlb_entry(env, physical, prot,
478
- address, access_type, index, mmu_idx);
479
- }
480
-
481
- return TLBRET_NOMATCH;
482
-}
483
-
484
-static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
485
- target_ulong dmw)
486
-{
487
- if (is_la64(env)) {
488
- return va & TARGET_VIRT_MASK;
489
- } else {
490
- uint32_t pseg = FIELD_EX32(dmw, CSR_DMW_32, PSEG);
491
- return (va & MAKE_64BIT_MASK(0, R_CSR_DMW_32_VSEG_SHIFT)) | \
492
- (pseg << R_CSR_DMW_32_VSEG_SHIFT);
493
- }
494
-}
495
-
496
-static int get_physical_address(CPULoongArchState *env, hwaddr *physical,
497
- int *prot, target_ulong address,
498
- MMUAccessType access_type, int mmu_idx)
499
-{
500
- int user_mode = mmu_idx == MMU_IDX_USER;
501
- int kernel_mode = mmu_idx == MMU_IDX_KERNEL;
502
- uint32_t plv, base_c, base_v;
503
- int64_t addr_high;
504
- uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
505
- uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
506
-
507
- /* Check PG and DA */
508
- if (da & !pg) {
509
- *physical = address & TARGET_PHYS_MASK;
510
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
511
- return TLBRET_MATCH;
512
- }
513
-
514
- plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT);
515
- if (is_la64(env)) {
516
- base_v = address >> R_CSR_DMW_64_VSEG_SHIFT;
517
- } else {
518
- base_v = address >> R_CSR_DMW_32_VSEG_SHIFT;
519
- }
520
- /* Check direct map window */
521
- for (int i = 0; i < 4; i++) {
522
- if (is_la64(env)) {
523
- base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG);
524
- } else {
525
- base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG);
526
- }
527
- if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
528
- *physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
529
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
530
- return TLBRET_MATCH;
531
- }
532
- }
533
-
534
- /* Check valid extension */
535
- addr_high = sextract64(address, TARGET_VIRT_ADDR_SPACE_BITS, 16);
536
- if (!(addr_high == 0 || addr_high == -1)) {
537
- return TLBRET_BADADDR;
538
- }
539
-
540
- /* Mapped address */
541
- return loongarch_map_address(env, physical, prot, address,
542
- access_type, mmu_idx);
543
-}
544
-
545
-hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
546
-{
547
- LoongArchCPU *cpu = LOONGARCH_CPU(cs);
548
- CPULoongArchState *env = &cpu->env;
549
- hwaddr phys_addr;
550
- int prot;
551
-
552
- if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
553
- cpu_mmu_index(env, false)) != 0) {
554
- return -1;
555
- }
556
- return phys_addr;
557
-}
558
-
559
static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
560
MMUAccessType access_type, int tlb_error)
561
{
562
--
122
--
563
2.25.1
123
2.43.5
diff view generated by jsdifflib
New patch
1
Property kvm-pv-ipi is added to paravirt ipi feature, it is specially
2
for kvm mode.
1
3
4
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
5
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
target/loongarch/cpu.h | 1 +
8
target/loongarch/kvm/kvm.c | 18 ++++++++++++++++++
9
target/loongarch/loongarch-qmp-cmds.c | 2 +-
10
3 files changed, 20 insertions(+), 1 deletion(-)
11
12
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/cpu.h
15
+++ b/target/loongarch/cpu.h
16
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
17
OnOffAuto pmu;
18
OnOffAuto lsx;
19
OnOffAuto lasx;
20
+ OnOffAuto kvm_pv_ipi;
21
22
/* 'compatible' string for this CPU for Linux device trees */
23
const char *dtb_compatible;
24
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/loongarch/kvm/kvm.c
27
+++ b/target/loongarch/kvm/kvm.c
28
@@ -XXX,XX +XXX,XX @@ static void loongarch_set_pmu(Object *obj, bool value, Error **errp)
29
cpu->pmu = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
30
}
31
32
+static bool kvm_pv_ipi_get(Object *obj, Error **errp)
33
+{
34
+ return LOONGARCH_CPU(obj)->kvm_pv_ipi != ON_OFF_AUTO_OFF;
35
+}
36
+
37
+static void kvm_pv_ipi_set(Object *obj, bool value, Error **errp)
38
+{
39
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
40
+
41
+ cpu->kvm_pv_ipi = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
42
+}
43
+
44
void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
45
{
46
cpu->lbt = ON_OFF_AUTO_AUTO;
47
@@ -XXX,XX +XXX,XX @@ void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
48
loongarch_set_pmu);
49
object_property_set_description(OBJECT(cpu), "pmu",
50
"Set off to disable performance monitor unit.");
51
+
52
+ cpu->kvm_pv_ipi = ON_OFF_AUTO_AUTO;
53
+ object_property_add_bool(OBJECT(cpu), "kvm-pv-ipi", kvm_pv_ipi_get,
54
+ kvm_pv_ipi_set);
55
+ object_property_set_description(OBJECT(cpu), "kvm-pv-ipi",
56
+ "Set off to disable KVM paravirt IPI.");
57
}
58
59
int kvm_arch_destroy_vcpu(CPUState *cs)
60
diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/loongarch/loongarch-qmp-cmds.c
63
+++ b/target/loongarch/loongarch-qmp-cmds.c
64
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
65
}
66
67
static const char *cpu_model_advertised_features[] = {
68
- "lsx", "lasx", "lbt", "pmu", NULL
69
+ "lsx", "lasx", "lbt", "pmu", "kvm-pv-ipi", NULL
70
};
71
72
CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
73
--
74
2.43.5
diff view generated by jsdifflib
New patch
1
Paravirt ipi feature is OnOffAuto type, feature detection is added
2
to check whether it is supported by KVM host.
1
3
4
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
5
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
target/loongarch/cpu.h | 2 ++
8
target/loongarch/kvm/kvm.c | 36 +++++++++++++++++++++++++++++++++++-
9
2 files changed, 37 insertions(+), 1 deletion(-)
10
11
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/cpu.h
14
+++ b/target/loongarch/cpu.h
15
@@ -XXX,XX +XXX,XX @@ enum loongarch_features {
16
LOONGARCH_FEATURE_LASX,
17
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
18
LOONGARCH_FEATURE_PMU,
19
+ LOONGARCH_FEATURE_PV_IPI,
20
};
21
22
typedef struct LoongArchBT {
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
24
lbt_t lbt;
25
26
uint32_t cpucfg[21];
27
+ uint32_t pv_features;
28
29
/* LoongArch CSRs */
30
uint64_t CSR_CRMD;
31
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/loongarch/kvm/kvm.c
34
+++ b/target/loongarch/kvm/kvm.c
35
@@ -XXX,XX +XXX,XX @@
36
#include "qemu/osdep.h"
37
#include <sys/ioctl.h>
38
#include <linux/kvm.h>
39
-
40
+#include "asm-loongarch/kvm_para.h"
41
#include "qapi/error.h"
42
#include "qemu/timer.h"
43
#include "qemu/error-report.h"
44
@@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
45
ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
46
return (ret == 0);
47
48
+ case LOONGARCH_FEATURE_PV_IPI:
49
+ attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
50
+ attr.attr = KVM_LOONGARCH_VM_FEAT_PV_IPI;
51
+ ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
52
+ return (ret == 0);
53
+
54
default:
55
return false;
56
}
57
@@ -XXX,XX +XXX,XX @@ static int kvm_cpu_check_pmu(CPUState *cs, Error **errp)
58
return 0;
59
}
60
61
+static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp)
62
+{
63
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
64
+ CPULoongArchState *env = cpu_env(cs);
65
+ bool kvm_supported;
66
+
67
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PV_IPI);
68
+ if (cpu->kvm_pv_ipi == ON_OFF_AUTO_ON) {
69
+ if (!kvm_supported) {
70
+ error_setg(errp, "'pv_ipi' feature not supported by KVM host");
71
+ return -ENOTSUP;
72
+ }
73
+ } else if (cpu->kvm_pv_ipi != ON_OFF_AUTO_AUTO) {
74
+ kvm_supported = false;
75
+ }
76
+
77
+ if (kvm_supported) {
78
+ env->pv_features |= BIT(KVM_FEATURE_IPI);
79
+ }
80
+
81
+ return 0;
82
+}
83
+
84
int kvm_arch_init_vcpu(CPUState *cs)
85
{
86
uint64_t val;
87
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
88
error_report_err(local_err);
89
}
90
91
+ ret = kvm_cpu_check_pv_features(cs, &local_err);
92
+ if (ret < 0) {
93
+ error_report_err(local_err);
94
+ }
95
+
96
return ret;
97
}
98
99
--
100
2.43.5
diff view generated by jsdifflib
New patch
1
The similiar with cpucfg register, paravirt ipi feature is set in
2
function kvm_arch_put_registers(). Instead the paravirt feature can
3
be enabled only once, it cannot be changed dynamically.
1
4
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
7
---
8
target/loongarch/kvm/kvm.c | 36 ++++++++++++++++++++++++++++++++++++
9
1 file changed, 36 insertions(+)
10
11
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/kvm/kvm.c
14
+++ b/target/loongarch/kvm/kvm.c
15
@@ -XXX,XX +XXX,XX @@ static int kvm_set_stealtime(CPUState *cs)
16
return 0;
17
}
18
19
+static int kvm_set_pv_features(CPUState *cs)
20
+{
21
+ CPULoongArchState *env = cpu_env(cs);
22
+ int err;
23
+ uint64_t val;
24
+ struct kvm_device_attr attr = {
25
+ .group = KVM_LOONGARCH_VCPU_CPUCFG,
26
+ .attr = CPUCFG_KVM_FEATURE,
27
+ .addr = (uint64_t)&val,
28
+ };
29
+
30
+ err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
31
+ if (err) {
32
+ return 0;
33
+ }
34
+
35
+ val = env->pv_features;
36
+ err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
37
+ if (err) {
38
+ error_report("Fail to set pv feature "TARGET_FMT_lx " with error %s",
39
+ val, strerror(errno));
40
+ return err;
41
+ }
42
+
43
+ return 0;
44
+}
45
+
46
static int kvm_loongarch_get_regs_core(CPUState *cs)
47
{
48
int ret = 0;
49
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs, Error **errp)
50
int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
51
{
52
int ret;
53
+ static int once;
54
55
ret = kvm_loongarch_put_regs_core(cs);
56
if (ret) {
57
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
58
return ret;
59
}
60
61
+ if (!once) {
62
+ ret = kvm_set_pv_features(cs);
63
+ if (ret) {
64
+ return ret;
65
+ }
66
+ once = 1;
67
+ }
68
+
69
if (level >= KVM_PUT_FULL_STATE) {
70
/*
71
* only KVM_PUT_FULL_STATE is required, kvm kernel will clear
72
--
73
2.43.5
diff view generated by jsdifflib
New patch
1
Property kvm-steal-time is added for kvm steal time feature, it is
2
specially for kvm mode.
1
3
4
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
5
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
target/loongarch/cpu.h | 1 +
8
target/loongarch/kvm/kvm.c | 18 ++++++++++++++++++
9
target/loongarch/loongarch-qmp-cmds.c | 2 +-
10
3 files changed, 20 insertions(+), 1 deletion(-)
11
12
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/cpu.h
15
+++ b/target/loongarch/cpu.h
16
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
17
OnOffAuto lsx;
18
OnOffAuto lasx;
19
OnOffAuto kvm_pv_ipi;
20
+ OnOffAuto kvm_steal_time;
21
22
/* 'compatible' string for this CPU for Linux device trees */
23
const char *dtb_compatible;
24
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/loongarch/kvm/kvm.c
27
+++ b/target/loongarch/kvm/kvm.c
28
@@ -XXX,XX +XXX,XX @@ static void kvm_pv_ipi_set(Object *obj, bool value, Error **errp)
29
cpu->kvm_pv_ipi = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
30
}
31
32
+static bool kvm_steal_time_get(Object *obj, Error **errp)
33
+{
34
+ return LOONGARCH_CPU(obj)->kvm_steal_time != ON_OFF_AUTO_OFF;
35
+}
36
+
37
+static void kvm_steal_time_set(Object *obj, bool value, Error **errp)
38
+{
39
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
40
+
41
+ cpu->kvm_steal_time = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
42
+}
43
+
44
void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
45
{
46
cpu->lbt = ON_OFF_AUTO_AUTO;
47
@@ -XXX,XX +XXX,XX @@ void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
48
kvm_pv_ipi_set);
49
object_property_set_description(OBJECT(cpu), "kvm-pv-ipi",
50
"Set off to disable KVM paravirt IPI.");
51
+
52
+ cpu->kvm_steal_time = ON_OFF_AUTO_AUTO;
53
+ object_property_add_bool(OBJECT(cpu), "kvm-steal-time", kvm_steal_time_get,
54
+ kvm_steal_time_set);
55
+ object_property_set_description(OBJECT(cpu), "kvm-steal-time",
56
+ "Set off to disable KVM steal time.");
57
}
58
59
int kvm_arch_destroy_vcpu(CPUState *cs)
60
diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/loongarch/loongarch-qmp-cmds.c
63
+++ b/target/loongarch/loongarch-qmp-cmds.c
64
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
65
}
66
67
static const char *cpu_model_advertised_features[] = {
68
- "lsx", "lasx", "lbt", "pmu", "kvm-pv-ipi", NULL
69
+ "lsx", "lasx", "lbt", "pmu", "kvm-pv-ipi", "kvm-steal-time", NULL
70
};
71
72
CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
73
--
74
2.43.5
diff view generated by jsdifflib
New patch
1
Paravirt steal time feature is OnOffAuto type, feature detection is added
2
to check whether it is supported on KVM host.
1
3
4
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
5
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
target/loongarch/cpu.h | 1 +
8
target/loongarch/kvm/kvm.c | 20 ++++++++++++++++++++
9
2 files changed, 21 insertions(+)
10
11
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/cpu.h
14
+++ b/target/loongarch/cpu.h
15
@@ -XXX,XX +XXX,XX @@ enum loongarch_features {
16
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
17
LOONGARCH_FEATURE_PMU,
18
LOONGARCH_FEATURE_PV_IPI,
19
+ LOONGARCH_FEATURE_STEALTIME,
20
};
21
22
typedef struct LoongArchBT {
23
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/loongarch/kvm/kvm.c
26
+++ b/target/loongarch/kvm/kvm.c
27
@@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
28
ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
29
return (ret == 0);
30
31
+ case LOONGARCH_FEATURE_STEALTIME:
32
+ attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
33
+ attr.attr = KVM_LOONGARCH_VM_FEAT_PV_STEALTIME;
34
+ ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
35
+ return (ret == 0);
36
+
37
default:
38
return false;
39
}
40
@@ -XXX,XX +XXX,XX @@ static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp)
41
env->pv_features |= BIT(KVM_FEATURE_IPI);
42
}
43
44
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_STEALTIME);
45
+ if (cpu->kvm_steal_time == ON_OFF_AUTO_ON) {
46
+ if (!kvm_supported) {
47
+ error_setg(errp, "'kvm stealtime' feature not supported by KVM host");
48
+ return -ENOTSUP;
49
+ }
50
+ } else if (cpu->kvm_steal_time != ON_OFF_AUTO_AUTO) {
51
+ kvm_supported = false;
52
+ }
53
+
54
+ if (kvm_supported) {
55
+ env->pv_features |= BIT(KVM_FEATURE_STEAL_TIME);
56
+ }
57
+
58
return 0;
59
}
60
61
--
62
2.43.5
diff view generated by jsdifflib
New patch
1
Feature virtual extioi is loongArch virt machine property rather than
2
vCPU property in qemu side. However it is vCPU property in KVM kernel
3
side, here add loongArch virt machine property checking and enable virt
4
extioi feature when vCPU is created.
1
5
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
7
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
8
---
9
hw/loongarch/virt.c | 8 --------
10
include/hw/loongarch/virt.h | 9 +++++++++
11
target/loongarch/kvm/kvm.c | 10 ++++++++++
12
3 files changed, 19 insertions(+), 8 deletions(-)
13
14
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/loongarch/virt.c
17
+++ b/hw/loongarch/virt.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/virtio/virtio-iommu.h"
20
#include "qemu/error-report.h"
21
22
-static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
23
-{
24
- if (lvms->veiointc == ON_OFF_AUTO_OFF) {
25
- return false;
26
- }
27
- return true;
28
-}
29
-
30
static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
31
void *opaque, Error **errp)
32
{
33
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/loongarch/virt.h
36
+++ b/include/hw/loongarch/virt.h
37
@@ -XXX,XX +XXX,XX @@ struct LoongArchVirtMachineState {
38
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
39
void virt_acpi_setup(LoongArchVirtMachineState *lvms);
40
void virt_fdt_setup(LoongArchVirtMachineState *lvms);
41
+
42
+static inline bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
43
+{
44
+ if (lvms->veiointc == ON_OFF_AUTO_OFF) {
45
+ return false;
46
+ }
47
+ return true;
48
+}
49
+
50
#endif
51
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/loongarch/kvm/kvm.c
54
+++ b/target/loongarch/kvm/kvm.c
55
@@ -XXX,XX +XXX,XX @@
56
#include "exec/address-spaces.h"
57
#include "hw/boards.h"
58
#include "hw/irq.h"
59
+#include "hw/loongarch/virt.h"
60
#include "qemu/log.h"
61
#include "hw/loader.h"
62
#include "system/runstate.h"
63
@@ -XXX,XX +XXX,XX @@ static int kvm_cpu_check_pmu(CPUState *cs, Error **errp)
64
65
static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp)
66
{
67
+ MachineState *ms = MACHINE(qdev_get_machine());
68
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
69
CPULoongArchState *env = cpu_env(cs);
70
bool kvm_supported;
71
@@ -XXX,XX +XXX,XX @@ static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp)
72
env->pv_features |= BIT(KVM_FEATURE_STEAL_TIME);
73
}
74
75
+ if (object_dynamic_cast(OBJECT(ms), TYPE_LOONGARCH_VIRT_MACHINE)) {
76
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms);
77
+
78
+ if (virt_is_veiointc_enabled(lvms)) {
79
+ env->pv_features |= BIT(KVM_FEATURE_VIRT_EXTIOI);
80
+ }
81
+ }
82
+
83
return 0;
84
}
85
86
--
87
2.43.5
diff view generated by jsdifflib