!443 Automatically generate code patches with openeuler !233 !241 !240 !237 !244 !234

From: @kuhnchen18 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
This commit is contained in:
openeuler-ci-bot 2022-02-11 14:28:02 +00:00 committed by Gitee
commit 6d95282b1e
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
32 changed files with 5536 additions and 1 deletions

View File

@ -0,0 +1,33 @@
From d0586db311e8b78732923ce46f149fdf8251a59c Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 16:10:22 +0800
Subject: [PATCH] block: bugfix: Don't pause vm when NOSPACE EIO happened
When backend disk is FULL and disk IO type is 'dataplane',
QEMU will pause the vm, and this may cause endless-loop in
QEMU main thread if we do the snapshot merge now.
When backend disk is FULL, only reporting an error rather
than pausing the virtual machine.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
blockdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/blockdev.c b/blockdev.c
index 37e3ee6f26..3ce294ec4a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -556,7 +556,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
qdict_put_str(bs_opts, "driver", buf);
}
- on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
+ on_write_error = BLOCKDEV_ON_ERROR_REPORT;
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
on_write_error = parse_block_error_action(buf, 0, &error);
if (error) {
--
2.27.0

View File

@ -0,0 +1,43 @@
From 87d8b7dcd880e0cef0c043dfef5ae649652cfe21 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 11:51:43 +0800
Subject: [PATCH] block: bugfix: disable process AIO when attach scsi disk
When initializing the virtio-scsi disk, hd_geometry_guess() will
be called to process AIO. At this time, the scsi disk has not
been fully initialized, and some fields in struct SCSIDiskState,
such as vendor and version, are NULL. If processing AIO at this
time, qemu may crash down.
Add aio_disable_external() before hd_geometry_guess() to disable
processing AIO at that time.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
hw/block/block.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/block/block.c b/hw/block/block.c
index 26c0767552..2cfc93a68e 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -224,9 +224,16 @@ bool blkconf_geometry(BlockConf *conf, int *ptrans,
Error **errp)
{
if (!conf->cyls && !conf->heads && !conf->secs) {
+ AioContext *ctx = blk_get_aio_context(conf->blk);
+
+ /* Callers may not expect this function to dispatch aio handlers, so
+ * disable external aio such as guest device emulation.
+ */
+ aio_disable_external(ctx);
hd_geometry_guess(conf->blk,
&conf->cyls, &conf->heads, &conf->secs,
ptrans);
+ aio_enable_external(ctx);
} else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
*ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs);
}
--
2.27.0

View File

@ -0,0 +1,47 @@
From 0a2c96ee5a3463e82397afb9cb36f340a93264c2 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 11:29:15 +0800
Subject: [PATCH] block: disallow block jobs when there is a BDRV_O_INACTIVE
flag
Currently, migration will put a BDRV_O_INACTIVE flag
on bs's open_flags until another resume being called. In that case,
any IO from vm or block jobs will cause a qemu crash with an assert
'assert(!(bs->open_flags & BDRV_O_INACTIVE))' failure in bdrv_co_pwritev
function. we hereby disallow block jobs by faking a blocker.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
block.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/block.c b/block.c
index 0ac5b163d2..26c3982567 100644
--- a/block.c
+++ b/block.c
@@ -6692,6 +6692,22 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
bdrv_get_device_or_node_name(bs));
return true;
}
+
+ /*
+ * When migration puts a BDRV_O_INACTIVE flag on driver's open_flags,
+ * we fake a blocker that doesn't exist. From now on, block jobs
+ * will not be permitted.
+ */
+ if ((op == BLOCK_OP_TYPE_RESIZE || op == BLOCK_OP_TYPE_COMMIT_SOURCE ||
+ op == BLOCK_OP_TYPE_MIRROR_SOURCE || op == BLOCK_OP_TYPE_MIRROR_TARGET) &&
+ (bs->open_flags & BDRV_O_INACTIVE)) {
+ if (errp) {
+ error_setg(errp, "block device is in use by migration with"
+ " a driver BDRV_O_INACTIVE flag setted");
+ }
+ return true;
+ }
+
return false;
}
--
2.27.0

View File

@ -0,0 +1,49 @@
From 21b172a3ce13c3b499e4265628f7d7c7e1189749 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 11:18:21 +0800
Subject: [PATCH] block: enable cache mode of empty cdrom
enable cache mode even if cdrom is empty
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
blockdev.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/blockdev.c b/blockdev.c
index 10a73fa423..37e3ee6f26 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -492,6 +492,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
QDict *interval_dict = NULL;
QList *interval_list = NULL;
const char *id;
+ const char *cache;
BlockdevDetectZeroesOptions detect_zeroes =
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
const char *throttling_group = NULL;
@@ -583,6 +584,21 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false);
+ if (!file || !*file) {
+ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH);
+ if (cache && !strcmp(cache, "on")) {
+ bdrv_flags |= BDRV_O_NO_FLUSH;
+ }
+
+ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_DIRECT);
+ if (cache && !strcmp(cache, "on")) {
+ bdrv_flags |= BDRV_O_NOCACHE;
+ }
+
+ qdict_del(bs_opts, BDRV_OPT_CACHE_NO_FLUSH);
+ qdict_del(bs_opts, BDRV_OPT_CACHE_DIRECT);
+ }
+
/* init */
if ((!file || !*file) && !qdict_size(bs_opts)) {
BlockBackendRootState *blk_rs;
--
2.27.0

View File

@ -0,0 +1,125 @@
From 124d427a1fdae2d1eeed433093ec4ab78b81237e Mon Sep 17 00:00:00 2001
From: "shenghualong@huawei.com" <shenghualong@huawei.com>
Date: Thu, 10 Feb 2022 11:11:37 +0800
Subject: [PATCH] freeclock: add qmp command to get time offset of vm in
seconds
When setting the system time in VM, a RTC_CHANGE event will be reported.
However, if libvirt is restarted while the event is be reporting, the
event will be lost and we will get the old time (not the time we set in
VM) after rebooting the VM.
We save the delta time in QEMU and add a rtc-date-diff qmp to get the
delta time so that libvirt can get the latest time in VM according to
the qmp after libvirt is restarted.
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: zhangxinhao <zhangxinhao1@huawei.com>
---
include/qemu-common.h | 4 +++-
monitor/qmp-cmds.c | 5 +++++
qapi/misc.json | 9 +++++++++
qapi/pragma.json | 3 ++-
softmmu/rtc.c | 13 ++++++++++++-
5 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 73bcf763ed..9ed8832152 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -27,7 +27,9 @@ int qemu_main(int argc, char **argv, char **envp);
#endif
void qemu_get_timedate(struct tm *tm, int offset);
-int qemu_timedate_diff(struct tm *tm);
+time_t qemu_timedate_diff(struct tm *tm);
+time_t get_rtc_date_diff(void);
+void set_rtc_date_diff(time_t diff);
void *qemu_oom_check(void *ptr);
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 343353e27a..98868cee03 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -466,3 +466,8 @@ HumanReadableText *qmp_x_query_irq(Error **errp)
return human_readable_text_from_str(buf);
}
+
+int64_t qmp_query_rtc_date_diff(Error **errp)
+{
+ return get_rtc_date_diff();
+}
diff --git a/qapi/misc.json b/qapi/misc.json
index 358548abe1..5b6d653682 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -527,3 +527,12 @@
'data': { '*option': 'str' },
'returns': ['CommandLineOptionInfo'],
'allow-preconfig': true }
+
+##
+# @query-rtc-date-diff:
+#
+# get vm's time offset
+#
+# Since: 2.8
+##
+{ 'command': 'query-rtc-date-diff', 'returns': 'int64' }
diff --git a/qapi/pragma.json b/qapi/pragma.json
index 3bc0335d1f..b37f6de445 100644
--- a/qapi/pragma.json
+++ b/qapi/pragma.json
@@ -26,7 +26,8 @@
'qom-get',
'query-tpm-models',
'query-tpm-types',
- 'ringbuf-read' ],
+ 'ringbuf-read',
+ 'query-rtc-date-diff' ],
# Externally visible types whose member names may use uppercase
'member-name-exceptions': [ # visible in:
'ACPISlotType', # query-acpi-ospm-status
diff --git a/softmmu/rtc.c b/softmmu/rtc.c
index 5632684fc9..57bb8bba7c 100644
--- a/softmmu/rtc.c
+++ b/softmmu/rtc.c
@@ -43,6 +43,7 @@ static time_t rtc_ref_start_datetime;
static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */
static int rtc_host_datetime_offset = -1; /* valid & used only with
RTC_BASE_DATETIME */
+static time_t rtc_date_diff = 0;
QEMUClockType rtc_clock;
/***********************************************************/
/* RTC reference time/date access */
@@ -84,7 +85,7 @@ void qemu_get_timedate(struct tm *tm, int offset)
}
}
-int qemu_timedate_diff(struct tm *tm)
+time_t qemu_timedate_diff(struct tm *tm)
{
time_t seconds;
@@ -107,6 +108,16 @@ int qemu_timedate_diff(struct tm *tm)
return seconds - qemu_ref_timedate(QEMU_CLOCK_HOST);
}
+time_t get_rtc_date_diff(void)
+{
+ return rtc_date_diff;
+}
+
+void set_rtc_date_diff(time_t diff)
+{
+ rtc_date_diff = diff;
+}
+
static void configure_rtc_base_datetime(const char *startdate)
{
time_t rtc_start_datetime;
--
2.27.0

View File

@ -0,0 +1,30 @@
From 3d0846d864384be3d08a54ca6e2ce247a5cee952 Mon Sep 17 00:00:00 2001
From: l00500761 <liuxiangdong5@huawei.com>
Date: Thu, 10 Feb 2022 14:25:30 +0800
Subject: [PATCH] freeclock: set rtc_date_diff for X86
Set rtc_date_diff in mc146818rtc.
Signed-off-by: l00500761 <liuxiangdong5@huawei.com>
Signed-off-by: zhangxinhao <zhangxinhao1@huawei.com>
---
hw/rtc/mc146818rtc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 4fbafddb22..af1df9aaeb 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -616,7 +616,8 @@ static void rtc_set_time(RTCState *s)
s->base_rtc = mktimegm(&tm);
s->last_update = qemu_clock_get_ns(rtc_clock);
- qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
+ set_rtc_date_diff(qemu_timedate_diff(&tm));
+ qapi_event_send_rtc_change(get_rtc_date_diff());
}
static void rtc_set_cmos(RTCState *s, const struct tm *tm)
--
2.27.0

View File

@ -0,0 +1,30 @@
From 1e6bae1d13302594b6e63d88e8627fa477966cf4 Mon Sep 17 00:00:00 2001
From: "shenghualong@huawei.com" <shenghualong@huawei.com>
Date: Thu, 10 Feb 2022 14:23:28 +0800
Subject: [PATCH] freeclock: set rtc_date_diff for arm
Set rtc_date_diff in pl031.
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: zhangxinhao <zhangxinhao1@huawei.com>
---
hw/rtc/pl031.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c
index e7ced90b02..da8b061e91 100644
--- a/hw/rtc/pl031.c
+++ b/hw/rtc/pl031.c
@@ -143,7 +143,8 @@ static void pl031_write(void * opaque, hwaddr offset,
s->tick_offset += value - pl031_get_count(s);
qemu_get_timedate(&tm, s->tick_offset);
- qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
+ set_rtc_date_diff(qemu_timedate_diff(&tm));
+ qapi_event_send_rtc_change(get_rtc_date_diff());
pl031_set_alarm(s);
break;
--
2.27.0

View File

@ -0,0 +1,28 @@
From 9a8de722b047ba66f70e87fb29b877935c187457 Mon Sep 17 00:00:00 2001
From: Lichang Zhao <zhaolichang@huawei.com>
Date: Thu, 10 Feb 2022 16:54:06 +0800
Subject: [PATCH] hw/net/rocker: fix security vulnerability
fix security vulnerability
Signed-off-by: Lichang zhao <zhaolichang@huawei.com>
Signed-off-by: Jinhao Gao <gaojinhao@huawei.com>
---
hw/net/rocker/rocker_of_dpa.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index b3b8c5bb6d..8ac26e6beb 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -2070,6 +2070,7 @@ static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group,
err_out:
group->l2_flood.group_count = 0;
g_free(group->l2_flood.group_ids);
+ group->l2_flood.group_ids = NULL;
g_free(tlvs);
return err;
--
2.27.0

View File

@ -0,0 +1,459 @@
From 93f01916f0c1e11f38edb8ccc4118c940d9c089f Mon Sep 17 00:00:00 2001
From: eillon <yezhenyu2@huawei.com>
Date: Tue, 8 Feb 2022 22:43:59 -0500
Subject: [PATCH] hw/usb: reduce the vpcu cost of UHCI when VNC disconnect
Reduce the vpcu cost by set a lower FRAME_TIMER_FREQ of the UHCI
when VNC client disconnected. This can reduce about 3% cost of
vcpu thread.
Signed-off-by: eillon <yezhenyu2@huawei.com>
---
hw/usb/core.c | 5 ++--
hw/usb/desc.c | 7 +++--
hw/usb/dev-hid.c | 2 +-
hw/usb/hcd-uhci.c | 63 ++++++++++++++++++++++++++++++++++------
hw/usb/hcd-uhci.h | 1 +
hw/usb/host-libusb.c | 32 ++++++++++++++++++++
include/hw/usb.h | 1 +
include/qemu/timer.h | 28 ++++++++++++++++++
ui/vnc.c | 4 +++
util/qemu-timer.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
10 files changed, 197 insertions(+), 15 deletions(-)
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 975f76250a..51b36126ca 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -87,7 +87,7 @@ void usb_device_reset(USBDevice *dev)
return;
}
usb_device_handle_reset(dev);
- dev->remote_wakeup = 0;
+ dev->remote_wakeup &= ~USB_DEVICE_REMOTE_WAKEUP;
dev->addr = 0;
dev->state = USB_STATE_DEFAULT;
}
@@ -105,7 +105,8 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
*/
return;
}
- if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
+ if ((dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP)
+ && dev->port && dev->port->ops->wakeup) {
dev->port->ops->wakeup(dev->port);
}
if (bus->ops->wakeup_endpoint) {
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index 8b6eaea407..78bbe74c71 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -751,7 +751,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
if (config->bmAttributes & USB_CFG_ATT_SELFPOWER) {
data[0] |= 1 << USB_DEVICE_SELF_POWERED;
}
- if (dev->remote_wakeup) {
+ if (dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP) {
data[0] |= 1 << USB_DEVICE_REMOTE_WAKEUP;
}
data[1] = 0x00;
@@ -761,14 +761,15 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
}
case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
+ dev->remote_wakeup &= ~USB_DEVICE_REMOTE_WAKEUP;
ret = 0;
}
trace_usb_clear_device_feature(dev->addr, value, ret);
break;
case DeviceOutRequest | USB_REQ_SET_FEATURE:
+ dev->remote_wakeup |= USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED;
if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
+ dev->remote_wakeup |= USB_DEVICE_REMOTE_WAKEUP;
ret = 0;
}
trace_usb_set_device_feature(dev->addr, value, ret);
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 1c7ae97c30..9fb89f6955 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -745,7 +745,7 @@ static int usb_ptr_post_load(void *opaque, int version_id)
{
USBHIDState *s = opaque;
- if (s->dev.remote_wakeup) {
+ if (s->dev.remote_wakeup & USB_DEVICE_REMOTE_WAKEUP) {
hid_pointer_activate(&s->hid);
}
return 0;
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index d1b5657d72..693c68f445 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -44,6 +44,8 @@
#include "hcd-uhci.h"
#define FRAME_TIMER_FREQ 1000
+#define FRAME_TIMER_FREQ_LAZY 10
+#define USB_DEVICE_NEED_NORMAL_FREQ "QEMU USB Tablet"
#define FRAME_MAX_LOOPS 256
@@ -111,6 +113,22 @@ static void uhci_async_cancel(UHCIAsync *async);
static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td);
static void uhci_resume(void *opaque);
+static int64_t uhci_frame_timer_freq = FRAME_TIMER_FREQ_LAZY;
+
+static void uhci_set_frame_freq(int freq)
+{
+ if (freq <= 0) {
+ return;
+ }
+
+ uhci_frame_timer_freq = freq;
+}
+
+static qemu_usb_controller qemu_uhci = {
+ .name = "uhci",
+ .qemu_set_freq = uhci_set_frame_freq,
+};
+
static inline int32_t uhci_queue_token(UHCI_TD *td)
{
if ((td->token & (0xf << 15)) == 0) {
@@ -353,7 +371,7 @@ static int uhci_post_load(void *opaque, int version_id)
if (version_id < 2) {
s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ);
+ (NANOSECONDS_PER_SECOND / uhci_frame_timer_freq);
}
return 0;
}
@@ -394,8 +412,29 @@ static void uhci_port_write(void *opaque, hwaddr addr,
if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
/* start frame processing */
trace_usb_uhci_schedule_start();
- s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ);
+
+ /*
+ * If the frequency of frame_timer is too slow, Guest OS (Win2012) would become
+ * blue-screen after hotplugging some vcpus.
+ * If this USB device support the remote-wakeup, the UHCI controller
+ * will enter global suspend mode when there is no input for several seconds.
+ * In this case, Qemu will delete the frame_timer. Since the frame_timer has been deleted,
+ * there is no influence to the performance of Vms. So, we can change the frequency to 1000.
+ * After that the frequency will be safe when we trigger the frame_timer again.
+ * Excepting this, there are two ways to change the frequency:
+ * 1)VNC connect/disconnect;2)attach/detach USB device.
+ */
+ if ((uhci_frame_timer_freq != FRAME_TIMER_FREQ)
+ && (s->ports[0].port.dev)
+ && (!memcmp(s->ports[0].port.dev->product_desc,
+ USB_DEVICE_NEED_NORMAL_FREQ, strlen(USB_DEVICE_NEED_NORMAL_FREQ)))
+ && (s->ports[0].port.dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED)) {
+ qemu_log("turn up the frequency of UHCI controller to %d\n", FRAME_TIMER_FREQ);
+ uhci_frame_timer_freq = FRAME_TIMER_FREQ;
+ }
+
+ s->frame_time = NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ;
+ s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->frame_time;
timer_mod(s->frame_timer, s->expire_time);
s->status &= ~UHCI_STS_HCHALTED;
} else if (!(val & UHCI_CMD_RS)) {
@@ -1083,7 +1122,6 @@ static void uhci_frame_timer(void *opaque)
UHCIState *s = opaque;
uint64_t t_now, t_last_run;
int i, frames;
- const uint64_t frame_t = NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ;
s->completions_only = false;
qemu_bh_cancel(s->bh);
@@ -1099,14 +1137,14 @@ static void uhci_frame_timer(void *opaque)
}
/* We still store expire_time in our state, for migration */
- t_last_run = s->expire_time - frame_t;
+ t_last_run = s->expire_time - s->frame_time;
t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* Process up to MAX_FRAMES_PER_TICK frames */
- frames = (t_now - t_last_run) / frame_t;
+ frames = (t_now - t_last_run) / s->frame_time;
if (frames > s->maxframes) {
int skipped = frames - s->maxframes;
- s->expire_time += skipped * frame_t;
+ s->expire_time += skipped * s->frame_time;
s->frnum = (s->frnum + skipped) & 0x7ff;
frames -= skipped;
}
@@ -1123,7 +1161,7 @@ static void uhci_frame_timer(void *opaque)
/* The spec says frnum is the frame currently being processed, and
* the guest must look at frnum - 1 on interrupt, so inc frnum now */
s->frnum = (s->frnum + 1) & 0x7ff;
- s->expire_time += frame_t;
+ s->expire_time += s->frame_time;
}
/* Complete the previous frame(s) */
@@ -1134,7 +1172,12 @@ static void uhci_frame_timer(void *opaque)
}
s->pending_int_mask = 0;
- timer_mod(s->frame_timer, t_now + frame_t);
+ /* expire_time is calculated from last frame_time, we should calculate it
+ * according to new frame_time which equals to
+ * NANOSECONDS_PER_SECOND / uhci_frame_timer_freq */
+ s->expire_time -= s->frame_time - NANOSECONDS_PER_SECOND / uhci_frame_timer_freq;
+ s->frame_time = NANOSECONDS_PER_SECOND / uhci_frame_timer_freq;
+ timer_mod(s->frame_timer, t_now + s->frame_time);
}
static const MemoryRegionOps uhci_ioport_ops = {
@@ -1196,8 +1239,10 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
s->bh = qemu_bh_new(uhci_bh, s);
s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s);
s->num_ports_vmstate = NB_PORTS;
+ s->frame_time = NANOSECONDS_PER_SECOND / uhci_frame_timer_freq;
QTAILQ_INIT(&s->queues);
+ qemu_register_usb_controller(&qemu_uhci, QEMU_USB_CONTROLLER_UHCI);
memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s,
"uhci", 0x20);
diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h
index c85ab7868e..5194d22ab4 100644
--- a/hw/usb/hcd-uhci.h
+++ b/hw/usb/hcd-uhci.h
@@ -50,6 +50,7 @@ typedef struct UHCIState {
uint16_t status;
uint16_t intr; /* interrupt enable register */
uint16_t frnum; /* frame number */
+ uint64_t frame_time; /* frame time in ns */
uint32_t fl_base_addr; /* frame list base address */
uint8_t sof_timing;
uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index d0d46dd0a4..8f521ad586 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -945,6 +945,30 @@ static void usb_host_ep_update(USBHostDevice *s)
libusb_free_config_descriptor(conf);
}
+static unsigned int usb_get_controller_type(int speed)
+{
+ unsigned int type = MAX_USB_CONTROLLER_TYPES;
+
+ switch (speed) {
+ case USB_SPEED_SUPER:
+ type = QEMU_USB_CONTROLLER_XHCI;
+ break;
+ case USB_SPEED_HIGH:
+ type = QEMU_USB_CONTROLLER_EHCI;
+ break;
+ case USB_SPEED_FULL:
+ type = QEMU_USB_CONTROLLER_UHCI;
+ break;
+ case USB_SPEED_LOW:
+ type = QEMU_USB_CONTROLLER_OHCI;
+ break;
+ default:
+ break;
+ }
+
+ return type;
+}
+
static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
{
USBDevice *udev = USB_DEVICE(s);
@@ -1054,6 +1078,12 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd)
}
trace_usb_host_open_success(bus_num, addr);
+
+ /* change ehci frame time freq when USB passthrough */
+ qemu_log("usb host speed is %d\n", udev->speed);
+ qemu_timer_set_mode(QEMU_TIMER_USB_NORMAL_MODE,
+ usb_get_controller_type(udev->speed));
+
return 0;
fail:
@@ -1129,6 +1159,8 @@ static int usb_host_close(USBHostDevice *s)
}
usb_host_auto_check(NULL);
+ qemu_timer_set_mode(QEMU_TIMER_USB_LAZY_MODE,
+ usb_get_controller_type(udev->speed));
return 0;
}
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 33668dd0a9..fa3a176159 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -142,6 +142,7 @@
#define USB_DEVICE_SELF_POWERED 0
#define USB_DEVICE_REMOTE_WAKEUP 1
+#define USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED 2
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 88ef114689..d263fad9a4 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -91,6 +91,34 @@ struct QEMUTimer {
int scale;
};
+#define QEMU_USB_NORMAL_FREQ 1000
+#define QEMU_USB_LAZY_FREQ 10
+#define MAX_USB_CONTROLLER_TYPES 4
+#define QEMU_USB_CONTROLLER_OHCI 0
+#define QEMU_USB_CONTROLLER_UHCI 1
+#define QEMU_USB_CONTROLLER_EHCI 2
+#define QEMU_USB_CONTROLLER_XHCI 3
+
+typedef void (*QEMUSetFreqHandler) (int freq);
+
+typedef struct qemu_usb_controller {
+ const char *name;
+ QEMUSetFreqHandler qemu_set_freq;
+} qemu_usb_controller;
+
+typedef qemu_usb_controller* qemu_usb_controller_ptr;
+
+enum qemu_timer_mode {
+ QEMU_TIMER_USB_NORMAL_MODE = 1 << 0, /* Set when VNC connect or
+ * with usb dev passthrough
+ */
+ QEMU_TIMER_USB_LAZY_MODE = 1 << 1, /* Set when VNC disconnect */
+};
+
+int qemu_register_usb_controller(qemu_usb_controller_ptr controller,
+ unsigned int type);
+int qemu_timer_set_mode(enum qemu_timer_mode mode, unsigned int type);
+
extern QEMUTimerListGroup main_loop_tlg;
/*
diff --git a/ui/vnc.c b/ui/vnc.c
index af02522e84..bc86c20370 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1379,6 +1379,8 @@ void vnc_disconnect_finish(VncState *vs)
g_free(vs->zrle);
g_free(vs->tight);
g_free(vs);
+
+ qemu_timer_set_mode(QEMU_TIMER_USB_LAZY_MODE, QEMU_USB_CONTROLLER_UHCI);
}
size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err)
@@ -3333,6 +3335,8 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
}
}
}
+
+ qemu_timer_set_mode(QEMU_TIMER_USB_NORMAL_MODE, QEMU_USB_CONTROLLER_UHCI);
}
void vnc_start_protocol(VncState *vs)
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
index f36c75e594..40e8c83722 100644
--- a/util/qemu-timer.c
+++ b/util/qemu-timer.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/timer.h"
#include "qemu/lockable.h"
@@ -75,6 +76,74 @@ struct QEMUTimerList {
QemuEvent timers_done_ev;
};
+typedef struct qemu_controller_timer_state {
+ qemu_usb_controller_ptr controller;
+ int refs;
+} controller_timer_state;
+
+typedef controller_timer_state* controller_timer_state_ptr;
+
+static controller_timer_state uhci_timer_state = {
+ .controller = NULL,
+ .refs = 0,
+};
+
+static controller_timer_state_ptr \
+ qemu_usb_controller_tab[MAX_USB_CONTROLLER_TYPES] = {NULL,
+ &uhci_timer_state,
+ NULL, NULL};
+
+int qemu_register_usb_controller(qemu_usb_controller_ptr controller,
+ unsigned int type)
+{
+ if (type != QEMU_USB_CONTROLLER_UHCI) {
+ return 0;
+ }
+
+ /* for companion EHCI controller will create three UHCI controllers,
+ * we init it only once.
+ */
+ if (!qemu_usb_controller_tab[type]->controller) {
+ qemu_log("the usb controller (%d) registed frame handler\n", type);
+ qemu_usb_controller_tab[type]->controller = controller;
+ }
+
+ return 0;
+}
+
+int qemu_timer_set_mode(enum qemu_timer_mode mode, unsigned int type)
+{
+ if (type != QEMU_USB_CONTROLLER_UHCI) {
+ qemu_log("the usb controller (%d) no need change frame frep\n", type);
+ return 0;
+ }
+
+ if (!qemu_usb_controller_tab[type]->controller) {
+ qemu_log("the usb controller (%d) not registed yet\n", type);
+ return 0;
+ }
+
+ if (mode == QEMU_TIMER_USB_NORMAL_MODE) {
+ if (qemu_usb_controller_tab[type]->refs++ > 0) {
+ return 0;
+ }
+ qemu_usb_controller_tab[type]->controller->
+ qemu_set_freq(QEMU_USB_NORMAL_FREQ);
+ qemu_log("Set the controller (%d) of freq %d HZ,\n",
+ type, QEMU_USB_NORMAL_FREQ);
+ } else {
+ if (--qemu_usb_controller_tab[type]->refs > 0) {
+ return 0;
+ }
+ qemu_usb_controller_tab[type]->controller->
+ qemu_set_freq(QEMU_USB_LAZY_FREQ);
+ qemu_log("Set the controller(type:%d) of freq %d HZ,\n",
+ type, QEMU_USB_LAZY_FREQ);
+ }
+
+ return 0;
+}
+
/**
* qemu_clock_ptr:
* @type: type of clock
--
2.27.0

View File

@ -0,0 +1,64 @@
From 475988057789a1f4dcd7354c8a07fd37dcbac79f Mon Sep 17 00:00:00 2001
From: Yanan Wang <wangyanan55@huawei.com>
Date: Thu, 10 Feb 2022 20:06:01 +0800
Subject: [PATCH] i386: cache passthrough: Update AMD 8000_001D.EAX[25:14]
based on vCPU topo
On AMD target, when host cache passthrough is disabled we will
emulate the guest caches with default values and initialize the
shared cpu list of the caches based on vCPU topology. However
when host cache passthrough is enabled, the shared cpu list is
consistent with host regardless what the vCPU topology is.
For example, when cache passthrough is enabled, running a guest
with vThreads=1 on a host with pThreads=2, we will get that there
are every *two* logical vCPUs sharing a L1/L2 cache, which is not
consistent with the vCPU topology (vThreads=1).
So let's reinitialize BITs[25:14] of AMD CPUID 8000_001D.EAX
based on the actual vCPU topology instead of host pCPU topology.
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
---
target/i386/cpu.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c1fe2895fd..002e32650d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5724,9 +5724,31 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
break;
case 0x8000001D:
+ /* Populate AMD Processor Cache Information */
*eax = 0;
if (cpu->cache_info_passthrough) {
host_cpuid(index, count, eax, ebx, ecx, edx);
+
+ /*
+ * Clear BITs[25:14] and then update them based on the guest
+ * vCPU topology, like what we do in encode_cache_cpuid8000001d
+ * when cache_info_passthrough is not enabled.
+ */
+ *eax &= ~0x03FFC000;
+ switch (count) {
+ case 0: /* L1 dcache info */
+ case 1: /* L1 icache info */
+ case 2: /* L2 cache info */
+ *eax |= ((topo_info.threads_per_core - 1) << 14);
+ break;
+ case 3: /* L3 cache info */
+ *eax |= ((topo_info.cores_per_die *
+ topo_info.threads_per_core - 1) << 14);
+ break;
+ default: /* end of info */
+ *eax = *ebx = *ecx = *edx = 0;
+ break;
+ }
break;
}
switch (count) {
--
2.27.0

View File

@ -0,0 +1,88 @@
From 3eaa433ca1cbee753698893b7732819ba2e31302 Mon Sep 17 00:00:00 2001
From: Jian Wang <wangjian161@huawei.com>
Date: Thu, 10 Feb 2022 19:43:55 +0800
Subject: [PATCH] i386: cache passthrough: Update Intel CPUID4.EAX[25:14] based
on vCPU topo
On Intel target, when host cache passthrough is disabled we will
emulate the guest caches with default values and initialize the
shared cpu list of the caches based on vCPU topology. However when
host cache passthrough is enabled, the shared cpu list is consistent
with host regardless what the vCPU topology is.
For example, when cache passthrough is enabled, running a guest
with vThreads=1 on a host with pThreads=2, we will get that there
are every *two* logical vCPUs sharing a L1/L2 cache, which is not
consistent with the vCPU topology (vThreads=1).
So let's reinitialize BITs[25:14] of Intel CPUID 4 based on the
actual vCPU topology instead of host pCPU topology.
Signed-off-by: Jian Wang <wangjian161@huawei.com>
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
---
target/i386/cpu.c | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 868cf3e7e8..c1fe2895fd 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5196,7 +5196,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
{
X86CPU *cpu = env_archcpu(env);
CPUState *cs = env_cpu(env);
- uint32_t die_offset;
+ uint32_t die_offset, smt_width;
uint32_t limit;
uint32_t signature[3];
X86CPUTopoInfo topo_info;
@@ -5205,6 +5205,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
topo_info.cores_per_die = cs->nr_cores;
topo_info.threads_per_core = cs->nr_threads;
+ die_offset = apicid_die_offset(&topo_info);
+ smt_width = apicid_smt_width(&topo_info);
+
/* Calculate & apply limits for different index ranges */
if (index >= 0xC0000000) {
limit = env->cpuid_xlevel2;
@@ -5272,8 +5275,25 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
/* cache info: needed for Core compatibility */
if (cpu->cache_info_passthrough) {
host_cpuid(index, count, eax, ebx, ecx, edx);
- /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
- *eax &= ~0xFC000000;
+ /*
+ * QEMU gives out its own APIC IDs, never pass down bits 31..26.
+ * Update the cache topo bits 25..14, according to the guest
+ * vCPU topology instead of the host pCPU topology.
+ */
+ *eax &= ~0xFFFFC000;
+ switch (count) {
+ case 0: /* L1 dcache info */
+ case 1: /* L1 icache info */
+ case 2: /* L2 cache info */
+ *eax |= ((1 << smt_width) - 1) << 14;
+ break;
+ case 3: /* L3 cache info */
+ *eax |= ((1 << die_offset) - 1) << 14;
+ break;
+ default: /* end of info */
+ *eax = *ebx = *ecx = *edx = 0;
+ break;
+ }
if ((*eax & 31) && cs->nr_cores > 1) {
*eax |= (cs->nr_cores - 1) << 26;
}
@@ -5298,7 +5318,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
eax, ebx, ecx, edx);
break;
case 3: /* L3 cache info */
- die_offset = apicid_die_offset(&topo_info);
if (cpu->enable_l3_cache) {
encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache,
(1 << die_offset), cs->nr_cores,
--
2.27.0

View File

@ -0,0 +1,45 @@
From 4b156248776f734d63fe37629d56c40234fda9c0 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 10:42:33 +0800
Subject: [PATCH] nbd/server.c: fix invalid read after client was already free
In the process of NBD equipment pressurization, executing QEMU NBD will
lead to the failure of IO distribution and go to NBD_ Out process of trip().
If two or more IO go to the out process, client NBD will release in nbd_request_put().
The user after free problem that is read again in close().
Through the NBD_ Save the value of client > closing before the out process in trip
to solve the use after free problem.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
nbd/server.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/nbd/server.c b/nbd/server.c
index 4630dd7322..37515ed520 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -2606,6 +2606,7 @@ static coroutine_fn void nbd_trip(void *opaque)
NBDRequestData *req;
NBDRequest request = { 0 }; /* GCC thinks it can be used uninitialized */
int ret;
+ bool client_closing;
Error *local_err = NULL;
trace_nbd_trip();
@@ -2681,8 +2682,11 @@ disconnect:
if (local_err) {
error_reportf_err(local_err, "Disconnect client, due to: ");
}
+ client_closing = client->closing;
nbd_request_put(req);
- client_close(client, true);
+ if (!client_closing) {
+ client_close(client, true);
+ }
nbd_client_put(client);
}
--
2.27.0

View File

@ -0,0 +1,35 @@
From de6f3fb0cf92e04c0989a9065910158eecbe4304 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 10:48:58 +0800
Subject: [PATCH] qemu-nbd: make native as the default aio mode
When the file system is dealing with multithreading concurrent writing to a file,
the performance will be degraded because of the lock.
At present, the default AIO mode of QEMU NBD is threads. In the case of large blocks,
because IO is divided into small pieces and multiple queues, it will become multithreading
concurrent writing the same file. Due to the file system, the performance will be greatly reduced.
If you change to native mode, this problem will not exist.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
qemu-nbd.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/qemu-nbd.c b/qemu-nbd.c
index c6c20df68a..15a4bc4018 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -800,6 +800,10 @@ int main(int argc, char **argv)
trace_init_file();
qemu_set_log(LOG_TRACE);
+ if (!seen_aio && (flags & BDRV_O_NOCACHE)) {
+ flags |= BDRV_O_NATIVE_AIO;
+ }
+
socket_activation = check_socket_activation();
if (socket_activation == 0) {
setup_address_and_port(&bindto, &port);
--
2.27.0

View File

@ -0,0 +1,42 @@
From f665f7836a019cc8bb8d46d076508afc761923f0 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 10:55:08 +0800
Subject: [PATCH] qemu-nbd: set timeout to qemu-nbd socket
In case of insufficient memory and kill-9,
the NBD socket cannot be processed and stuck all the time.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
nbd/client.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/nbd/client.c b/nbd/client.c
index 30d5383cb1..8ed50140f2 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -24,6 +24,8 @@
#include "nbd-internal.h"
#include "qemu/cutils.h"
+#define NBD_TIMEOUT_SECONDS 30
+
/* Definitions for opaque data types */
static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
@@ -1301,6 +1303,12 @@ int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info,
}
}
+ if (ioctl(fd, NBD_SET_TIMEOUT, NBD_TIMEOUT_SECONDS) < 0) {
+ int serrno = errno;
+ error_setg(errp, "Failed setting timeout");
+ return -serrno;
+ }
+
trace_nbd_init_finish();
return 0;
--
2.27.0

View File

@ -0,0 +1,36 @@
From 56f59125707c0222bbb5d7f820792aba17c3db08 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 11:10:42 +0800
Subject: [PATCH] qemu-pr: fixed ioctl failed for multipath disk
We use ioctl to detect multipath devices. However, we only set flags in
struct dm_ioctl (the argument to ioctl) and left other fields in random,
which may cause the failure of calling ioctl. Hence, we set other
fields to 0 to avoid the failure.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
scsi/qemu-pr-helper.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
index f281daeced..bbb9b57741 100644
--- a/scsi/qemu-pr-helper.c
+++ b/scsi/qemu-pr-helper.c
@@ -288,9 +288,12 @@ static void multipath_pr_init(void)
static int is_mpath(int fd)
{
- struct dm_ioctl dm = { .flags = DM_NOFLUSH_FLAG };
+ struct dm_ioctl dm;
struct dm_target_spec *tgt;
+ memset(&dm, 0, sizeof(struct dm_ioctl));
+ dm.flags = DM_NOFLUSH_FLAG;
+
tgt = dm_dev_ioctl(fd, DM_TABLE_STATUS, &dm);
if (!tgt) {
if (errno == ENXIO) {
--
2.27.0

View File

@ -1,6 +1,6 @@
Name: qemu
Version: 6.2.0
Release: 8
Release: 9
Epoch: 2
Summary: QEMU is a generic and open source machine emulator and virtualizer
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
@ -47,6 +47,37 @@ Patch0034: Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch
Patch0035: cpu-features-fix-bug-for-memory-leakage.patch
Patch0036: monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch
Patch0037: oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch
Patch0038: nbd-server.c-fix-invalid-read-after-client-was-alrea.patch
Patch0039: qemu-nbd-make-native-as-the-default-aio-mode.patch
Patch0040: qemu-nbd-set-timeout-to-qemu-nbd-socket.patch
Patch0041: qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch
Patch0042: block-enable-cache-mode-of-empty-cdrom.patch
Patch0043: block-disallow-block-jobs-when-there-is-a-BDRV_O_INA.patch
Patch0044: scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch
Patch0045: block-bugfix-disable-process-AIO-when-attach-scsi-di.patch
Patch0046: block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch
Patch0047: scsi-bugfix-fix-division-by-zero.patch
Patch0048: i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch
Patch0049: i386-cache-passthrough-Update-AMD-8000_001D.EAX-25-1.patch
Patch0050: target-arm-convert-isar-regs-to-array.patch
Patch0051: target-arm-parse-cpu-feature-related-options.patch
Patch0052: target-arm-register-CPU-features-for-property.patch
Patch0053: target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch
Patch0054: target-arm-introduce-CPU-feature-dependency-mechanis.patch
Patch0055: target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch
Patch0056: target-arm-Add-CPU-features-to-query-cpu-model-expan.patch
Patch0057: target-arm-Add-more-CPU-features.patch
Patch0058: target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch
Patch0059: target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch
Patch0060: target-arm-Fix-write-redundant-values-to-kvm.patch
Patch0061: target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch
Patch0062: target-arm-Update-the-ID-registers-of-Kunpeng-920.patch
Patch0063: freeclock-add-qmp-command-to-get-time-offset-of-vm-i.patch
Patch0064: freeclock-set-rtc_date_diff-for-arm.patch
Patch0065: freeclock-set-rtc_date_diff-for-X86.patch
Patch0066: hw-usb-reduce-the-vpcu-cost-of-UHCI-when-VNC-disconn.patch
Patch0067: hw-net-rocker-fix-security-vulnerability.patch
Patch0068: tests-Disable-filemonitor-testcase.patch
BuildRequires: flex
BuildRequires: gcc
@ -491,6 +522,49 @@ getent passwd qemu >/dev/null || \
%endif
%changelog
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
- hw/net/rocker: fix security vulnerability
- tests: Disable filemonitor testcase
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
- hw/usb: reduce the vpcu cost of UHCI when VNC disconnect
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
- freeclock: add qmp command to get time offset of vm in seconds
- freeclock: set rtc_date_diff for arm
- freeclock: set rtc_date_diff for X86
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
- target/arm: convert isar regs to array
- target/arm: parse cpu feature related options
- target/arm: register CPU features for property
- target/arm: Allow ID registers to synchronize to KVM
- target/arm: introduce CPU feature dependency mechanism
- target/arm: introduce KVM_CAP_ARM_CPU_FEATURE
- target/arm: Add CPU features to query-cpu-model-expansion
- target/arm: Add more CPU features
- target/arm: ignore evtstrm and cpuid CPU features
- target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest
- target/arm: Fix write redundant values to kvm
- target/arm: clear EL2 and EL3 only when kvm is not enabled
- target/arm: Update the ID registers of Kunpeng-920
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
- i386: cache passthrough: Update Intel CPUID4.EAX[25:14] based on vCPU topo
- i386: cache passthrough: Update AMD 8000_001D.EAX[25:14] based on vCPU topo
* Fri Feb 11 2022 Chen Qun <kuhn.chenqun@huawei.com>
- nbd/server.c: fix invalid read after client was already free
- qemu-nbd: make native as the default aio mode
- qemu-nbd: set timeout to qemu-nbd socket
- qemu-pr: fixed ioctl failed for multipath disk
- block: enable cache mode of empty cdrom
- block: disallow block jobs when there is a BDRV_O_INACTIVE flag
- scsi: cdrom: Fix crash after remote cdrom detached
- block: bugfix: disable process AIO when attach scsi disk
- block: bugfix: Don't pause vm when NOSPACE EIO happened
- scsi: bugfix: fix division by zero
* Fri Feb 11 2022 imxcc <xingchaochao@huawei.com>
- migration: skip cache_drop for bios bootloader and
- ps2: fix oob in ps2 kbd

View File

@ -0,0 +1,57 @@
From ba8fd8a3d11655da0b51148e69c01b78794a3f69 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 16:34:05 +0800
Subject: [PATCH] scsi: bugfix: fix division by zero
Error of PRDM disk may cause divide by zero in
scsi_read_complete(), so add LOG and assert().
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
hw/scsi/scsi-generic.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 0306ccc7b1..1f51586048 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -179,6 +179,10 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
(r->req.cmd.buf[1] & 0x01)) {
page = r->req.cmd.buf[2];
if (page == 0xb0) {
+ if (s->blocksize == 0) {
+ qemu_log("device blocksize is 0!\n");
+ abort();
+ }
uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk);
uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk);
@@ -314,11 +318,23 @@ static void scsi_read_complete(void * opaque, int ret)
/* Snoop READ CAPACITY output to set the blocksize. */
if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
(ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
- s->blocksize = ldl_be_p(&r->buf[4]);
+ int new_blocksize = ldl_be_p(&r->buf[4]);
+ if (s->blocksize != new_blocksize) {
+ qemu_log("device id=%s type=%d: blocksize %d change to %d\n",
+ s->qdev.id ? s->qdev.id : "null", s->type,
+ s->blocksize, new_blocksize);
+ }
+ s->blocksize = new_blocksize;
s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
} else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
(r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
- s->blocksize = ldl_be_p(&r->buf[8]);
+ int new_blocksize = ldl_be_p(&r->buf[8]);
+ if (s->blocksize != new_blocksize) {
+ qemu_log("device id=%s type=%d: blocksize %d change to %d\n",
+ s->qdev.id ? s->qdev.id : "null", s->type,
+ s->blocksize, new_blocksize);
+ }
+ s->blocksize = new_blocksize;
s->max_lba = ldq_be_p(&r->buf[0]);
}
blk_set_guest_block_size(s->conf.blk, s->blocksize);
--
2.27.0

View File

@ -0,0 +1,35 @@
From 77496578b22e127eb50a5a8c463e92fb3245a7e0 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 11:42:47 +0800
Subject: [PATCH] scsi: cdrom: Fix crash after remote cdrom detached
There is a small window between the twice blk_is_available in
scsi_disk_emulate_command which would cause crash due to the later
assertion if the remote cdrom is detached in this window.
So this patch replaces assertions with return to avoid qemu crash.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
hw/scsi/scsi-disk.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index d4914178ea..a1053f4036 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1930,7 +1930,10 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
memset(outbuf, 0, r->buflen);
switch (req->cmd.buf[0]) {
case TEST_UNIT_READY:
- assert(blk_is_available(s->qdev.conf.blk));
+ if (!blk_is_available(s->qdev.conf.blk)) {
+ scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
+ return 0;
+ }
break;
case INQUIRY:
buflen = scsi_disk_emulate_inquiry(req, outbuf);
--
2.27.0

View File

@ -0,0 +1,90 @@
From e6dd7faeea77206d7e6589cbb54ad43926457052 Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Thu, 6 Aug 2020 16:14:58 +0800
Subject: [PATCH] target/arm: Add CPU features to query-cpu-model-expansion
Add CPU features to the result of query-cpu-model-expansion so that
other applications (such as libvirt) can know the supported CPU
features.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/cpu.c | 27 +++++++++++++++++++++++++++
target/arm/cpu.h | 2 ++
target/arm/monitor.c | 2 ++
3 files changed, 31 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 3024f4a3f5..2d6a26336f 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -25,6 +25,8 @@
#include "qemu/module.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
+#include "qapi/qmp/qdict.h"
+#include "qom/qom-qobject.h"
#include "cpu.h"
#ifdef CONFIG_TCG
#include "hw/core/tcg-cpu-ops.h"
@@ -1580,6 +1582,31 @@ static const CPUFeatureDep feature_dependencies[] = {
},
};
+void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features)
+{
+ Object *obj = OBJECT(cpu);
+ const char *name;
+ ObjectProperty *prop;
+ bool is_32bit = !arm_feature(&cpu->env, ARM_FEATURE_AARCH64);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cpu_features); ++i) {
+ if (is_32bit != cpu_features[i].is_32bit) {
+ continue;
+ }
+
+ name = cpu_features[i].name;
+ prop = object_property_find(obj, name);
+ if (prop) {
+ QObject *value;
+
+ assert(prop->get);
+ value = object_property_get_qobject(obj, name, &error_abort);
+ qdict_put_obj(features, name, value);
+ }
+ }
+}
+
static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 3dda33f347..947897d5ac 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -4398,4 +4398,6 @@ static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
#define cpu_isar_feature(name, cpu) \
({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
+void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features);
+
#endif
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
index 80c64fa355..4c6f1181d9 100644
--- a/target/arm/monitor.c
+++ b/target/arm/monitor.c
@@ -217,6 +217,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
}
}
+ arm_cpu_features_to_dict(ARM_CPU(obj), qdict_out);
+
if (!qdict_size(qdict_out)) {
qobject_unref(qdict_out);
} else {
--
2.27.0

View File

@ -0,0 +1,31 @@
From 85d5b46d8225c5875b8b3ff68967d46bcde9a549 Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Tue, 11 Aug 2020 10:28:10 +0800
Subject: [PATCH] target/arm: Add more CPU features
Add i8mm, bf16, and dgh CPU features for AArch64.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/cpu.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 2d6a26336f..1c1647a0a8 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1309,6 +1309,9 @@ static struct CPUFeatureInfo cpu_features[] = {
FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true),
FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true),
FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true),
+ FIELD_INFO("i8mm", ID_AA64ISAR1, I8MM, false, 1, 0, false),
+ FIELD_INFO("bf16", ID_AA64ISAR1, BF16, false, 1, 0, false),
+ FIELD_INFO("dgh", ID_AA64ISAR1, DGH, false, 1, 0, false),
FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true),
FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true),
--
2.27.0

View File

@ -0,0 +1,161 @@
From 0272c52e36ab95389e665ca19b129178b0b46eac Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Thu, 6 Aug 2020 16:14:40 +0800
Subject: [PATCH] target/arm: Allow ID registers to synchronize to KVM
There are 2 steps to synchronize the values of system registers from
CPU state to KVM:
1. write to the values of system registers from CPU state to
(index,value) list by write_cpustate_to_list;
2. write the values in (index,value) list to KVM by
write_list_to_kvmstate;
In step 1, the values of constant system registers are not allowed to
write to (index,value) list. However, a constant system register is
CONSTANT for guest but not for QEMU, which means, QEMU can set/modify
the value of constant system registers that is different from phsical
registers when startup. But if KVM is enabled, guest can not read the
values of the system registers which QEMU set unless they can be written
to (index,value) list. And why not try to write to KVM if kvm_sync is
true?
At the moment we call write_cpustate_to_list, all ID registers are
contant, including ID_PFR1_EL1 and ID_AA64PFR0_EL1 because GIC has been
initialized. Hence, let's give all ID registers a chance to write to
KVM. If the write is successful, then write to (index,value) list.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/helper.c | 31 ++++++++++++++++++++-----------
target/arm/kvm.c | 38 ++++++++++++++++++++++++++++++++++++++
target/arm/kvm_arm.h | 3 +++
3 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b8ea1dc1f6..79f77705c3 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -35,6 +35,7 @@
#include "exec/cpu_ldst.h"
#include "semihosting/common-semi.h"
#endif
+#include "kvm_arm.h"
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */
@@ -149,30 +150,38 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
ok = false;
continue;
}
- if (ri->type & ARM_CP_NO_RAW) {
+ /*
+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
+ * where 1<=crm<8, 0<=op2<8. Let's give ID registers a chance to
+ * synchronize to kvm.
+ */
+ if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync &&
+ ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && ri->crm > 0)) {
continue;
}
newval = read_raw_cp_reg(&cpu->env, ri);
if (kvm_sync) {
- /*
- * Only sync if the previous list->cpustate sync succeeded.
- * Rather than tracking the success/failure state for every
- * item in the list, we just recheck "does the raw write we must
- * have made in write_list_to_cpustate() read back OK" here.
- */
- uint64_t oldval = cpu->cpreg_values[i];
+ /* Only sync if we can sync to KVM successfully. */
+ uint64_t oldval;
+ uint64_t kvmval;
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
+ continue;
+ }
if (oldval == newval) {
continue;
}
- write_raw_cp_reg(&cpu->env, ri, oldval);
- if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
+ if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
+ continue;
+ }
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
+ kvmval != newval) {
continue;
}
- write_raw_cp_reg(&cpu->env, ri, newval);
+ kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
}
cpu->cpreg_values[i] = newval;
}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index bbf1ce7ba3..59d556724f 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -514,6 +514,44 @@ out:
return ret;
}
+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target)
+{
+ uint32_t v32;
+ int ret;
+
+ switch (regidx & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ ret = kvm_get_one_reg(CPU(cpu), regidx, &v32);
+ if (ret == 0) {
+ *target = v32;
+ }
+ return ret;
+ case KVM_REG_SIZE_U64:
+ return kvm_get_one_reg(CPU(cpu), regidx, target);
+ default:
+ return -1;
+ }
+}
+
+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source)
+{
+ uint32_t v32;
+
+ switch (regidx & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ v32 = *source;
+ if (v32 != *source) {
+ error_report("the value of source is too large");
+ return -1;
+ }
+ return kvm_set_one_reg(CPU(cpu), regidx, &v32);
+ case KVM_REG_SIZE_U64:
+ return kvm_set_one_reg(CPU(cpu), regidx, source);
+ default:
+ return -1;
+ }
+}
+
bool write_kvmstate_to_list(ARMCPU *cpu)
{
CPUState *cs = CPU(cpu);
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index b7f78b5215..f8e0e64363 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -528,4 +528,7 @@ static inline const char *its_class_name(void)
}
}
+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target);
+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source);
+
#endif
--
2.27.0

View File

@ -0,0 +1,119 @@
From 9680adfba5ca871f69a6fbd15b92571fc2a52d78 Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Wed, 9 Dec 2020 19:35:08 +0800
Subject: [PATCH] target/arm: Fix write redundant values to kvm
After modifying the value of a ID register, we'd better to try to write
it to KVM so that we can known the value is acceptable for KVM.
Because it may modify the registers' values of KVM, it's not suitable
for other registers.
(cherry-picked from a0d7a9de807639fcfcbe1fe037cb8772d459a9cf)
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/helper.c | 73 ++++++++++++++++++++++++++++++---------------
1 file changed, 49 insertions(+), 24 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 4c7b4cadfa..1dd5d64d96 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -134,6 +134,16 @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
return true;
}
+static bool is_id_reg(const ARMCPRegInfo *ri)
+{
+ /*
+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
+ * where 1<=crm<8, 0<=op2<8.
+ */
+ return ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 &&
+ ri->crm > 0 && ri->crm < 8;
+}
+
bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
{
/* Write the coprocessor state from cpu->env to the (index,value) list. */
@@ -150,38 +160,53 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
ok = false;
continue;
}
- /*
- * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
- * where 1<=crm<8, 0<=op2<8. Let's give ID registers a chance to
- * synchronize to kvm.
- */
- if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync &&
- ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && ri->crm > 0)) {
+ if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync && is_id_reg(ri))) {
continue;
}
newval = read_raw_cp_reg(&cpu->env, ri);
if (kvm_sync) {
- /* Only sync if we can sync to KVM successfully. */
- uint64_t oldval;
- uint64_t kvmval;
+ if (is_id_reg(ri)) {
+ /* Only sync if we can sync to KVM successfully. */
+ uint64_t oldval;
+ uint64_t kvmval;
- if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
- continue;
- }
- if (oldval == newval) {
- continue;
- }
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
+ continue;
+ }
+ if (oldval == newval) {
+ continue;
+ }
- if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
- continue;
- }
- if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
- kvmval != newval) {
- continue;
- }
+ if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
+ continue;
+ }
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
+ kvmval != newval) {
+ continue;
+ }
+
+ kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
+ } else {
+ /*
+ * Only sync if the previous list->cpustate sync succeeded.
+ * Rather than tracking the success/failure state for every
+ * item in the list, we just recheck "does the raw write we must
+ * have made in write_list_to_cpustate() read back OK" here.
+ */
+ uint64_t oldval = cpu->cpreg_values[i];
+
+ if (oldval == newval) {
+ continue;
+ }
- kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
+ write_raw_cp_reg(&cpu->env, ri, oldval);
+ if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
+ continue;
+ }
+
+ write_raw_cp_reg(&cpu->env, ri, newval);
+ }
}
cpu->cpreg_values[i] = newval;
}
--
2.27.0

View File

@ -0,0 +1,58 @@
From e2cb8b57278357c0a42cf7722b8c28b6f8d7585c Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Sat, 19 Sep 2020 09:04:45 +0800
Subject: [PATCH] target/arm: Update the ID registers of Kunpeng-920
The values of some ID registers in Kunpeng-920 are not exactly correct.
Let's update them. The values are read from Kunpeng-920 by calling
read_sysreg_s.
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/cpu64.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 287e7ac91c..3ec788fc29 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -262,10 +262,33 @@ static void aarch64_kunpeng_920_initfn(Object *obj)
cpu->midr = 0x480fd010;
cpu->ctr = 0x84448004;
- cpu->isar.regs[ID_AA64PFR0] = 0x11001111;
+ cpu->isar.regs[ID_ISAR0] = 0;
+ cpu->isar.regs[ID_ISAR1] = 0;
+ cpu->isar.regs[ID_ISAR2] = 0;
+ cpu->isar.regs[ID_ISAR3] = 0;
+ cpu->isar.regs[ID_ISAR4] = 0;
+ cpu->isar.regs[ID_ISAR5] = 0;
+ cpu->isar.regs[ID_MMFR0] = 0;
+ cpu->isar.regs[ID_MMFR1] = 0;
+ cpu->isar.regs[ID_MMFR2] = 0;
+ cpu->isar.regs[ID_MMFR3] = 0;
+ cpu->isar.regs[ID_MMFR4] = 0;
+ cpu->isar.regs[MVFR0] = 0;
+ cpu->isar.regs[MVFR1] = 0;
+ cpu->isar.regs[MVFR2] = 0;
+ cpu->isar.regs[ID_DFR0] = 0;
+ cpu->isar.regs[MVFR2] = 0;
+ cpu->isar.regs[MVFR2] = 0;
+ cpu->isar.regs[MVFR2] = 0;
+ cpu->isar.regs[ID_PFR0] = 0;
+ cpu->isar.regs[ID_PFR1] = 0;
+ cpu->isar.regs[ID_AA64PFR0] = 0x0000010011111111;
cpu->isar.regs[ID_AA64DFR0] = 0x110305408;
- cpu->isar.regs[ID_AA64ISAR0] = 0x10211120;
+ cpu->isar.regs[ID_AA64ISAR0] = 0x0001100010211120;
+ cpu->isar.regs[ID_AA64ISAR1] = 0x00011001;
cpu->isar.regs[ID_AA64MMFR0] = 0x101125;
+ cpu->isar.regs[ID_AA64MMFR1] = 0x10211122;
+ cpu->isar.regs[ID_AA64MMFR2] = 0x00001011;
}
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
--
2.27.0

View File

@ -0,0 +1,43 @@
From 20bd52038a960e0c959af38a5d3d7a6601db8e8b Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Mon, 21 Sep 2020 22:14:20 +0800
Subject: [PATCH] target/arm: clear EL2 and EL3 only when kvm is not enabled
When has_el2 and has_el3 are disabled, which is the default value for
virt machine, QEMU will clear the corresponding field in ID_PFR1_EL1 and
ID_AA64PFR0_EL1 to not expose EL3 and EL2 to guest. Because KVM doesn't
support to emulate ID registers in AArch64 before, it will not take
effect. Hence, clear EL2 and EL3 only when kvm is not enabled for
backwards compatibility.
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/cpu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1c1647a0a8..65163f5135 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2283,7 +2283,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
}
- if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3) {
+ if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3 && !kvm_enabled()) {
/* If the has_el3 CPU property is disabled then we need to disable the
* feature.
*/
@@ -2324,7 +2324,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
cpu->pmceid1 = 0;
}
- if (!arm_feature(env, ARM_FEATURE_EL2)) {
+ if (!arm_feature(env, ARM_FEATURE_EL2) && !kvm_enabled()) {
/* Disable the hypervisor feature bits in the processor feature
* registers if we don't have EL2. These are id_pfr1[15:12] and
* id_aa64pfr0_el1[11:8].
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
From 4558dc5590b89b1252baea2734c2b3668566e5cb Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Mon, 7 Sep 2020 14:07:07 +0800
Subject: [PATCH] target/arm: ignore evtstrm and cpuid CPU features
evtstrm and cpuid cann't be controlled by VMM:
1. evtstrm: The generic timer is configured to generate events at a
frequency of approximately 100KHz. It's controlled by the linux
kernel config CONFIG_ARM_ARCH_TIMER_EVTSTREAM.
2. cpuid: EL0 access to certain ID registers is available. It's always
set by linux kernel after 77c97b4ee2129 ("arm64: cpufeature: Expose
CPUID registers by emulation").
However, they are exposed by getauxval() and /proc/cpuinfo. Hence,
let's report and ignore the CPU features if someone set them.
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/cpu64.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 9e5179afbe..287e7ac91c 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -982,10 +982,37 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs)
return g_strdup("aarch64");
}
+static const char *unconfigurable_feats[] = {
+ "evtstrm",
+ "cpuid",
+ NULL
+};
+
+static bool is_configurable_feat(const char *name)
+{
+ int i;
+
+ for (i = 0; unconfigurable_feats[i]; ++i) {
+ if (g_strcmp0(unconfigurable_feats[i], name) == 0) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
static void
cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
{
- GlobalProperty *prop = g_new0(typeof(*prop), 1);
+ GlobalProperty *prop;
+
+ if (!is_configurable_feat(name)) {
+ info_report("CPU feature '%s' is not configurable by QEMU. Ignore it.",
+ name);
+ return;
+ }
+
+ prop = g_new0(typeof(*prop), 1);
prop->driver = typename;
prop->property = g_strdup(name);
prop->value = g_strdup(val);
--
2.27.0

View File

@ -0,0 +1,185 @@
From 632d58d1b908ee979074b589417f446c0a3be35d Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Thu, 6 Aug 2020 16:14:46 +0800
Subject: [PATCH] target/arm: introduce CPU feature dependency mechanism
Some CPU features are dependent on other CPU features. For example,
ID_AA64PFR0_EL1.FP field and ID_AA64PFR0_EL1.AdvSIMD must have the same
value, which means FP and ADVSIMD are dependent on each other, FPHP and
ADVSIMDHP are dependent on each other.
This commit introduces a mechanism for CPU feature dependency in
AArch64. We build a directed graph from the CPU feature dependency
relationship, each edge from->to means the `to` CPU feature is dependent
on the `from` CPU feature. And we will automatically enable/disable CPU
feature according to the directed graph.
For example, a, b, and c CPU features are in relationship a->b->c, which
means c is dependent on b and b is dependent on a. If c is enabled by
user, then a and b is enabled automatically. And if a is disabled by
user, then b and c is disabled automatically.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/cpu.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index c081ecc12b..ee09642dae 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1483,6 +1483,103 @@ static struct CPUFeatureInfo cpu_features[] = {
},
};
+typedef struct CPUFeatureDep {
+ CPUFeatureInfo from, to;
+} CPUFeatureDep;
+
+static const CPUFeatureDep feature_dependencies[] = {
+ {
+ .from = FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
+ .to = FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
+ },
+ {
+ .from = FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
+ .to = FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
+ },
+ {
+ .from = {
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
+ },
+ .to = {
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
+ },
+ },
+ {
+ .from = {
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
+ },
+ .to = {
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
+ },
+ },
+ {
+
+ .from = FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false),
+ .to = {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH,
+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "pmull", .is_32bit = false,
+ },
+ },
+ {
+
+ .from = FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
+ .to = {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
+ },
+ },
+ {
+ .from = FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false),
+ .to = {
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH,
+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false,
+ },
+ },
+ {
+ .from = FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
+ .to = FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
+ },
+ {
+ .from = FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
+ .to = FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
+ },
+ {
+ .from = FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
+ .to = FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
+ },
+ {
+ .from = FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
+ .to = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
+ },
+ {
+ .from = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
+ .to = {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
+ },
+ },
+ {
+ .from = {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
+ },
+ .to = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
+ },
+};
+
static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
@@ -1519,13 +1616,45 @@ static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
}
if (value) {
+ if (object_property_get_bool(obj, feat->name, NULL)) {
+ return;
+ }
isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
feat->shift, feat->length,
feat->min_value);
+ /* Auto enable the features which current feature is dependent on. */
+ for (int i = 0; i < ARRAY_SIZE(feature_dependencies); ++i) {
+ const CPUFeatureDep *d = &feature_dependencies[i];
+ if (strcmp(d->to.name, feat->name) != 0) {
+ continue;
+ }
+
+ object_property_set_bool(obj, d->from.name, true, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
} else {
+ if (!object_property_get_bool(obj, feat->name, NULL)) {
+ return;
+ }
isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
feat->shift, feat->length,
feat->ni_value);
+ /* Auto disable the features which are dependent on current feature. */
+ for (int i = 0; i < ARRAY_SIZE(feature_dependencies); ++i) {
+ const CPUFeatureDep *d = &feature_dependencies[i];
+ if (strcmp(d->from.name, feat->name) != 0) {
+ continue;
+ }
+
+ object_property_set_bool(obj, d->to.name, false, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
}
}
--
2.27.0

View File

@ -0,0 +1,93 @@
From 536aa9ecc3cb25c81c2df56230c690257189d4ef Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Thu, 6 Aug 2020 16:14:55 +0800
Subject: [PATCH] target/arm: introduce KVM_CAP_ARM_CPU_FEATURE
Introduce KVM_CAP_ARM_CPU_FEATURE to check whether KVM supports to set
CPU features in ARM.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
linux-headers/linux/kvm.h | 2 ++
target/arm/cpu.c | 5 +++++
target/arm/kvm64.c | 14 ++++++++++++++
target/arm/kvm_arm.h | 7 +++++++
4 files changed, 28 insertions(+)
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index bcaf66cc4d..5d8e42b8f8 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1113,6 +1113,8 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
#define KVM_CAP_ARM_MTE 205
+#define KVM_CAP_ARM_CPU_FEATURE 555
+
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index ee09642dae..3024f4a3f5 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1604,6 +1604,11 @@ static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
Error *local_err = NULL;
bool value;
+ if (!kvm_arm_cpu_feature_supported()) {
+ warn_report("KVM doesn't support to set CPU feature in arm. "
+ "Setting to `%s` is ignored.", name);
+ return;
+ }
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
return;
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 4f97e516c2..b34a87fd24 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -827,6 +827,20 @@ static int kvm_arm_sve_set_vls(CPUState *cs)
return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
}
+bool kvm_arm_cpu_feature_supported(void)
+{
+ static bool cpu_feature_initialized;
+ static bool cpu_feature_supported;
+
+ if (!cpu_feature_initialized) {
+ cpu_feature_supported = kvm_check_extension(kvm_state,
+ KVM_CAP_ARM_CPU_FEATURE);
+ cpu_feature_initialized = true;
+ }
+
+ return cpu_feature_supported;
+}
+
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
int kvm_arch_init_vcpu(CPUState *cs)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index f8e0e64363..82145607ec 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -306,6 +306,13 @@ bool kvm_arm_pmu_supported(void);
*/
bool kvm_arm_sve_supported(void);
+/**
+ * kvm_arm_cpu_feature_supported:
+ *
+ * Returns true if KVM can set CPU features and false otherwise.
+ */
+bool kvm_arm_cpu_feature_supported(void);
+
/**
* kvm_arm_get_max_vm_ipa_size:
* @ms: Machine state handle
--
2.27.0

View File

@ -0,0 +1,32 @@
From 3371917ea92265377f87692a717397267416c4aa Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Wed, 16 Sep 2020 19:40:28 +0800
Subject: [PATCH] target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest
Some AArch64 CPU doesn't support AArch32 mode, and the values of AArch32
registers are all 0. Hence, We'd better not to modify AArch32 registers
in AArch64 mode.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 79f77705c3..4c7b4cadfa 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6718,7 +6718,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
ARMCPU *cpu = env_archcpu(env);
uint64_t pfr1 = cpu->isar.regs[ID_PFR1];
- if (env->gicv3state) {
+ if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && env->gicv3state) {
pfr1 |= 1 << 28;
}
return pfr1;
--
2.27.0

View File

@ -0,0 +1,125 @@
From abd51f8d46b916efb37cb2c8face176bc83c0d5d Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Thu, 6 Aug 2020 16:14:35 +0800
Subject: [PATCH] target/arm: parse cpu feature related options
The implementation of CPUClass::parse_features only supports CPU
features in "feature=value" format. However, libvirt maybe send us a
CPU feature string in "+feature/-feature" format. Hence, we need to
override CPUClass::parse_features to support CPU feature string in both
"feature=value" and "+feature/-feature" format.
The logic of AArch64CPUClass::parse_features is similar to that of
X86CPUClass::parse_features.
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/cpu64.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 96a49a3158..9e5179afbe 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -982,6 +982,88 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs)
return g_strdup("aarch64");
}
+static void
+cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
+{
+ GlobalProperty *prop = g_new0(typeof(*prop), 1);
+ prop->driver = typename;
+ prop->property = g_strdup(name);
+ prop->value = g_strdup(val);
+ qdev_prop_register_global(prop);
+}
+
+static gint compare_string(gconstpointer a, gconstpointer b)
+{
+ return g_strcmp0(a, b);
+}
+
+static GList *plus_features, *minus_features;
+
+static void aarch64_cpu_parse_features(const char *typename, char *features,
+ Error **errp)
+{
+ GList *l;
+ char *featurestr; /* Single 'key=value" string being parsed */
+ static bool cpu_globals_initialized;
+
+ if (cpu_globals_initialized) {
+ return;
+ }
+ cpu_globals_initialized = true;
+
+ if (!features) {
+ return;
+ }
+ for (featurestr = strtok(features, ",");
+ featurestr;
+ featurestr = strtok(NULL, ",")) {
+ const char *name;
+ const char *val = NULL;
+ char *eq = NULL;
+
+ /* Compatibility syntax: */
+ if (featurestr[0] == '+') {
+ plus_features = g_list_append(plus_features,
+ g_strdup(featurestr + 1));
+ continue;
+ } else if (featurestr[0] == '-') {
+ minus_features = g_list_append(minus_features,
+ g_strdup(featurestr + 1));
+ continue;
+ }
+
+ eq = strchr(featurestr, '=');
+ name = featurestr;
+ if (eq) {
+ *eq++ = 0;
+ val = eq;
+ } else {
+ error_setg(errp, "Unsupported property format: %s", name);
+ return;
+ }
+
+ if (g_list_find_custom(plus_features, name, compare_string)) {
+ warn_report("Ambiguous CPU model string. "
+ "Don't mix both \"+%s\" and \"%s=%s\"",
+ name, name, val);
+ }
+ if (g_list_find_custom(minus_features, name, compare_string)) {
+ warn_report("Ambiguous CPU model string. "
+ "Don't mix both \"-%s\" and \"%s=%s\"",
+ name, name, val);
+ }
+ cpu_add_feat_as_prop(typename, name, val);
+ }
+
+ for (l = plus_features; l; l = l->next) {
+ cpu_add_feat_as_prop(typename, l->data, "on");
+ }
+
+ for (l = minus_features; l; l = l->next) {
+ cpu_add_feat_as_prop(typename, l->data, "off");
+ }
+}
+
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
@@ -991,6 +1073,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_num_core_regs = 34;
cc->gdb_core_xml_file = "aarch64-core.xml";
cc->gdb_arch_name = aarch64_gdb_arch_name;
+ cc->parse_features = aarch64_cpu_parse_features;
object_class_property_add_bool(oc, "aarch64", aarch64_cpu_get_aarch64,
aarch64_cpu_set_aarch64);
--
2.27.0

View File

@ -0,0 +1,399 @@
From 9fd09aabba558b39ca949ef376d05bc0779fdda6 Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
Date: Thu, 6 Aug 2020 16:14:37 +0800
Subject: [PATCH] target/arm: register CPU features for property
The Arm architecture specifies a number of ID registers that are
characterized as comprising a set of 4-bit ID fields. Each ID field
identifies the presence, and possibly the level of support for, a
particular feature in an implementation of the architecture. [1]
For most of the ID fields, there is a minimum presence value, equal to
or higher than which means the corresponding CPU feature is implemented.
Hence, we can use the minimum presence value to determine whether a CPU
feature is enabled and enable a CPU feature.
To disable a CPU feature, setting the corresponding ID field to 0x0/0xf
(for unsigned/signed field) seems as a good idea. However, it maybe
lead to some problems. For example, ID_AA64PFR0_EL1.FP is a signed ID
field. ID_AA64PFR0_EL1.FP == 0x0 represents the implementation of FP
(floating-point) and ID_AA64PFR0_EL1.FP == 0x1 represents the
implementation of FPHP (half-precision floating-point). If
ID_AA64PFR0_EL1.FP is set to 0xf when FPHP is disabled (which is also
disable FP), guest kernel maybe stuck. Hence, we add a ni_value (means
not-implemented value) to disable a CPU feature safely.
[1] D13.1.3 Principles of the ID scheme for fields in ID registers in
DDI.0487
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Dongxu Sun <sundongxu3@huawei.com>
---
target/arm/cpu.c | 343 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 343 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f1ce0474a3..c081ecc12b 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1211,6 +1211,347 @@ unsigned int gt_cntfrq_period_ns(ARMCPU *cpu)
NANOSECONDS_PER_SECOND / cpu->gt_cntfrq_hz : 1;
}
+/**
+ * CPUFeatureInfo:
+ * @reg: The ID register where the ID field is in.
+ * @name: The name of the CPU feature.
+ * @length: The bit length of the ID field.
+ * @shift: The bit shift of the ID field in the ID register.
+ * @min_value: The minimum value equal to or larger than which means the CPU
+ * feature is implemented.
+ * @ni_value: Not-implemented value. It will be set to the ID field when
+ * disabling the CPU feature. Usually, it's min_value - 1.
+ * @sign: Whether the ID field is signed.
+ * @is_32bit: Whether the CPU feature is for 32-bit.
+ *
+ * In ARM, a CPU feature is described by an ID field, which is a 4-bit field in
+ * an ID register.
+ */
+typedef struct CPUFeatureInfo {
+ CPUIDReg reg;
+ const char *name;
+ int length;
+ int shift;
+ int min_value;
+ int ni_value;
+ bool sign;
+ bool is_32bit;
+} CPUFeatureInfo;
+
+#define FIELD_INFO(feature_name, id_reg, field, s, min_val, ni_val, is32bit) { \
+ .reg = id_reg, \
+ .length = R_ ## id_reg ## _ ## field ## _LENGTH, \
+ .shift = R_ ## id_reg ## _ ## field ## _SHIFT, \
+ .sign = s, \
+ .min_value = min_val, \
+ .ni_value = ni_val, \
+ .name = feature_name, \
+ .is_32bit = is32bit, \
+}
+
+static struct CPUFeatureInfo cpu_features[] = {
+ FIELD_INFO("swap", ID_ISAR0, SWAP, false, 1, 0, true),
+ FIELD_INFO("bitcount", ID_ISAR0, BITCOUNT, false, 1, 0, true),
+ FIELD_INFO("bitfield", ID_ISAR0, BITFIELD, false, 1, 0, true),
+ FIELD_INFO("cmpbranch", ID_ISAR0, CMPBRANCH, false, 1, 0, true),
+ FIELD_INFO("coproc", ID_ISAR0, COPROC, false, 1, 0, true),
+ FIELD_INFO("debug", ID_ISAR0, DEBUG, false, 1, 0, true),
+ FIELD_INFO("device", ID_ISAR0, DIVIDE, false, 1, 0, true),
+
+ FIELD_INFO("endian", ID_ISAR1, ENDIAN, false, 1, 0, true),
+ FIELD_INFO("except", ID_ISAR1, EXCEPT, false, 1, 0, true),
+ FIELD_INFO("except_ar", ID_ISAR1, EXCEPT_AR, false, 1, 0, true),
+ FIELD_INFO("extend", ID_ISAR1, EXTEND, false, 1, 0, true),
+ FIELD_INFO("ifthen", ID_ISAR1, IFTHEN, false, 1, 0, true),
+ FIELD_INFO("immediate", ID_ISAR1, IMMEDIATE, false, 1, 0, true),
+ FIELD_INFO("interwork", ID_ISAR1, INTERWORK, false, 1, 0, true),
+ FIELD_INFO("jazelle", ID_ISAR1, JAZELLE, false, 1, 0, true),
+
+ FIELD_INFO("loadstore", ID_ISAR2, LOADSTORE, false, 1, 0, true),
+ FIELD_INFO("memhint", ID_ISAR2, MEMHINT, false, 1, 0, true),
+ FIELD_INFO("multiaccessint", ID_ISAR2, MULTIACCESSINT, false, 1, 0, true),
+ FIELD_INFO("mult", ID_ISAR2, MULT, false, 1, 0, true),
+ FIELD_INFO("mults", ID_ISAR2, MULTS, false, 1, 0, true),
+ FIELD_INFO("multu", ID_ISAR2, MULTU, false, 1, 0, true),
+ FIELD_INFO("psr_ar", ID_ISAR2, PSR_AR, false, 1, 0, true),
+ FIELD_INFO("reversal", ID_ISAR2, REVERSAL, false, 1, 0, true),
+
+ FIELD_INFO("saturate", ID_ISAR3, SATURATE, false, 1, 0, true),
+ FIELD_INFO("simd", ID_ISAR3, SIMD, false, 1, 0, true),
+ FIELD_INFO("svc", ID_ISAR3, SVC, false, 1, 0, true),
+ FIELD_INFO("synchprim", ID_ISAR3, SYNCHPRIM, false, 1, 0, true),
+ FIELD_INFO("tabbranch", ID_ISAR3, TABBRANCH, false, 1, 0, true),
+ FIELD_INFO("t32copy", ID_ISAR3, T32COPY, false, 1, 0, true),
+ FIELD_INFO("truenop", ID_ISAR3, TRUENOP, false, 1, 0, true),
+ FIELD_INFO("t32ee", ID_ISAR3, T32EE, false, 1, 0, true),
+
+ FIELD_INFO("unpriv", ID_ISAR4, UNPRIV, false, 1, 0, true),
+ FIELD_INFO("withshifts", ID_ISAR4, WITHSHIFTS, false, 1, 0, true),
+ FIELD_INFO("writeback", ID_ISAR4, WRITEBACK, false, 1, 0, true),
+ FIELD_INFO("smc", ID_ISAR4, SMC, false, 1, 0, true),
+ FIELD_INFO("barrier", ID_ISAR4, BARRIER, false, 1, 0, true),
+ FIELD_INFO("synchprim_frac", ID_ISAR4, SYNCHPRIM_FRAC, false, 1, 0, true),
+ FIELD_INFO("psr_m", ID_ISAR4, PSR_M, false, 1, 0, true),
+ FIELD_INFO("swp_frac", ID_ISAR4, SWP_FRAC, false, 1, 0, true),
+
+ FIELD_INFO("sevl", ID_ISAR5, SEVL, false, 1, 0, true),
+ FIELD_INFO("aes", ID_ISAR5, AES, false, 1, 0, true),
+ FIELD_INFO("sha1", ID_ISAR5, SHA1, false, 1, 0, true),
+ FIELD_INFO("sha2", ID_ISAR5, SHA2, false, 1, 0, true),
+ FIELD_INFO("crc32", ID_ISAR5, CRC32, false, 1, 0, true),
+ FIELD_INFO("rdm", ID_ISAR5, RDM, false, 1, 0, true),
+ FIELD_INFO("vcma", ID_ISAR5, VCMA, false, 1, 0, true),
+
+ FIELD_INFO("jscvt", ID_ISAR6, JSCVT, false, 1, 0, true),
+ FIELD_INFO("dp", ID_ISAR6, DP, false, 1, 0, true),
+ FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true),
+ FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true),
+ FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true),
+
+ FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true),
+ FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true),
+ FIELD_INFO("bpmaint", ID_MMFR3, BPMAINT, false, 1, 0, true),
+ FIELD_INFO("maintbcst", ID_MMFR3, MAINTBCST, false, 1, 0, true),
+ FIELD_INFO("pan", ID_MMFR3, PAN, false, 1, 0, true),
+ FIELD_INFO("cohwalk", ID_MMFR3, COHWALK, false, 1, 0, true),
+ FIELD_INFO("cmemsz", ID_MMFR3, CMEMSZ, false, 1, 0, true),
+ FIELD_INFO("supersec", ID_MMFR3, SUPERSEC, false, 1, 0, true),
+
+ FIELD_INFO("specsei", ID_MMFR4, SPECSEI, false, 1, 0, true),
+ FIELD_INFO("ac2", ID_MMFR4, AC2, false, 1, 0, true),
+ FIELD_INFO("xnx", ID_MMFR4, XNX, false, 1, 0, true),
+ FIELD_INFO("cnp", ID_MMFR4, CNP, false, 1, 0, true),
+ FIELD_INFO("hpds", ID_MMFR4, HPDS, false, 1, 0, true),
+ FIELD_INFO("lsm", ID_MMFR4, LSM, false, 1, 0, true),
+ FIELD_INFO("ccidx", ID_MMFR4, CCIDX, false, 1, 0, true),
+ FIELD_INFO("evt", ID_MMFR4, EVT, false, 1, 0, true),
+
+ FIELD_INFO("simdreg", MVFR0, SIMDREG, false, 1, 0, true),
+ FIELD_INFO("fpsp", MVFR0, FPSP, false, 1, 0, true),
+ FIELD_INFO("fpdp", MVFR0, FPDP, false, 1, 0, true),
+ FIELD_INFO("fptrap", MVFR0, FPTRAP, false, 1, 0, true),
+ FIELD_INFO("fpdivide", MVFR0, FPDIVIDE, false, 1, 0, true),
+ FIELD_INFO("fpsqrt", MVFR0, FPSQRT, false, 1, 0, true),
+ FIELD_INFO("fpshvec", MVFR0, FPSHVEC, false, 1, 0, true),
+ FIELD_INFO("fpround", MVFR0, FPROUND, false, 1, 0, true),
+
+ FIELD_INFO("fpftz", MVFR1, FPFTZ, false, 1, 0, true),
+ FIELD_INFO("fpdnan", MVFR1, FPDNAN, false, 1, 0, true),
+ FIELD_INFO("simdls", MVFR1, SIMDLS, false, 1, 0, true),
+ FIELD_INFO("simdint", MVFR1, SIMDINT, false, 1, 0, true),
+ FIELD_INFO("simdsp", MVFR1, SIMDSP, false, 1, 0, true),
+ FIELD_INFO("simdhp", MVFR1, SIMDHP, false, 1, 0, true),
+ FIELD_INFO("fphp", MVFR1, FPHP, false, 1, 0, true),
+ FIELD_INFO("simdfmac", MVFR1, SIMDFMAC, false, 1, 0, true),
+
+ FIELD_INFO("simdmisc", MVFR2, SIMDMISC, false, 1, 0, true),
+ FIELD_INFO("fpmisc", MVFR2, FPMISC, false, 1, 0, true),
+
+ FIELD_INFO("debugver", ID_AA64DFR0, DEBUGVER, false, 1, 0, false),
+ FIELD_INFO("tracever", ID_AA64DFR0, TRACEVER, false, 1, 0, false),
+ FIELD_INFO("pmuver", ID_AA64DFR0, PMUVER, false, 1, 0, false),
+ FIELD_INFO("brps", ID_AA64DFR0, BRPS, false, 1, 0, false),
+ FIELD_INFO("wrps", ID_AA64DFR0, WRPS, false, 1, 0, false),
+ FIELD_INFO("ctx_cmps", ID_AA64DFR0, CTX_CMPS, false, 1, 0, false),
+ FIELD_INFO("pmsver", ID_AA64DFR0, PMSVER, false, 1, 0, false),
+ FIELD_INFO("doublelock", ID_AA64DFR0, DOUBLELOCK, false, 1, 0, false),
+ FIELD_INFO("tracefilt", ID_AA64DFR0, TRACEFILT, false, 1, 0, false),
+
+ FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false),
+ FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false),
+ FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false),
+ FIELD_INFO("crc32", ID_AA64ISAR0, CRC32, false, 1, 0, false),
+ FIELD_INFO("atomics", ID_AA64ISAR0, ATOMIC, false, 1, 0, false),
+ FIELD_INFO("asimdrdm", ID_AA64ISAR0, RDM, false, 1, 0, false),
+ FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false),
+ FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false),
+ FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false),
+ FIELD_INFO("asimddp", ID_AA64ISAR0, DP, false, 1, 0, false),
+ FIELD_INFO("asimdfhm", ID_AA64ISAR0, FHM, false, 1, 0, false),
+ FIELD_INFO("flagm", ID_AA64ISAR0, TS, false, 1, 0, false),
+ FIELD_INFO("tlb", ID_AA64ISAR0, TLB, false, 1, 0, false),
+ FIELD_INFO("rng", ID_AA64ISAR0, RNDR, false, 1, 0, false),
+
+ FIELD_INFO("dcpop", ID_AA64ISAR1, DPB, false, 1, 0, false),
+ FIELD_INFO("papa", ID_AA64ISAR1, APA, false, 1, 0, false),
+ FIELD_INFO("api", ID_AA64ISAR1, API, false, 1, 0, false),
+ FIELD_INFO("jscvt", ID_AA64ISAR1, JSCVT, false, 1, 0, false),
+ FIELD_INFO("fcma", ID_AA64ISAR1, FCMA, false, 1, 0, false),
+ FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false),
+ FIELD_INFO("pacg", ID_AA64ISAR1, GPA, false, 1, 0, false),
+ FIELD_INFO("gpi", ID_AA64ISAR1, GPI, false, 1, 0, false),
+ FIELD_INFO("frint", ID_AA64ISAR1, FRINTTS, false, 1, 0, false),
+ FIELD_INFO("sb", ID_AA64ISAR1, SB, false, 1, 0, false),
+ FIELD_INFO("specres", ID_AA64ISAR1, SPECRES, false, 1, 0, false),
+
+ FIELD_INFO("el0", ID_AA64PFR0, EL0, false, 1, 0, false),
+ FIELD_INFO("el1", ID_AA64PFR0, EL1, false, 1, 0, false),
+ FIELD_INFO("el2", ID_AA64PFR0, EL2, false, 1, 0, false),
+ FIELD_INFO("el3", ID_AA64PFR0, EL3, false, 1, 0, false),
+ FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false),
+ FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false),
+ FIELD_INFO("gic", ID_AA64PFR0, GIC, false, 1, 0, false),
+ FIELD_INFO("ras", ID_AA64PFR0, RAS, false, 1, 0, false),
+ FIELD_INFO("sve", ID_AA64PFR0, SVE, false, 1, 0, false),
+
+ FIELD_INFO("bti", ID_AA64PFR1, BT, false, 1, 0, false),
+ FIELD_INFO("ssbs", ID_AA64PFR1, SSBS, false, 1, 0, false),
+ FIELD_INFO("mte", ID_AA64PFR1, MTE, false, 1, 0, false),
+ FIELD_INFO("ras_frac", ID_AA64PFR1, RAS_FRAC, false, 1, 0, false),
+
+ FIELD_INFO("parange", ID_AA64MMFR0, PARANGE, false, 1, 0, false),
+ FIELD_INFO("asidbits", ID_AA64MMFR0, ASIDBITS, false, 1, 0, false),
+ FIELD_INFO("bigend", ID_AA64MMFR0, BIGEND, false, 1, 0, false),
+ FIELD_INFO("snsmem", ID_AA64MMFR0, SNSMEM, false, 1, 0, false),
+ FIELD_INFO("bigendel0", ID_AA64MMFR0, BIGENDEL0, false, 1, 0, false),
+ FIELD_INFO("tgran16", ID_AA64MMFR0, TGRAN16, false, 1, 0, false),
+ FIELD_INFO("tgran64", ID_AA64MMFR0, TGRAN64, false, 1, 0, false),
+ FIELD_INFO("tgran4", ID_AA64MMFR0, TGRAN4, false, 1, 0, false),
+ FIELD_INFO("tgran16_2", ID_AA64MMFR0, TGRAN16_2, false, 1, 0, false),
+ FIELD_INFO("tgran64_2", ID_AA64MMFR0, TGRAN64_2, false, 1, 0, false),
+ FIELD_INFO("tgran4_2", ID_AA64MMFR0, TGRAN4_2, false, 1, 0, false),
+ FIELD_INFO("exs", ID_AA64MMFR0, EXS, false, 1, 0, false),
+
+ FIELD_INFO("hafdbs", ID_AA64MMFR1, HAFDBS, false, 1, 0, false),
+ FIELD_INFO("vmidbits", ID_AA64MMFR1, VMIDBITS, false, 1, 0, false),
+ FIELD_INFO("vh", ID_AA64MMFR1, VH, false, 1, 0, false),
+ FIELD_INFO("hpds", ID_AA64MMFR1, HPDS, false, 1, 0, false),
+ FIELD_INFO("lo", ID_AA64MMFR1, LO, false, 1, 0, false),
+ FIELD_INFO("pan", ID_AA64MMFR1, PAN, false, 1, 0, false),
+ FIELD_INFO("specsei", ID_AA64MMFR1, SPECSEI, false, 1, 0, false),
+ FIELD_INFO("xnx", ID_AA64MMFR1, XNX, false, 1, 0, false),
+
+ FIELD_INFO("cnp", ID_AA64MMFR2, CNP, false, 1, 0, false),
+ FIELD_INFO("uao", ID_AA64MMFR2, UAO, false, 1, 0, false),
+ FIELD_INFO("lsm", ID_AA64MMFR2, LSM, false, 1, 0, false),
+ FIELD_INFO("iesb", ID_AA64MMFR2, IESB, false, 1, 0, false),
+ FIELD_INFO("varange", ID_AA64MMFR2, VARANGE, false, 1, 0, false),
+ FIELD_INFO("ccidx", ID_AA64MMFR2, CCIDX, false, 1, 0, false),
+ FIELD_INFO("nv", ID_AA64MMFR2, NV, false, 1, 0, false),
+ FIELD_INFO("st", ID_AA64MMFR2, ST, false, 1, 0, false),
+ FIELD_INFO("uscat", ID_AA64MMFR2, AT, false, 1, 0, false),
+ FIELD_INFO("ids", ID_AA64MMFR2, IDS, false, 1, 0, false),
+ FIELD_INFO("fwb", ID_AA64MMFR2, FWB, false, 1, 0, false),
+ FIELD_INFO("ttl", ID_AA64MMFR2, TTL, false, 1, 0, false),
+ FIELD_INFO("bbm", ID_AA64MMFR2, BBM, false, 1, 0, false),
+ FIELD_INFO("evt", ID_AA64MMFR2, EVT, false, 1, 0, false),
+ FIELD_INFO("e0pd", ID_AA64MMFR2, E0PD, false, 1, 0, false),
+
+ FIELD_INFO("copdbg", ID_DFR0, COPDBG, false, 1, 0, false),
+ FIELD_INFO("copsdbg", ID_DFR0, COPSDBG, false, 1, 0, false),
+ FIELD_INFO("mmapdbg", ID_DFR0, MMAPDBG, false, 1, 0, false),
+ FIELD_INFO("coptrc", ID_DFR0, COPTRC, false, 1, 0, false),
+ FIELD_INFO("mmaptrc", ID_DFR0, MMAPTRC, false, 1, 0, false),
+ FIELD_INFO("mprofdbg", ID_DFR0, MPROFDBG, false, 1, 0, false),
+ FIELD_INFO("perfmon", ID_DFR0, PERFMON, false, 1, 0, false),
+ FIELD_INFO("tracefilt", ID_DFR0, TRACEFILT, false, 1, 0, false),
+
+ {
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH,
+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1,
+ .ni_value = 0, .name = "fphp", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH,
+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1,
+ .ni_value = 0, .name = "asimdhp", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH,
+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "pmull", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH,
+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "sha512", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_TS_LENGTH,
+ .shift = R_ID_AA64ISAR0_TS_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "flagm2", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_DPB_LENGTH,
+ .shift = R_ID_AA64ISAR1_DPB_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "dcpodp", .is_32bit = false,
+ },
+ {
+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH,
+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2,
+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false,
+ },
+};
+
+static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ ARMCPU *cpu = ARM_CPU(obj);
+ CPUFeatureInfo *feat = opaque;
+ int field_value = feat->sign ? sextract64(cpu->isar.regs[feat->reg],
+ feat->shift, feat->length) :
+ extract64(cpu->isar.regs[feat->reg],
+ feat->shift, feat->length);
+ bool value = field_value >= feat->min_value;
+
+ visit_type_bool(v, name, &value, errp);
+}
+
+static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
+ CPUFeatureInfo *feat = opaque;
+ Error *local_err = NULL;
+ bool value;
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_bool(v, name, &value, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ if (value) {
+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
+ feat->shift, feat->length,
+ feat->min_value);
+ } else {
+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg],
+ feat->shift, feat->length,
+ feat->ni_value);
+ }
+}
+
+static void arm_cpu_register_feature_props(ARMCPU *cpu)
+{
+ int i;
+ int num = ARRAY_SIZE(cpu_features);
+ ObjectProperty *op;
+ CPUARMState *env = &cpu->env;
+
+ for (i = 0; i < num; i++) {
+ if ((arm_feature(env, ARM_FEATURE_AARCH64) && cpu_features[i].is_32bit)
+ || (!arm_feature(env, ARM_FEATURE_AARCH64) &&
+ cpu_features[i].is_32bit)) {
+ continue;
+ }
+ op = object_property_find(OBJECT(cpu), cpu_features[i].name);
+ if (!op) {
+ object_property_add(OBJECT(cpu), cpu_features[i].name, "bool",
+ arm_cpu_get_bit_prop,
+ arm_cpu_set_bit_prop,
+ NULL, &cpu_features[i]);
+ }
+ }
+}
+
void arm_cpu_post_init(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@@ -1319,6 +1660,8 @@ void arm_cpu_post_init(Object *obj)
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
+ arm_cpu_register_feature_props(cpu);
+
if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) {
qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property);
}
--
2.27.0

View File

@ -0,0 +1,31 @@
From 4f09a1c2aa855aab666d729defce4c7f0466cb77 Mon Sep 17 00:00:00 2001
From: Ying Fang <fangying1@huawei.com>
Date: Thu, 10 Feb 2022 17:16:55 +0800
Subject: [PATCH] tests: Disable filemonitor testcase
Since filemonitor testcase requires that host kernel being a LTS version,
we cannot guarantee that on OBS system. Lets disable it by default.
Signed-off-by: Ying Fang <fangying1@huawei.com>
Signed-off-by: Jinhao Gao <gaojinhao@huawei.com>
---
tests/unit/meson.build | 3 ---
1 file changed, 3 deletions(-)
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index acac3622ed..c21d817874 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -129,9 +129,6 @@ if have_system
'test-vmstate': [migration, io],
'test-yank': ['socket-helpers.c', qom, io, chardev]
}
- if 'CONFIG_INOTIFY1' in config_host
- tests += {'test-util-filemonitor': []}
- endif
# Some tests: test-char, test-qdev-global-props, and test-qga,
# are not runnable under TSan due to a known issue.
--
2.27.0