FROMLIST: virt: geniezone: Enable PTP for synchronizing time between host and guest VMs

Enabled Precision Time Protocol (PTP) for improved host-guest VM time
synchronization, optimizing operations needing precise clock sync in
virtual environment.

Signed-off-by: Kevenny Hsieh <kevenny.hsieh@mediatek.com>
Signed-off-by: Yi-De Wu <yi-de.wu@mediatek.com>
Signed-off-by: Liju Chen <liju-clr.chen@mediatek.com>
Change-Id: Id236519e48e44713b20d75b80524921ddc0abc3f
Bug: 379230831
Link: https://lore.kernel.org/lkml/20241114100802.4116-22-liju-clr.chen@mediatek.com/
This commit is contained in:
Kevenny Hsieh
2023-08-08 23:08:05 +08:00
committed by Liju-clr Chen
parent 66a0f826f2
commit 76dceb11f2
6 changed files with 80 additions and 3 deletions
+1 -1
View File
@@ -4,6 +4,6 @@
#
include $(srctree)/drivers/virt/geniezone/Makefile
gzvm-y += vm.o vcpu.o vgic.o
gzvm-y += vm.o vcpu.o vgic.o hvc.o
obj-$(CONFIG_MTK_GZVM) += gzvm.o
+3
View File
@@ -83,6 +83,8 @@ int gzvm_hypcall_wrapper(unsigned long a0, unsigned long a1,
* @__pad: add an explicit '__u32 __pad;' in the middle to make it clear
* what the actual layout is.
* @lr: The array of LRs(list registers).
* @vtimer_offset: The offset maintained by hypervisor that is host cycle count
* when guest VM startup.
*
* - Keep the same layout of hypervisor data struct.
* - Sync list registers back for acking virtual device interrupt status.
@@ -91,6 +93,7 @@ struct gzvm_vcpu_hwstate {
__le32 nr_lrs;
__le32 __pad;
__le64 lr[GIC_V3_NR_LRS];
__le64 vtimer_offset;
};
static inline unsigned int
+73
View File
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2023 MediaTek Inc.
*/
#include <linux/clocksource.h>
#include <linux/kernel.h>
#include <linux/timekeeping.h>
#include <linux/soc/mediatek/gzvm_drv.h>
#include "gzvm_arch_common.h"
#define GZVM_PTP_VIRT_COUNTER 0
#define GZVM_PTP_PHYS_COUNTER 1
/**
* gzvm_handle_ptp_time() - Sync time between host and guest VM
* @vcpu: Pointer to struct gzvm_vcpu_run in userspace
* @counter: Counter type from guest VM
* Return: Always return 0 because there are no cases of failure
*
* The following register values will be passed to the guest VM
* for time synchronization:
* regs->x0 (upper 32 bits) wall clock time
* regs->x1 (lower 32 bits) wall clock time
* regs->x2 (upper 32 bits) cycles
* regs->x3 (lower 32 bits) cycles
*/
static int gzvm_handle_ptp_time(struct gzvm_vcpu *vcpu, int counter)
{
struct system_time_snapshot snapshot;
u64 cycles = 0;
ktime_get_snapshot(&snapshot);
switch (counter) {
case GZVM_PTP_VIRT_COUNTER:
cycles = snapshot.cycles -
le64_to_cpu(vcpu->hwstate->vtimer_offset);
break;
case GZVM_PTP_PHYS_COUNTER:
cycles = snapshot.cycles;
break;
default:
break;
}
vcpu->run->hypercall.args[0] = upper_32_bits(snapshot.real);
vcpu->run->hypercall.args[1] = lower_32_bits(snapshot.real);
vcpu->run->hypercall.args[2] = upper_32_bits(cycles);
vcpu->run->hypercall.args[3] = lower_32_bits(cycles);
return 0;
}
/**
* gzvm_arch_handle_guest_hvc() - Handle architecture-related guest hvc
* @vcpu: Pointer to struct gzvm_vcpu_run in userspace
* Return:
* * true - This hvc has been processed, no need to back to VMM.
* * false - This hvc has not been processed, require userspace.
*/
bool gzvm_arch_handle_guest_hvc(struct gzvm_vcpu *vcpu)
{
int ret, counter;
switch (vcpu->run->hypercall.args[0]) {
case GZVM_HVC_PTP:
counter = vcpu->run->hypercall.args[1];
ret = gzvm_handle_ptp_time(vcpu, counter);
return (ret == 0) ? true : false;
default:
break;
}
return false;
}
+1 -2
View File
@@ -56,7 +56,6 @@ bool gzvm_handle_guest_hvc(struct gzvm_vcpu *vcpu)
ret = gzvm_handle_relinquish(vcpu, ipa);
return (ret == 0) ? true : false;
default:
break;
return gzvm_arch_handle_guest_hvc(vcpu);
}
return false;
}
+1
View File
@@ -252,6 +252,7 @@ int gzvm_handle_page_fault(struct gzvm_vcpu *vcpu);
bool gzvm_handle_guest_exception(struct gzvm_vcpu *vcpu);
int gzvm_handle_relinquish(struct gzvm_vcpu *vcpu, phys_addr_t ipa);
bool gzvm_handle_guest_hvc(struct gzvm_vcpu *vcpu);
bool gzvm_arch_handle_guest_hvc(struct gzvm_vcpu *vcpu);
int gzvm_arch_create_device(u16 vm_id, struct gzvm_create_device *gzvm_dev);
int gzvm_arch_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
+1
View File
@@ -198,6 +198,7 @@ enum {
/* hypercall definitions of GZVM_EXIT_HYPERCALL */
enum {
GZVM_HVC_PTP = 0x86000001,
GZVM_HVC_MEM_RELINQUISH = 0xc6000009,
};