Skip to content

Commit e59e294

Browse files
committed
feat: add vm reset
Signed-off-by: Jose Martins <[email protected]>
1 parent d7c6e50 commit e59e294

File tree

4 files changed

+86
-4
lines changed

4 files changed

+86
-4
lines changed

src/arch/armv8/vm.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,16 @@ static unsigned long vm_cpuid_to_mpidr(struct vm* vm, vcpuid_t cpuid)
4545
return mpidr;
4646
}
4747

48+
void vm_arch_reset(struct vm* vm)
49+
{
50+
vgic_reset(vm);
51+
}
52+
4853
void vcpu_arch_init(struct vcpu* vcpu, struct vm* vm)
4954
{
5055
vcpu->arch.vmpidr = vm_cpuid_to_mpidr(vm, vcpu->id);
5156
sysreg_vmpidr_el2_write(vcpu->arch.vmpidr);
5257

53-
vcpu->arch.psci_ctx.state = vcpu->id == 0 ? ON : OFF;
54-
5558
vcpu_arch_profile_init(vcpu, vm);
5659

5760
vgic_cpu_init(vcpu);
@@ -78,6 +81,10 @@ void vcpu_arch_reset(struct vcpu* vcpu, vaddr_t entry)
7881
* TODO: ARMv8-A ARM mentions another implementation optional registers that reset to a known
7982
* value.
8083
*/
84+
85+
vcpu->arch.psci_ctx.state = vcpu->id == 0 ? ON : OFF;
86+
87+
vgic_cpu_reset(vcpu);
8188
}
8289

8390
static inline bool vcpu_psci_state_on(struct vcpu* vcpu)

src/arch/riscv/vm.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ void vcpu_arch_init(struct vcpu* vcpu, struct vm* vm)
2929
UNUSED_ARG(vm);
3030

3131
vcpu->arch.sbi_ctx.lock = SPINLOCK_INITVAL;
32-
vcpu->arch.sbi_ctx.state = vcpu->id == 0 ? STARTED : STOPPED;
3332
}
3433

3534
void vcpu_arch_reset(struct vcpu* vcpu, vaddr_t entry)
@@ -59,6 +58,8 @@ void vcpu_arch_reset(struct vcpu* vcpu, vaddr_t entry)
5958
csrs_vstval_write(0);
6059
csrs_hvip_write(0);
6160
csrs_vsatp_write(0);
61+
62+
vcpu->arch.sbi_ctx.state = vcpu->id == 0 ? STARTED : STOPPED;
6263
}
6364

6465
unsigned long vcpu_readreg(struct vcpu* vcpu, unsigned long reg)
@@ -95,3 +96,8 @@ void vcpu_arch_run(struct vcpu* vcpu)
9596
cpu_idle();
9697
}
9798
}
99+
100+
void vm_arch_reset(struct vm* vm)
101+
{
102+
virqc_reset(vm);
103+
}

src/core/inc/vm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ void vcpu_init(struct vcpu* vcpu, struct vm* vm, vaddr_t entry);
117117
void vm_msg_broadcast(struct vm* vm, struct cpu_msg* msg);
118118
cpumap_t vm_translate_to_pcpu_mask(struct vm* vm, cpumap_t mask, size_t len);
119119
cpumap_t vm_translate_to_vcpu_mask(struct vm* vm, cpumap_t mask, size_t len);
120+
bool vm_reset(struct vm* vm);
120121

121122
static inline struct vcpu* vm_get_vcpu(struct vm* vm, vcpuid_t vcpuid)
122123
{
@@ -176,5 +177,6 @@ unsigned long vcpu_readpc(struct vcpu* vcpu);
176177
void vcpu_writepc(struct vcpu* vcpu, unsigned long pc);
177178
void vcpu_arch_run(struct vcpu* vcpu);
178179
void vcpu_arch_reset(struct vcpu* vcpu, vaddr_t entry);
180+
void vm_arch_reset(struct vm* vm);
179181

180182
#endif /* __VM_H__ */

src/core/vm.c

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,73 @@ __attribute__((weak)) cpumap_t vm_translate_to_vcpu_mask(struct vm* vm, cpumap_t
349349

350350
void vcpu_run(struct vcpu* vcpu)
351351
{
352-
cpu()->vcpu->active = true;
353352
vcpu_arch_run(vcpu);
354353
}
354+
355+
static void vm_vcpu_reset(struct vm* vm)
356+
{
357+
struct vcpu* vcpu = cpu()->vcpu;
358+
359+
if (vcpu->vm->id != vm->id) {
360+
ERROR("Trying to reset vm not hosted in this cpu");
361+
}
362+
363+
cpu_sync_and_clear_msgs(&vm->sync);
364+
365+
if (vm->master == cpu()->id) {
366+
vm_arch_reset(vm);
367+
for (size_t i = 0; i < vm->config->platform.region_num; i++) {
368+
struct vm_mem_region* reg = &vm->config->platform.regions[i];
369+
bool img_is_in_rgn = range_in_range(vm->config->image.base_addr, vm->config->image.size,
370+
reg->base, reg->size);
371+
if (img_is_in_rgn) {
372+
vm_install_image(vm, reg);
373+
break;
374+
}
375+
}
376+
}
377+
378+
cpu_sync_barrier(&vcpu->vm->sync);
379+
380+
vcpu_arch_reset(vcpu, vm->config->entry);
381+
382+
vcpu_arch_run(vcpu);
383+
}
384+
385+
enum VM_EVENTS { VM_RESET };
386+
387+
static void vm_msg_handler(uint32_t event, uint64_t data)
388+
{
389+
UNUSED_ARG(data);
390+
391+
switch (event) {
392+
case VM_RESET:
393+
vm_vcpu_reset(cpu()->vcpu->vm);
394+
break;
395+
default:
396+
break;
397+
}
398+
}
399+
400+
CPU_MSG_HANDLER(vm_msg_handler, VM_IPI_ID)
401+
402+
bool vm_reset(struct vm* vm)
403+
{
404+
bool res;
405+
406+
if (vm->config->image.inplace) {
407+
res = false;
408+
} else {
409+
struct cpu_msg msg;
410+
msg.handler = (uint32_t)VM_IPI_ID;
411+
msg.event = VM_RESET;
412+
413+
vm_msg_broadcast(vm, &msg);
414+
415+
vm_vcpu_reset(vm);
416+
417+
res = true;
418+
}
419+
420+
return res;
421+
}

0 commit comments

Comments
 (0)