Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
16035a3
RISC-V: Fix the typo in Scountovf CSR name
atishp04 Apr 20, 2024
fb206fc
RISC-V: Add FIRMWARE_READ_HI definition
atishp04 Apr 20, 2024
162964b
drivers/perf: riscv: Read upper bits of a firmware counter
atishp04 Apr 20, 2024
1b877ce
drivers/perf: riscv: Use BIT macro for shifting operations
atishp04 Apr 20, 2024
cda39c6
RISC-V: Add SBI PMU snapshot definitions
atishp04 Apr 20, 2024
c3f6044
RISC-V: KVM: Rename the SBI_STA_SHMEM_DISABLE to a generic name
atishp04 Apr 20, 2024
c892dfa
RISC-V: Use the minor version mask while computing sbi version
atishp04 Apr 20, 2024
fdeb1db
drivers/perf: riscv: Fix counter mask iteration for RV32
atishp04 Apr 20, 2024
220e15b
drivers/perf: riscv: Implement SBI PMU snapshot function
atishp04 Apr 20, 2024
7078270
RISC-V: KVM: No need to update the counter value during reset
atishp04 Apr 20, 2024
ec013b0
RISC-V: KVM: No need to exit to the user space if perf event failed
atishp04 Apr 20, 2024
4c330d8
RISC-V: KVM: Implement SBI PMU Snapshot feature
atishp04 Apr 20, 2024
5954414
RISC-V: KVM: Add perf sampling support for guests
atishp04 Apr 20, 2024
98c8930
RISC-V: KVM: Support 64 bit firmware counters on RV32
atishp04 Apr 20, 2024
b38dae2
RISC-V: KVM: Improve firmware counter read function
atishp04 Apr 20, 2024
5751f39
selftests/kvm: Fix issues with $(SPLIT_TESTS)
bonzini Jan 22, 2024
c238590
KVM: arm64: selftests: Split arch_timer test code
xiaobo55x Jan 22, 2024
b76a73a
KVM: riscv: selftests: Add exception handling support
xiaobo55x Jan 22, 2024
722a210
KVM: riscv: selftests: Add guest helper to get vcpu id
xiaobo55x Jan 22, 2024
66d47d8
KVM: riscv: selftests: Change vcpu_has_ext to a common function
xiaobo55x Jan 22, 2024
856bccd
KVM: riscv: selftests: Add sstc timer test
xiaobo55x Jan 22, 2024
1af8273
KVM: riscv: selftests: Move sbi definitions to its own header file
atishp04 Apr 20, 2024
38713c3
KVM: riscv: selftests: Add helper functions for extension checks
atishp04 Apr 20, 2024
5475797
KVM: riscv: selftests: Add Sscofpmf to get-reg-list test
atishp04 Apr 20, 2024
ef495c4
KVM: riscv: selftests: Add SBI PMU extension definitions
atishp04 Apr 20, 2024
4d7c7d3
KVM: riscv: selftests: Add SBI PMU selftest
atishp04 Apr 20, 2024
37c4ce6
KVM: riscv: selftests: Add a test for PMU snapshot functionality
atishp04 Apr 20, 2024
9dbc694
KVM: riscv: selftests: Add a test for counter overflow
atishp04 Apr 20, 2024
16cc57b
KVM: riscv: selftests: Add commandline option for SBI PMU test
atishp04 Apr 20, 2024
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
5 changes: 3 additions & 2 deletions arch/riscv/include/asm/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@
#define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT)
#define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \
(_AC(1, UL) << IRQ_S_TIMER) | \
(_AC(1, UL) << IRQ_S_EXT))
(_AC(1, UL) << IRQ_S_EXT) | \
(_AC(1, UL) << IRQ_PMU_OVF))

/* AIA CSR bits */
#define TOPI_IID_SHIFT 16
Expand Down Expand Up @@ -292,7 +293,7 @@
#define CSR_HPMCOUNTER30H 0xc9e
#define CSR_HPMCOUNTER31H 0xc9f

#define CSR_SSCOUNTOVF 0xda0
#define CSR_SCOUNTOVF 0xda0

#define CSR_SSTATUS 0x100
#define CSR_SIE 0x104
Expand Down
16 changes: 14 additions & 2 deletions arch/riscv/include/asm/kvm_vcpu_pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static_assert(RISCV_KVM_MAX_COUNTERS <= 64);

struct kvm_fw_event {
/* Current value of the event */
unsigned long value;
u64 value;

/* Event monitoring status */
bool started;
Expand All @@ -37,6 +37,7 @@ struct kvm_pmc {
bool started;
/* Monitoring event ID */
unsigned long event_idx;
struct kvm_vcpu *vcpu;
};

/* PMU data structure per vcpu */
Expand All @@ -51,6 +52,12 @@ struct kvm_pmu {
bool init_done;
/* Bit map of all the virtual counter used */
DECLARE_BITMAP(pmc_in_use, RISCV_KVM_MAX_COUNTERS);
/* Bit map of all the virtual counter overflown */
DECLARE_BITMAP(pmc_overflown, RISCV_KVM_MAX_COUNTERS);
/* The address of the counter snapshot area (guest physical address) */
gpa_t snapshot_addr;
/* The actual data of the snapshot */
struct riscv_pmu_snapshot_data *sdata;
};

#define vcpu_to_pmu(vcpu) (&(vcpu)->arch.pmu_context)
Expand Down Expand Up @@ -83,9 +90,14 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba
unsigned long ctr_mask, unsigned long flags,
unsigned long eidx, u64 evtdata,
struct kvm_vcpu_sbi_return *retdata);
int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
int kvm_riscv_vcpu_pmu_fw_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
struct kvm_vcpu_sbi_return *retdata);
int kvm_riscv_vcpu_pmu_fw_ctr_read_hi(struct kvm_vcpu *vcpu, unsigned long cidx,
struct kvm_vcpu_sbi_return *retdata);
void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu);
int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long saddr_low,
unsigned long saddr_high, unsigned long flags,
struct kvm_vcpu_sbi_return *retdata);
void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu);

Expand Down
38 changes: 25 additions & 13 deletions arch/riscv/include/asm/sbi.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ enum sbi_ext_pmu_fid {
SBI_EXT_PMU_COUNTER_START,
SBI_EXT_PMU_COUNTER_STOP,
SBI_EXT_PMU_COUNTER_FW_READ,
SBI_EXT_PMU_COUNTER_FW_READ_HI,
SBI_EXT_PMU_SNAPSHOT_SET_SHMEM,
};

union sbi_pmu_ctr_info {
Expand All @@ -148,6 +150,13 @@ union sbi_pmu_ctr_info {
};
};

/* Data structure to contain the pmu snapshot data */
struct riscv_pmu_snapshot_data {
u64 ctr_overflow_mask;
u64 ctr_values[64];
u64 reserved[447];
};

#define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
#define RISCV_PMU_RAW_EVENT_IDX 0x20000

Expand Down Expand Up @@ -233,20 +242,22 @@ enum sbi_pmu_ctr_type {
#define SBI_PMU_EVENT_IDX_INVALID 0xFFFFFFFF

/* Flags defined for config matching function */
#define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0)
#define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1)
#define SBI_PMU_CFG_FLAG_AUTO_START (1 << 2)
#define SBI_PMU_CFG_FLAG_SET_VUINH (1 << 3)
#define SBI_PMU_CFG_FLAG_SET_VSINH (1 << 4)
#define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5)
#define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6)
#define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7)
#define SBI_PMU_CFG_FLAG_SKIP_MATCH BIT(0)
#define SBI_PMU_CFG_FLAG_CLEAR_VALUE BIT(1)
#define SBI_PMU_CFG_FLAG_AUTO_START BIT(2)
#define SBI_PMU_CFG_FLAG_SET_VUINH BIT(3)
#define SBI_PMU_CFG_FLAG_SET_VSINH BIT(4)
#define SBI_PMU_CFG_FLAG_SET_UINH BIT(5)
#define SBI_PMU_CFG_FLAG_SET_SINH BIT(6)
#define SBI_PMU_CFG_FLAG_SET_MINH BIT(7)

/* Flags defined for counter start function */
#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
#define SBI_PMU_START_FLAG_SET_INIT_VALUE BIT(0)
#define SBI_PMU_START_FLAG_INIT_SNAPSHOT BIT(1)

/* Flags defined for counter stop function */
#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
#define SBI_PMU_STOP_FLAG_RESET BIT(0)
#define SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT BIT(1)

enum sbi_ext_dbcn_fid {
SBI_EXT_DBCN_CONSOLE_WRITE = 0,
Expand Down Expand Up @@ -328,7 +339,7 @@ struct sbi_sta_struct {
u8 pad[47];
} __packed;

#define SBI_STA_SHMEM_DISABLE -1
#define SBI_SHMEM_DISABLE -1

/* SBI spec version fields */
#define SBI_SPEC_VERSION_DEFAULT 0x1
Expand All @@ -346,6 +357,7 @@ struct sbi_sta_struct {
#define SBI_ERR_ALREADY_AVAILABLE -6
#define SBI_ERR_ALREADY_STARTED -7
#define SBI_ERR_ALREADY_STOPPED -8
#define SBI_ERR_NO_SHMEM -9

extern unsigned long sbi_spec_version;
struct sbiret {
Expand Down Expand Up @@ -417,8 +429,8 @@ static inline unsigned long sbi_minor_version(void)
static inline unsigned long sbi_mk_version(unsigned long major,
unsigned long minor)
{
return ((major & SBI_SPEC_VERSION_MAJOR_MASK) <<
SBI_SPEC_VERSION_MAJOR_SHIFT) | minor;
return ((major & SBI_SPEC_VERSION_MAJOR_MASK) << SBI_SPEC_VERSION_MAJOR_SHIFT)
| (minor & SBI_SPEC_VERSION_MINOR_MASK);
}

int sbi_err_map_linux_errno(int err);
Expand Down
6 changes: 3 additions & 3 deletions arch/riscv/kernel/paravirt.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static int sbi_sta_steal_time_set_shmem(unsigned long lo, unsigned long hi,
ret = sbi_ecall(SBI_EXT_STA, SBI_EXT_STA_STEAL_TIME_SET_SHMEM,
lo, hi, flags, 0, 0, 0);
if (ret.error) {
if (lo == SBI_STA_SHMEM_DISABLE && hi == SBI_STA_SHMEM_DISABLE)
if (lo == SBI_SHMEM_DISABLE && hi == SBI_SHMEM_DISABLE)
pr_warn("Failed to disable steal-time shmem");
else
pr_warn("Failed to set steal-time shmem");
Expand All @@ -84,8 +84,8 @@ static int pv_time_cpu_online(unsigned int cpu)

static int pv_time_cpu_down_prepare(unsigned int cpu)
{
return sbi_sta_steal_time_set_shmem(SBI_STA_SHMEM_DISABLE,
SBI_STA_SHMEM_DISABLE, 0);
return sbi_sta_steal_time_set_shmem(SBI_SHMEM_DISABLE,
SBI_SHMEM_DISABLE, 0);
}

static u64 pv_time_steal_clock(int cpu)
Expand Down
5 changes: 5 additions & 0 deletions arch/riscv/kvm/aia.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,9 @@ void kvm_riscv_aia_enable(void)
enable_percpu_irq(hgei_parent_irq,
irq_get_trigger_type(hgei_parent_irq));
csr_set(CSR_HIE, BIT(IRQ_S_GEXT));
/* Enable IRQ filtering for overflow interrupt only if sscofpmf is present */
if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
csr_write(CSR_HVIEN, BIT(IRQ_PMU_OVF));
}

void kvm_riscv_aia_disable(void)
Expand All @@ -563,6 +566,8 @@ void kvm_riscv_aia_disable(void)
return;
hgctrl = get_cpu_ptr(&aia_hgei);

if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
csr_clear(CSR_HVIEN, BIT(IRQ_PMU_OVF));
/* Disable per-CPU SGEI interrupt */
csr_clear(CSR_HIE, BIT(IRQ_S_GEXT));
disable_percpu_irq(hgei_parent_irq);
Expand Down
15 changes: 12 additions & 3 deletions arch/riscv/kvm/vcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,13 @@ void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu)
}
}

/* Sync up the HVIP.LCOFIP bit changes (only clear) by the guest */
if ((csr->hvip ^ hvip) & (1UL << IRQ_PMU_OVF)) {
if (!(hvip & (1UL << IRQ_PMU_OVF)) &&
!test_and_set_bit(IRQ_PMU_OVF, v->irqs_pending_mask))
clear_bit(IRQ_PMU_OVF, v->irqs_pending);
}

/* Sync-up AIA high interrupts */
kvm_riscv_vcpu_aia_sync_interrupts(vcpu);

Expand All @@ -395,7 +402,8 @@ int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)
if (irq < IRQ_LOCAL_MAX &&
irq != IRQ_VS_SOFT &&
irq != IRQ_VS_TIMER &&
irq != IRQ_VS_EXT)
irq != IRQ_VS_EXT &&
irq != IRQ_PMU_OVF)
return -EINVAL;

set_bit(irq, vcpu->arch.irqs_pending);
Expand All @@ -410,14 +418,15 @@ int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)
int kvm_riscv_vcpu_unset_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)
{
/*
* We only allow VS-mode software, timer, and external
* We only allow VS-mode software, timer, counter overflow and external
* interrupts when irq is one of the local interrupts
* defined by RISC-V privilege specification.
*/
if (irq < IRQ_LOCAL_MAX &&
irq != IRQ_VS_SOFT &&
irq != IRQ_VS_TIMER &&
irq != IRQ_VS_EXT)
irq != IRQ_VS_EXT &&
irq != IRQ_PMU_OVF)
return -EINVAL;

clear_bit(irq, vcpu->arch.irqs_pending);
Expand Down
6 changes: 6 additions & 0 deletions arch/riscv/kvm/vcpu_onereg.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
KVM_ISA_EXT_ARR(SMSTATEEN),
KVM_ISA_EXT_ARR(SSAIA),
KVM_ISA_EXT_ARR(SSNPM),
KVM_ISA_EXT_ARR(SSCOFPMF),
KVM_ISA_EXT_ARR(SSTC),
KVM_ISA_EXT_ARR(SVADE),
KVM_ISA_EXT_ARR(SVADU),
Expand Down Expand Up @@ -122,6 +123,9 @@ static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext)
* Guest OS can use Svadu only when host OS enable Svadu.
*/
return arch_has_hw_pte_young();
case KVM_RISCV_ISA_EXT_SSCOFPMF:
/* Sscofpmf depends on interrupt filtering defined in ssaia */
return __riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSAIA);
case KVM_RISCV_ISA_EXT_V:
return riscv_v_vstate_ctrl_user_allowed();
default:
Expand All @@ -141,6 +145,8 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
case KVM_RISCV_ISA_EXT_M:
case KVM_RISCV_ISA_EXT_SMNPM:
case KVM_RISCV_ISA_EXT_SSNPM:
/* There is not architectural config bit to disable sscofpmf completely */
case KVM_RISCV_ISA_EXT_SSCOFPMF:
case KVM_RISCV_ISA_EXT_SSTC:
case KVM_RISCV_ISA_EXT_SVINVAL:
case KVM_RISCV_ISA_EXT_SVNAPOT:
Expand Down
Loading