Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

executor: sys/linux: arm64: implement SYZOS_API_WFI_WFE #5619

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions executor/common_kvm_arm64_syzos.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ typedef enum {
SYZOS_API_MEMWRITE,
SYZOS_API_ITS_SETUP,
SYZOS_API_ITS_SEND_CMD,
SYZOS_API_WFI_WFE,
SYZOS_API_STOP, // Must be the last one
} syzos_api_id;

Expand All @@ -41,6 +42,11 @@ struct api_call_uexit {
uint64 exit_code;
};

struct api_call_1 {
struct api_call_header header;
uint64 arg;
};

struct api_call_2 {
struct api_call_header header;
uint64 args[2];
Expand Down Expand Up @@ -96,6 +102,7 @@ static void guest_handle_irq_setup(struct api_call_irq_setup* cmd);
static void guest_handle_memwrite(struct api_call_memwrite* cmd);
static void guest_handle_its_setup(struct api_call_3* cmd);
static void guest_handle_its_send_cmd(struct api_call_its_send_cmd* cmd);
static void guest_handle_wfi_wfe(struct api_call_1* cmd);

typedef enum {
UEXIT_END = (uint64)-1,
Expand Down Expand Up @@ -157,6 +164,10 @@ guest_main(uint64 size, uint64 cpu)
guest_handle_its_send_cmd((struct api_call_its_send_cmd*)cmd);
break;
}
case SYZOS_API_WFI_WFE: {
guest_handle_wfi_wfe((struct api_call_1*)cmd);
break;
}
}
addr += cmd->size;
size -= cmd->size;
Expand Down Expand Up @@ -585,6 +596,20 @@ GUEST_CODE static noinline void guest_handle_its_setup(struct api_call_3* cmd)
guest_prepare_its(cmd->args[0], cmd->args[1], cmd->args[2]);
}

GUEST_CODE static noinline void guest_handle_wfi_wfe(struct api_call_1* cmd)
{
switch (cmd->arg) {
case 0: {
asm volatile("wfi");
break;
}
case 1: {
asm volatile("wfe");
break;
}
}
}

// Registers saved by one_irq_handler() and received by guest_irq_handler().
struct ex_regs {
uint64 regs[31];
Expand Down
1 change: 1 addition & 0 deletions sys/linux/dev_kvm_arm64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,5 @@ syzos_api_call [
memwrite syzos_api[6, syzos_api_memwrite]
its_setup syzos_api[7, syzos_api_its_setup]
its_send_cmd syzos_api[8, syzos_api_its_send_cmd]
wfi_wfe syzos_api[9, int64[0:1]]
] [varlen]
21 changes: 21 additions & 0 deletions sys/linux/test/arm64-syz_kvm_setup_syzos_vm-wfi
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
# requires: arch=arm64 -threaded
#
r0 = openat$kvm(0, &AUTO='/dev/kvm\x00', 0x0, 0x0)
r1 = ioctl$KVM_CREATE_VM(r0, AUTO, 0x0)
r2 = syz_kvm_setup_syzos_vm(r1, &(0x7f0000c00000/0x400000)=nil)
r3 = syz_kvm_add_vcpu(r2, &AUTO={0x0, &AUTO=[@wfi_wfe={AUTO, AUTO, 0x1}], AUTO}, 0x0, 0x0)
syz_kvm_vgic_v3_setup(r1, 0x1, 0x100)

r4 = ioctl$KVM_GET_VCPU_MMAP_SIZE(r0, AUTO)
r5 = mmap$KVM_VCPU(&(0x7f0000009000/0x1000)=nil, r4, 0x3, 0x1, r3, 0x0)

# Run till the end of guest_main(). 0xffffffffffffffff is UEXIT_END.
#
ioctl$KVM_RUN(r3, AUTO, 0x0)
syz_kvm_assert_syzos_uexit(r5, 0xffffffffffffffff)

ioctl$KVM_IRQ_LINE(r1, AUTO, &AUTO={0x1000020, 0x1}) (async)

ioctl$KVM_RUN(r3, AUTO, 0x0)
syz_kvm_assert_syzos_uexit(r5, 0xffffffffffffffff)
Loading