!948 LoongArch: Update patches
From: @HHH_SONG Reviewed-by: @imxcc Signed-off-by: @imxcc
This commit is contained in:
commit
533e153ae6
434
hw-intc-loongarch_extioi-Add-virt-extension-support.patch
Normal file
434
hw-intc-loongarch_extioi-Add-virt-extension-support.patch
Normal file
@ -0,0 +1,434 @@
|
||||
From 04aef27ede108edd63d288dd3bb395e22a603f42 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Mon, 11 Mar 2024 15:01:31 +0800
|
||||
Subject: [PATCH] hw/intc/loongarch_extioi: Add virt extension support
|
||||
|
||||
With hardware extioi, irq can be routed to four vcpus with hardware
|
||||
extioi. This patch adds virt extension support, sot that irq can
|
||||
be routed to 256 vcpus.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
---
|
||||
hw/intc/loongarch_extioi.c | 88 ++++++++++++++++++++-
|
||||
hw/loongarch/virt.c | 122 ++++++++++++++++++++++++++---
|
||||
include/hw/intc/loongarch_extioi.h | 21 +++++
|
||||
include/hw/loongarch/virt.h | 3 +
|
||||
target/loongarch/cpu.h | 1 +
|
||||
5 files changed, 220 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
|
||||
index bdfa3b481e..fa23e247ca 100644
|
||||
--- a/hw/intc/loongarch_extioi.c
|
||||
+++ b/hw/intc/loongarch_extioi.c
|
||||
@@ -143,15 +143,17 @@ static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq,
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
cpu = val & 0xff;
|
||||
- cpu = ctz32(cpu);
|
||||
- cpu = (cpu >= 4) ? 0 : cpu;
|
||||
+ if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) {
|
||||
+ cpu = ctz32(cpu);
|
||||
+ cpu = (cpu >= 4) ? 0 : cpu;
|
||||
+ }
|
||||
val = val >> 8;
|
||||
|
||||
if (s->sw_coremap[irq + i] == cpu) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (notify && test_bit(irq, (unsigned long *)s->isr)) {
|
||||
+ if (notify && test_bit(irq + i, (unsigned long *)s->isr)) {
|
||||
/*
|
||||
* lower irq at old cpu and raise irq at new cpu
|
||||
*/
|
||||
@@ -265,6 +267,61 @@ static const MemoryRegionOps extioi_ops = {
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
+static MemTxResult extioi_virt_readw(void *opaque, hwaddr addr, uint64_t *data,
|
||||
+ unsigned size, MemTxAttrs attrs)
|
||||
+{
|
||||
+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
|
||||
+
|
||||
+ switch (addr) {
|
||||
+ case EXTIOI_VIRT_FEATURES:
|
||||
+ *data = s->features;
|
||||
+ break;
|
||||
+ case EXTIOI_VIRT_CONFIG:
|
||||
+ *data = s->status;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return MEMTX_OK;
|
||||
+}
|
||||
+
|
||||
+static MemTxResult extioi_virt_writew(void *opaque, hwaddr addr,
|
||||
+ uint64_t val, unsigned size,
|
||||
+ MemTxAttrs attrs)
|
||||
+{
|
||||
+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
|
||||
+
|
||||
+ switch (addr) {
|
||||
+ case EXTIOI_VIRT_FEATURES:
|
||||
+ return MEMTX_ACCESS_ERROR;
|
||||
+
|
||||
+ case EXTIOI_VIRT_CONFIG:
|
||||
+ /*
|
||||
+ * extioi features can only be set at disabled status
|
||||
+ */
|
||||
+ if ((s->status & BIT(EXTIOI_ENABLE)) && val) {
|
||||
+ return MEMTX_ACCESS_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ s->status = val & s->features;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return MEMTX_OK;
|
||||
+}
|
||||
+
|
||||
+static const MemoryRegionOps extioi_virt_ops = {
|
||||
+ .read_with_attrs = extioi_virt_readw,
|
||||
+ .write_with_attrs = extioi_virt_writew,
|
||||
+ .impl.min_access_size = 4,
|
||||
+ .impl.max_access_size = 4,
|
||||
+ .valid.min_access_size = 4,
|
||||
+ .valid.max_access_size = 8,
|
||||
+ .endianness = DEVICE_LITTLE_ENDIAN,
|
||||
+};
|
||||
+
|
||||
static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev);
|
||||
@@ -284,6 +341,16 @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
|
||||
memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops,
|
||||
s, "extioi_system_mem", 0x900);
|
||||
sysbus_init_mmio(sbd, &s->extioi_system_mem);
|
||||
+
|
||||
+ if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) {
|
||||
+ memory_region_init_io(&s->virt_extend, OBJECT(s), &extioi_virt_ops,
|
||||
+ s, "extioi_virt", EXTIOI_VIRT_SIZE);
|
||||
+ sysbus_init_mmio(sbd, &s->virt_extend);
|
||||
+ s->features |= EXTIOI_VIRT_HAS_FEATURES;
|
||||
+ } else {
|
||||
+ s->status |= BIT(EXTIOI_ENABLE);
|
||||
+ }
|
||||
+
|
||||
s->cpu = g_new0(ExtIOICore, s->num_cpu);
|
||||
if (s->cpu == NULL) {
|
||||
error_setg(errp, "Memory allocation for ExtIOICore faile");
|
||||
@@ -304,6 +371,16 @@ static void loongarch_extioi_finalize(Object *obj)
|
||||
g_free(s->cpu);
|
||||
}
|
||||
|
||||
+static void loongarch_extioi_reset(DeviceState *d)
|
||||
+{
|
||||
+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(d);
|
||||
+
|
||||
+ /* use legacy interrupt routing method by default */
|
||||
+ if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) {
|
||||
+ s->status = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int vmstate_extioi_post_load(void *opaque, int version_id)
|
||||
{
|
||||
LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
|
||||
@@ -347,12 +424,16 @@ static const VMStateDescription vmstate_loongarch_extioi = {
|
||||
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchExtIOI, num_cpu,
|
||||
vmstate_extioi_core, ExtIOICore),
|
||||
+ VMSTATE_UINT32(features, LoongArchExtIOI),
|
||||
+ VMSTATE_UINT32(status, LoongArchExtIOI),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static Property extioi_properties[] = {
|
||||
DEFINE_PROP_UINT32("num-cpu", LoongArchExtIOI, num_cpu, 1),
|
||||
+ DEFINE_PROP_BIT("has-virtualization-extension", LoongArchExtIOI, features,
|
||||
+ EXTIOI_HAS_VIRT_EXTENSION, 0),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -361,6 +442,7 @@ static void loongarch_extioi_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = loongarch_extioi_realize;
|
||||
+ dc->reset = loongarch_extioi_reset;
|
||||
device_class_set_props(dc, extioi_properties);
|
||||
dc->vmsd = &vmstate_loongarch_extioi;
|
||||
}
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 6ef40fa24a..01e59f3a95 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/rtc.h"
|
||||
+#include "sysemu/tcg.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
#include "hw/loongarch/virt.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/irq.h"
|
||||
@@ -54,6 +56,31 @@ struct loaderparams {
|
||||
const char *initrd_filename;
|
||||
};
|
||||
|
||||
+static bool virt_is_veiointc_enabled(LoongArchMachineState *lams)
|
||||
+{
|
||||
+ if (lams->veiointc == ON_OFF_AUTO_OFF) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
|
||||
+ OnOffAuto veiointc = lams->veiointc;
|
||||
+
|
||||
+ visit_type_OnOffAuto(v, name, &veiointc, errp);
|
||||
+}
|
||||
+
|
||||
+static void virt_set_veiointc(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
|
||||
+
|
||||
+ visit_type_OnOffAuto(v, name, &lams->veiointc, errp);
|
||||
+}
|
||||
+
|
||||
static PFlashCFI01 *virt_flash_create1(LoongArchMachineState *lams,
|
||||
const char *name,
|
||||
const char *alias_prop_name)
|
||||
@@ -618,9 +645,18 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
/* Create EXTIOI device */
|
||||
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
|
||||
qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus);
|
||||
+ if (virt_is_veiointc_enabled(lams)) {
|
||||
+ qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
|
||||
+ }
|
||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
|
||||
+
|
||||
memory_region_add_subregion(&lams->system_iocsr, APIC_BASE,
|
||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
|
||||
+ if (virt_is_veiointc_enabled(lams)) {
|
||||
+ memory_region_add_subregion(&lams->system_iocsr, EXTIOI_VIRT_BASE,
|
||||
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
|
||||
+ }
|
||||
+ lams->extioi = extioi;
|
||||
|
||||
/*
|
||||
* connect ext irq to the cpu irq
|
||||
@@ -780,32 +816,87 @@ static void loongarch_direct_kernel_boot(LoongArchMachineState *lams,
|
||||
}
|
||||
}
|
||||
|
||||
-static void loongarch_qemu_write(void *opaque, hwaddr addr,
|
||||
- uint64_t val, unsigned size)
|
||||
+static MemTxResult loongarch_qemu_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
+ unsigned size, MemTxAttrs attrs)
|
||||
{
|
||||
+ LoongArchMachineState *lams = LOONGARCH_MACHINE(opaque);
|
||||
+ uint64_t features;
|
||||
+
|
||||
+ switch (addr) {
|
||||
+ case MISC_FUNC_REG:
|
||||
+ if (!virt_is_veiointc_enabled(lams)) {
|
||||
+ return MEMTX_OK;
|
||||
+ }
|
||||
+
|
||||
+ features = address_space_ldl(&lams->as_iocsr,
|
||||
+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
|
||||
+ attrs, NULL);
|
||||
+ if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) {
|
||||
+ features |= BIT(EXTIOI_ENABLE);
|
||||
+ }
|
||||
+ if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) {
|
||||
+ features |= BIT(EXTIOI_ENABLE_INT_ENCODE);
|
||||
+ }
|
||||
+
|
||||
+ address_space_stl(&lams->as_iocsr,
|
||||
+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
|
||||
+ features, attrs, NULL);
|
||||
+ }
|
||||
+
|
||||
+ return MEMTX_OK;
|
||||
}
|
||||
|
||||
-static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
|
||||
+static MemTxResult loongarch_qemu_read(void *opaque, hwaddr addr,
|
||||
+ uint64_t *data,
|
||||
+ unsigned size, MemTxAttrs attrs)
|
||||
{
|
||||
+ LoongArchMachineState *lams = LOONGARCH_MACHINE(opaque);
|
||||
+ uint64_t ret = 0;
|
||||
+ int features;
|
||||
+
|
||||
switch (addr) {
|
||||
case VERSION_REG:
|
||||
- return 0x11ULL;
|
||||
+ ret = 0x11ULL;
|
||||
+ break;
|
||||
case FEATURE_REG:
|
||||
- return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
|
||||
- 1ULL << IOCSRF_CSRIPI;
|
||||
+ ret = 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
|
||||
+ 1ULL << IOCSRF_CSRIPI;
|
||||
+ if (kvm_enabled()) {
|
||||
+ ret |= 1ULL << IOCSRF_VM;
|
||||
+ }
|
||||
+ break;
|
||||
case VENDOR_REG:
|
||||
- return 0x6e6f73676e6f6f4cULL; /* "Loongson" */
|
||||
+ ret = 0x6e6f73676e6f6f4cULL; /* "Loongson" */
|
||||
+ break;
|
||||
case CPUNAME_REG:
|
||||
- return 0x303030354133ULL; /* "3A5000" */
|
||||
+ ret = 0x303030354133ULL; /* "3A5000" */
|
||||
+ break;
|
||||
case MISC_FUNC_REG:
|
||||
- return 1ULL << IOCSRM_EXTIOI_EN;
|
||||
+ if (!virt_is_veiointc_enabled(lams)) {
|
||||
+ ret |= BIT_ULL(IOCSRM_EXTIOI_EN);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ features = address_space_ldl(&lams->as_iocsr,
|
||||
+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
|
||||
+ attrs, NULL);
|
||||
+ if (features & BIT(EXTIOI_ENABLE)) {
|
||||
+ ret |= BIT_ULL(IOCSRM_EXTIOI_EN);
|
||||
+ }
|
||||
+
|
||||
+ if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) {
|
||||
+ ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE);
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
- return 0ULL;
|
||||
+
|
||||
+ *data = ret;
|
||||
+ return MEMTX_OK;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps loongarch_qemu_ops = {
|
||||
- .read = loongarch_qemu_read,
|
||||
- .write = loongarch_qemu_write,
|
||||
+ .read_with_attrs = loongarch_qemu_read,
|
||||
+ .write_with_attrs = loongarch_qemu_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 4,
|
||||
@@ -1010,6 +1101,9 @@ static void loongarch_machine_initfn(Object *obj)
|
||||
{
|
||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
|
||||
|
||||
+ if (tcg_enabled()) {
|
||||
+ lams->veiointc = ON_OFF_AUTO_OFF;
|
||||
+ }
|
||||
lams->acpi = ON_OFF_AUTO_AUTO;
|
||||
lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
|
||||
lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
|
||||
@@ -1197,6 +1291,10 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
|
||||
NULL, NULL);
|
||||
object_class_property_set_description(oc, "acpi",
|
||||
"Enable ACPI");
|
||||
+ object_class_property_add(oc, "v-eiointc", "OnOffAuto",
|
||||
+ virt_get_veiointc, virt_set_veiointc, NULL, NULL);
|
||||
+ object_class_property_set_description(oc, "v-eiointc",
|
||||
+ "Enable Virt Extend I/O Interrupt Controller");
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
||||
#ifdef CONFIG_TPM
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
|
||||
diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
|
||||
index a0a46b888c..98f348c49d 100644
|
||||
--- a/include/hw/intc/loongarch_extioi.h
|
||||
+++ b/include/hw/intc/loongarch_extioi.h
|
||||
@@ -40,6 +40,24 @@
|
||||
#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET)
|
||||
#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET)
|
||||
|
||||
+#define EXTIOI_VIRT_BASE (0x40000000)
|
||||
+#define EXTIOI_VIRT_SIZE (0x1000)
|
||||
+#define EXTIOI_VIRT_FEATURES (0x0)
|
||||
+#define EXTIOI_HAS_VIRT_EXTENSION (0)
|
||||
+#define EXTIOI_HAS_ENABLE_OPTION (1)
|
||||
+#define EXTIOI_HAS_INT_ENCODE (2)
|
||||
+#define EXTIOI_HAS_CPU_ENCODE (3)
|
||||
+#define EXTIOI_VIRT_HAS_FEATURES (BIT(EXTIOI_HAS_VIRT_EXTENSION) \
|
||||
+ | BIT(EXTIOI_HAS_ENABLE_OPTION)\
|
||||
+ | BIT(EXTIOI_HAS_INT_ENCODE) \
|
||||
+ | BIT(EXTIOI_HAS_CPU_ENCODE))
|
||||
+#define EXTIOI_VIRT_CONFIG (0x4)
|
||||
+#define EXTIOI_ENABLE (1)
|
||||
+#define EXTIOI_ENABLE_INT_ENCODE (2)
|
||||
+#define EXTIOI_ENABLE_CPU_ENCODE (3)
|
||||
+#define EXTIOI_VIRT_COREMAP_START (0x40)
|
||||
+#define EXTIOI_VIRT_COREMAP_END (0x240)
|
||||
+
|
||||
typedef struct ExtIOICore {
|
||||
uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];
|
||||
DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS);
|
||||
@@ -51,6 +69,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI)
|
||||
struct LoongArchExtIOI {
|
||||
SysBusDevice parent_obj;
|
||||
uint32_t num_cpu;
|
||||
+ uint32_t features;
|
||||
+ uint32_t status;
|
||||
/* hardware state */
|
||||
uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
|
||||
uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
|
||||
@@ -64,5 +84,6 @@ struct LoongArchExtIOI {
|
||||
qemu_irq irq[EXTIOI_IRQS];
|
||||
ExtIOICore *cpu;
|
||||
MemoryRegion extioi_system_mem;
|
||||
+ MemoryRegion virt_extend;
|
||||
};
|
||||
#endif /* LOONGARCH_EXTIOI_H */
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 252f7df7f4..99447fd1d6 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -45,16 +45,19 @@ struct LoongArchMachineState {
|
||||
Notifier machine_done;
|
||||
Notifier powerdown_notifier;
|
||||
OnOffAuto acpi;
|
||||
+ OnOffAuto veiointc;
|
||||
char *oem_id;
|
||||
char *oem_table_id;
|
||||
DeviceState *acpi_ged;
|
||||
int fdt_size;
|
||||
DeviceState *platform_bus_dev;
|
||||
+ DeviceState *extioi;
|
||||
PCIBus *pci_bus;
|
||||
PFlashCFI01 *flash[2];
|
||||
MemoryRegion system_iocsr;
|
||||
MemoryRegion iocsr_mem;
|
||||
AddressSpace as_iocsr;
|
||||
+ int features;
|
||||
};
|
||||
|
||||
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 4aba8aba4c..4749d41c8c 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -36,6 +36,7 @@
|
||||
#define CPUNAME_REG 0x20
|
||||
#define MISC_FUNC_REG 0x420
|
||||
#define IOCSRM_EXTIOI_EN 48
|
||||
+#define IOCSRM_EXTIOI_INT_ENCODE 49
|
||||
|
||||
#define IOCSR_MEM_SIZE 0x428
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
36
qemu.spec
36
qemu.spec
@ -3,7 +3,7 @@
|
||||
|
||||
Name: qemu
|
||||
Version: 8.2.0
|
||||
Release: 12
|
||||
Release: 13
|
||||
Epoch: 11
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
|
||||
@ -259,6 +259,16 @@ Patch0242: hw-isa-vt82c686-Keep-track-of-PIRQ-PINT-pins-separat.patch
|
||||
Patch0243: target-i386-Introduce-Icelake-Server-v7-to-enable-TS.patch
|
||||
Patch0244: target-i386-Add-new-CPU-model-SierraForest.patch
|
||||
Patch0245: target-i386-Export-RFDS-bit-to-guests.patch
|
||||
Patch0246: target-loongarch-Fix-qemu-system-loongarch64-assert-.patch
|
||||
Patch0247: target-loongarch-Fix-qemu-loongarch64-hang-when-exec.patch
|
||||
Patch0248: target-loongarch-Fix-tlb-huge-page-loading-issue.patch
|
||||
Patch0249: target-loongarch-kvm-Add-software-breakpoint-support.patch
|
||||
Patch0250: target-loongarch-kvm-sync-kernel-header-files.patch
|
||||
Patch0251: hw-intc-loongarch_extioi-Add-virt-extension-support.patch
|
||||
Patch0252: target-loongarch-kvm-Add-pmu-support.patch
|
||||
Patch0253: target-loongarch-kvm-Fix-vm-restore-failed.patch
|
||||
Patch0254: target-loongarch-kvm-Add-pv-steal-time-support.patch
|
||||
Patch0255: target-loongarch-kvm-fpu-save-the-vreg-registers-hig.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: gcc
|
||||
@ -856,7 +866,19 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu May 10 2024 zhangxianting <zhangxianting@uniontech.com> - 11:8.2.0-12
|
||||
* Mon May 20 2024 Song Gao <gaosong@loongson.cn> - 11:8.2.0-13
|
||||
- target/loongarch: Fix qemu-system-loongarch64 assert
|
||||
- target/loongarch: Fix qemu-loongarch64 hang when executing 'll.d $t0, $t0, 0'
|
||||
- target/loongarch: Fix tlb huge page loading issue
|
||||
- target/loongarch/kvm: Add software breakpoint support
|
||||
- target/loongarch/kvm: sync kernel header files
|
||||
- hw/intc/loongarch_extioi: Add virt extension support
|
||||
- target/loongarch/kvm: Add pmu support
|
||||
- target/loongarch/kvm: Fix vm restore failed
|
||||
- target/loongarch/kvm: Add pv steal time support
|
||||
- target/loongarch/kvm: fpu save the vreg registers high
|
||||
|
||||
* Fri May 10 2024 zhangxianting <zhangxianting@uniontech.com> - 11:8.2.0-12
|
||||
- target/i386: Export RFDS bit to guests
|
||||
- target/i386: Add new CPU model SierraForest
|
||||
- target/i386: Introduce Icelake-Server-v7 to enable TSX
|
||||
@ -867,10 +889,7 @@ getent passwd qemu >/dev/null || \
|
||||
- arm/virt: Don't modify smp.max_cpus when vcpu hotplug disabled
|
||||
- acpi/cpu: Fix detection of present cpu
|
||||
|
||||
* Wed Apr 17 2024 zhangxianting <zhangxianting@uniontech.com> - 11:8.2.0-11
|
||||
- remove chrpath
|
||||
|
||||
* Mon Apr 22 2024 Jiabo Feng <fengjiabo1@huawei.com> - 11:8.2.0-10
|
||||
* Mon Apr 22 2024 Jiabo Feng <fengjiabo1@huawei.com> - 11:8.2.0-11
|
||||
- hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set(CVE-2024-3447)
|
||||
- hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs(CVE-2024-3446)
|
||||
- hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs(CVE-2024-3446)
|
||||
@ -883,9 +902,12 @@ getent passwd qemu >/dev/null || \
|
||||
- hw/scsi/scsi-generic: Fix io_timeout property not applying
|
||||
- tests: bios-tables-test: Rename smbios type 4 related test functions
|
||||
|
||||
* Thu Apr 18 2024 Tao Yang <yangtao286@huawei.com> - 11:8.2.0-9
|
||||
* Thu Apr 18 2024 Tao Yang <yangtao286@huawei.com> - 11:8.2.0-10
|
||||
- add '--enable-slirp' compilation options
|
||||
|
||||
* Wed Apr 17 2024 zhangxianting <zhangxianting@uniontech.com> - 11:8.2.0-9
|
||||
- remove chrpath
|
||||
|
||||
* Wed Apr 17 2024 Jiabo Feng <fengjiabo1@huawei.com> - 11:8.2.0-8
|
||||
- include/ui/rect.h: fix qemu_rect_init() mis-assignment
|
||||
|
||||
|
||||
45
target-loongarch-Fix-qemu-loongarch64-hang-when-exec.patch
Normal file
45
target-loongarch-Fix-qemu-loongarch64-hang-when-exec.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 6d175f9d5d5b9f46ee2f1a6fe00249bb817b5dc6 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Wed, 20 Mar 2024 09:39:55 +0800
|
||||
Subject: [PATCH] target/loongarch: Fix qemu-loongarch64 hang when
|
||||
executing 'll.d $t0, $t0, 0'
|
||||
|
||||
On gen_ll, if a->imm is zero, make_address_x return src1,
|
||||
but the load to destination may clobber src1. We use a new
|
||||
destination to fix this problem.
|
||||
|
||||
Fixes: c5af6628f4be (target/loongarch: Extract make_address_i() helper)
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240320013955.1561311-1-gaosong@loongson.cn>
|
||||
---
|
||||
target/loongarch/tcg/insn_trans/trans_atomic.c.inc | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/tcg/insn_trans/trans_atomic.c.inc b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
|
||||
index 80c2e286fd..974bc2a70f 100644
|
||||
--- a/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
|
||||
+++ b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
|
||||
@@ -5,14 +5,14 @@
|
||||
|
||||
static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
|
||||
{
|
||||
- TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
|
||||
+ TCGv t1 = tcg_temp_new();
|
||||
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
|
||||
TCGv t0 = make_address_i(ctx, src1, a->imm);
|
||||
|
||||
- tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, mop);
|
||||
+ tcg_gen_qemu_ld_i64(t1, t0, ctx->mem_idx, mop);
|
||||
tcg_gen_st_tl(t0, tcg_env, offsetof(CPULoongArchState, lladdr));
|
||||
- tcg_gen_st_tl(dest, tcg_env, offsetof(CPULoongArchState, llval));
|
||||
- gen_set_gpr(a->rd, dest, EXT_NONE);
|
||||
+ tcg_gen_st_tl(t1, tcg_env, offsetof(CPULoongArchState, llval));
|
||||
+ gen_set_gpr(a->rd, t1, EXT_NONE);
|
||||
|
||||
return true;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
136
target-loongarch-Fix-qemu-system-loongarch64-assert-.patch
Normal file
136
target-loongarch-Fix-qemu-system-loongarch64-assert-.patch
Normal file
@ -0,0 +1,136 @@
|
||||
From 3db0118d3663c5d56841dac30e4bf95ccfff21bd Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Tue, 2 Apr 2024 09:39:36 +0800
|
||||
Subject: [PATCH] target/loongarch: Fix qemu-system-loongarch64 assert
|
||||
failed with the option '-d int'
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
qemu-system-loongarch64 assert failed with the option '-d int',
|
||||
the helper_idle() raise an exception EXCP_HLT, but the exception name is undefined.
|
||||
|
||||
-----
|
||||
merge patch:
|
||||
|
||||
0cbb322f70e8a87e4acbffecef5ea8f9448f3513(target/loongarch/cpu.c: typo fix: expection)
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Message-Id: <20240321123606.1704900-1-gaosong@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 74 +++++++++++++++++++++++-------------------
|
||||
1 file changed, 40 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index b098b1c6f3..0b3f954b64 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -43,33 +43,45 @@ const char * const fregnames[32] = {
|
||||
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
|
||||
};
|
||||
|
||||
-static const char * const excp_names[] = {
|
||||
- [EXCCODE_INT] = "Interrupt",
|
||||
- [EXCCODE_PIL] = "Page invalid exception for load",
|
||||
- [EXCCODE_PIS] = "Page invalid exception for store",
|
||||
- [EXCCODE_PIF] = "Page invalid exception for fetch",
|
||||
- [EXCCODE_PME] = "Page modified exception",
|
||||
- [EXCCODE_PNR] = "Page Not Readable exception",
|
||||
- [EXCCODE_PNX] = "Page Not Executable exception",
|
||||
- [EXCCODE_PPI] = "Page Privilege error",
|
||||
- [EXCCODE_ADEF] = "Address error for instruction fetch",
|
||||
- [EXCCODE_ADEM] = "Address error for Memory access",
|
||||
- [EXCCODE_SYS] = "Syscall",
|
||||
- [EXCCODE_BRK] = "Break",
|
||||
- [EXCCODE_INE] = "Instruction Non-Existent",
|
||||
- [EXCCODE_IPE] = "Instruction privilege error",
|
||||
- [EXCCODE_FPD] = "Floating Point Disabled",
|
||||
- [EXCCODE_FPE] = "Floating Point Exception",
|
||||
- [EXCCODE_DBP] = "Debug breakpoint",
|
||||
- [EXCCODE_BCE] = "Bound Check Exception",
|
||||
- [EXCCODE_SXD] = "128 bit vector instructions Disable exception",
|
||||
- [EXCCODE_ASXD] = "256 bit vector instructions Disable exception",
|
||||
+struct TypeExcp {
|
||||
+ int32_t exccode;
|
||||
+ const char * const name;
|
||||
+};
|
||||
+
|
||||
+static const struct TypeExcp excp_names[] = {
|
||||
+ {EXCCODE_INT, "Interrupt"},
|
||||
+ {EXCCODE_PIL, "Page invalid exception for load"},
|
||||
+ {EXCCODE_PIS, "Page invalid exception for store"},
|
||||
+ {EXCCODE_PIF, "Page invalid exception for fetch"},
|
||||
+ {EXCCODE_PME, "Page modified exception"},
|
||||
+ {EXCCODE_PNR, "Page Not Readable exception"},
|
||||
+ {EXCCODE_PNX, "Page Not Executable exception"},
|
||||
+ {EXCCODE_PPI, "Page Privilege error"},
|
||||
+ {EXCCODE_ADEF, "Address error for instruction fetch"},
|
||||
+ {EXCCODE_ADEM, "Address error for Memory access"},
|
||||
+ {EXCCODE_SYS, "Syscall"},
|
||||
+ {EXCCODE_BRK, "Break"},
|
||||
+ {EXCCODE_INE, "Instruction Non-Existent"},
|
||||
+ {EXCCODE_IPE, "Instruction privilege error"},
|
||||
+ {EXCCODE_FPD, "Floating Point Disabled"},
|
||||
+ {EXCCODE_FPE, "Floating Point Exception"},
|
||||
+ {EXCCODE_DBP, "Debug breakpoint"},
|
||||
+ {EXCCODE_BCE, "Bound Check Exception"},
|
||||
+ {EXCCODE_SXD, "128 bit vector instructions Disable exception"},
|
||||
+ {EXCCODE_ASXD, "256 bit vector instructions Disable exception"},
|
||||
+ {EXCP_HLT, "EXCP_HLT"},
|
||||
};
|
||||
|
||||
const char *loongarch_exception_name(int32_t exception)
|
||||
{
|
||||
- assert(excp_names[exception]);
|
||||
- return excp_names[exception];
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(excp_names); i++) {
|
||||
+ if (excp_names[i].exccode == exception) {
|
||||
+ return excp_names[i].name;
|
||||
+ }
|
||||
+ }
|
||||
+ return "Unknown";
|
||||
}
|
||||
|
||||
void G_NORETURN do_raise_exception(CPULoongArchState *env,
|
||||
@@ -78,7 +90,7 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env,
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
|
||||
- qemu_log_mask(CPU_LOG_INT, "%s: %d (%s)\n",
|
||||
+ qemu_log_mask(CPU_LOG_INT, "%s: exception: %d (%s)\n",
|
||||
__func__,
|
||||
exception,
|
||||
loongarch_exception_name(exception));
|
||||
@@ -159,22 +171,16 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
|
||||
CPULoongArchState *env = &cpu->env;
|
||||
bool update_badinstr = 1;
|
||||
int cause = -1;
|
||||
- const char *name;
|
||||
bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR);
|
||||
uint32_t vec_size = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS);
|
||||
|
||||
if (cs->exception_index != EXCCODE_INT) {
|
||||
- if (cs->exception_index < 0 ||
|
||||
- cs->exception_index >= ARRAY_SIZE(excp_names)) {
|
||||
- name = "unknown";
|
||||
- } else {
|
||||
- name = excp_names[cs->exception_index];
|
||||
- }
|
||||
-
|
||||
qemu_log_mask(CPU_LOG_INT,
|
||||
"%s enter: pc " TARGET_FMT_lx " ERA " TARGET_FMT_lx
|
||||
- " TLBRERA " TARGET_FMT_lx " %s exception\n", __func__,
|
||||
- env->pc, env->CSR_ERA, env->CSR_TLBRERA, name);
|
||||
+ " TLBRERA " TARGET_FMT_lx " exception: %d (%s)\n",
|
||||
+ __func__, env->pc, env->CSR_ERA, env->CSR_TLBRERA,
|
||||
+ cs->exception_index,
|
||||
+ loongarch_exception_name(cs->exception_index));
|
||||
}
|
||||
|
||||
switch (cs->exception_index) {
|
||||
--
|
||||
2.33.0
|
||||
|
||||
208
target-loongarch-Fix-tlb-huge-page-loading-issue.patch
Normal file
208
target-loongarch-Fix-tlb-huge-page-loading-issue.patch
Normal file
@ -0,0 +1,208 @@
|
||||
From c5938b5f858ee8904893e08999df1af1ae13b063 Mon Sep 17 00:00:00 2001
|
||||
From: Xianglai Li <lixianglai@loongson.cn>
|
||||
Date: Mon, 18 Mar 2024 15:03:32 +0800
|
||||
Subject: [PATCH] target/loongarch: Fix tlb huge page loading issue
|
||||
|
||||
When we use qemu tcg simulation, the page size of bios is 4KB.
|
||||
When using the level 2 super huge page (page size is 1G) to create the page table,
|
||||
it is found that the content of the corresponding address space is abnormal,
|
||||
resulting in the bios can not start the operating system and graphical interface normally.
|
||||
|
||||
The lddir and ldpte instruction emulation has
|
||||
a problem with the use of super huge page processing above level 2.
|
||||
The page size is not correctly calculated,
|
||||
resulting in the wrong page size of the table entry found by tlb.
|
||||
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240318070332.1273939-1-lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu-csr.h | 3 +
|
||||
target/loongarch/internals.h | 5 --
|
||||
target/loongarch/tcg/tlb_helper.c | 113 +++++++++++++++++++++---------
|
||||
3 files changed, 82 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
|
||||
index c59d7a9fcb..0834e91f30 100644
|
||||
--- a/target/loongarch/cpu-csr.h
|
||||
+++ b/target/loongarch/cpu-csr.h
|
||||
@@ -67,6 +67,9 @@ FIELD(TLBENTRY, D, 1, 1)
|
||||
FIELD(TLBENTRY, PLV, 2, 2)
|
||||
FIELD(TLBENTRY, MAT, 4, 2)
|
||||
FIELD(TLBENTRY, G, 6, 1)
|
||||
+FIELD(TLBENTRY, HUGE, 6, 1)
|
||||
+FIELD(TLBENTRY, HGLOBAL, 12, 1)
|
||||
+FIELD(TLBENTRY, LEVEL, 13, 2)
|
||||
FIELD(TLBENTRY_32, PPN, 8, 24)
|
||||
FIELD(TLBENTRY_64, PPN, 12, 36)
|
||||
FIELD(TLBENTRY_64, NR, 61, 1)
|
||||
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
|
||||
index a2fc54c8a7..944153b180 100644
|
||||
--- a/target/loongarch/internals.h
|
||||
+++ b/target/loongarch/internals.h
|
||||
@@ -16,11 +16,6 @@
|
||||
#define TARGET_PHYS_MASK MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS)
|
||||
#define TARGET_VIRT_MASK MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS)
|
||||
|
||||
-/* Global bit used for lddir/ldpte */
|
||||
-#define LOONGARCH_PAGE_HUGE_SHIFT 6
|
||||
-/* Global bit for huge page */
|
||||
-#define LOONGARCH_HGLOBAL_SHIFT 12
|
||||
-
|
||||
void loongarch_translate_init(void);
|
||||
|
||||
void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
|
||||
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
|
||||
index 804ab7a263..eedd1ac376 100644
|
||||
--- a/target/loongarch/tcg/tlb_helper.c
|
||||
+++ b/target/loongarch/tcg/tlb_helper.c
|
||||
@@ -17,6 +17,34 @@
|
||||
#include "exec/log.h"
|
||||
#include "cpu-csr.h"
|
||||
|
||||
+static void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
|
||||
+ uint64_t *dir_width, target_ulong level)
|
||||
+{
|
||||
+ switch (level) {
|
||||
+ case 1:
|
||||
+ *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE);
|
||||
+ *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE);
|
||||
+ *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH);
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE);
|
||||
+ *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH);
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE);
|
||||
+ *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH);
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* level may be zero for ldpte */
|
||||
+ *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE);
|
||||
+ *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
|
||||
MMUAccessType access_type, int tlb_error)
|
||||
{
|
||||
@@ -486,7 +514,25 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
|
||||
target_ulong badvaddr, index, phys, ret;
|
||||
int shift;
|
||||
uint64_t dir_base, dir_width;
|
||||
- bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1;
|
||||
+
|
||||
+ if (unlikely((level == 0) || (level > 4))) {
|
||||
+ qemu_log_mask(LOG_GUEST_ERROR,
|
||||
+ "Attepted LDDIR with level %"PRId64"\n", level);
|
||||
+ return base;
|
||||
+ }
|
||||
+
|
||||
+ if (FIELD_EX64(base, TLBENTRY, HUGE)) {
|
||||
+ if (unlikely(level == 4)) {
|
||||
+ qemu_log_mask(LOG_GUEST_ERROR,
|
||||
+ "Attempted use of level 4 huge page\n");
|
||||
+ }
|
||||
+
|
||||
+ if (FIELD_EX64(base, TLBENTRY, LEVEL)) {
|
||||
+ return base;
|
||||
+ } else {
|
||||
+ return FIELD_DP64(base, TLBENTRY, LEVEL, level);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
badvaddr = env->CSR_TLBRBADV;
|
||||
base = base & TARGET_PHYS_MASK;
|
||||
@@ -495,30 +541,7 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
|
||||
shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
|
||||
shift = (shift + 1) * 3;
|
||||
|
||||
- if (huge) {
|
||||
- return base;
|
||||
- }
|
||||
- switch (level) {
|
||||
- case 1:
|
||||
- dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE);
|
||||
- dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH);
|
||||
- break;
|
||||
- case 2:
|
||||
- dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE);
|
||||
- dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH);
|
||||
- break;
|
||||
- case 3:
|
||||
- dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE);
|
||||
- dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH);
|
||||
- break;
|
||||
- case 4:
|
||||
- dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE);
|
||||
- dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH);
|
||||
- break;
|
||||
- default:
|
||||
- do_raise_exception(env, EXCCODE_INE, GETPC());
|
||||
- return 0;
|
||||
- }
|
||||
+ get_dir_base_width(env, &dir_base, &dir_width, level);
|
||||
index = (badvaddr >> dir_base) & ((1 << dir_width) - 1);
|
||||
phys = base | index << shift;
|
||||
ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
|
||||
@@ -531,20 +554,42 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
|
||||
CPUState *cs = env_cpu(env);
|
||||
target_ulong phys, tmp0, ptindex, ptoffset0, ptoffset1, ps, badv;
|
||||
int shift;
|
||||
- bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1;
|
||||
uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE);
|
||||
uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH);
|
||||
+ uint64_t dir_base, dir_width;
|
||||
|
||||
+ /*
|
||||
+ * The parameter "base" has only two types,
|
||||
+ * one is the page table base address,
|
||||
+ * whose bit 6 should be 0,
|
||||
+ * and the other is the huge page entry,
|
||||
+ * whose bit 6 should be 1.
|
||||
+ */
|
||||
base = base & TARGET_PHYS_MASK;
|
||||
+ if (FIELD_EX64(base, TLBENTRY, HUGE)) {
|
||||
+ /*
|
||||
+ * Gets the huge page level and Gets huge page size.
|
||||
+ * Clears the huge page level information in the entry.
|
||||
+ * Clears huge page bit.
|
||||
+ * Move HGLOBAL bit to GLOBAL bit.
|
||||
+ */
|
||||
+ get_dir_base_width(env, &dir_base, &dir_width,
|
||||
+ FIELD_EX64(base, TLBENTRY, LEVEL));
|
||||
+
|
||||
+ base = FIELD_DP64(base, TLBENTRY, LEVEL, 0);
|
||||
+ base = FIELD_DP64(base, TLBENTRY, HUGE, 0);
|
||||
+ if (FIELD_EX64(base, TLBENTRY, HGLOBAL)) {
|
||||
+ base = FIELD_DP64(base, TLBENTRY, HGLOBAL, 0);
|
||||
+ base = FIELD_DP64(base, TLBENTRY, G, 1);
|
||||
+ }
|
||||
|
||||
- if (huge) {
|
||||
- /* Huge Page. base is paddr */
|
||||
- tmp0 = base ^ (1 << LOONGARCH_PAGE_HUGE_SHIFT);
|
||||
- /* Move Global bit */
|
||||
- tmp0 = ((tmp0 & (1 << LOONGARCH_HGLOBAL_SHIFT)) >>
|
||||
- LOONGARCH_HGLOBAL_SHIFT) << R_TLBENTRY_G_SHIFT |
|
||||
- (tmp0 & (~(1 << LOONGARCH_HGLOBAL_SHIFT)));
|
||||
- ps = ptbase + ptwidth - 1;
|
||||
+ ps = dir_base + dir_width - 1;
|
||||
+ /*
|
||||
+ * Huge pages are evenly split into parity pages
|
||||
+ * when loaded into the tlb,
|
||||
+ * so the tlb page size needs to be divided by 2.
|
||||
+ */
|
||||
+ tmp0 = base;
|
||||
if (odd) {
|
||||
tmp0 += MAKE_64BIT_MASK(ps, 1);
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
224
target-loongarch-kvm-Add-pmu-support.patch
Normal file
224
target-loongarch-kvm-Add-pmu-support.patch
Normal file
@ -0,0 +1,224 @@
|
||||
From 57db061a63243c64c07624740fc039ddcc4777a2 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 22 Mar 2024 19:26:35 +0800
|
||||
Subject: [PATCH] target/loongarch/kvm: Add pmu support
|
||||
|
||||
This patch adds PMU support
|
||||
e.g
|
||||
'... -cpu max,pmu=on,pmnum=[1-16]';
|
||||
'... -cpu max,pmu=on' (default pmnum = 4);
|
||||
'... -cpu max,pmu=off' (disable PMU)
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 64 +++++++++++++++++++++++++++
|
||||
target/loongarch/cpu.h | 2 +
|
||||
target/loongarch/kvm/kvm.c | 55 ++++++++++++++++++++++-
|
||||
target/loongarch/loongarch-qmp-cmds.c | 2 +-
|
||||
4 files changed, 121 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index fdb819c2cf..bc557f207b 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/qemu-print.h"
|
||||
+#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/module.h"
|
||||
#include "sysemu/qtest.h"
|
||||
@@ -19,6 +20,7 @@
|
||||
#include "internals.h"
|
||||
#include "fpu/softfloat-helpers.h"
|
||||
#include "cpu-csr.h"
|
||||
+#include "qapi/visitor.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "vec.h"
|
||||
#ifdef CONFIG_KVM
|
||||
@@ -426,6 +428,14 @@ static void loongarch_la464_initfn(Object *obj)
|
||||
data = FIELD_DP32(data, CPUCFG5, CC_DIV, 1);
|
||||
env->cpucfg[5] = data;
|
||||
|
||||
+ if (kvm_enabled()) {
|
||||
+ data = 0;
|
||||
+ data = FIELD_DP32(data, CPUCFG6, PMP, 1);
|
||||
+ data = FIELD_DP32(data, CPUCFG6, PMNUM, 3);
|
||||
+ data = FIELD_DP32(data, CPUCFG6, PMBITS, 63);
|
||||
+ env->cpucfg[6] = data;
|
||||
+ }
|
||||
+
|
||||
data = 0;
|
||||
data = FIELD_DP32(data, CPUCFG16, L1_IUPRE, 1);
|
||||
data = FIELD_DP32(data, CPUCFG16, L1_DPRE, 1);
|
||||
@@ -660,6 +670,48 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
+static bool loongarch_get_pmu(Object *obj, Error **errp)
|
||||
+{
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
+
|
||||
+ return !!(FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP));
|
||||
+}
|
||||
+
|
||||
+static void loongarch_set_pmu(Object *obj, bool value, Error **errp)
|
||||
+{
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
+
|
||||
+ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, value);
|
||||
+}
|
||||
+
|
||||
+static void loongarch_get_pmnum(Object *obj, Visitor *v,
|
||||
+ const char *name, void *opaque,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
+ uint32_t value = FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMNUM);
|
||||
+
|
||||
+ visit_type_uint32(v, name, &value, errp);
|
||||
+}
|
||||
+
|
||||
+static void loongarch_set_pmnum(Object *obj, Visitor *v,
|
||||
+ const char *name, void *opaque,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
+ uint32_t *value= opaque;
|
||||
+
|
||||
+ if (!visit_type_uint32(v, name, value, errp)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if ((*value <= PMNUM_MAX) && (*value > 0)) {
|
||||
+ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, *value -1);
|
||||
+ } else {
|
||||
+ error_report("Performance counter number need be in [1- %d]\n", PMNUM_MAX);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void loongarch_cpu_post_init(Object *obj)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
@@ -672,6 +724,18 @@ void loongarch_cpu_post_init(Object *obj)
|
||||
object_property_add_bool(obj, "lasx", loongarch_get_lasx,
|
||||
loongarch_set_lasx);
|
||||
}
|
||||
+
|
||||
+ if (kvm_enabled()) {
|
||||
+ object_property_add_bool(obj, "pmu", loongarch_get_pmu,
|
||||
+ loongarch_set_pmu);
|
||||
+ if (FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)) {
|
||||
+ uint32_t value = 4;
|
||||
+ object_property_add(obj, "pmnum", "uint32",
|
||||
+ loongarch_get_pmnum,
|
||||
+ loongarch_set_pmnum, NULL,
|
||||
+ (void *)&value);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static void loongarch_cpu_init(Object *obj)
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 4749d41c8c..80cad24fa1 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -186,6 +186,8 @@ FIELD(CPUCFG6, PMNUM, 4, 4)
|
||||
FIELD(CPUCFG6, PMBITS, 8, 6)
|
||||
FIELD(CPUCFG6, UPM, 14, 1)
|
||||
|
||||
+#define PMNUM_MAX 16
|
||||
+
|
||||
/* cpucfg[16] bits */
|
||||
FIELD(CPUCFG16, L1_IUPRE, 0, 1)
|
||||
FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 49d02076ad..5dda631b2b 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -573,6 +573,53 @@ static int kvm_check_cpucfg2(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int kvm_check_cpucfg6(CPUState *cs)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint64_t val;
|
||||
+ struct kvm_device_attr attr = {
|
||||
+ .group = KVM_LOONGARCH_VCPU_CPUCFG,
|
||||
+ .attr = 6,
|
||||
+ .addr = (uint64_t)&val,
|
||||
+ };
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
|
||||
+ CPULoongArchState *env = &cpu->env;
|
||||
+
|
||||
+ ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
|
||||
+ if (!ret) {
|
||||
+ kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
|
||||
+
|
||||
+ if (FIELD_EX32(env->cpucfg[6], CPUCFG6, PMP)) {
|
||||
+ /* Check PMP */
|
||||
+ if (!FIELD_EX32(val, CPUCFG6, PMP)) {
|
||||
+ error_report("'pmu' feature not supported by KVM on this host"
|
||||
+ " Please disable 'pmu' with "
|
||||
+ "'... -cpu XXX,pmu=off ...'\n");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ /* Check PMNUM */
|
||||
+ int guest_pmnum = FIELD_EX32(env->cpucfg[6], CPUCFG6, PMNUM);
|
||||
+ int host_pmnum = FIELD_EX32(val, CPUCFG6, PMNUM);
|
||||
+ if (guest_pmnum > host_pmnum){
|
||||
+ warn_report("The guest pmnum %d larger than KVM support %d\n",
|
||||
+ guest_pmnum, host_pmnum);
|
||||
+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6,
|
||||
+ PMNUM, host_pmnum);
|
||||
+ }
|
||||
+ /* Check PMBITS */
|
||||
+ int guest_pmbits = FIELD_EX32(env->cpucfg[6], CPUCFG6, PMBITS);
|
||||
+ int host_pmbits = FIELD_EX32(val, CPUCFG6, PMBITS);
|
||||
+ if (guest_pmbits != host_pmbits) {
|
||||
+ warn_report("The host not support PMBITS %d\n", guest_pmbits);
|
||||
+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6,
|
||||
+ PMBITS, host_pmbits);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int kvm_loongarch_put_cpucfg(CPUState *cs)
|
||||
{
|
||||
int i, ret = 0;
|
||||
@@ -586,7 +633,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
- }
|
||||
+ }
|
||||
+ if (i == 6) {
|
||||
+ ret = kvm_check_cpucfg6(cs);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
val = env->cpucfg[i];
|
||||
ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
|
||||
if (ret < 0) {
|
||||
diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c
|
||||
index 645672ff59..2612f43de9 100644
|
||||
--- a/target/loongarch/loongarch-qmp-cmds.c
|
||||
+++ b/target/loongarch/loongarch-qmp-cmds.c
|
||||
@@ -42,7 +42,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
|
||||
}
|
||||
|
||||
static const char *cpu_model_advertised_features[] = {
|
||||
- "lsx", "lasx", NULL
|
||||
+ "lsx", "lasx", "pmu", "pmnum", NULL
|
||||
};
|
||||
|
||||
CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||
--
|
||||
2.33.0
|
||||
|
||||
169
target-loongarch-kvm-Add-pv-steal-time-support.patch
Normal file
169
target-loongarch-kvm-Add-pv-steal-time-support.patch
Normal file
@ -0,0 +1,169 @@
|
||||
From 8b69a1b340da95cacdff252927ca8aef9d43c33a Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Wed, 24 Apr 2024 16:06:33 +0800
|
||||
Subject: [PATCH] target/loongarch/kvm: Add pv steal time support
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
---
|
||||
linux-headers/asm-loongarch/kvm.h | 2 ++
|
||||
target/loongarch/cpu.h | 3 ++
|
||||
target/loongarch/kvm/kvm.c | 50 ++++++++++++++++++++++++++++
|
||||
target/loongarch/kvm/kvm_loongarch.h | 2 ++
|
||||
target/loongarch/machine.c | 25 ++++++++++++++
|
||||
5 files changed, 82 insertions(+)
|
||||
|
||||
diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h
|
||||
index 4cec8c1601..81fec85f0a 100644
|
||||
--- a/linux-headers/asm-loongarch/kvm.h
|
||||
+++ b/linux-headers/asm-loongarch/kvm.h
|
||||
@@ -84,6 +84,8 @@ struct kvm_fpu {
|
||||
#define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG)
|
||||
#define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)
|
||||
#define KVM_LOONGARCH_VCPU_CPUCFG 0
|
||||
+#define KVM_LOONGARCH_VCPU_PVTIME_CTRL 1
|
||||
+#define KVM_LOONGARCH_VCPU_PVTIME_GPA 0
|
||||
|
||||
struct kvm_debug_exit_arch {
|
||||
};
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 80cad24fa1..0ed24051af 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -365,6 +365,9 @@ typedef struct CPUArchState {
|
||||
/* Store ipistate to access from this struct */
|
||||
DeviceState *ipistate;
|
||||
#endif
|
||||
+ struct {
|
||||
+ uint64_t guest_addr;
|
||||
+ } st;
|
||||
} CPULoongArchState;
|
||||
|
||||
/**
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 5dda631b2b..e1d521a1de 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -649,6 +649,56 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int kvm_loongarch_put_pvtime(LoongArchCPU *cpu)
|
||||
+{
|
||||
+ CPULoongArchState *env = &cpu->env;
|
||||
+ int err;
|
||||
+ struct kvm_device_attr attr = {
|
||||
+ .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL,
|
||||
+ .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA,
|
||||
+ .addr = (uint64_t)&env->st.guest_addr,
|
||||
+ };
|
||||
+
|
||||
+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr);
|
||||
+ if (err != 0) {
|
||||
+ /* It's ok even though kvm has not such attr */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_DEVICE_ATTR, attr);
|
||||
+ if (err != 0) {
|
||||
+ error_report("PVTIME IPA: KVM_SET_DEVICE_ATTR: %s", strerror(-err));
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int kvm_loongarch_get_pvtime(LoongArchCPU *cpu)
|
||||
+{
|
||||
+ CPULoongArchState *env = &cpu->env;
|
||||
+ int err;
|
||||
+ struct kvm_device_attr attr = {
|
||||
+ .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL,
|
||||
+ .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA,
|
||||
+ .addr = (uint64_t)&env->st.guest_addr,
|
||||
+ };
|
||||
+
|
||||
+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr);
|
||||
+ if (err != 0) {
|
||||
+ /* It's ok even though kvm has not such attr */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_DEVICE_ATTR, attr);
|
||||
+ if (err != 0) {
|
||||
+ error_report("PVTIME IPA: KVM_GET_DEVICE_ATTR: %s", strerror(-err));
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int kvm_arch_get_registers(CPUState *cs)
|
||||
{
|
||||
int ret;
|
||||
diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h
|
||||
index d945b6bb82..551878a725 100644
|
||||
--- a/target/loongarch/kvm/kvm_loongarch.h
|
||||
+++ b/target/loongarch/kvm/kvm_loongarch.h
|
||||
@@ -12,5 +12,7 @@
|
||||
|
||||
int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
|
||||
void kvm_arch_reset_vcpu(CPULoongArchState *env);
|
||||
+int kvm_loongarch_put_pvtime(LoongArchCPU *cpu);
|
||||
+int kvm_loongarch_get_pvtime(LoongArchCPU *cpu);
|
||||
|
||||
#endif
|
||||
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
|
||||
index 4443caed2d..ec5abe56db 100644
|
||||
--- a/target/loongarch/machine.c
|
||||
+++ b/target/loongarch/machine.c
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "cpu.h"
|
||||
#include "migration/cpu.h"
|
||||
#include "vec.h"
|
||||
+#include "kvm/kvm_loongarch.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
|
||||
static const VMStateDescription vmstate_fpu_reg = {
|
||||
.name = "fpu_reg",
|
||||
@@ -122,15 +124,38 @@ const VMStateDescription vmstate_tlb = {
|
||||
}
|
||||
};
|
||||
|
||||
+static int cpu_post_load(void *opaque, int version_id)
|
||||
+{
|
||||
+#ifdef CONFIG_KVM
|
||||
+ LoongArchCPU *cpu = opaque;
|
||||
+ kvm_loongarch_put_pvtime(cpu);
|
||||
+#endif
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int cpu_pre_save(void *opaque)
|
||||
+{
|
||||
+#ifdef CONFIG_KVM
|
||||
+ LoongArchCPU *cpu = opaque;
|
||||
+ kvm_loongarch_get_pvtime(cpu);
|
||||
+#endif
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* LoongArch CPU state */
|
||||
const VMStateDescription vmstate_loongarch_cpu = {
|
||||
.name = "cpu",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
+ .post_load = cpu_post_load,
|
||||
+ .pre_save = cpu_pre_save,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
|
||||
VMSTATE_UINTTL(env.pc, LoongArchCPU),
|
||||
|
||||
+ /* PV time */
|
||||
+ VMSTATE_UINT64(env.st.guest_addr, LoongArchCPU),
|
||||
+
|
||||
/* Remaining CSRs */
|
||||
VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
|
||||
VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU),
|
||||
--
|
||||
2.33.0
|
||||
|
||||
132
target-loongarch-kvm-Add-software-breakpoint-support.patch
Normal file
132
target-loongarch-kvm-Add-software-breakpoint-support.patch
Normal file
@ -0,0 +1,132 @@
|
||||
From 6a301af275fd684c197cf7a2e73fc265993478da Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Sun, 18 Feb 2024 15:00:25 +0800
|
||||
Subject: [PATCH] target/loongarch/kvm: Add software breakpoint support
|
||||
|
||||
With KVM virtualization, debug exception is passthrough to
|
||||
to guest kernel rather than host mode. Here hypercall
|
||||
instruction with special hypercall code is used for sw
|
||||
breakpoint usage.
|
||||
|
||||
Now only software breakpoint is supported, and itt is allowed
|
||||
to insert/remove software breakpoint. Later hardware breakpoint
|
||||
will be added.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
---
|
||||
target/loongarch/kvm/kvm.c | 77 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 77 insertions(+)
|
||||
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index c19978a970..49d02076ad 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "trace.h"
|
||||
|
||||
static bool cap_has_mp_state;
|
||||
+static unsigned int brk_insn;
|
||||
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
||||
KVM_CAP_LAST_INFO
|
||||
};
|
||||
@@ -675,7 +676,14 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
|
||||
|
||||
int kvm_arch_init_vcpu(CPUState *cs)
|
||||
{
|
||||
+ uint64_t val;
|
||||
+
|
||||
qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
|
||||
+
|
||||
+ if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) {
|
||||
+ brk_insn = val;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -755,6 +763,68 @@ bool kvm_arch_cpu_check_are_resettable(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
+
|
||||
+void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
|
||||
+{
|
||||
+ if (kvm_sw_breakpoints_active(cpu)) {
|
||||
+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
|
||||
+{
|
||||
+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
|
||||
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) {
|
||||
+ error_report("%s failed", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
|
||||
+{
|
||||
+ static uint32_t brk;
|
||||
+
|
||||
+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) ||
|
||||
+ brk != brk_insn ||
|
||||
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) {
|
||||
+ error_report("%s failed", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type)
|
||||
+{
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
+int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type)
|
||||
+{
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
+void kvm_arch_remove_all_hw_breakpoints(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run)
|
||||
+{
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
|
||||
+ CPULoongArchState *env = &cpu->env;
|
||||
+
|
||||
+ kvm_cpu_synchronize_state(cs);
|
||||
+ if (cs->singlestep_enabled) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (kvm_find_sw_breakpoint(cs, env->pc)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -774,6 +844,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
||||
run->iocsr_io.len,
|
||||
run->iocsr_io.is_write);
|
||||
break;
|
||||
+
|
||||
+ case KVM_EXIT_DEBUG:
|
||||
+ if (kvm_loongarch_handle_debug(cs, run)) {
|
||||
+ ret = EXCP_DEBUG;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
ret = -1;
|
||||
warn_report("KVM: unknown exit reason %d", run->exit_reason);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
28
target-loongarch-kvm-Fix-vm-restore-failed.patch
Normal file
28
target-loongarch-kvm-Fix-vm-restore-failed.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 7cf9ed3844ed3340165121e5fd7dcb959ee80d15 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Wed, 24 Apr 2024 14:18:46 +0800
|
||||
Subject: [PATCH] target/loongarch/kvm: Fix vm restore failed
|
||||
|
||||
The vmstate_loongarch_cpu need kvm_state_counter.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
---
|
||||
target/loongarch/machine.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
|
||||
index 1c4e01d076..4443caed2d 100644
|
||||
--- a/target/loongarch/machine.c
|
||||
+++ b/target/loongarch/machine.c
|
||||
@@ -191,6 +191,8 @@ const VMStateDescription vmstate_loongarch_cpu = {
|
||||
VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX,
|
||||
0, vmstate_tlb, LoongArchTLB),
|
||||
|
||||
+ VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
|
||||
+
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription*[]) {
|
||||
--
|
||||
2.33.0
|
||||
|
||||
43
target-loongarch-kvm-fpu-save-the-vreg-registers-hig.patch
Normal file
43
target-loongarch-kvm-fpu-save-the-vreg-registers-hig.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 7a3573ce009afa271168829da86e2c70c63fa58a Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Tue, 14 May 2024 19:07:52 +0800
|
||||
Subject: [PATCH] target/loongarch/kvm: fpu save the vreg registers high
|
||||
192bit
|
||||
|
||||
On kvm side, get_fpu/set_fpu save the vreg registers high 192bits,
|
||||
but QEMU missing.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240514110752.989572-1-gaosong@loongson.cn>
|
||||
---
|
||||
target/loongarch/kvm/kvm.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index e1d521a1de..5c88270132 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -444,6 +444,9 @@ static int kvm_loongarch_get_regs_fp(CPUState *cs)
|
||||
env->fcsr0 = fpu.fcsr;
|
||||
for (i = 0; i < 32; i++) {
|
||||
env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
|
||||
+ env->fpr[i].vreg.UD[1] = fpu.fpr[i].val64[1];
|
||||
+ env->fpr[i].vreg.UD[2] = fpu.fpr[i].val64[2];
|
||||
+ env->fpr[i].vreg.UD[3] = fpu.fpr[i].val64[3];
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
env->cf[i] = fpu.fcc & 0xFF;
|
||||
@@ -465,6 +468,9 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs)
|
||||
fpu.fcc = 0;
|
||||
for (i = 0; i < 32; i++) {
|
||||
fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
|
||||
+ fpu.fpr[i].val64[1] = env->fpr[i].vreg.UD[1];
|
||||
+ fpu.fpr[i].val64[2] = env->fpr[i].vreg.UD[2];
|
||||
+ fpu.fpr[i].val64[3] = env->fpr[i].vreg.UD[3];
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
--
|
||||
2.33.0
|
||||
|
||||
41
target-loongarch-kvm-sync-kernel-header-files.patch
Normal file
41
target-loongarch-kvm-sync-kernel-header-files.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From b7e49ac3b4e7dbfc9ba4645a85962294883c251a Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 13 Mar 2024 10:04:33 +0800
|
||||
Subject: [PATCH] target/loongarch/kvm: sync kernel header files
|
||||
|
||||
sync kernel header files.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
---
|
||||
linux-headers/asm-loongarch/kvm.h | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h
|
||||
index 923d0bd382..4cec8c1601 100644
|
||||
--- a/linux-headers/asm-loongarch/kvm.h
|
||||
+++ b/linux-headers/asm-loongarch/kvm.h
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
|
||||
#define __KVM_HAVE_READONLY_MEM
|
||||
+#define __KVM_HAVE_GUEST_DEBUG
|
||||
|
||||
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
|
||||
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
|
||||
|
||||
+#define KVM_GUESTDBG_USE_SW_BP 0x00010000
|
||||
/*
|
||||
* for KVM_GET_REGS and KVM_SET_REGS
|
||||
*/
|
||||
@@ -74,6 +76,8 @@ struct kvm_fpu {
|
||||
|
||||
#define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1)
|
||||
#define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2)
|
||||
+/* Debugging: Special instruction for software breakpoint */
|
||||
+#define KVM_REG_LOONGARCH_DEBUG_INST (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3)
|
||||
|
||||
#define LOONGARCH_REG_SHIFT 3
|
||||
#define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT))
|
||||
--
|
||||
2.33.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user