Skip to content

Commit d8d8db8

Browse files
lixianglaigregkh
authored andcommitted
LoongArch: KVM: Compile switch.S directly into the kernel
commit 5203012 upstream. If we directly compile the switch.S file into the kernel, the address of the kvm_exc_entry function will definitely be within the DMW memory area. Therefore, we will no longer need to perform a copy relocation of the kvm_exc_entry. So this patch compiles switch.S directly into the kernel, and then remove the copy relocation execution logic for the kvm_exc_entry function. Signed-off-by: Xianglai Li <lixianglai@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 20ac98f commit d8d8db8

6 files changed

Lines changed: 40 additions & 42 deletions

File tree

arch/loongarch/Kbuild

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ obj-y += mm/
33
obj-y += net/
44
obj-y += vdso/
55

6-
obj-$(CONFIG_KVM) += kvm/
6+
obj-$(subst m,y,$(CONFIG_KVM)) += kvm/
77
obj-$(CONFIG_BUILTIN_DTB) += boot/dts/
88

99
# for cleaning

arch/loongarch/include/asm/asm-prototypes.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,23 @@ __int128_t __ashlti3(__int128_t a, int b);
1212
__int128_t __ashrti3(__int128_t a, int b);
1313
__int128_t __lshrti3(__int128_t a, int b);
1414
#endif
15+
16+
struct kvm_run;
17+
struct kvm_vcpu;
18+
struct loongarch_fpu;
19+
20+
void kvm_exc_entry(void);
21+
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
22+
23+
void kvm_save_fpu(struct loongarch_fpu *fpu);
24+
void kvm_restore_fpu(struct loongarch_fpu *fpu);
25+
26+
#ifdef CONFIG_CPU_HAS_LSX
27+
void kvm_save_lsx(struct loongarch_fpu *fpu);
28+
void kvm_restore_lsx(struct loongarch_fpu *fpu);
29+
#endif
30+
31+
#ifdef CONFIG_CPU_HAS_LASX
32+
void kvm_save_lasx(struct loongarch_fpu *fpu);
33+
void kvm_restore_lasx(struct loongarch_fpu *fpu);
34+
#endif

arch/loongarch/include/asm/kvm_host.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ struct kvm_context {
7373
struct kvm_world_switch {
7474
int (*exc_entry)(void);
7575
int (*enter_guest)(struct kvm_run *run, struct kvm_vcpu *vcpu);
76-
unsigned long page_order;
7776
};
7877

7978
#define MAX_PGTABLE_LEVELS 4
@@ -317,8 +316,6 @@ void kvm_exc_entry(void);
317316
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
318317

319318
extern unsigned long vpid_mask;
320-
extern const unsigned long kvm_exception_size;
321-
extern const unsigned long kvm_enter_guest_size;
322319
extern struct kvm_world_switch *kvm_loongarch_ops;
323320

324321
#define SW_GCSR (1 << 0)

arch/loongarch/kvm/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ include $(srctree)/virt/kvm/Makefile.kvm
99

1010
obj-$(CONFIG_KVM) += kvm.o
1111

12+
obj-y += switch.o
13+
1214
kvm-y += exit.o
1315
kvm-y += interrupt.o
1416
kvm-y += main.o
1517
kvm-y += mmu.o
16-
kvm-y += switch.o
1718
kvm-y += timer.o
1819
kvm-y += tlb.o
1920
kvm-y += vcpu.o

arch/loongarch/kvm/main.c

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,7 @@ void kvm_arch_disable_virtualization_cpu(void)
320320

321321
static int kvm_loongarch_env_init(void)
322322
{
323-
int cpu, order;
324-
void *addr;
323+
int cpu;
325324
struct kvm_context *context;
326325

327326
vmcs = alloc_percpu(struct kvm_context);
@@ -337,30 +336,8 @@ static int kvm_loongarch_env_init(void)
337336
return -ENOMEM;
338337
}
339338

340-
/*
341-
* PGD register is shared between root kernel and kvm hypervisor.
342-
* So world switch entry should be in DMW area rather than TLB area
343-
* to avoid page fault reenter.
344-
*
345-
* In future if hardware pagetable walking is supported, we won't
346-
* need to copy world switch code to DMW area.
347-
*/
348-
order = get_order(kvm_exception_size + kvm_enter_guest_size);
349-
addr = (void *)__get_free_pages(GFP_KERNEL, order);
350-
if (!addr) {
351-
free_percpu(vmcs);
352-
vmcs = NULL;
353-
kfree(kvm_loongarch_ops);
354-
kvm_loongarch_ops = NULL;
355-
return -ENOMEM;
356-
}
357-
358-
memcpy(addr, kvm_exc_entry, kvm_exception_size);
359-
memcpy(addr + kvm_exception_size, kvm_enter_guest, kvm_enter_guest_size);
360-
flush_icache_range((unsigned long)addr, (unsigned long)addr + kvm_exception_size + kvm_enter_guest_size);
361-
kvm_loongarch_ops->exc_entry = addr;
362-
kvm_loongarch_ops->enter_guest = addr + kvm_exception_size;
363-
kvm_loongarch_ops->page_order = order;
339+
kvm_loongarch_ops->exc_entry = (void *)kvm_exc_entry;
340+
kvm_loongarch_ops->enter_guest = (void *)kvm_enter_guest;
364341

365342
vpid_mask = read_csr_gstat();
366343
vpid_mask = (vpid_mask & CSR_GSTAT_GIDBIT) >> CSR_GSTAT_GIDBIT_SHIFT;
@@ -380,16 +357,10 @@ static int kvm_loongarch_env_init(void)
380357

381358
static void kvm_loongarch_env_exit(void)
382359
{
383-
unsigned long addr;
384-
385360
if (vmcs)
386361
free_percpu(vmcs);
387362

388363
if (kvm_loongarch_ops) {
389-
if (kvm_loongarch_ops->exc_entry) {
390-
addr = (unsigned long)kvm_loongarch_ops->exc_entry;
391-
free_pages(addr, kvm_loongarch_ops->page_order);
392-
}
393364
kfree(kvm_loongarch_ops);
394365
}
395366
}

arch/loongarch/kvm/switch.S

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <asm/asm.h>
88
#include <asm/asmmacro.h>
99
#include <asm/loongarch.h>
10+
#include <asm/page.h>
1011
#include <asm/regdef.h>
1112
#include <asm/unwind_hints.h>
1213

@@ -108,8 +109,13 @@
108109
* - is still in guest mode, such as pgd table/vmid registers etc,
109110
* - will fix with hw page walk enabled in future
110111
* load kvm_vcpu from reserved CSR KVM_VCPU_KS, and save a2 to KVM_TEMP_KS
112+
*
113+
* PGD register is shared between root kernel and kvm hypervisor.
114+
* So world switch entry should be in DMW area rather than TLB area
115+
* to avoid page fault re-enter.
111116
*/
112117
.text
118+
.p2align PAGE_SHIFT
113119
.cfi_sections .debug_frame
114120
SYM_CODE_START(kvm_exc_entry)
115121
UNWIND_HINT_END_OF_STACK
@@ -198,8 +204,8 @@ ret_to_host:
198204
kvm_restore_host_gpr a2
199205
jr ra
200206

201-
SYM_INNER_LABEL(kvm_exc_entry_end, SYM_L_LOCAL)
202207
SYM_CODE_END(kvm_exc_entry)
208+
EXPORT_SYMBOL_GPL(kvm_exc_entry)
203209

204210
/*
205211
* int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu)
@@ -223,22 +229,24 @@ SYM_FUNC_START(kvm_enter_guest)
223229
/* Save kvm_vcpu to kscratch */
224230
csrwr a1, KVM_VCPU_KS
225231
kvm_switch_to_guest
226-
SYM_INNER_LABEL(kvm_enter_guest_end, SYM_L_LOCAL)
227232
SYM_FUNC_END(kvm_enter_guest)
233+
EXPORT_SYMBOL_GPL(kvm_enter_guest)
228234

229235
SYM_FUNC_START(kvm_save_fpu)
230236
fpu_save_csr a0 t1
231237
fpu_save_double a0 t1
232238
fpu_save_cc a0 t1 t2
233239
jr ra
234240
SYM_FUNC_END(kvm_save_fpu)
241+
EXPORT_SYMBOL_GPL(kvm_save_fpu)
235242

236243
SYM_FUNC_START(kvm_restore_fpu)
237244
fpu_restore_double a0 t1
238245
fpu_restore_csr a0 t1 t2
239246
fpu_restore_cc a0 t1 t2
240247
jr ra
241248
SYM_FUNC_END(kvm_restore_fpu)
249+
EXPORT_SYMBOL_GPL(kvm_restore_fpu)
242250

243251
#ifdef CONFIG_CPU_HAS_LSX
244252
SYM_FUNC_START(kvm_save_lsx)
@@ -247,13 +255,15 @@ SYM_FUNC_START(kvm_save_lsx)
247255
lsx_save_data a0 t1
248256
jr ra
249257
SYM_FUNC_END(kvm_save_lsx)
258+
EXPORT_SYMBOL_GPL(kvm_save_lsx)
250259

251260
SYM_FUNC_START(kvm_restore_lsx)
252261
lsx_restore_data a0 t1
253262
fpu_restore_cc a0 t1 t2
254263
fpu_restore_csr a0 t1 t2
255264
jr ra
256265
SYM_FUNC_END(kvm_restore_lsx)
266+
EXPORT_SYMBOL_GPL(kvm_restore_lsx)
257267
#endif
258268

259269
#ifdef CONFIG_CPU_HAS_LASX
@@ -263,17 +273,16 @@ SYM_FUNC_START(kvm_save_lasx)
263273
lasx_save_data a0 t1
264274
jr ra
265275
SYM_FUNC_END(kvm_save_lasx)
276+
EXPORT_SYMBOL_GPL(kvm_save_lasx)
266277

267278
SYM_FUNC_START(kvm_restore_lasx)
268279
lasx_restore_data a0 t1
269280
fpu_restore_cc a0 t1 t2
270281
fpu_restore_csr a0 t1 t2
271282
jr ra
272283
SYM_FUNC_END(kvm_restore_lasx)
284+
EXPORT_SYMBOL_GPL(kvm_restore_lasx)
273285
#endif
274-
.section ".rodata"
275-
SYM_DATA(kvm_exception_size, .quad kvm_exc_entry_end - kvm_exc_entry)
276-
SYM_DATA(kvm_enter_guest_size, .quad kvm_enter_guest_end - kvm_enter_guest)
277286

278287
#ifdef CONFIG_CPU_HAS_LBT
279288
STACK_FRAME_NON_STANDARD kvm_restore_fpu

0 commit comments

Comments
 (0)