Re: [PATCH v7 11/12] migration/dirtyrate: Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function

2020-09-12 Thread Zheng Chuan



On 2020/9/10 22:27, Li Qiang wrote:
> Chuan Zheng  于2020年9月9日周三 下午10:14写道:
>>
>> Implement qmp_cal_dirty_rate()/qmp_get_dirty_rate() function which could be 
>> called
>>
>> Signed-off-by: Chuan Zheng 
>> ---
>>  migration/dirtyrate.c | 62 
>> +++
>>  qapi/migration.json   | 50 +
>>  2 files changed, 112 insertions(+)
>>
>> diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
>> index 2f9ac34..e9e9e35 100644
>> --- a/migration/dirtyrate.c
>> +++ b/migration/dirtyrate.c
>> @@ -61,6 +61,24 @@ static int dirtyrate_set_state(int *state, int old_state, 
>> int new_state)
>>  }
>>  }
>>
>> +static struct DirtyRateInfo *query_dirty_rate_info(void)
>> +{
>> +int64_t dirty_rate = DirtyStat.dirty_rate;
>> +struct DirtyRateInfo *info = g_malloc0(sizeof(DirtyRateInfo));
>> +
>> +if (CalculatingState == DIRTY_RATE_STATUS_MEASURED) {
> 
> Should we use atomic read 'CalculatingState'? The qmp thread maybe run
> with the sampled thread.
> 
OK, will optimize it in V8
>> +info->dirty_rate = dirty_rate;
>> +} else {
>> +info->dirty_rate = -1;
>> +}
>> +
>> +info->status = CalculatingState;
>> +info->start_time = DirtyStat.start_time;
>> +info->calc_time = DirtyStat.calc_time;
>> +
>> +return info;
>> +}
>> +
> 
> 
>>  static void reset_dirtyrate_stat(void)
>>  {
>>  DirtyStat.total_dirty_samples = 0;
>> @@ -331,6 +349,8 @@ static void calculate_dirtyrate(struct DirtyRateConfig 
>> config)
>>
>>  msec = config.sample_period_seconds * 1000;
>>  msec = set_sample_page_period(msec, initial_time);
>> +DirtyStat.start_time = initial_time / 1000;
>> +DirtyStat.calc_time = msec / 1000;
>>
>>  rcu_read_lock();
>>  if (compare_page_hash_info(block_dinfo, block_index) < 0) {
>> @@ -362,3 +382,45 @@ void *get_dirtyrate_thread(void *arg)
>>DIRTY_RATE_STATUS_MEASURED);
>>  return NULL;
>>  }
>> +
>> +void qmp_calc_dirty_rate(int64_t calc_time, Error **errp)
>> +{
>> +static struct DirtyRateConfig config;
>> +QemuThread thread;
>> +int ret;
>> +
>> +/*
>> + * If the dirty rate is already being measured, don't attempt to start.
>> + */
>> +if (CalculatingState == DIRTY_RATE_STATUS_MEASURING) {
> 
> atomic read?
> 
>> +error_setg(errp, "the dirty rate is already being measured.");
>> +return;
>> +}
>> +
>> +if (!get_sample_page_period(calc_time)) {
>> +error_setg(errp, "calc-time is out of range[%d, %d].",
>> + MIN_FETCH_DIRTYRATE_TIME_SEC,
>> + MAX_FETCH_DIRTYRATE_TIME_SEC);
>> +return;
>> +}
>> +
>> +/*
>> + * Init calculation state as unstarted.
>> + */
>> +ret = dirtyrate_set_state(, CalculatingState,
>> +  DIRTY_RATE_STATUS_UNSTARTED);
>> +if (ret == -1) {
>> +error_setg(errp, "init dirty rate calculation state failed.");
>> +return;
>> +}
>> +
>> +config.sample_period_seconds = calc_time;
>> +config.sample_pages_per_gigabytes = DIRTYRATE_DEFAULT_SAMPLE_PAGES;
>> +qemu_thread_create(, "get_dirtyrate", get_dirtyrate_thread,
>> +   (void *), QEMU_THREAD_DETACHED);
>> +}
>> +
>> +struct DirtyRateInfo *qmp_query_dirty_rate(Error **errp)
>> +{
>> +return query_dirty_rate_info();
>> +}
>> diff --git a/qapi/migration.json b/qapi/migration.json
>> index 061ff25..4b980a0 100644
>> --- a/qapi/migration.json
>> +++ b/qapi/migration.json
>> @@ -1737,3 +1737,53 @@
>>  ##
>>  { 'enum': 'DirtyRateStatus',
>>'data': [ 'unstarted', 'measuring', 'measured'] }
>> +
>> +##
>> +# @DirtyRateInfo:
>> +#
>> +# Information about current dirty page rate of vm.
>> +#
>> +# @dirty-rate: @dirtyrate describing the dirty page rate of vm
>> +#  in units of MB/s.
>> +#  If this field return '-1', it means querying is not
>> +#  start or not complete.
>> +#
>> +# @status: status containing dirtyrate query status includes
>> +#  'unstarted' or 'measuring' or 'measured'
>> +#
>> +# @start-time: start time in units of second for calculation
>> +#
>> +# @calc-time: time in units of second for sample dirty pages
>> +#
>> +# Since: 5.2
>> +#
>> +##
>> +{ 'struct': 'DirtyRateInfo',
>> +  'data': {'dirty-rate': 'int64',
>> +   'status': 'DirtyRateStatus',
>> +   'start-time': 'int64',
>> +   'calc-time': 'int64'} }
>> +
>> +##
>> +# @calc-dirty-rate:
>> +#
>> +# start calculating dirty page rate for vm
>> +#
>> +# @calc-time: time in units of second for sample dirty pages
>> +#
>> +# Since: 5.2
>> +#
>> +# Example:
>> +#   {"command": "calc-dirty-rate", "data": {"calc-time": 1} }
>> +#
>> +##
>> +{ 'command': 'calc-dirty-rate', 'data': {'calc-time': 'int64'} }
>> +
>> +##
>> +# @query-dirty-rate:
>> +#
>> +# query dirty page rate in units of MB/s for vm
>> +#
>> +# Since: 5.2
>> +##
>> 

Re: [PATCH v7 09/12] migration/dirtyrate: Implement set_sample_page_period() and get_sample_page_period()

2020-09-12 Thread Zheng Chuan



On 2020/9/10 21:59, Li Qiang wrote:
> Chuan Zheng  于2020年9月9日周三 下午10:15写道:
>>
>> Implement set_sample_page_period()/get_sample_page_period() to sleep
>> specific time between sample actions.
>>
>> Signed-off-by: Chuan Zheng 
>> Reviewed-by: Dr. David Alan Gilbert 
>> Reviewed-by: David Edmondson 
>> ---
>>  migration/dirtyrate.c | 24 
>>  migration/dirtyrate.h |  6 ++
>>  2 files changed, 30 insertions(+)
>>
>> diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
>> index ae1959b..8a30261 100644
>> --- a/migration/dirtyrate.c
>> +++ b/migration/dirtyrate.c
>> @@ -27,6 +27,30 @@
>>  static int CalculatingState = DIRTY_RATE_STATUS_UNSTARTED;
>>  static struct DirtyRateStat DirtyStat;
>>
>> +static int64_t set_sample_page_period(int64_t msec, int64_t initial_time)
>> +{
>> +int64_t current_time;
>> +
>> +current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
>> +if ((current_time - initial_time) >= msec) {
>> +msec = current_time - initial_time;
>> +} else {
>> +g_usleep((msec + initial_time - current_time) * 1000);
>> +}
>> +
>> +return msec;
>> +}
>> +
>> +static bool get_sample_page_period(int64_t sec)
> 
> 
> This function name may confuse people the this will get the period.
> But in fact you just check whether the 'period' is valid.
> I think it is better to name it to be 'is_sample_period_valid' or
> something meaningful.
> 
> Thanks,
> Li Qiang
> 
Sure, will optimize it in later patch update.

>> +{
>> +if (sec < MIN_FETCH_DIRTYRATE_TIME_SEC ||
>> +sec > MAX_FETCH_DIRTYRATE_TIME_SEC) {
>> +return false;
>> +}
>> +
>> +return true;
>> +}
>> +
>>  static int dirtyrate_set_state(int *state, int old_state, int new_state)
>>  {
>>  assert(new_state < DIRTY_RATE_STATUS__MAX);
>> diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h
>> index faaf9da..8f9bc80 100644
>> --- a/migration/dirtyrate.h
>> +++ b/migration/dirtyrate.h
>> @@ -29,6 +29,12 @@
>>   */
>>  #define MIN_RAMBLOCK_SIZE 128
>>
>> +/*
>> + * Take 1s as minimum time for calculation duration
>> + */
>> +#define MIN_FETCH_DIRTYRATE_TIME_SEC  1
>> +#define MAX_FETCH_DIRTYRATE_TIME_SEC  60
>> +
>>  struct DirtyRateConfig {
>>  uint64_t sample_pages_per_gigabytes; /* sample pages per GB */
>>  int64_t sample_period_seconds; /* time duration between two sampling */
>> --
>> 1.8.3.1
>>
>>
> 
> .
> 



Re: [PATCH v7 06/12] migration/dirtyrate: Record hash results for each sampled page

2020-09-12 Thread Zheng Chuan



On 2020/9/10 21:51, Li Qiang wrote:
> Chuan Zheng  于2020年9月9日周三 下午10:14写道:
>>
>> Record hash results for each sampled page, crc32 is taken to calculate
>> hash results for each sampled length in TARGET_PAGE_SIZE.
>>
>> Signed-off-by: Chuan Zheng 
>> Signed-off-by: YanYing Zhuang 
>> Reviewed-by: David Edmondson 
>> ---
>>  migration/dirtyrate.c | 125 
>> ++
>>  1 file changed, 125 insertions(+)
>>
>> diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
>> index d56cd93..bc87269 100644
>> --- a/migration/dirtyrate.c
>> +++ b/migration/dirtyrate.c
>> @@ -10,6 +10,7 @@
>>   * See the COPYING file in the top-level directory.
>>   */
>>
>> +#include 
>>  #include "qemu/osdep.h"
>>  #include "qapi/error.h"
>>  #include "cpu.h"
>> @@ -68,6 +69,130 @@ static void update_dirtyrate(uint64_t msec)
>>  DirtyStat.dirty_rate = dirtyrate;
>>  }
>>
>> +/*
>> + * get hash result for the sampled memory with length of TARGET_PAGE_SIZE
>> + * in ramblock, which starts from ramblock base address.
>> + */
>> +static uint32_t get_ramblock_vfn_hash(struct RamblockDirtyInfo *info,
>> +  uint64_t vfn)
>> +{
>> +uint32_t crc;
>> +
>> +crc = crc32(0, (info->ramblock_addr +
>> +vfn * TARGET_PAGE_SIZE), TARGET_PAGE_SIZE);
>> +
>> +return crc;
>> +}
>> +
>> +static int save_ramblock_hash(struct RamblockDirtyInfo *info)
>> +{
>> +unsigned int sample_pages_count;
>> +int i;
>> +GRand *rand;
>> +
>> +sample_pages_count = info->sample_pages_count;
>> +
>> +/* ramblock size less than one page, return success to skip this 
>> ramblock */
>> +if (unlikely(info->ramblock_pages == 0 || sample_pages_count == 0)) {
>> +return 0;
>> +}
>> +
>> +info->hash_result = g_try_malloc0_n(sample_pages_count,
>> +sizeof(uint32_t));
>> +if (!info->hash_result) {
>> +return -1;
>> +}
>> +
>> +info->sample_page_vfn = g_try_malloc0_n(sample_pages_count,
>> +sizeof(uint64_t));
>> +if (!info->sample_page_vfn) {
>> +g_free(info->hash_result);
>> +return -1;
>> +}
>> +
>> +rand  = g_rand_new();
>> +for (i = 0; i < sample_pages_count; i++) {
>> +info->sample_page_vfn[i] = g_rand_int_range(rand, 0,
>> +info->ramblock_pages - 
>> 1);
>> +info->hash_result[i] = get_ramblock_vfn_hash(info,
>> + 
>> info->sample_page_vfn[i]);
>> +}
>> +g_rand_free(rand);
>> +
>> +return 0;
>> +}
>> +
>> +static void get_ramblock_dirty_info(RAMBlock *block,
>> +struct RamblockDirtyInfo *info,
>> +struct DirtyRateConfig *config)
>> +{
>> +uint64_t sample_pages_per_gigabytes = 
>> config->sample_pages_per_gigabytes;
>> +
>> +/* Right shift 30 bits to calc ramblock size in GB */
>> +info->sample_pages_count = (qemu_ram_get_used_length(block) *
>> +sample_pages_per_gigabytes) >> 30;
>> +/* Right shift TARGET_PAGE_BITS to calc page count */
>> +info->ramblock_pages = qemu_ram_get_used_length(block) >>
>> +   TARGET_PAGE_BITS;
>> +info->ramblock_addr = qemu_ram_get_host_addr(block);
>> +strcpy(info->idstr, qemu_ram_get_idstr(block));
>> +}
>> +
>> +static struct RamblockDirtyInfo *
>> +alloc_ramblock_dirty_info(int *block_index,
>> +  struct RamblockDirtyInfo *block_dinfo)
>> +{
>> +struct RamblockDirtyInfo *info = NULL;
>> +int index = *block_index;
>> +
>> +if (!block_dinfo) {
>> +index = 0;
>> +block_dinfo = g_try_new(struct RamblockDirtyInfo, 1);
>> +} else {
>> +index++;
>> +block_dinfo = g_try_realloc(block_dinfo, (index + 1) *
>> +sizeof(struct RamblockDirtyInfo));
>> +}
>> +if (!block_dinfo) {
>> +return NULL;
> 
> What if this case happens the 'index' has been increased?  but the
> allocation is failed.
> 
>> +}
>> +
>> +info = _dinfo[index];
>> +*block_index = index;
>> +memset(info, 0, sizeof(struct RamblockDirtyInfo));
>> +
>> +return block_dinfo;
>> +}
>> +
>> +static int record_ramblock_hash_info(struct RamblockDirtyInfo **block_dinfo,
>> + struct DirtyRateConfig config,
>> + int *block_index)
>> +{
>> +struct RamblockDirtyInfo *info = NULL;
>> +struct RamblockDirtyInfo *dinfo = NULL;
>> +RAMBlock *block = NULL;
>> +int index = 0;
>> +
>> +RAMBLOCK_FOREACH_MIGRATABLE(block) {
>> +dinfo = alloc_ramblock_dirty_info(, dinfo);
> 
> Here for every migratable block, you call 'alloc_ramblock_dirty_info'.
> This also complicates the 'alloc_ramblock_dirty_info' itself as:

Re: Moving to C11? (was Re: Redefinition of typedefs (C11 feature))

2020-09-12 Thread Eduardo Habkost
On Sat, Sep 12, 2020 at 08:45:19AM +0200, Thomas Huth wrote:
> On 11/09/2020 22.06, Eduardo Habkost wrote:
> > On Fri, Sep 11, 2020 at 08:06:10PM +0100, Peter Maydell wrote:
> >> On Fri, 11 Sep 2020 at 19:49, Eduardo Habkost  wrote:
> >>>
> >>> I'm wondering: do our supported build host platforms all include
> >>> compilers that are new enough to let us redefine typedefs?
> >>>
> >>> The ability to redefine typedefs is a C11 feature which would be
> >>> very useful for simplifying our QOM boilerplate code.  The
> >>> feature is supported by GCC since 2011 (v4.6.0)[1], and by clang
> >>> since 2012 (v3.1)[2].
> >>
> >> In configure we mandate either GCC v4.8 or better, or
> >> clang v3.4 or better, or XCode Clang v5.1 or better
> >> (Apple uses a different version numbering setup to upstream).
> >> So you should probably double-check that that xcode clang has
> >> what you want, but it looks like we're good to go otherwise.
> > 
> > Can anybody confirm if the following is accurate?
> > 
> > https://gist.github.com/yamaya/2924292#file-xcode-clang-vers-L67
> > # Xcode 5.1 (5B130a)
> > Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
> > Target: x86_64-apple-darwin13.1.0
> > Thread model: posix
> > 
> > If we know we have GCC 4.8+ or clang 3.4+, can we move to C11 and
> > start using -std=gnu11?
> 
> You don't have to switch to gnu11, redefintions of typedefs are already
> fine in gnu99, they are a gnu extension there to the c99 standard.
> 
> See also:
> https://git.qemu.org/?p=qemu.git;a=commitdiff;h=7be41675f7cb16b
> 
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg585581.html

They still trigger a warning with gnu99 on clang:

$ clang --version
clang version 10.0.0 (Fedora 10.0.0-2.fc32)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ cat test.c
typedef struct A A;
typedef struct A A;
$ clang -std=gnu11 -c test.c
$ clang -std=gnu99 -c test.c
test.c:2:18: warning: redefinition of typedef 'A' is a C11 feature 
[-Wtypedef-redefinition]
typedef struct A A;
 ^
test.c:1:18: note: previous definition is here
typedef struct A A;
 ^
1 warning generated.
$ 

-- 
Eduardo




[PATCH v3 4/6] migration/tls: extract cleanup function for common-use

2020-09-12 Thread Chuan Zheng
multifd channel cleanup is need if multifd handshake failed,
let's extract it.

Signed-off-by: Chuan Zheng 
Signed-off-by: Yan Jin 
Reviewed-by: Daniel P. Berrangé 
---
 migration/multifd.c | 34 ++
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/migration/multifd.c b/migration/multifd.c
index 3e41d9e..fe08911 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -720,6 +720,23 @@ out:
 return NULL;
 }
 
+static void multifd_new_send_channel_cleanup(MultiFDSendParams *p,
+ QIOChannel *ioc, Error *err)
+{
+ migrate_set_error(migrate_get_current(), err);
+ /* Error happen, we need to tell who pay attention to me */
+ qemu_sem_post(_send_state->channels_ready);
+ qemu_sem_post(>sem_sync);
+ /*
+  * Although multifd_send_thread is not created, but main migration
+  * thread neet to judge whether it is running, so we need to mark
+  * its status.
+  */
+ p->quit = true;
+ object_unref(OBJECT(ioc));
+ error_free(err);
+}
+
 static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
 {
 MultiFDSendParams *p = opaque;
@@ -728,25 +745,18 @@ static void multifd_new_send_channel_async(QIOTask *task, 
gpointer opaque)
 
 trace_multifd_new_send_channel_async(p->id);
 if (qio_task_propagate_error(task, _err)) {
-migrate_set_error(migrate_get_current(), local_err);
-/* Error happen, we need to tell who pay attention to me */
-qemu_sem_post(_send_state->channels_ready);
-qemu_sem_post(>sem_sync);
-/*
- * Although multifd_send_thread is not created, but main migration
- * thread neet to judge whether it is running, so we need to mark
- * its status.
- */
-p->quit = true;
-object_unref(OBJECT(sioc));
-error_free(local_err);
+goto cleanup;
 } else {
 p->c = QIO_CHANNEL(sioc);
 qio_channel_set_delay(p->c, false);
 p->running = true;
 qemu_thread_create(>thread, p->name, multifd_send_thread, p,
QEMU_THREAD_JOINABLE);
+return;
 }
+
+cleanup:
+multifd_new_send_channel_cleanup(p, sioc, local_err);
 }
 
 int multifd_save_setup(Error **errp)
-- 
1.8.3.1




[PATCH v3 1/6] migration/tls: save hostname into MigrationState

2020-09-12 Thread Chuan Zheng
hostname is need in multifd-tls, save hostname into MigrationState.

Signed-off-by: Chuan Zheng 
Signed-off-by: Yan Jin 
---
 migration/channel.c   | 6 ++
 migration/migration.c | 1 +
 migration/migration.h | 5 +
 3 files changed, 12 insertions(+)

diff --git a/migration/channel.c b/migration/channel.c
index 20e4c8e..0e4104a 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -66,6 +66,11 @@ void migration_channel_connect(MigrationState *s,
 trace_migration_set_outgoing_channel(
 ioc, object_get_typename(OBJECT(ioc)), hostname, error);
 
+/* Save hostname into MigrationState for handshake */
+if (hostname) {
+s->hostname = g_strdup(hostname);
+}
+
 if (!error) {
 if (s->parameters.tls_creds &&
 *s->parameters.tls_creds &&
@@ -90,5 +95,6 @@ void migration_channel_connect(MigrationState *s,
 }
 }
 migrate_fd_connect(s, error);
+g_free(s->hostname);
 error_free(error);
 }
diff --git a/migration/migration.c b/migration/migration.c
index 58a5452..e20b778 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1883,6 +1883,7 @@ void migrate_init(MigrationState *s)
 s->migration_thread_running = false;
 error_free(s->error);
 s->error = NULL;
+s->hostname = NULL;
 
 migrate_set_state(>state, MIGRATION_STATUS_NONE, 
MIGRATION_STATUS_SETUP);
 
diff --git a/migration/migration.h b/migration/migration.h
index bdc7450..bc96322 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -259,6 +259,11 @@ struct MigrationState
  * (which is in 4M chunk).
  */
 uint8_t clear_bitmap_shift;
+
+/*
+ * This save hostname when out-going migration starts
+ */
+char *hostname;
 };
 
 void migrate_set_state(int *state, int old_state, int new_state);
-- 
1.8.3.1




[PATCH v3 6/6] migration/tls: add trace points for multifd-tls

2020-09-12 Thread Chuan Zheng
add trace points for multifd-tls for debug.

Signed-off-by: Chuan Zheng 
Signed-off-by: Yan Jin 
---
 migration/multifd.c| 10 +-
 migration/trace-events |  4 
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/migration/multifd.c b/migration/multifd.c
index 8aea4e0..0760502 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -732,7 +732,11 @@ static void multifd_tls_outgoing_handshake(QIOTask *task,
 QIOChannel *ioc = QIO_CHANNEL(qio_task_get_source(task));
 Error *err = NULL;
 
-qio_task_propagate_error(task, );
+if (qio_task_propagate_error(task, )) {
+trace_multifd_tls_outgoing_handshake_error(ioc, error_get_pretty(err));
+} else {
+trace_multifd_tls_outgoing_handshake_complete(ioc);
+}
 multifd_channel_connect(p, ioc, err);
 }
 
@@ -749,6 +753,7 @@ static void multifd_tls_channel_connect(MultiFDSendParams 
*p,
 return;
 }
 
+trace_multifd_tls_outgoing_handshake_start(ioc, tioc, hostname);
 qio_channel_set_name(QIO_CHANNEL(tioc), "multifd-tls-outgoing");
 qio_channel_tls_handshake(tioc,
   multifd_tls_outgoing_handshake,
@@ -764,6 +769,9 @@ static bool multifd_channel_connect(MultiFDSendParams *p,
 {
 MigrationState *s = p->s;
 
+trace_multifd_set_outgoing_channel(
+ioc, object_get_typename(OBJECT(ioc)), s->hostname, error);
+
 if (!error) {
 if (s->parameters.tls_creds &&
 *s->parameters.tls_creds &&
diff --git a/migration/trace-events b/migration/trace-events
index 7ba2fa6..faf52a8 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -129,6 +129,10 @@ multifd_send_sync_main_wait(uint8_t id) "channel %d"
 multifd_send_terminate_threads(bool error) "error %d"
 multifd_send_thread_end(uint8_t id, uint64_t packets, uint64_t pages) "channel 
%d packets %" PRIu64 " pages %"  PRIu64
 multifd_send_thread_start(uint8_t id) "%d"
+multifd_tls_outgoing_handshake_start(void *ioc, void *tioc, const char 
*hostname) "ioc=%p tioc=%p hostname=%s"
+multifd_tls_outgoing_handshake_error(void *ioc, const char *err) "ioc=%p 
err=%s"
+multifd_tls_outgoing_handshake_complete(void *ioc, void) "ioc=%p"
+multifd_set_outgoing_channel(void *ioc, const char *ioctype, const char 
*hostname, void *err)  "ioc=%p ioctype=%s hostname=%s err=%p"
 
 # migration.c
 await_return_path_close_on_source_close(void) ""
-- 
1.8.3.1




[PATCH v3 2/6] migration/tls: extract migration_tls_client_create for common-use

2020-09-12 Thread Chuan Zheng
migration_tls_client_create will be used in multifd-tls, let's
extract it.

Signed-off-by: Chuan Zheng 
Signed-off-by: Yan Jin 
Reviewed-by: Daniel P. Berrangé 
---
 migration/tls.c | 26 ++
 migration/tls.h |  6 ++
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/migration/tls.c b/migration/tls.c
index 7a02ec8..186be8a 100644
--- a/migration/tls.c
+++ b/migration/tls.c
@@ -22,7 +22,6 @@
 #include "channel.h"
 #include "migration.h"
 #include "tls.h"
-#include "io/channel-tls.h"
 #include "crypto/tlscreds.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
@@ -125,11 +124,10 @@ static void migration_tls_outgoing_handshake(QIOTask 
*task,
 object_unref(OBJECT(ioc));
 }
 
-
-void migration_tls_channel_connect(MigrationState *s,
-   QIOChannel *ioc,
-   const char *hostname,
-   Error **errp)
+QIOChannelTLS *migration_tls_client_create(MigrationState *s,
+   QIOChannel *ioc,
+   const char *hostname,
+   Error **errp)
 {
 QCryptoTLSCreds *creds;
 QIOChannelTLS *tioc;
@@ -137,7 +135,7 @@ void migration_tls_channel_connect(MigrationState *s,
 creds = migration_tls_get_creds(
 s, QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, errp);
 if (!creds) {
-return;
+return NULL;
 }
 
 if (s->parameters.tls_hostname && *s->parameters.tls_hostname) {
@@ -145,11 +143,23 @@ void migration_tls_channel_connect(MigrationState *s,
 }
 if (!hostname) {
 error_setg(errp, "No hostname available for TLS");
-return;
+return NULL;
 }
 
 tioc = qio_channel_tls_new_client(
 ioc, creds, hostname, errp);
+
+return tioc;
+}
+
+void migration_tls_channel_connect(MigrationState *s,
+   QIOChannel *ioc,
+   const char *hostname,
+   Error **errp)
+{
+QIOChannelTLS *tioc;
+
+tioc = migration_tls_client_create(s, ioc, hostname, errp);
 if (!tioc) {
 return;
 }
diff --git a/migration/tls.h b/migration/tls.h
index cdd7000..0cfbe36 100644
--- a/migration/tls.h
+++ b/migration/tls.h
@@ -22,11 +22,17 @@
 #define QEMU_MIGRATION_TLS_H
 
 #include "io/channel.h"
+#include "io/channel-tls.h"
 
 void migration_tls_channel_process_incoming(MigrationState *s,
 QIOChannel *ioc,
 Error **errp);
 
+QIOChannelTLS *migration_tls_client_create(MigrationState *s,
+   QIOChannel *ioc,
+   const char *hostname,
+   Error **errp);
+
 void migration_tls_channel_connect(MigrationState *s,
QIOChannel *ioc,
const char *hostname,
-- 
1.8.3.1




[PATCH v3 5/6] migration/tls: add support for multifd tls-handshake

2020-09-12 Thread Chuan Zheng
Similar like migration main thread, we need to do handshake
for each multifd thread.

Signed-off-by: Chuan Zheng 
Signed-off-by: Yan Jin 
Reviewed-by: Daniel P. Berrangé 
---
 migration/multifd.c | 77 +++--
 1 file changed, 75 insertions(+), 2 deletions(-)

diff --git a/migration/multifd.c b/migration/multifd.c
index fe08911..8aea4e0 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -20,6 +20,7 @@
 #include "ram.h"
 #include "migration.h"
 #include "socket.h"
+#include "tls.h"
 #include "qemu-file.h"
 #include "trace.h"
 #include "multifd.h"
@@ -720,6 +721,77 @@ out:
 return NULL;
 }
 
+static bool multifd_channel_connect(MultiFDSendParams *p,
+QIOChannel *ioc,
+Error *error);
+
+static void multifd_tls_outgoing_handshake(QIOTask *task,
+   gpointer opaque)
+{
+MultiFDSendParams *p = opaque;
+QIOChannel *ioc = QIO_CHANNEL(qio_task_get_source(task));
+Error *err = NULL;
+
+qio_task_propagate_error(task, );
+multifd_channel_connect(p, ioc, err);
+}
+
+static void multifd_tls_channel_connect(MultiFDSendParams *p,
+QIOChannel *ioc,
+Error **errp)
+{
+MigrationState *s = p->s;
+const char *hostname = p->tls_hostname;
+QIOChannelTLS *tioc;
+
+tioc = migration_tls_client_create(s, ioc, hostname, errp);
+if (!tioc) {
+return;
+}
+
+qio_channel_set_name(QIO_CHANNEL(tioc), "multifd-tls-outgoing");
+qio_channel_tls_handshake(tioc,
+  multifd_tls_outgoing_handshake,
+  p,
+  NULL,
+  NULL);
+
+}
+
+static bool multifd_channel_connect(MultiFDSendParams *p,
+QIOChannel *ioc,
+Error *error)
+{
+MigrationState *s = p->s;
+
+if (!error) {
+if (s->parameters.tls_creds &&
+*s->parameters.tls_creds &&
+!object_dynamic_cast(OBJECT(ioc),
+ TYPE_QIO_CHANNEL_TLS)) {
+multifd_tls_channel_connect(p, ioc, );
+if (!error) {
+/*
+ * tls_channel_connect will call back to this
+ * function after the TLS handshake,
+ * so we mustn't call multifd_send_thread until then
+ */
+return false;
+} else {
+return true;
+}
+} else {
+/* update for tls qio channel */
+p->c = ioc;
+qemu_thread_create(>thread, p->name, multifd_send_thread, p,
+   QEMU_THREAD_JOINABLE);
+   }
+   return false;
+}
+
+return true;
+}
+
 static void multifd_new_send_channel_cleanup(MultiFDSendParams *p,
  QIOChannel *ioc, Error *err)
 {
@@ -750,8 +822,9 @@ static void multifd_new_send_channel_async(QIOTask *task, 
gpointer opaque)
 p->c = QIO_CHANNEL(sioc);
 qio_channel_set_delay(p->c, false);
 p->running = true;
-qemu_thread_create(>thread, p->name, multifd_send_thread, p,
-   QEMU_THREAD_JOINABLE);
+if (multifd_channel_connect(p, sioc, local_err)) {
+goto cleanup;
+}
 return;
 }
 
-- 
1.8.3.1




[PATCH v3 0/6] *** Add Multifd support for TLS migration ***

2020-09-12 Thread Chuan Zheng
v2 -> v3:
rebase patches on master

v1 -> v2:
fix memoryleak of MigrationState hostname
add tls_hostname into MultiFDSendParams for handshake use
fix function alignment
squash Patch005 and Patch006
add ioc into trace-events

TLS migration could easily reach bottleneck of cpu because of encryption
and decryption in migration thread.
In our test, the tls migration could only reach 300MB/s under bandwidth
of 500MB/s.

Inspired by multifd, we add multifd support for tls migration to make fully
use of given net bandwidth at the cost of multi-cpus and could reduce
at most of 100% migration time with 4U16G test vm.

Evaluate migration time of migration vm.
The VM specifications for migration are as follows:
- VM use 4-K page;
- the number of VCPU is 4;
- the total memory is 16Gigabit;
- use 'mempress' tool to pressurize VM(mempress 4096 100);
- migration flag is 73755 (8219 + 65536 (TLS)) vs 204827 (8219 + 65536 (TLS) + 
131072(Multifd))

+++
|  | TLS   |  MultiFD + TLS (2 channel) 
   |
t---
| mempress 1024 120|   25.035s |   15.067s  
   |

| mempress 1024 200|   48.798s |   25.334s  
   |


Chuan Zheng (6):
  migration/tls: save hostname into MigrationState
  migration/tls: extract migration_tls_client_create for common-use
  migration/tls: add MigrationState and tls_hostname into
MultiFDSendParams
  migration/tls: extract cleanup function for common-use
  migration/tls: add support for multifd tls-handshake
  migration/tls: add trace points for multifd-tls

 migration/channel.c|   6 +++
 migration/migration.c  |   1 +
 migration/migration.h  |   5 ++
 migration/multifd.c| 124 +++--
 migration/multifd.h|   4 ++
 migration/tls.c|  26 +++
 migration/tls.h|   6 +++
 migration/trace-events |   4 ++
 8 files changed, 154 insertions(+), 22 deletions(-)

-- 
1.8.3.1




[PATCH v3 3/6] migration/tls: add MigrationState and tls_hostname into MultiFDSendParams

2020-09-12 Thread Chuan Zheng
MigrationState is need for tls session build and tls hostname is need
for tls handshake, add both MigrationState and tls_hostname
into MultiFDSendParams.

Signed-off-by: Chuan Zheng 
Signed-off-by: Yan Jin 
---
 migration/multifd.c | 5 +
 migration/multifd.h | 4 
 2 files changed, 9 insertions(+)

diff --git a/migration/multifd.c b/migration/multifd.c
index d044120..3e41d9e 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -543,11 +543,14 @@ void multifd_save_cleanup(void)
 
 socket_send_channel_destroy(p->c);
 p->c = NULL;
+p->s = NULL;
 qemu_mutex_destroy(>mutex);
 qemu_sem_destroy(>sem);
 qemu_sem_destroy(>sem_sync);
 g_free(p->name);
 p->name = NULL;
+g_free(p->tls_hostname);
+p->tls_hostname = NULL;
 multifd_pages_clear(p->pages);
 p->pages = NULL;
 p->packet_len = 0;
@@ -779,6 +782,8 @@ int multifd_save_setup(Error **errp)
 p->packet->magic = cpu_to_be32(MULTIFD_MAGIC);
 p->packet->version = cpu_to_be32(MULTIFD_VERSION);
 p->name = g_strdup_printf("multifdsend_%d", i);
+p->s = migrate_get_current();
+p->tls_hostname = g_strdup(p->s->hostname);
 socket_send_channel_create(multifd_new_send_channel_async, p);
 }
 
diff --git a/migration/multifd.h b/migration/multifd.h
index 448a03d..2b400e7 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -66,11 +66,15 @@ typedef struct {
 } MultiFDPages_t;
 
 typedef struct {
+/* Migration State */
+MigrationState *s;
 /* this fields are not changed once the thread is created */
 /* channel number */
 uint8_t id;
 /* channel thread name */
 char *name;
+/* tls hostname */
+char *tls_hostname;
 /* channel thread id */
 QemuThread thread;
 /* communication channel */
-- 
1.8.3.1




[Bug 1895363] Re: borland IDEs double up cursor key presses (need timing on PS2 port input)

2020-09-12 Thread Michael Slade
Just found the complete conversation regarding the abovementioned patch:

https://lists.nongnu.org/archive/html/qemu-devel/2009-08/msg01182.html

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1895363

Title:
  borland IDEs double up cursor key presses (need timing on PS2 port
  input)

Status in QEMU:
  New

Bug description:
  Most DOS-era IDEs from Borland (I have tried Borland C++ 2.0, Borland
  C++ 3.1 and Turbo Pascal 7.1) exhibit strange responses to the
  keyboard.  Cursor keys are registered twice, so each press of a cursor
  key causes the cursor to move twice. Also the other keys occasionally
  are missed or duplicated.

  From an internet search, the problem appears to be this.  These
  programs read the PS2 input register multiple times per incoming byte,
  on the assumption that the byte will remain there for at least a few
  hundred microseconds, before the next byte (if any) appears there.
  qemu treats a read of the register by the guest as an acknowledgement
  of the incoming byte and puts the next byte into the register
  immediately, thus breaking the programs that expect each successive
  byte to stay in place for a while.

  The obvious solution is to use a timer to advance through the queued
  bytes.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1895363/+subscriptions



[REPORT] Nightly Performance Tests - Saturday, September 12, 2020

2020-09-12 Thread Ahmed Karaman

Host CPU : Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Host Memory  : 15.49 GB

Start Time (UTC) : 2020-09-12 23:30:02
End Time (UTC)   : 2020-09-13 00:10:47
Execution Time   : 0:40:45.297747

Status   : SUCCESS

Note:
Changes denoted by '-' are less than 0.01%.


SUMMARY REPORT - COMMIT c47edb8d

AVERAGE RESULTS

Target  Instructions  Latest  v5.1.0
--    --  --
aarch642 158 533 305   - +1.704%
alpha  1 914 937 425   - +3.522%
arm8 076 539 818   - +2.308%
hppa   4 261 680 617   - +3.163%
m68k   2 690 300 478   - +7.134%
mips   1 861 900 008   - +2.484%
mipsel 2 008 241 691   - +2.676%
mips64 1 918 606 346   - +2.816%
mips64el   2 051 547 798   - +3.025%
ppc2 480 190 796   -  +3.11%
ppc64  2 576 721 225   - +3.143%
ppc64le2 558 836 762   - +3.172%
riscv641 406 697 771   - +2.649%
s390x  3 158 142 233   - +3.119%
sh42 364 602 125   - +3.341%
sparc643 318 709 670   - +3.855%
x86_64 1 775 943 554   - +2.167%


   DETAILED RESULTS

Test Program: dijkstra_double

Target  Instructions  Latest  v5.1.0
--    --  --
aarch643 062 765 352   -  +1.43%
alpha  3 191 834 824   - +3.695%
arm   16 357 303 898   - +2.348%
hppa   7 228 395 763   - +3.086%
m68k   4 294 066 146   - +9.693%
mips   3 051 312 576   - +2.423%
mipsel 3 231 549 566   -  +2.87%
mips64 3 245 796 511   - +2.595%
mips64el   3 414 208 805   - +3.021%
ppc4 914 573 969   - +4.741%
ppc64  5 098 162 490   - +4.565%
ppc64le5 082 404 015   -  +4.58%
riscv642 192 282 536   - +1.955%
s390x  4 584 590 861   - +2.898%
sh43 949 193 845   - +3.468%
sparc644 586 114 994   - +4.235%
x86_64 2 484 250 046   - +1.757%


Test Program: dijkstra_int32

Target  Instructions  Latest  v5.1.0
--    --  --
aarch642 210 379 662   - +1.502%
alpha  1 494 102 952   - +2.148%
arm8 263 056 483   - +2.667%
hppa   5 207 314 014   - +3.047%
m68k   1 725 886 877   - +2.528%
mips   1 495 105 629   - +1.484%
mipsel 1 497 169 390   - +1.481%
mips64 1 715 399 279   - +1.892%
mips64el   1 695 203 817   - +1.909%
ppc2 014 616 952   - +1.822%
ppc64  2 206 274 942   - +2.139%
ppc64le2 197 983 658   - +2.145%
riscv641 354 893 842   - +2.394%
s390x  2 916 099 097   - +1.236%
sh41 990 686 479   - +2.677%
sparc642 874 151 831   - +3.827%
x86_64 1 554 140 253   -  +2.13%


Test Program: matmult_double

Target  Instructions  Latest  v5.1.0
--    --  --
aarch641 412 439 264   - +0.313%
alpha  3 233 958 824   - +7.472%
arm8 545 314 889   -  +1.09%
hppa   3 483 524 691   - +4.466%
m68k   3 919 118 621   -+18.433%
mips   2 344 642 485   - +4.085%
mipsel 3 329 922 487   - +5.178%
mips64 2 359 012 166   - +4.074%

[Bug 1895363] Re: borland IDEs double up cursor key presses (need timing on PS2 port input)

2020-09-12 Thread Michael Slade
This virtualbox bug talks about the same thing, and also mentions qemu:

https://www.virtualbox.org/ticket/58

One of the people in the conversation created a patch for qemu which
wasn't accepted:

http://qemu.11.n7.nabble.com/PATCH-Fix-for-DOS-keyboard-problems-
td114076.html


** Bug watch added: Virtualbox Trac #58
   http://www.virtualbox.org/ticket/58

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1895363

Title:
  borland IDEs double up cursor key presses (need timing on PS2 port
  input)

Status in QEMU:
  New

Bug description:
  Most DOS-era IDEs from Borland (I have tried Borland C++ 2.0, Borland
  C++ 3.1 and Turbo Pascal 7.1) exhibit strange responses to the
  keyboard.  Cursor keys are registered twice, so each press of a cursor
  key causes the cursor to move twice. Also the other keys occasionally
  are missed or duplicated.

  From an internet search, the problem appears to be this.  These
  programs read the PS2 input register multiple times per incoming byte,
  on the assumption that the byte will remain there for at least a few
  hundred microseconds, before the next byte (if any) appears there.
  qemu treats a read of the register by the guest as an acknowledgement
  of the incoming byte and puts the next byte into the register
  immediately, thus breaking the programs that expect each successive
  byte to stay in place for a while.

  The obvious solution is to use a timer to advance through the queued
  bytes.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1895363/+subscriptions



Re: [PATCH v2 00/15] hw/block/nvme: Support Namespace Types and Zoned Namespace Command Set

2020-09-12 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200912225430.1772-1-dmitry.fomic...@wdc.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

N/A. Internal error while reading log file



The full log is available at
http://patchew.org/logs/20200912225430.1772-1-dmitry.fomic...@wdc.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH v8 00/27] W32, W64 msys2/mingw patches

2020-09-12 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200912224431.1428-1-luoyongg...@gmail.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

N/A. Internal error while reading log file



The full log is available at
http://patchew.org/logs/20200912224431.1428-1-luoyongg...@gmail.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[PATCH v2 10/15] hw/block/nvme: Support Zoned Namespace Command Set

2020-09-12 Thread Dmitry Fomichev
The emulation code has been changed to advertise NVM Command Set when
"zoned" device property is not set (default) and Zoned Namespace
Command Set otherwise.

Handlers for three new NVMe commands introduced in Zoned Namespace
Command Set specification are added, namely for Zone Management
Receive, Zone Management Send and Zone Append.

Device initialization code has been extended to create a proper
configuration for zoned operation using device properties.

Read/Write command handler is modified to only allow writes at the
write pointer if the namespace is zoned. For Zone Append command,
writes implicitly happen at the write pointer and the starting write
pointer value is returned as the result of the command. Write Zeroes
handler is modified to add zoned checks that are identical to those
done as a part of Write flow.

The code to support for Zone Descriptor Extensions is not included in
this commit and ZDES 0 is always reported. A later commit in this
series will add ZDE support.

This commit doesn't yet include checks for active and open zone
limits. It is assumed that there are no limits on either active or
open zones.

Signed-off-by: Niklas Cassel 
Signed-off-by: Hans Holmberg 
Signed-off-by: Ajay Joshi 
Signed-off-by: Chaitanya Kulkarni 
Signed-off-by: Matias Bjorling 
Signed-off-by: Aravind Ramesh 
Signed-off-by: Shin'ichiro Kawasaki 
Signed-off-by: Adam Manzanares 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c | 995 ++--
 1 file changed, 966 insertions(+), 29 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 6dd6bf9183..1b0e06002c 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -53,6 +53,7 @@
 #include "qemu/osdep.h"
 #include "qemu/units.h"
 #include "qemu/error-report.h"
+#include "crypto/random.h"
 #include "hw/block/block.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pci.h"
@@ -125,6 +126,98 @@ static uint16_t nvme_sqid(NvmeRequest *req)
 return le16_to_cpu(req->sq->sqid);
 }
 
+/*
+ * Add a zone to the tail of a zone list.
+ */
+static void nvme_add_zone_tail(NvmeCtrl *n, NvmeNamespace *ns, NvmeZoneList 
*zl,
+   NvmeZone *zone)
+{
+uint32_t idx = (uint32_t)(zone - ns->zone_array);
+
+assert(nvme_zone_not_in_list(zone));
+
+if (!zl->size) {
+zl->head = zl->tail = idx;
+zone->next = zone->prev = NVME_ZONE_LIST_NIL;
+} else {
+ns->zone_array[zl->tail].next = idx;
+zone->prev = zl->tail;
+zone->next = NVME_ZONE_LIST_NIL;
+zl->tail = idx;
+}
+zl->size++;
+}
+
+/*
+ * Remove a zone from a zone list. The zone must be linked in the list.
+ */
+static void nvme_remove_zone(NvmeCtrl *n, NvmeNamespace *ns, NvmeZoneList *zl,
+ NvmeZone *zone)
+{
+uint32_t idx = (uint32_t)(zone - ns->zone_array);
+
+assert(!nvme_zone_not_in_list(zone));
+
+--zl->size;
+if (zl->size == 0) {
+zl->head = NVME_ZONE_LIST_NIL;
+zl->tail = NVME_ZONE_LIST_NIL;
+} else if (idx == zl->head) {
+zl->head = zone->next;
+ns->zone_array[zl->head].prev = NVME_ZONE_LIST_NIL;
+} else if (idx == zl->tail) {
+zl->tail = zone->prev;
+ns->zone_array[zl->tail].next = NVME_ZONE_LIST_NIL;
+} else {
+ns->zone_array[zone->next].prev = zone->prev;
+ns->zone_array[zone->prev].next = zone->next;
+}
+
+zone->prev = zone->next = 0;
+}
+
+static void nvme_assign_zone_state(NvmeCtrl *n, NvmeNamespace *ns,
+   NvmeZone *zone, uint8_t state)
+{
+if (!nvme_zone_not_in_list(zone)) {
+switch (nvme_get_zone_state(zone)) {
+case NVME_ZONE_STATE_EXPLICITLY_OPEN:
+nvme_remove_zone(n, ns, ns->exp_open_zones, zone);
+break;
+case NVME_ZONE_STATE_IMPLICITLY_OPEN:
+nvme_remove_zone(n, ns, ns->imp_open_zones, zone);
+break;
+case NVME_ZONE_STATE_CLOSED:
+nvme_remove_zone(n, ns, ns->closed_zones, zone);
+break;
+case NVME_ZONE_STATE_FULL:
+nvme_remove_zone(n, ns, ns->full_zones, zone);
+}
+   }
+
+nvme_set_zone_state(zone, state);
+
+switch (state) {
+case NVME_ZONE_STATE_EXPLICITLY_OPEN:
+nvme_add_zone_tail(n, ns, ns->exp_open_zones, zone);
+break;
+case NVME_ZONE_STATE_IMPLICITLY_OPEN:
+nvme_add_zone_tail(n, ns, ns->imp_open_zones, zone);
+break;
+case NVME_ZONE_STATE_CLOSED:
+nvme_add_zone_tail(n, ns, ns->closed_zones, zone);
+break;
+case NVME_ZONE_STATE_FULL:
+nvme_add_zone_tail(n, ns, ns->full_zones, zone);
+break;
+default:
+zone->d.za = 0;
+/* fall through */
+case NVME_ZONE_STATE_READ_ONLY:
+zone->tstamp = 0;
+}
+}
+
 static bool nvme_addr_is_cmb(NvmeCtrl *n, hwaddr addr)
 {
 hwaddr low = n->ctrl_mem.addr;
@@ -483,6 +576,33 @@ static void nvme_post_cqes(void *opaque)
  

[PATCH v2 14/15] hw/block/nvme: Use zone metadata file for persistence

2020-09-12 Thread Dmitry Fomichev
A ZNS drive that is emulated by this module is currently initialized
with all zones Empty upon startup. However, actual ZNS SSDs save the
state and condition of all zones in their internal NVRAM in the event
of power loss. When such a drive is powered up again, it closes or
finishes all zones that were open at the moment of shutdown. Besides
that, the write pointer position as well as the state and condition
of all zones is preserved across power-downs.

This commit adds the capability to have a persistent zone metadata
to the device. The new optional module property, "zone_file",
is introduced. If added to the command line, this property specifies
the name of the file that stores the zone metadata. If "zone_file" is
omitted, the device will be initialized with all zones empty, the same
as before.

If zone metadata is configured to be persistent, then zone descriptor
extensions also persist across controller shutdowns.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c | 370 +---
 hw/block/nvme.h |  37 +
 2 files changed, 386 insertions(+), 21 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index f0a03bea75..3e8e6e1472 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -111,6 +111,8 @@ static const uint32_t nvme_feature_cap[NVME_FID_MAX] = {
 };
 
 static void nvme_process_sq(void *opaque);
+static void nvme_sync_zone_file(NvmeCtrl *n, NvmeNamespace *ns,
+NvmeZone *zone, int len);
 
 static uint16_t nvme_cid(NvmeRequest *req)
 {
@@ -146,6 +148,7 @@ static void nvme_add_zone_tail(NvmeCtrl *n, NvmeNamespace 
*ns, NvmeZoneList *zl,
 zl->tail = idx;
 }
 zl->size++;
+nvme_set_zone_meta_dirty(n, ns, true);
 }
 
 /*
@@ -162,12 +165,15 @@ static void nvme_remove_zone(NvmeCtrl *n, NvmeNamespace 
*ns, NvmeZoneList *zl,
 if (zl->size == 0) {
 zl->head = NVME_ZONE_LIST_NIL;
 zl->tail = NVME_ZONE_LIST_NIL;
+nvme_set_zone_meta_dirty(n, ns, true);
 } else if (idx == zl->head) {
 zl->head = zone->next;
 ns->zone_array[zl->head].prev = NVME_ZONE_LIST_NIL;
+nvme_set_zone_meta_dirty(n, ns, true);
 } else if (idx == zl->tail) {
 zl->tail = zone->prev;
 ns->zone_array[zl->tail].next = NVME_ZONE_LIST_NIL;
+nvme_set_zone_meta_dirty(n, ns, true);
 } else {
 ns->zone_array[zone->next].prev = zone->prev;
 ns->zone_array[zone->prev].next = zone->next;
@@ -194,6 +200,7 @@ static NvmeZone *nvme_remove_zone_head(NvmeCtrl *n, 
NvmeNamespace *ns,
 ns->zone_array[zl->head].prev = NVME_ZONE_LIST_NIL;
 }
 zone->prev = zone->next = 0;
+nvme_set_zone_meta_dirty(n, ns, true);
 }
 
 return zone;
@@ -297,6 +304,7 @@ static void nvme_assign_zone_state(NvmeCtrl *n, 
NvmeNamespace *ns,
 case NVME_ZONE_STATE_READ_ONLY:
 zone->tstamp = 0;
 }
+nvme_sync_zone_file(n, ns, zone, sizeof(NvmeZone));
 }
 
 static bool nvme_addr_is_cmb(NvmeCtrl *n, hwaddr addr)
@@ -3357,9 +3365,114 @@ static const MemoryRegionOps nvme_cmb_ops = {
 },
 };
 
-static int nvme_init_zone_meta(NvmeCtrl *n, NvmeNamespace *ns,
+static int nvme_validate_zone_file(NvmeCtrl *n, NvmeNamespace *ns,
+   uint64_t capacity)
+{
+NvmeZoneMeta *meta = ns->zone_meta;
+NvmeZone *zone = ns->zone_array;
+uint64_t start = 0, zone_size = n->zone_size;
+int i, n_imp_open = 0, n_exp_open = 0, n_closed = 0, n_full = 0;
+
+if (meta->magic != NVME_ZONE_META_MAGIC) {
+return 1;
+}
+if (meta->version != NVME_ZONE_META_VER) {
+return 2;
+}
+if (meta->zone_size != zone_size) {
+return 3;
+}
+if (meta->zone_capacity != n->zone_capacity) {
+return 4;
+}
+if (meta->nr_offline_zones != n->params.nr_offline_zones) {
+return 5;
+}
+if (meta->nr_rdonly_zones != n->params.nr_rdonly_zones) {
+return 6;
+}
+if (meta->lba_size != n->conf.logical_block_size) {
+return 7;
+}
+if (meta->zd_extension_size != n->params.zd_extension_size) {
+return 8;
+}
+
+for (i = 0; i < n->num_zones; i++, zone++) {
+if (start + zone_size > capacity) {
+zone_size = capacity - start;
+}
+if (zone->d.zt != NVME_ZONE_TYPE_SEQ_WRITE) {
+return 9;
+}
+if (zone->d.zcap != n->zone_capacity) {
+return 10;
+}
+if (zone->d.zslba != start) {
+return 11;
+}
+switch (nvme_get_zone_state(zone)) {
+case NVME_ZONE_STATE_EMPTY:
+case NVME_ZONE_STATE_OFFLINE:
+case NVME_ZONE_STATE_READ_ONLY:
+if (zone->d.wp != start) {
+return 12;
+}
+break;
+case NVME_ZONE_STATE_IMPLICITLY_OPEN:
+if (zone->d.wp < start ||
+zone->d.wp >= zone->d.zslba + zone->d.zcap) {
+  

[PATCH v2 09/15] hw/block/nvme: Define Zoned NS Command Set trace events

2020-09-12 Thread Dmitry Fomichev
The Zoned Namespace Command Set / Namespace Types implementation that
is being introduced in this series adds a good number of trace events.
Combine all tracepoint definitions into a separate patch to make
reviewing more convenient.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/trace-events | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index 2414dcbc79..53c7a2fd1f 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -90,6 +90,17 @@ pci_nvme_mmio_shutdown_cleared(void) "shutdown bit cleared"
 pci_nvme_cmd_supp_and_effects_log_read(void) "commands supported and effects 
log read"
 pci_nvme_css_nvm_cset_selected_by_host(uint32_t cc) "NVM command set selected 
by host, bar.cc=0x%"PRIx32""
 pci_nvme_css_all_csets_sel_by_host(uint32_t cc) "all supported command sets 
selected by host, bar.cc=0x%"PRIx32""
+pci_nvme_open_zone(uint64_t slba, uint32_t zone_idx, int all) "open zone, 
slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
+pci_nvme_close_zone(uint64_t slba, uint32_t zone_idx, int all) "close zone, 
slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
+pci_nvme_finish_zone(uint64_t slba, uint32_t zone_idx, int all) "finish zone, 
slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
+pci_nvme_reset_zone(uint64_t slba, uint32_t zone_idx, int all) "reset zone, 
slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
+pci_nvme_offline_zone(uint64_t slba, uint32_t zone_idx, int all) "offline 
zone, slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
+pci_nvme_set_descriptor_extension(uint64_t slba, uint32_t zone_idx) "set zone 
descriptor extension, slba=%"PRIu64", idx=%"PRIu32""
+pci_nvme_zd_extension_set(uint32_t zone_idx) "set descriptor extension for 
zone_idx=%"PRIu32""
+pci_nvme_power_on_close(uint32_t state, uint64_t slba) "zone state=%"PRIu32", 
slba=%"PRIu64" transitioned to Closed state"
+pci_nvme_power_on_reset(uint32_t state, uint64_t slba) "zone state=%"PRIu32", 
slba=%"PRIu64" transitioned to Empty state"
+pci_nvme_power_on_full(uint32_t state, uint64_t slba) "zone state=%"PRIu32", 
slba=%"PRIu64" transitioned to Full state"
+pci_nvme_mapped_zone_file(char *zfile_name, int ret) "mapped zone file %s, 
error %d"
 
 # nvme traces for error conditions
 pci_nvme_err_mdts(uint16_t cid, size_t len) "cid %"PRIu16" len %zu"
@@ -102,9 +113,23 @@ pci_nvme_err_invalid_ns(uint32_t ns, uint32_t limit) 
"invalid namespace %u not w
 pci_nvme_err_invalid_opc(uint8_t opc) "invalid opcode 0x%"PRIx8""
 pci_nvme_err_invalid_admin_opc(uint8_t opc) "invalid admin opcode 0x%"PRIx8""
 pci_nvme_err_invalid_lba_range(uint64_t start, uint64_t len, uint64_t limit) 
"Invalid LBA start=%"PRIu64" len=%"PRIu64" limit=%"PRIu64""
+pci_nvme_err_unaligned_zone_cmd(uint8_t action, uint64_t slba, uint64_t zslba) 
"unaligned zone op 0x%"PRIx32", got slba=%"PRIu64", zslba=%"PRIu64""
+pci_nvme_err_invalid_zone_state_transition(uint8_t state, uint8_t action, 
uint64_t slba, uint8_t attrs) "0x%"PRIx32"->0x%"PRIx32", slba=%"PRIu64", 
attrs=0x%"PRIx32""
+pci_nvme_err_write_not_at_wp(uint64_t slba, uint64_t zone, uint64_t wp) 
"writing at slba=%"PRIu64", zone=%"PRIu64", but wp=%"PRIu64""
+pci_nvme_err_append_not_at_start(uint64_t slba, uint64_t zone) "appending at 
slba=%"PRIu64", but zone=%"PRIu64""
+pci_nvme_err_zone_write_not_ok(uint64_t slba, uint32_t nlb, uint32_t status) 
"slba=%"PRIu64", nlb=%"PRIu32", status=0x%"PRIx16""
+pci_nvme_err_zone_read_not_ok(uint64_t slba, uint32_t nlb, uint32_t status) 
"slba=%"PRIu64", nlb=%"PRIu32", status=0x%"PRIx16""
+pci_nvme_err_append_too_large(uint64_t slba, uint32_t nlb, uint8_t zasl) 
"slba=%"PRIu64", nlb=%"PRIu32", zasl=%"PRIu8""
+pci_nvme_err_insuff_active_res(uint32_t max_active) "max_active=%"PRIu32" zone 
limit exceeded"
+pci_nvme_err_insuff_open_res(uint32_t max_open) "max_open=%"PRIu32" zone limit 
exceeded"
+pci_nvme_err_zone_file_invalid(int error) "validation error=%"PRIi32""
+pci_nvme_err_zd_extension_map_error(uint32_t zone_idx) "can't map descriptor 
extension for zone_idx=%"PRIu32""
+pci_nvme_err_invalid_changed_zone_list_offset(uint64_t ofs) "changed zone list 
log offset must be 0, got %"PRIu64""
+pci_nvme_err_invalid_changed_zone_list_len(uint32_t len) "changed zone list 
log size is 4096, got %"PRIu32""
 pci_nvme_err_invalid_effects_log_offset(uint64_t ofs) "commands supported and 
effects log offset must be 0, got %"PRIu64""
 pci_nvme_err_change_css_when_enabled(void) "changing CC.CSS while controller 
is enabled"
 pci_nvme_err_only_nvm_cmd_set_avail(void) "setting 110b CC.CSS, but only NVM 
command set is enabled"
+pci_nvme_err_only_zoned_cmd_set_avail(void) "setting 001b CC.CSS, but only 
ZONED+NVM command set is enabled"
 pci_nvme_err_invalid_iocsci(uint32_t idx) "unsupported command set combination 
index %"PRIu32""
 pci_nvme_err_invalid_del_sq(uint16_t qid) "invalid submission queue deletion, 
sid=%"PRIu16""
 pci_nvme_err_invalid_create_sq_cqid(uint16_t cqid) "failed creating submission 
queue, invalid 

[PATCH v2 06/15] hw/block/nvme: Add support for Namespace Types

2020-09-12 Thread Dmitry Fomichev
From: Niklas Cassel 

Namespace Types introduce a new command set, "I/O Command Sets",
that allows the host to retrieve the command sets associated with
a namespace. Introduce support for the command set and enable
detection for the NVM Command Set.

The new workflows for identify commands rely heavily on zero-filled
identify structs. E.g., certain CNS commands are defined to return
a zero-filled identify struct when an inactive namespace NSID
is supplied.

Add a helper function in order to avoid code duplication when
reporting zero-filled identify structures.

Signed-off-by: Niklas Cassel 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c | 208 +++-
 1 file changed, 188 insertions(+), 20 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 4bd88f4046..004f1c9578 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1153,6 +1153,19 @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeRequest 
*req)
 return NVME_SUCCESS;
 }
 
+static uint16_t nvme_rpt_empty_id_struct(NvmeCtrl *n, uint64_t prp1,
+ uint64_t prp2, NvmeRequest *req)
+{
+uint16_t status;
+
+status = nvme_map_prp(n, prp1, prp2, NVME_IDENTIFY_DATA_SIZE, req);
+if (status) {
+return status;
+}
+nvme_fill_data(>qsg, >iov, 0, 0);
+return NVME_SUCCESS;
+}
+
 static uint16_t nvme_identify_ctrl(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
@@ -1165,6 +1178,21 @@ static uint16_t nvme_identify_ctrl(NvmeCtrl *n, 
NvmeRequest *req)
 prp2, DMA_DIRECTION_FROM_DEVICE, req);
 }
 
+static uint16_t nvme_identify_ctrl_csi(NvmeCtrl *n, NvmeRequest *req)
+{
+NvmeIdentify *c = (NvmeIdentify *)>cmd;
+uint64_t prp1 = le64_to_cpu(c->prp1);
+uint64_t prp2 = le64_to_cpu(c->prp2);
+
+trace_pci_nvme_identify_ctrl_csi(c->csi);
+
+if (c->csi == NVME_CSI_NVM) {
+return nvme_rpt_empty_id_struct(n, prp1, prp2, req);
+}
+
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+
 static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeNamespace *ns;
@@ -1181,11 +1209,37 @@ static uint16_t nvme_identify_ns(NvmeCtrl *n, 
NvmeRequest *req)
 }
 
 ns = >namespaces[nsid - 1];
+assert(nsid == ns->nsid);
 
 return nvme_dma_prp(n, (uint8_t *)>id_ns, sizeof(ns->id_ns), prp1,
 prp2, DMA_DIRECTION_FROM_DEVICE, req);
 }
 
+static uint16_t nvme_identify_ns_csi(NvmeCtrl *n, NvmeRequest *req)
+{
+NvmeIdentify *c = (NvmeIdentify *)>cmd;
+NvmeNamespace *ns;
+uint32_t nsid = le32_to_cpu(c->nsid);
+uint64_t prp1 = le64_to_cpu(c->prp1);
+uint64_t prp2 = le64_to_cpu(c->prp2);
+
+trace_pci_nvme_identify_ns_csi(nsid, c->csi);
+
+if (unlikely(nsid == 0 || nsid > n->num_namespaces)) {
+trace_pci_nvme_err_invalid_ns(nsid, n->num_namespaces);
+return NVME_INVALID_NSID | NVME_DNR;
+}
+
+ns = >namespaces[nsid - 1];
+assert(nsid == ns->nsid);
+
+if (c->csi == NVME_CSI_NVM) {
+return nvme_rpt_empty_id_struct(n, prp1, prp2, req);
+}
+
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+
 static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
@@ -1225,23 +1279,51 @@ static uint16_t nvme_identify_nslist(NvmeCtrl *n, 
NvmeRequest *req)
 return ret;
 }
 
+static uint16_t nvme_identify_nslist_csi(NvmeCtrl *n, NvmeRequest *req)
+{
+NvmeIdentify *c = (NvmeIdentify *)>cmd;
+static const int data_len = NVME_IDENTIFY_DATA_SIZE;
+uint32_t min_nsid = le32_to_cpu(c->nsid);
+uint64_t prp1 = le64_to_cpu(c->prp1);
+uint64_t prp2 = le64_to_cpu(c->prp2);
+uint32_t *list;
+uint16_t ret;
+int i, j = 0;
+
+trace_pci_nvme_identify_nslist_csi(min_nsid, c->csi);
+
+if (c->csi != NVME_CSI_NVM) {
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+
+list = g_malloc0(data_len);
+for (i = 0; i < n->num_namespaces; i++) {
+if (i < min_nsid) {
+continue;
+}
+list[j++] = cpu_to_le32(i + 1);
+if (j == data_len / sizeof(uint32_t)) {
+break;
+}
+}
+ret = nvme_dma_prp(n, (uint8_t *)list, data_len, prp1, prp2,
+   DMA_DIRECTION_FROM_DEVICE, req);
+g_free(list);
+return ret;
+}
+
 static uint16_t nvme_identify_ns_descr_list(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
+NvmeNamespace *ns;
 uint32_t nsid = le32_to_cpu(c->nsid);
 uint64_t prp1 = le64_to_cpu(c->prp1);
 uint64_t prp2 = le64_to_cpu(c->prp2);
-
-uint8_t list[NVME_IDENTIFY_DATA_SIZE];
-
-struct data {
-struct {
-NvmeIdNsDescr hdr;
-uint8_t v[16];
-} uuid;
-};
-
-struct data *ns_descrs = (struct data *)list;
+void *buf_ptr;
+NvmeIdNsDescr *desc;
+static const int data_len = NVME_IDENTIFY_DATA_SIZE;
+uint8_t *buf;
+

[PATCH v2 12/15] hw/block/nvme: Support Zone Descriptor Extensions

2020-09-12 Thread Dmitry Fomichev
Zone Descriptor Extension is a label that can be assigned to a zone.
It can be set to an Empty zone and it stays assigned until the zone
is reset.

This commit adds a new optional module property, "zone_descr_ext_size".
Its value must be a multiple of 64 bytes. If this value is non-zero,
it becomes possible to assign extensions of that size to any Empty
zones. The default value for this property is 0, therefore setting
extensions is disabled by default.

Signed-off-by: Hans Holmberg 
Signed-off-by: Dmitry Fomichev 
Reviewed-by: Klaus Jensen 
---
 hw/block/nvme.c | 73 ++---
 hw/block/nvme.h |  8 ++
 2 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index df536fd736..ec7fade674 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1355,6 +1355,26 @@ static bool nvme_cond_offline_all(uint8_t state)
 return state == NVME_ZONE_STATE_READ_ONLY;
 }
 
+static uint16_t nvme_set_zd_ext(NvmeCtrl *n, NvmeNamespace *ns,
+NvmeZone *zone, uint8_t state)
+{
+uint16_t status;
+
+if (state == NVME_ZONE_STATE_EMPTY) {
+nvme_auto_transition_zone(n, ns, false, true);
+status = nvme_aor_check(n, ns, 1, 0);
+if (status != NVME_SUCCESS) {
+return status;
+}
+nvme_aor_inc_active(n, ns);
+zone->d.za |= NVME_ZA_ZD_EXT_VALID;
+nvme_assign_zone_state(n, ns, zone, NVME_ZONE_STATE_CLOSED);
+return NVME_SUCCESS;
+}
+
+return NVME_ZONE_INVAL_TRANSITION;
+}
+
 typedef uint16_t (*op_handler_t)(NvmeCtrl *, NvmeNamespace *, NvmeZone *,
  uint8_t);
 typedef bool (*need_to_proc_zone_t)(uint8_t);
@@ -1389,12 +1409,14 @@ static uint16_t nvme_zone_mgmt_send(NvmeCtrl *n, 
NvmeRequest *req)
 NvmeCmd *cmd = (NvmeCmd *)>cmd;
 NvmeNamespace *ns = req->ns;
 uint32_t dw13 = le32_to_cpu(cmd->cdw13);
+uint64_t prp1, prp2;
 uint64_t slba = 0;
 uint32_t zone_idx = 0;
 uint16_t status;
 uint8_t action, state;
 bool all;
 NvmeZone *zone;
+uint8_t *zd_ext;
 
 action = dw13 & 0xff;
 all = dw13 & 0x100;
@@ -1449,7 +1471,24 @@ static uint16_t nvme_zone_mgmt_send(NvmeCtrl *n, 
NvmeRequest *req)
 
 case NVME_ZONE_ACTION_SET_ZD_EXT:
 trace_pci_nvme_set_descriptor_extension(slba, zone_idx);
-return NVME_INVALID_FIELD | NVME_DNR;
+if (all || !n->params.zd_extension_size) {
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+zd_ext = nvme_get_zd_extension(n, ns, zone_idx);
+prp1 = le64_to_cpu(cmd->dptr.prp1);
+prp2 = le64_to_cpu(cmd->dptr.prp2);
+status = nvme_dma_prp(n, zd_ext, n->params.zd_extension_size,
+  prp1, prp2, DMA_DIRECTION_TO_DEVICE, req);
+if (status) {
+trace_pci_nvme_err_zd_extension_map_error(zone_idx);
+return status;
+}
+
+status = nvme_set_zd_ext(n, ns, zone, state);
+if (status == NVME_SUCCESS) {
+trace_pci_nvme_zd_extension_set(zone_idx);
+return status;
+}
 break;
 
 default:
@@ -1529,7 +1568,7 @@ static uint16_t nvme_zone_mgmt_recv(NvmeCtrl *n, 
NvmeRequest *req)
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
-if (zra == NVME_ZONE_REPORT_EXTENDED) {
+if (zra == NVME_ZONE_REPORT_EXTENDED && !n->params.zd_extension_size) {
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
@@ -1541,6 +1580,9 @@ static uint16_t nvme_zone_mgmt_recv(NvmeCtrl *n, 
NvmeRequest *req)
 partial = (dw13 >> 16) & 0x01;
 
 zone_entry_sz = sizeof(NvmeZoneDescr);
+if (zra == NVME_ZONE_REPORT_EXTENDED) {
+zone_entry_sz += n->params.zd_extension_size;
+}
 
 max_zones = (len - sizeof(NvmeZoneReportHeader)) / zone_entry_sz;
 buf = g_malloc0(len);
@@ -1572,6 +1614,14 @@ static uint16_t nvme_zone_mgmt_recv(NvmeCtrl *n, 
NvmeRequest *req)
 z->wp = cpu_to_le64(~0ULL);
 }
 
+if (zra == NVME_ZONE_REPORT_EXTENDED) {
+if (zs->d.za & NVME_ZA_ZD_EXT_VALID) {
+memcpy(buf_p, nvme_get_zd_extension(n, ns, zone_idx),
+   n->params.zd_extension_size);
+}
+buf_p += n->params.zd_extension_size;
+}
+
 zone_idx++;
 }
 
@@ -2686,7 +2736,6 @@ static uint16_t nvme_aer(NvmeCtrl *n, NvmeRequest *req)
 
 n->aer_reqs[n->outstanding_aers] = req;
 n->outstanding_aers++;
-
 if (!QTAILQ_EMPTY(>aer_queue)) {
 nvme_process_aers(n);
 }
@@ -3320,6 +3369,7 @@ static int nvme_init_zone_meta(NvmeCtrl *n, NvmeNamespace 
*ns,
 ns->imp_open_zones = g_malloc0(sizeof(NvmeZoneList));
 ns->closed_zones = g_malloc0(sizeof(NvmeZoneList));
 ns->full_zones = g_malloc0(sizeof(NvmeZoneList));
+ns->zd_extensions = g_malloc0(n->params.zd_extension_size * n->num_zones);
 zone = ns->zone_array;
 
 nvme_init_zone_list(ns->exp_open_zones);
@@ 

[PATCH v2 08/15] hw/block/nvme: Make Zoned NS Command Set definitions

2020-09-12 Thread Dmitry Fomichev
Define values and structures that are needed to support Zoned
Namespace Command Set (NVMe TP 4053) in PCI NVMe controller emulator.

All new protocol definitions are located in include/block/nvme.h
and everything added that is specific to this implementation is kept
in hw/block/nvme.h.

In order to improve scalability, all open, closed and full zones
are organized in separate linked lists. Consequently, almost all
zone operations don't require scanning of the entire zone array
(which potentially can be quite large) - it is only necessary to
enumerate one or more zone lists. Zone lists are designed to be
position-independent as they can be persisted to the backing file
as a part of zone metadata. NvmeZoneList struct defined in this patch
serves as a head of every zone list.

NvmeZone structure encapsulates NvmeZoneDescriptor defined in Zoned
Command Set specification and adds a few more fields that are
internal to this implementation.

Signed-off-by: Niklas Cassel 
Signed-off-by: Hans Holmberg 
Signed-off-by: Ajay Joshi 
Signed-off-by: Matias Bjorling 
Signed-off-by: Shin'ichiro Kawasaki 
Signed-off-by: Alexey Bogoslavsky 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.h  | 124 +++
 include/block/nvme.h | 107 +
 2 files changed, 231 insertions(+)

diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index dec337bbf9..9514c58919 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -3,6 +3,9 @@
 
 #include "block/nvme.h"
 
+#define NVME_DEFAULT_ZONE_SIZE   128 /* MiB */
+#define NVME_DEFAULT_MAX_ZA_SIZE 128 /* KiB */
+
 typedef struct NvmeParams {
 char *serial;
 uint32_t num_queues; /* deprecated since 5.1 */
@@ -12,6 +15,13 @@ typedef struct NvmeParams {
 uint8_t  aerl;
 uint32_t aer_max_queued;
 uint8_t  mdts;
+
+boolzoned;
+boolcross_zone_read;
+uint8_t fill_pattern;
+uint32_tzasl_kb;
+uint64_tzone_size_mb;
+uint64_tzone_capacity_mb;
 } NvmeParams;
 
 typedef struct NvmeAsyncEvent {
@@ -24,6 +34,7 @@ typedef struct NvmeRequest {
 struct NvmeNamespace*ns;
 BlockAIOCB  *aiocb;
 uint16_tstatus;
+int64_t fill_ofs;
 NvmeCqe cqe;
 NvmeCmd cmd;
 BlockAcctCookie acct;
@@ -62,12 +73,36 @@ typedef struct NvmeCQueue {
 QTAILQ_HEAD(, NvmeRequest) req_list;
 } NvmeCQueue;
 
+typedef struct NvmeZone {
+NvmeZoneDescr   d;
+uint64_ttstamp;
+uint32_tnext;
+uint32_tprev;
+uint8_t rsvd80[8];
+} NvmeZone;
+
+#define NVME_ZONE_LIST_NILUINT_MAX
+
+typedef struct NvmeZoneList {
+uint32_thead;
+uint32_ttail;
+uint32_tsize;
+uint8_t rsvd12[4];
+} NvmeZoneList;
+
 typedef struct NvmeNamespace {
 NvmeIdNsid_ns;
 uint32_tnsid;
 uint8_t csi;
 boolattached;
 QemuUUIDuuid;
+
+NvmeIdNsZoned   *id_ns_zoned;
+NvmeZone*zone_array;
+NvmeZoneList*exp_open_zones;
+NvmeZoneList*imp_open_zones;
+NvmeZoneList*closed_zones;
+NvmeZoneList*full_zones;
 } NvmeNamespace;
 
 static inline NvmeLBAF *nvme_ns_lbaf(NvmeNamespace *ns)
@@ -126,6 +161,15 @@ typedef struct NvmeCtrl {
 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
 int aer_queued;
 
+int zone_file_fd;
+uint32_tnum_zones;
+uint64_tzone_size;
+uint64_tzone_capacity;
+uint64_tzone_array_size;
+uint32_tzone_size_log2;
+uint32_tzasl_bs;
+uint8_t zasl;
+
 NvmeNamespace   *namespaces;
 NvmeSQueue  **sq;
 NvmeCQueue  **cq;
@@ -141,6 +185,86 @@ static inline uint64_t nvme_ns_nlbas(NvmeCtrl *n, 
NvmeNamespace *ns)
 return n->ns_size >> nvme_ns_lbads(ns);
 }
 
+static inline uint8_t nvme_get_zone_state(NvmeZone *zone)
+{
+return zone->d.zs >> 4;
+}
+
+static inline void nvme_set_zone_state(NvmeZone *zone, enum NvmeZoneState 
state)
+{
+zone->d.zs = state << 4;
+}
+
+static inline uint64_t nvme_zone_rd_boundary(NvmeCtrl *n, NvmeZone *zone)
+{
+return zone->d.zslba + n->zone_size;
+}
+
+static inline uint64_t nvme_zone_wr_boundary(NvmeZone *zone)
+{
+return zone->d.zslba + zone->d.zcap;
+}
+
+static inline bool nvme_wp_is_valid(NvmeZone *zone)
+{
+uint8_t st = nvme_get_zone_state(zone);
+
+return st != NVME_ZONE_STATE_FULL &&
+   st != NVME_ZONE_STATE_READ_ONLY &&
+   st != NVME_ZONE_STATE_OFFLINE;
+}
+
+/*
+ * Initialize a zone list head.
+ */
+static inline void nvme_init_zone_list(NvmeZoneList *zl)
+{
+zl->head = NVME_ZONE_LIST_NIL;
+zl->tail = NVME_ZONE_LIST_NIL;
+zl->size = 0;
+}
+
+/*
+ * Initialize the number of entries contained in a zone list.
+ */
+static inline uint32_t nvme_zone_list_size(NvmeZoneList *zl)
+{
+return 

[PATCH v2 00/15] hw/block/nvme: Support Namespace Types and Zoned Namespace Command Set

2020-09-12 Thread Dmitry Fomichev
v1 -> v2:

 - Rebased on top of qemu-nvme/next branch.
 - Incorporated feedback from Klaus and Alistair.
 - Dropped "Simulate Zone Active excursions" patch.
   Excursion behavior may depend on the internal controller
   architecture and therefore be vendor-specific.
 - Dropped support for Zone Attributes and zoned AENs for now.
   These features can be added in a future series.
 - NS Types support is extended to handle active/inactive namespaces.
 - Update the write pointer after backing storage I/O completion, not
   before. This makes the emulation to run correctly in case of
   backing device failures.
 - Avoid division in the I/O path if the device zone size is
   a power of two (the most common case). Zone index then can be
   calculated by using bit shift.
 - A few reported bugs have been fixed.
 - Indentation in function definitions has been changed to make it
   the same as the rest of the code.


Zoned Namespace (ZNS) Command Set is a newly introduced command set
published by the NVM Express, Inc. organization as TP 4053. The main
design goals of ZNS are to provide hardware designers the means to
reduce NVMe controller complexity and to allow achieving a better I/O
latency and throughput. SSDs that implement this interface are
commonly known as ZNS SSDs.

This command set is implementing a zoned storage model, similarly to
ZAC/ZBC. As such, there is already support in Linux, allowing one to
perform the majority of tasks needed for managing ZNS SSDs.

The Zoned Namespace Command Set relies on another TP, known as
Namespace Types (NVMe TP 4056), which introduces support for having
multiple command sets per namespace.

Both ZNS and Namespace Types specifications can be downloaded by
visiting the following link -

https://nvmexpress.org/wp-content/uploads/NVM-Express-1.4-Ratified-TPs.zip

This patch series adds Namespace Types support and zoned namespace
emulation capability to the existing NVMe PCI device.

The patchset is organized as follows -

The first several patches are preparatory and are added to allow for
an easier review of the subsequent commits. The group of patches that
follows adds NS Types support with only NVM Command Set being
available. Finally, the last group of commits makes definitions and
adds new code to support Zoned Namespace Command Set.

Based-on: https://www.mail-archive.com/qemu-devel@nongnu.org/msg736817.html


*** BLURB HERE ***

Ajay Joshi (1):
  hw/block/nvme: Define 64 bit cqe.result

Dmitry Fomichev (11):
  hw/block/nvme: Report actual LBA data shift in LBAF
  hw/block/nvme: Add Commands Supported and Effects log
  hw/block/nvme: Define trace events related to NS Types
  hw/block/nvme: Make Zoned NS Command Set definitions
  hw/block/nvme: Define Zoned NS Command Set trace events
  hw/block/nvme: Support Zoned Namespace Command Set
  hw/block/nvme: Introduce max active and open zone limits
  hw/block/nvme: Support Zone Descriptor Extensions
  hw/block/nvme: Add injection of Offline/Read-Only zones
  hw/block/nvme: Use zone metadata file for persistence
  hw/block/nvme: Document zoned parameters in usage text

Niklas Cassel (3):
  hw/block/nvme: Introduce the Namespace Types definitions
  hw/block/nvme: Add support for Namespace Types
  hw/block/nvme: Add support for active/inactive namespaces

 block/nvme.c  |2 +-
 block/trace-events|2 +-
 hw/block/nvme.c   | 1932 -
 hw/block/nvme.h   |  190 
 hw/block/trace-events |   38 +
 include/block/nvme.h  |  210 -
 6 files changed, 2308 insertions(+), 66 deletions(-)

-- 
2.21.0




[PATCH v2 13/15] hw/block/nvme: Add injection of Offline/Read-Only zones

2020-09-12 Thread Dmitry Fomichev
ZNS specification defines two zone conditions for the zones that no
longer can function properly, possibly because of flash wear or other
internal fault. It is useful to be able to "inject" a small number of
such zones for testing purposes.

This commit defines two optional device properties, "offline_zones"
and "rdonly_zones". Users can assign non-zero values to these variables
to specify the number of zones to be initialized as Offline or
Read-Only. The actual number of injected zones may be smaller than the
requested amount - Read-Only and Offline counts are expected to be much
smaller than the total number of zones on a drive.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c | 46 ++
 hw/block/nvme.h |  2 ++
 2 files changed, 48 insertions(+)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index ec7fade674..f0a03bea75 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -3361,8 +3361,11 @@ static int nvme_init_zone_meta(NvmeCtrl *n, 
NvmeNamespace *ns,
uint64_t capacity)
 {
 NvmeZone *zone;
+Error *err;
 uint64_t start = 0, zone_size = n->zone_size;
+uint32_t rnd;
 int i;
+uint16_t zs;
 
 ns->zone_array = g_malloc0(n->zone_array_size);
 ns->exp_open_zones = g_malloc0(sizeof(NvmeZoneList));
@@ -3392,6 +3395,37 @@ static int nvme_init_zone_meta(NvmeCtrl *n, 
NvmeNamespace *ns,
 start += zone_size;
 }
 
+/* If required, make some zones Offline or Read Only */
+
+for (i = 0; i < n->params.nr_offline_zones; i++) {
+do {
+qcrypto_random_bytes(, sizeof(rnd), );
+rnd %= n->num_zones;
+} while (rnd < n->params.max_open_zones);
+zone = >zone_array[rnd];
+zs = nvme_get_zone_state(zone);
+if (zs != NVME_ZONE_STATE_OFFLINE) {
+nvme_set_zone_state(zone, NVME_ZONE_STATE_OFFLINE);
+} else {
+i--;
+}
+}
+
+for (i = 0; i < n->params.nr_rdonly_zones; i++) {
+do {
+qcrypto_random_bytes(, sizeof(rnd), );
+rnd %= n->num_zones;
+} while (rnd < n->params.max_open_zones);
+zone = >zone_array[rnd];
+zs = nvme_get_zone_state(zone);
+if (zs != NVME_ZONE_STATE_OFFLINE &&
+zs != NVME_ZONE_STATE_READ_ONLY) {
+nvme_set_zone_state(zone, NVME_ZONE_STATE_READ_ONLY);
+} else {
+i--;
+}
+}
+
 return 0;
 }
 
@@ -3440,6 +3474,16 @@ static void nvme_zoned_init_ctrl(NvmeCtrl *n, Error 
**errp)
 " adjusting", n->params.max_active_zones, nz);
 n->params.max_active_zones = nz;
 }
+if (n->params.max_open_zones < nz) {
+if (n->params.nr_offline_zones > nz - n->params.max_open_zones) {
+n->params.nr_offline_zones = nz - n->params.max_open_zones;
+}
+if (n->params.nr_rdonly_zones >
+nz - n->params.max_open_zones - n->params.nr_offline_zones) {
+n->params.nr_rdonly_zones =
+nz - n->params.max_open_zones - n->params.nr_offline_zones;
+}
+}
 if (n->params.zd_extension_size) {
 if (n->params.zd_extension_size & 0x3f) {
 error_setg(errp,
@@ -3872,6 +3916,8 @@ static Property nvme_props[] = {
params.zd_extension_size, 0),
 DEFINE_PROP_UINT32("max_active", NvmeCtrl, params.max_active_zones, 0),
 DEFINE_PROP_UINT32("max_open", NvmeCtrl, params.max_open_zones, 0),
+DEFINE_PROP_UINT32("offline_zones", NvmeCtrl, params.nr_offline_zones, 0),
+DEFINE_PROP_UINT32("rdonly_zones", NvmeCtrl, params.nr_rdonly_zones, 0),
 DEFINE_PROP_BOOL("cross_zone_read", NvmeCtrl, params.cross_zone_read, 
true),
 DEFINE_PROP_UINT8("fill_pattern", NvmeCtrl, params.fill_pattern, 0),
 DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index e53388ba66..9a5f4787b7 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -25,6 +25,8 @@ typedef struct NvmeParams {
 uint32_tmax_active_zones;
 uint32_tmax_open_zones;
 uint32_tzd_extension_size;
+uint32_tnr_offline_zones;
+uint32_tnr_rdonly_zones;
 } NvmeParams;
 
 typedef struct NvmeAsyncEvent {
-- 
2.21.0




[PATCH v8 27/27] Revert "configure: add --ninja option"

2020-09-12 Thread Yonggang Luo
This reverts commit 48328880fddf0145bdccc499160fb24dfabfbd41.

The --ninja option doesn't need anymore because of upgrade meson to 0.55.2
At that version we can use ninjatool

Signed-off-by: Yonggang Luo 
---
 configure | 16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/configure b/configure
index af86ba1db3..dc7cc0f411 100755
--- a/configure
+++ b/configure
@@ -535,7 +535,6 @@ rng_none="no"
 secret_keyring=""
 libdaxctl=""
 meson=""
-ninja=""
 skip_meson=no
 gettext=""
 
@@ -1003,8 +1002,6 @@ for opt do
   ;;
   --meson=*) meson="$optarg"
   ;;
-  --ninja=*) ninja="$optarg"
-  ;;
   --smbd=*) smbd="$optarg"
   ;;
   --extra-cflags=*)
@@ -1777,7 +1774,6 @@ Advanced options (experts only):
   --python=PYTHON  use specified python [$python]
   --sphinx-build=SPHINXuse specified sphinx-build [$sphinx_build]
   --meson=MESONuse specified meson [$meson]
-  --ninja=NINJAuse specified ninja [$ninja]
   --smbd=SMBD  use specified smbd [$smbd]
   --with-git=GIT   use specified git [$git]
   --static enable static build [$static]
@@ -2014,16 +2010,6 @@ case "$meson" in
 *) meson=$(command -v meson) ;;
 esac
 
-# Probe for ninja (used for compdb)
-
-if test -z "$ninja"; then
-for c in ninja ninja-build samu; do
-if has $c; then
-ninja=$(command -v "$c")
-break
-fi
-done
-fi
 
 # Check that the C compiler works. Doing this here before testing
 # the host CPU ensures that we had a valid CC to autodetect the
@@ -7952,7 +7938,7 @@ fi
 mv $cross config-meson.cross
 
 rm -rf meson-private meson-info meson-logs
-NINJA=${ninja:-$PWD/ninjatool} $meson setup \
+NINJA=$PWD/ninjatool $meson setup \
 --prefix "${pre_prefix}$prefix" \
 --libdir "${pre_prefix}$libdir" \
 --libexecdir "${pre_prefix}$libexecdir" \
-- 
2.28.0.windows.1




[PATCH v2 04/15] hw/block/nvme: Introduce the Namespace Types definitions

2020-09-12 Thread Dmitry Fomichev
From: Niklas Cassel 

Define the structures and constants required to implement
Namespace Types support.

Signed-off-by: Niklas Cassel 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c  |  2 +-
 hw/block/nvme.h  |  3 ++
 include/block/nvme.h | 74 +++-
 3 files changed, 64 insertions(+), 15 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 39c2d5b0b4..4bd88f4046 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1259,7 +1259,7 @@ static uint16_t nvme_identify_ns_descr_list(NvmeCtrl *n, 
NvmeRequest *req)
  * here.
  */
 ns_descrs->uuid.hdr.nidt = NVME_NIDT_UUID;
-ns_descrs->uuid.hdr.nidl = NVME_NIDT_UUID_LEN;
+ns_descrs->uuid.hdr.nidl = NVME_NIDL_UUID;
 stl_be_p(_descrs->uuid.v, nsid);
 
 return nvme_dma_prp(n, list, NVME_IDENTIFY_DATA_SIZE, prp1, prp2,
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index 190c974b6c..252e2d5921 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -64,6 +64,9 @@ typedef struct NvmeCQueue {
 
 typedef struct NvmeNamespace {
 NvmeIdNsid_ns;
+uint32_tnsid;
+uint8_t csi;
+QemuUUIDuuid;
 } NvmeNamespace;
 
 static inline NvmeLBAF *nvme_ns_lbaf(NvmeNamespace *ns)
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 62136a906f..f2cff5aa6b 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -51,6 +51,11 @@ enum NvmeCapMask {
 CAP_PMR_MASK   = 0x1,
 };
 
+enum NvmeCapCssBits {
+CAP_CSS_NVM= 0x01,
+CAP_CSS_CSI_SUPP   = 0x40,
+};
+
 #define NVME_CAP_MQES(cap)  (((cap) >> CAP_MQES_SHIFT)   & CAP_MQES_MASK)
 #define NVME_CAP_CQR(cap)   (((cap) >> CAP_CQR_SHIFT)& CAP_CQR_MASK)
 #define NVME_CAP_AMS(cap)   (((cap) >> CAP_AMS_SHIFT)& CAP_AMS_MASK)
@@ -102,6 +107,12 @@ enum NvmeCcMask {
 CC_IOCQES_MASK  = 0xf,
 };
 
+enum NvmeCcCss {
+CSS_NVM_ONLY= 0,
+CSS_CSI = 6,
+CSS_ADMIN_ONLY  = 7,
+};
+
 #define NVME_CC_EN(cc) ((cc >> CC_EN_SHIFT) & CC_EN_MASK)
 #define NVME_CC_CSS(cc)((cc >> CC_CSS_SHIFT)& CC_CSS_MASK)
 #define NVME_CC_MPS(cc)((cc >> CC_MPS_SHIFT)& CC_MPS_MASK)
@@ -110,6 +121,21 @@ enum NvmeCcMask {
 #define NVME_CC_IOSQES(cc) ((cc >> CC_IOSQES_SHIFT) & CC_IOSQES_MASK)
 #define NVME_CC_IOCQES(cc) ((cc >> CC_IOCQES_SHIFT) & CC_IOCQES_MASK)
 
+#define NVME_SET_CC_EN(cc, val) \
+(cc |= (uint32_t)((val) & CC_EN_MASK) << CC_EN_SHIFT)
+#define NVME_SET_CC_CSS(cc, val)\
+(cc |= (uint32_t)((val) & CC_CSS_MASK) << CC_CSS_SHIFT)
+#define NVME_SET_CC_MPS(cc, val)\
+(cc |= (uint32_t)((val) & CC_MPS_MASK) << CC_MPS_SHIFT)
+#define NVME_SET_CC_AMS(cc, val)\
+(cc |= (uint32_t)((val) & CC_AMS_MASK) << CC_AMS_SHIFT)
+#define NVME_SET_CC_SHN(cc, val)\
+(cc |= (uint32_t)((val) & CC_SHN_MASK) << CC_SHN_SHIFT)
+#define NVME_SET_CC_IOSQES(cc, val) \
+(cc |= (uint32_t)((val) & CC_IOSQES_MASK) << CC_IOSQES_SHIFT)
+#define NVME_SET_CC_IOCQES(cc, val) \
+(cc |= (uint32_t)((val) & CC_IOCQES_MASK) << CC_IOCQES_SHIFT)
+
 enum NvmeCstsShift {
 CSTS_RDY_SHIFT  = 0,
 CSTS_CFS_SHIFT  = 1,
@@ -524,8 +550,13 @@ typedef struct QEMU_PACKED NvmeIdentify {
 uint64_trsvd2[2];
 uint64_tprp1;
 uint64_tprp2;
-uint32_tcns;
-uint32_trsvd11[5];
+uint8_t cns;
+uint8_t rsvd10;
+uint16_tctrlid;
+uint16_tnvmsetid;
+uint8_t rsvd11;
+uint8_t csi;
+uint32_trsvd12[4];
 } NvmeIdentify;
 
 typedef struct QEMU_PACKED NvmeRwCmd {
@@ -647,6 +678,7 @@ enum NvmeStatusCodes {
 NVME_MD_SGL_LEN_INVALID = 0x0010,
 NVME_SGL_DESCR_TYPE_INVALID = 0x0011,
 NVME_INVALID_USE_OF_CMB = 0x0012,
+NVME_CMD_SET_CMB_REJECTED   = 0x002b,
 NVME_LBA_RANGE  = 0x0080,
 NVME_CAP_EXCEEDED   = 0x0081,
 NVME_NS_NOT_READY   = 0x0082,
@@ -773,11 +805,15 @@ typedef struct QEMU_PACKED NvmePSD {
 
 #define NVME_IDENTIFY_DATA_SIZE 4096
 
-enum {
-NVME_ID_CNS_NS = 0x0,
-NVME_ID_CNS_CTRL   = 0x1,
-NVME_ID_CNS_NS_ACTIVE_LIST = 0x2,
-NVME_ID_CNS_NS_DESCR_LIST  = 0x3,
+enum NvmeIdCns {
+NVME_ID_CNS_NS= 0x00,
+NVME_ID_CNS_CTRL  = 0x01,
+NVME_ID_CNS_NS_ACTIVE_LIST= 0x02,
+NVME_ID_CNS_NS_DESCR_LIST = 0x03,
+NVME_ID_CNS_CS_NS = 0x05,
+NVME_ID_CNS_CS_CTRL   = 0x06,
+NVME_ID_CNS_CS_NS_ACTIVE_LIST = 0x07,
+NVME_ID_CNS_IO_COMMAND_SET= 0x1c,
 };
 
 typedef struct QEMU_PACKED NvmeIdCtrl {
@@ -924,6 +960,7 @@ enum NvmeFeatureIds {
 NVME_WRITE_ATOMICITY= 0xa,
 NVME_ASYNCHRONOUS_EVENT_CONF= 0xb,
 NVME_TIMESTAMP  = 0xe,
+NVME_COMMAND_SET_PROFILE= 0x19,
 NVME_SOFTWARE_PROGRESS_MARKER   = 0x80,
 NVME_FID_MAX= 0x100,
 };
@@ -1008,18 +1045,26 @@ typedef struct QEMU_PACKED NvmeIdNsDescr {
 uint8_t 

[PATCH v2 05/15] hw/block/nvme: Define trace events related to NS Types

2020-09-12 Thread Dmitry Fomichev
A few trace events are defined that are relevant to implementing
Namespace Types (NVMe TP 4056).

Signed-off-by: Dmitry Fomichev 
Reviewed-by: Klaus Jensen 
---
 hw/block/trace-events | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index 79c9da652d..2414dcbc79 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -46,8 +46,12 @@ pci_nvme_create_cq(uint64_t addr, uint16_t cqid, uint16_t 
vector, uint16_t size,
 pci_nvme_del_sq(uint16_t qid) "deleting submission queue sqid=%"PRIu16""
 pci_nvme_del_cq(uint16_t cqid) "deleted completion queue, cqid=%"PRIu16""
 pci_nvme_identify_ctrl(void) "identify controller"
+pci_nvme_identify_ctrl_csi(uint8_t csi) "identify controller, csi=0x%"PRIx8""
 pci_nvme_identify_ns(uint32_t ns) "nsid %"PRIu32""
+pci_nvme_identify_ns_csi(uint32_t ns, uint8_t csi) "nsid=%"PRIu32", 
csi=0x%"PRIx8""
 pci_nvme_identify_nslist(uint32_t ns) "nsid %"PRIu32""
+pci_nvme_identify_nslist_csi(uint16_t ns, uint8_t csi) "nsid=%"PRIu16", 
csi=0x%"PRIx8""
+pci_nvme_identify_cmd_set(void) "identify i/o command set"
 pci_nvme_identify_ns_descr_list(uint32_t ns) "nsid %"PRIu32""
 pci_nvme_get_log(uint16_t cid, uint8_t lid, uint8_t lsp, uint8_t rae, uint32_t 
len, uint64_t off) "cid %"PRIu16" lid 0x%"PRIx8" lsp 0x%"PRIx8" rae 0x%"PRIx8" 
len %"PRIu32" off %"PRIu64""
 pci_nvme_getfeat(uint16_t cid, uint8_t fid, uint8_t sel, uint32_t cdw11) "cid 
%"PRIu16" fid 0x%"PRIx8" sel 0x%"PRIx8" cdw11 0x%"PRIx32""
@@ -84,6 +88,8 @@ pci_nvme_mmio_stopped(void) "cleared controller enable bit"
 pci_nvme_mmio_shutdown_set(void) "shutdown bit set"
 pci_nvme_mmio_shutdown_cleared(void) "shutdown bit cleared"
 pci_nvme_cmd_supp_and_effects_log_read(void) "commands supported and effects 
log read"
+pci_nvme_css_nvm_cset_selected_by_host(uint32_t cc) "NVM command set selected 
by host, bar.cc=0x%"PRIx32""
+pci_nvme_css_all_csets_sel_by_host(uint32_t cc) "all supported command sets 
selected by host, bar.cc=0x%"PRIx32""
 
 # nvme traces for error conditions
 pci_nvme_err_mdts(uint16_t cid, size_t len) "cid %"PRIu16" len %zu"
@@ -97,6 +103,9 @@ pci_nvme_err_invalid_opc(uint8_t opc) "invalid opcode 
0x%"PRIx8""
 pci_nvme_err_invalid_admin_opc(uint8_t opc) "invalid admin opcode 0x%"PRIx8""
 pci_nvme_err_invalid_lba_range(uint64_t start, uint64_t len, uint64_t limit) 
"Invalid LBA start=%"PRIu64" len=%"PRIu64" limit=%"PRIu64""
 pci_nvme_err_invalid_effects_log_offset(uint64_t ofs) "commands supported and 
effects log offset must be 0, got %"PRIu64""
+pci_nvme_err_change_css_when_enabled(void) "changing CC.CSS while controller 
is enabled"
+pci_nvme_err_only_nvm_cmd_set_avail(void) "setting 110b CC.CSS, but only NVM 
command set is enabled"
+pci_nvme_err_invalid_iocsci(uint32_t idx) "unsupported command set combination 
index %"PRIu32""
 pci_nvme_err_invalid_del_sq(uint16_t qid) "invalid submission queue deletion, 
sid=%"PRIu16""
 pci_nvme_err_invalid_create_sq_cqid(uint16_t cqid) "failed creating submission 
queue, invalid cqid=%"PRIu16""
 pci_nvme_err_invalid_create_sq_sqid(uint16_t sqid) "failed creating submission 
queue, invalid sqid=%"PRIu16""
@@ -152,6 +161,7 @@ pci_nvme_ub_db_wr_invalid_cq(uint32_t qid) "completion 
queue doorbell write for
 pci_nvme_ub_db_wr_invalid_cqhead(uint32_t qid, uint16_t new_head) "completion 
queue doorbell write value beyond queue size, cqid=%"PRIu32", 
new_head=%"PRIu16", ignoring"
 pci_nvme_ub_db_wr_invalid_sq(uint32_t qid) "submission queue doorbell write 
for nonexistent queue, sqid=%"PRIu32", ignoring"
 pci_nvme_ub_db_wr_invalid_sqtail(uint32_t qid, uint16_t new_tail) "submission 
queue doorbell write value beyond queue size, sqid=%"PRIu32", 
new_head=%"PRIu16", ignoring"
+pci_nvme_ub_unknown_css_value(void) "unknown value in cc.css field"
 
 # xen-block.c
 xen_block_realize(const char *type, uint32_t disk, uint32_t partition) "%s 
d%up%u"
-- 
2.21.0




[PATCH v2 15/15] hw/block/nvme: Document zoned parameters in usage text

2020-09-12 Thread Dmitry Fomichev
Added brief descriptions of the new device properties that are
now available to users to configure features of Zoned Namespace
Command Set in the emulator.

This patch is for documentation only, no functionality change.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c | 43 +--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 3e8e6e1472..9b1d80a204 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -9,7 +9,7 @@
  */
 
 /**
- * Reference Specs: http://www.nvmexpress.org, 1.2, 1.1, 1.0e
+ * Reference Specs: http://www.nvmexpress.org, 1.4, 1.3, 1.2, 1.1, 1.0e
  *
  *  https://nvmexpress.org/developers/nvme-specification/
  */
@@ -22,7 +22,7 @@
  *  [pmrdev=,] \
  *  max_ioqpairs=, \
  *  aerl=, aer_max_queued=, \
- *  mdts=
+ *  mdts=, zoned=
  *
  * Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
  * offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
@@ -48,6 +48,45 @@
  *   completion when there are no oustanding AERs. When the maximum number of
  *   enqueued events are reached, subsequent events will be dropped.
  *
+ * Setting `zoned` to true makes the device to support zoned namespaces.
+ * In this case, of the following options are available to configure zoned
+ * operation:
+ * zone_size=
+ *
+ * zone_capacity=
+ * The value 0 (default) forces zone capacity to be the same as zone
+ * size. The value of this property may not exceed zone size.
+ *
+ * zone_file=
+ * Zone metadata file, if specified, allows zone information
+ * to be persistent across shutdowns and restarts.
+ *
+ * zone_descr_ext_size=
+ * This value needs to be specified in 64B units. If it is zero,
+ * namespace(s) will not support zone descriptor extensions.
+ *
+ * max_active=
+ *
+ * max_open=
+ *
+ * zone_append_size_limit=
+ * The maximum I/O size that can be supported by Zone Append
+ * command. Since internally this this value is maintained as
+ * ZASL = log2( / ), some
+ * values assigned to this property may be rounded down and
+ * result in a lower maximum ZA data size being in effect.
+ * If MDTS property is not assigned, the default value of 128KiB is
+ * used as ZASL.
+ *
+ * offline_zones=
+ *
+ * rdonly_zones=
+ *
+ * cross_zone_read=
+ *
+ * fill_pattern=
+ * The byte pattern to return for any portions of unwritten data
+ * during read.
  */
 
 #include "qemu/osdep.h"
-- 
2.21.0




[PATCH v2 02/15] hw/block/nvme: Report actual LBA data shift in LBAF

2020-09-12 Thread Dmitry Fomichev
Calculate the data shift value to report based on the set value of
logical_block_size device property.

In the process, use a local variable to calculate the LBA format
index instead of the hardcoded value 0. This makes the code more
readable and it will make it easier to add support for multiple LBA
formats in the future.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c |  4 +++-
 hw/block/nvme.h | 11 +++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 3a90d80694..1cfc136042 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -2203,6 +2203,7 @@ static void nvme_init_namespace(NvmeCtrl *n, 
NvmeNamespace *ns, Error **errp)
 {
 int64_t bs_size;
 NvmeIdNs *id_ns = >id_ns;
+int lba_index;
 
 bs_size = blk_getlength(n->conf.blk);
 if (bs_size < 0) {
@@ -2212,7 +2213,8 @@ static void nvme_init_namespace(NvmeCtrl *n, 
NvmeNamespace *ns, Error **errp)
 
 n->ns_size = bs_size;
 
-id_ns->lbaf[0].ds = BDRV_SECTOR_BITS;
+lba_index = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas);
+id_ns->lbaf[lba_index].ds = nvme_ilog2(n->conf.logical_block_size);
 id_ns->nsze = cpu_to_le64(nvme_ns_nlbas(n, ns));
 
 /* no thin provisioning */
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index 52ba794f2e..190c974b6c 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -137,4 +137,15 @@ static inline uint64_t nvme_ns_nlbas(NvmeCtrl *n, 
NvmeNamespace *ns)
 return n->ns_size >> nvme_ns_lbads(ns);
 }
 
+static inline int nvme_ilog2(uint64_t i)
+{
+int log = -1;
+
+while (i) {
+i >>= 1;
+log++;
+}
+return log;
+}
+
 #endif /* HW_NVME_H */
-- 
2.21.0




[PATCH v8 26/27] meson: remove --ninja option in configure.

2020-09-12 Thread Yonggang Luo
Signed-off-by: Yonggang Luo 
---
 .cirrus.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.cirrus.yml b/.cirrus.yml
index 1ff9f0a72f..87bd110d28 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -99,7 +99,7 @@ windows_msys2_task:
 mingw-w64-x86_64-zstd"
   script:
 - C:\tools\msys64\usr\bin\bash.exe -lc "mkdir build"
-- C:\tools\msys64\usr\bin\bash.exe -lc "cd build && ../configure 
--python=python3 --ninja=ninja"
+- C:\tools\msys64\usr\bin\bash.exe -lc "cd build && ../configure 
--python=python3"
 - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make 
-j$NUMBER_OF_PROCESSORS"
   test_script:
 - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make V=1 check"
-- 
2.28.0.windows.1




[PATCH v2 03/15] hw/block/nvme: Add Commands Supported and Effects log

2020-09-12 Thread Dmitry Fomichev
This log page becomes necessary to implement to allow checking for
Zone Append command support in Zoned Namespace Command Set.

This commit adds the code to report this log page for NVM Command
Set only. The parts that are specific to zoned operation will be
added later in the series.

Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c   | 44 ++-
 hw/block/trace-events |  2 ++
 include/block/nvme.h  | 19 +++
 3 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 1cfc136042..39c2d5b0b4 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -957,6 +957,46 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t rae, 
uint32_t buf_len,
 DMA_DIRECTION_FROM_DEVICE, req);
 }
 
+static uint16_t nvme_cmd_effects(NvmeCtrl *n, uint32_t buf_len,
+ uint64_t off, NvmeRequest *req)
+{
+NvmeCmd *cmd = >cmd;
+uint64_t prp1 = le64_to_cpu(cmd->dptr.prp1);
+uint64_t prp2 = le64_to_cpu(cmd->dptr.prp2);
+NvmeEffectsLog cmd_eff_log = {};
+uint32_t *iocs = cmd_eff_log.iocs;
+uint32_t *acs = cmd_eff_log.acs;
+uint32_t trans_len;
+
+trace_pci_nvme_cmd_supp_and_effects_log_read();
+
+if (off >= sizeof(cmd_eff_log)) {
+trace_pci_nvme_err_invalid_effects_log_offset(off);
+return NVME_INVALID_FIELD | NVME_DNR;
+}
+
+acs[NVME_ADM_CMD_DELETE_SQ] = NVME_CMD_EFFECTS_CSUPP;
+acs[NVME_ADM_CMD_CREATE_SQ] = NVME_CMD_EFFECTS_CSUPP;
+acs[NVME_ADM_CMD_DELETE_CQ] = NVME_CMD_EFFECTS_CSUPP;
+acs[NVME_ADM_CMD_CREATE_CQ] = NVME_CMD_EFFECTS_CSUPP;
+acs[NVME_ADM_CMD_IDENTIFY] = NVME_CMD_EFFECTS_CSUPP;
+acs[NVME_ADM_CMD_SET_FEATURES] = NVME_CMD_EFFECTS_CSUPP;
+acs[NVME_ADM_CMD_GET_FEATURES] = NVME_CMD_EFFECTS_CSUPP;
+acs[NVME_ADM_CMD_GET_LOG_PAGE] = NVME_CMD_EFFECTS_CSUPP;
+acs[NVME_ADM_CMD_ASYNC_EV_REQ] = NVME_CMD_EFFECTS_CSUPP;
+
+iocs[NVME_CMD_FLUSH] = NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC;
+iocs[NVME_CMD_WRITE_ZEROES] = NVME_CMD_EFFECTS_CSUPP |
+  NVME_CMD_EFFECTS_LBCC;
+iocs[NVME_CMD_WRITE] = NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC;
+iocs[NVME_CMD_READ] = NVME_CMD_EFFECTS_CSUPP;
+
+trans_len = MIN(sizeof(cmd_eff_log) - off, buf_len);
+
+return nvme_dma_prp(n, ((uint8_t *)_eff_log) + off, trans_len,
+prp1, prp2, DMA_DIRECTION_FROM_DEVICE, req);
+}
+
 static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest *req)
 {
 NvmeCmd *cmd = >cmd;
@@ -1000,6 +1040,8 @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest 
*req)
 return nvme_smart_info(n, rae, len, off, req);
 case NVME_LOG_FW_SLOT_INFO:
 return nvme_fw_log_info(n, len, off, req);
+case NVME_LOG_CMD_EFFECTS:
+return nvme_cmd_effects(n, len, off, req);
 default:
 trace_pci_nvme_err_invalid_log_page(nvme_cid(req), lid);
 return NVME_INVALID_FIELD | NVME_DNR;
@@ -2350,7 +2392,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
*pci_dev)
 id->acl = 3;
 id->aerl = n->params.aerl;
 id->frmw = (NVME_NUM_FW_SLOTS << 1) | NVME_FRMW_SLOT1_RO;
-id->lpa = NVME_LPA_EXTENDED;
+id->lpa = NVME_LPA_CSE | NVME_LPA_EXTENDED;
 
 /* recommended default value (~70 C) */
 id->wctemp = cpu_to_le16(NVME_TEMPERATURE_WARNING);
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 72cf2d15cb..79c9da652d 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -83,6 +83,7 @@ pci_nvme_mmio_start_success(void) "setting controller enable 
bit succeeded"
 pci_nvme_mmio_stopped(void) "cleared controller enable bit"
 pci_nvme_mmio_shutdown_set(void) "shutdown bit set"
 pci_nvme_mmio_shutdown_cleared(void) "shutdown bit cleared"
+pci_nvme_cmd_supp_and_effects_log_read(void) "commands supported and effects 
log read"
 
 # nvme traces for error conditions
 pci_nvme_err_mdts(uint16_t cid, size_t len) "cid %"PRIu16" len %zu"
@@ -95,6 +96,7 @@ pci_nvme_err_invalid_ns(uint32_t ns, uint32_t limit) "invalid 
namespace %u not w
 pci_nvme_err_invalid_opc(uint8_t opc) "invalid opcode 0x%"PRIx8""
 pci_nvme_err_invalid_admin_opc(uint8_t opc) "invalid admin opcode 0x%"PRIx8""
 pci_nvme_err_invalid_lba_range(uint64_t start, uint64_t len, uint64_t limit) 
"Invalid LBA start=%"PRIu64" len=%"PRIu64" limit=%"PRIu64""
+pci_nvme_err_invalid_effects_log_offset(uint64_t ofs) "commands supported and 
effects log offset must be 0, got %"PRIu64""
 pci_nvme_err_invalid_del_sq(uint16_t qid) "invalid submission queue deletion, 
sid=%"PRIu16""
 pci_nvme_err_invalid_create_sq_cqid(uint16_t cqid) "failed creating submission 
queue, invalid cqid=%"PRIu16""
 pci_nvme_err_invalid_create_sq_sqid(uint16_t sqid) "failed creating submission 
queue, invalid sqid=%"PRIu16""
diff --git a/include/block/nvme.h b/include/block/nvme.h
index ac0ccfcb26..62136a906f 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h

[PATCH v8 24/27] ci: Enable msys2 ci in cirrus

2020-09-12 Thread Yonggang Luo
Install msys2 in a proper way refer to 
https://github.com/cirruslabs/cirrus-ci-docs/issues/699
The https://wiki.qemu.org/Hosts/W32#Native_builds_with_MSYS2 need to be updated.
There is no need of --cross-prefix, open mingw64.exe instead of msys2.exe then 
we don't
need the --cross-prefix, besides we using environment variable settings:
MSYS: winsymlinks:nativestrict
MSYSTEM: MINGW64
CHERE_INVOKING: 1
to opening mingw64 native shell.
We now running tests with make -i check to skip tests errors.

Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
---
 .cirrus.yml | 60 +
 1 file changed, 60 insertions(+)

diff --git a/.cirrus.yml b/.cirrus.yml
index 690c6882e8..1ff9f0a72f 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -44,3 +44,63 @@ macos_xcode_task:
--enable-werror --cc=clang || { cat config.log; exit 1; }
 - gmake -j$(sysctl -n hw.ncpu)
 - gmake check
+
+windows_msys2_task:
+  windows_container:
+image: cirrusci/windowsservercore:cmake
+os_version: 2019
+cpu: 8
+memory: 8G
+  env:
+MSYS: winsymlinks:nativestrict
+MSYSTEM: MINGW64
+CHERE_INVOKING: 1
+  printenv_script:
+- C:\tools\msys64\usr\bin\bash.exe -lc 'printenv'
+  install_script:
+- C:\tools\msys64\usr\bin\bash.exe -lc "cd /c/tools && curl -O 
http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz;
+- C:\tools\msys64\usr\bin\bash.exe -lc "cd /c/tools && curl -O 
http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig;
+- C:\tools\msys64\usr\bin\bash.exe -lc "cd /c/tools && pacman -U 
--noconfirm msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
+- C:\tools\msys64\usr\bin\bash.exe -lc "pacman -Sy --noconfirm"
+- C:\tools\msys64\usr\bin\bash.exe -lc "pacman --needed --noconfirm -S 
bash pacman pacman-mirrors msys2-runtime"
+- taskkill /F /IM gpg-agent.exe
+- C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Su"
+- C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -S --needed
+base-devel
+git
+mingw-w64-x86_64-python
+mingw-w64-x86_64-python-setuptools
+mingw-w64-x86_64-toolchain
+mingw-w64-x86_64-SDL2
+mingw-w64-x86_64-SDL2_image
+mingw-w64-x86_64-gtk3
+mingw-w64-x86_64-glib2
+mingw-w64-x86_64-ninja
+mingw-w64-x86_64-make
+mingw-w64-x86_64-jemalloc
+mingw-w64-x86_64-lzo2
+mingw-w64-x86_64-zstd
+mingw-w64-x86_64-libjpeg-turbo
+mingw-w64-x86_64-pixman
+mingw-w64-x86_64-libgcrypt
+mingw-w64-x86_64-capstone
+mingw-w64-x86_64-libpng
+mingw-w64-x86_64-libssh
+mingw-w64-x86_64-libxml2
+mingw-w64-x86_64-snappy
+mingw-w64-x86_64-libusb
+mingw-w64-x86_64-usbredir
+mingw-w64-x86_64-libtasn1
+mingw-w64-x86_64-libnfs
+mingw-w64-x86_64-nettle
+mingw-w64-x86_64-cyrus-sasl
+mingw-w64-x86_64-curl
+mingw-w64-x86_64-gnutls
+mingw-w64-x86_64-zstd"
+  script:
+- C:\tools\msys64\usr\bin\bash.exe -lc "mkdir build"
+- C:\tools\msys64\usr\bin\bash.exe -lc "cd build && ../configure 
--python=python3 --ninja=ninja"
+- C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make 
-j$NUMBER_OF_PROCESSORS"
+  test_script:
+- C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make V=1 check"
+
-- 
2.28.0.windows.1




[PATCH v8 25/27] meson: upgrade meson for execute custom ninjatool under msys2 properly

2020-09-12 Thread Yonggang Luo
* Bump versions to 0.55.2 for release

* Tag Info:
object 008d13038f95e7c7d8ad553f14e408da5b94c360
type commit
tag 0.55.2
tagger Jussi Pakkanen  2020/9/11 1:24:47

Signed-off-by: Yonggang Luo 
---
 meson | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson b/meson
index 68ed748f84..008d13038f 16
--- a/meson
+++ b/meson
@@ -1 +1 @@
-Subproject commit 68ed748f84f14c2d4e62dcbd123816e5898eb04c
+Subproject commit 008d13038f95e7c7d8ad553f14e408da5b94c360
-- 
2.28.0.windows.1




[PATCH v2 11/15] hw/block/nvme: Introduce max active and open zone limits

2020-09-12 Thread Dmitry Fomichev
Added two module properties, "max_active" and "max_open" to control
the maximum number of zones that can be active or open. Once these
variables are set to non-default values, these limits are checked
during I/O and Too Many Active or Too Many Open command status is
returned if they are exceeded.

Signed-off-by: Hans Holmberg 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c | 179 +++-
 hw/block/nvme.h |   4 ++
 2 files changed, 181 insertions(+), 2 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 1b0e06002c..df536fd736 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -176,6 +176,87 @@ static void nvme_remove_zone(NvmeCtrl *n, NvmeNamespace 
*ns, NvmeZoneList *zl,
 zone->prev = zone->next = 0;
 }
 
+/*
+ * Take the first zone out from a list, return NULL if the list is empty.
+ */
+static NvmeZone *nvme_remove_zone_head(NvmeCtrl *n, NvmeNamespace *ns,
+   NvmeZoneList *zl)
+{
+NvmeZone *zone = nvme_peek_zone_head(ns, zl);
+
+if (zone) {
+--zl->size;
+if (zl->size == 0) {
+zl->head = NVME_ZONE_LIST_NIL;
+zl->tail = NVME_ZONE_LIST_NIL;
+} else {
+zl->head = zone->next;
+ns->zone_array[zl->head].prev = NVME_ZONE_LIST_NIL;
+}
+zone->prev = zone->next = 0;
+}
+
+return zone;
+}
+
+/*
+ * Check if we can open a zone without exceeding open/active limits.
+ * AOR stands for "Active and Open Resources" (see TP 4053 section 2.5).
+ */
+static int nvme_aor_check(NvmeCtrl *n, NvmeNamespace *ns,
+  uint32_t act, uint32_t opn)
+{
+if (n->params.max_active_zones != 0 &&
+ns->nr_active_zones + act > n->params.max_active_zones) {
+trace_pci_nvme_err_insuff_active_res(n->params.max_active_zones);
+return NVME_ZONE_TOO_MANY_ACTIVE | NVME_DNR;
+}
+if (n->params.max_open_zones != 0 &&
+ns->nr_open_zones + opn > n->params.max_open_zones) {
+trace_pci_nvme_err_insuff_open_res(n->params.max_open_zones);
+return NVME_ZONE_TOO_MANY_OPEN | NVME_DNR;
+}
+
+return NVME_SUCCESS;
+}
+
+static inline void nvme_aor_inc_open(NvmeCtrl *n, NvmeNamespace *ns)
+{
+assert(ns->nr_open_zones >= 0);
+if (n->params.max_open_zones) {
+ns->nr_open_zones++;
+assert(ns->nr_open_zones <= n->params.max_open_zones);
+}
+}
+
+static inline void nvme_aor_dec_open(NvmeCtrl *n, NvmeNamespace *ns)
+{
+if (n->params.max_open_zones) {
+assert(ns->nr_open_zones > 0);
+ns->nr_open_zones--;
+}
+assert(ns->nr_open_zones >= 0);
+}
+
+static inline void nvme_aor_inc_active(NvmeCtrl *n, NvmeNamespace *ns)
+{
+assert(ns->nr_active_zones >= 0);
+if (n->params.max_active_zones) {
+ns->nr_active_zones++;
+assert(ns->nr_active_zones <= n->params.max_active_zones);
+}
+}
+
+static inline void nvme_aor_dec_active(NvmeCtrl *n, NvmeNamespace *ns)
+{
+if (n->params.max_active_zones) {
+assert(ns->nr_active_zones > 0);
+ns->nr_active_zones--;
+assert(ns->nr_active_zones >= ns->nr_open_zones);
+}
+assert(ns->nr_active_zones >= 0);
+}
+
 static void nvme_assign_zone_state(NvmeCtrl *n, NvmeNamespace *ns,
NvmeZone *zone, uint8_t state)
 {
@@ -715,6 +796,24 @@ static inline uint16_t nvme_check_bounds(NvmeCtrl *n, 
NvmeNamespace *ns,
 return NVME_SUCCESS;
 }
 
+static void nvme_auto_transition_zone(NvmeCtrl *n, NvmeNamespace *ns,
+  bool implicit, bool adding_active)
+{
+NvmeZone *zone;
+
+if (implicit && n->params.max_open_zones &&
+ns->nr_open_zones == n->params.max_open_zones) {
+zone = nvme_remove_zone_head(n, ns, ns->imp_open_zones);
+if (zone) {
+/*
+ * Automatically close this implicitly open zone.
+ */
+nvme_aor_dec_open(n, ns);
+nvme_assign_zone_state(n, ns, zone, NVME_ZONE_STATE_CLOSED);
+}
+}
+}
+
 static uint16_t nvme_check_zone_write(NvmeZone *zone, uint64_t slba,
   uint32_t nlb)
 {
@@ -792,6 +891,23 @@ static uint16_t nvme_check_zone_read(NvmeCtrl *n, NvmeZone 
*zone, uint64_t slba,
 return status;
 }
 
+static uint16_t nvme_auto_open_zone(NvmeCtrl *n, NvmeNamespace *ns,
+NvmeZone *zone)
+{
+uint16_t status = NVME_SUCCESS;
+uint8_t zs = nvme_get_zone_state(zone);
+
+if (zs == NVME_ZONE_STATE_EMPTY) {
+nvme_auto_transition_zone(n, ns, true, true);
+status = nvme_aor_check(n, ns, 1, 1);
+} else if (zs == NVME_ZONE_STATE_CLOSED) {
+nvme_auto_transition_zone(n, ns, true, false);
+status = nvme_aor_check(n, ns, 0, 1);
+}
+
+return status;
+}
+
 static inline uint32_t nvme_zone_idx(NvmeCtrl *n, uint64_t slba)
 {
 return n->zone_size_log2 > 0 ? 

[PATCH v8 20/27] tests: Fixes test-io-channel-file by mask only owner file state mask bits

2020-09-12 Thread Yonggang Luo
This is the error on msys2/mingw
Running test test-io-channel-file
**
ERROR:../tests/test-io-channel-file.c:59:test_io_channel_file_helper: assertion 
failed (TEST_MASK & ~mask == st.st_mode & 0777): (384 == 438)
ERROR test-io-channel-file - Bail out! 
ERROR:../tests/test-io-channel-file.c:59:test_io_channel_file_helper: assertion 
failed (TEST_MASK & ~mask == st.st_mode & 0777): (384 == 438)

Signed-off-by: Yonggang Luo 
---
 tests/test-io-channel-file.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tests/test-io-channel-file.c b/tests/test-io-channel-file.c
index bac2b07562..1b0e8d7c1b 100644
--- a/tests/test-io-channel-file.c
+++ b/tests/test-io-channel-file.c
@@ -28,6 +28,12 @@
 #define TEST_FILE "tests/test-io-channel-file.txt"
 #define TEST_MASK 0600
 
+#ifdef _WIN32
+#define TEST_MASK_EXPECT 0700
+#else
+#define TEST_MASK_EXPECT 0777
+#endif
+
 static void test_io_channel_file_helper(int flags)
 {
 QIOChannel *src, *dst;
@@ -56,7 +62,9 @@ static void test_io_channel_file_helper(int flags)
 umask(mask);
 ret = stat(TEST_FILE, );
 g_assert_cmpint(ret, >, -1);
-g_assert_cmpuint(TEST_MASK & ~mask, ==, st.st_mode & 0777);
+/* On Windows the stat() function in the C library checks only
+ the FAT-style READONLY attribute and does not look at the ACL at all. */
+g_assert_cmpuint(TEST_MASK & ~mask, ==, st.st_mode & TEST_MASK_EXPECT);
 
 unlink(TEST_FILE);
 object_unref(OBJECT(src));
-- 
2.28.0.windows.1




[PATCH v8 23/27] rcu: fixes test-logging.c by call drain_call_rcu before rmdir_full

2020-09-12 Thread Yonggang Luo
drain_call_rcu is necessary on win32, because under win32, if you
don't close the file before remove it, the remove would be fail.

Signed-off-by: Yonggang Luo 
---
 tests/test-logging.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/test-logging.c b/tests/test-logging.c
index 783fe09a27..8b1522cfed 100644
--- a/tests/test-logging.c
+++ b/tests/test-logging.c
@@ -210,6 +210,8 @@ int main(int argc, char **argv)
  tmp_path, test_logfile_lock);
 
 rc = g_test_run();
+qemu_log_close();
+drain_call_rcu();
 
 rmdir_full(tmp_path);
 return rc;
-- 
2.28.0.windows.1




[PATCH v8 22/27] tests: Fixes test-qdev-global-props.c

2020-09-12 Thread Yonggang Luo
On win32 the line ending are \r\n, so we skip the \n in function 
test_dynamic_globalprop

Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
---
 tests/test-qdev-global-props.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index 8a3c14d92c..be6bcfc46b 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -251,10 +251,10 @@ static void test_dynamic_globalprop(void)
 g_test_trap_assert_passed();
 g_test_trap_assert_stderr_unmatched("*prop1*");
 g_test_trap_assert_stderr_unmatched("*prop2*");
-g_test_trap_assert_stderr("*warning: global dynamic-prop-type-bad.prop3 
has invalid class name\n*");
+g_test_trap_assert_stderr("*warning: global dynamic-prop-type-bad.prop3 
has invalid class name*");
 g_test_trap_assert_stderr_unmatched("*prop4*");
-g_test_trap_assert_stderr("*warning: global nohotplug-type.prop5=105 not 
used\n*");
-g_test_trap_assert_stderr("*warning: global nondevice-type.prop6 has 
invalid class name\n*");
+g_test_trap_assert_stderr("*warning: global nohotplug-type.prop5=105 not 
used*");
+g_test_trap_assert_stderr("*warning: global nondevice-type.prop6 has 
invalid class name*");
 g_test_trap_assert_stdout("");
 }
 
-- 
2.28.0.windows.1




[PATCH v2 07/15] hw/block/nvme: Add support for active/inactive namespaces

2020-09-12 Thread Dmitry Fomichev
From: Niklas Cassel 

In NVMe, a namespace is active if it exists and is attached to the
controller.

CAP.CSS (together with the I/O Command Set data structure) defines what
command sets are supported by the controller.

CC.CSS (together with Set Profile) can be set to enable a subset of the
available command sets. The namespaces belonging to a disabled command set
will not be able to attach to the controller, and will thus be inactive.

E.g., if the user sets CC.CSS to Admin Only, NVM namespaces should be
marked as inactive.

The identify namespace, the identify namespace CSI specific, and the namespace
list commands have two different versions, one that only shows active
namespaces, and the other version that shows existing namespaces, regardless
of whether the namespace is attached or not.

Add an attached member to struct NvmeNamespace, and implement the missing CNS
commands.

The added functionality will also simplify the implementation of namespace
management in the future, since namespace management can also attach and
detach namespaces.

Signed-off-by: Niklas Cassel 
Signed-off-by: Dmitry Fomichev 
---
 hw/block/nvme.c  | 54 
 hw/block/nvme.h  |  1 +
 include/block/nvme.h | 20 +---
 3 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 004f1c9578..6dd6bf9183 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1193,7 +1193,8 @@ static uint16_t nvme_identify_ctrl_csi(NvmeCtrl *n, 
NvmeRequest *req)
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
-static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeRequest *req)
+static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeRequest *req,
+ bool only_active)
 {
 NvmeNamespace *ns;
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
@@ -1211,11 +1212,16 @@ static uint16_t nvme_identify_ns(NvmeCtrl *n, 
NvmeRequest *req)
 ns = >namespaces[nsid - 1];
 assert(nsid == ns->nsid);
 
+if (only_active && !ns->attached) {
+return nvme_rpt_empty_id_struct(n, prp1, prp2, req);
+}
+
 return nvme_dma_prp(n, (uint8_t *)>id_ns, sizeof(ns->id_ns), prp1,
 prp2, DMA_DIRECTION_FROM_DEVICE, req);
 }
 
-static uint16_t nvme_identify_ns_csi(NvmeCtrl *n, NvmeRequest *req)
+static uint16_t nvme_identify_ns_csi(NvmeCtrl *n, NvmeRequest *req,
+ bool only_active)
 {
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
 NvmeNamespace *ns;
@@ -1233,6 +1239,10 @@ static uint16_t nvme_identify_ns_csi(NvmeCtrl *n, 
NvmeRequest *req)
 ns = >namespaces[nsid - 1];
 assert(nsid == ns->nsid);
 
+if (only_active && !ns->attached) {
+return nvme_rpt_empty_id_struct(n, prp1, prp2, req);
+}
+
 if (c->csi == NVME_CSI_NVM) {
 return nvme_rpt_empty_id_struct(n, prp1, prp2, req);
 }
@@ -1240,7 +1250,8 @@ static uint16_t nvme_identify_ns_csi(NvmeCtrl *n, 
NvmeRequest *req)
 return NVME_INVALID_FIELD | NVME_DNR;
 }
 
-static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeRequest *req)
+static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeRequest *req,
+ bool only_active)
 {
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
 static const int data_len = NVME_IDENTIFY_DATA_SIZE;
@@ -1265,7 +1276,7 @@ static uint16_t nvme_identify_nslist(NvmeCtrl *n, 
NvmeRequest *req)
 
 list = g_malloc0(data_len);
 for (i = 0; i < n->num_namespaces; i++) {
-if (i < min_nsid) {
+if (i < min_nsid || (only_active && !n->namespaces[i].attached)) {
 continue;
 }
 list[j++] = cpu_to_le32(i + 1);
@@ -1279,7 +1290,8 @@ static uint16_t nvme_identify_nslist(NvmeCtrl *n, 
NvmeRequest *req)
 return ret;
 }
 
-static uint16_t nvme_identify_nslist_csi(NvmeCtrl *n, NvmeRequest *req)
+static uint16_t nvme_identify_nslist_csi(NvmeCtrl *n, NvmeRequest *req,
+ bool only_active)
 {
 NvmeIdentify *c = (NvmeIdentify *)>cmd;
 static const int data_len = NVME_IDENTIFY_DATA_SIZE;
@@ -1298,7 +1310,8 @@ static uint16_t nvme_identify_nslist_csi(NvmeCtrl *n, 
NvmeRequest *req)
 
 list = g_malloc0(data_len);
 for (i = 0; i < n->num_namespaces; i++) {
-if (i < min_nsid) {
+if (i < min_nsid || c->csi != n->namespaces[i].csi ||
+(only_active && !n->namespaces[i].attached)) {
 continue;
 }
 list[j++] = cpu_to_le32(i + 1);
@@ -1390,17 +1403,25 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeRequest 
*req)
 
 switch (le32_to_cpu(c->cns)) {
 case NVME_ID_CNS_NS:
-return nvme_identify_ns(n, req);
+return nvme_identify_ns(n, req, true);
 case NVME_ID_CNS_CS_NS:
-return nvme_identify_ns_csi(n, req);
+return nvme_identify_ns_csi(n, req, true);
+case NVME_ID_CNS_NS_PRESENT:
+return nvme_identify_ns(n, req, false);
+case 

[PATCH v8 18/27] tests: Fixes test-io-channel-socket.c tests under msys2/mingw

2020-09-12 Thread Yonggang Luo
Currently test-io-channel-socket doesn't init with
qemu_init_main_loop
and that's cause the qemu_aio_context not inited,
and the following is the stack when null pointer accessed:

qemu_fd_register (c:\work\xemu\qemu\util\main-loop.c:336)
qemu_try_set_nonblock (c:\work\xemu\qemu\util\oslib-win32.c:224)
qemu_set_nonblock (c:\work\xemu\qemu\util\oslib-win32.c:230)
socket_can_bind_connect (c:\work\xemu\qemu\tests\socket-helpers.c:93)
socket_check_protocol_support (c:\work\xemu\qemu\tests\socket-helpers.c:141)
main (c:\work\xemu\qemu\tests\test-io-channel-socket.c:568)
__tmainCRTStartup (@__tmainCRTStartup:142)
mainCRTStartup (@1400014f6..140001539:3)
BaseThreadInitThunk (@BaseThreadInitThunk:9)
RtlUserThreadStart (@RtlUserThreadStart:12)

Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
---
 tests/test-io-channel-socket.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c
index d43083a766..743577d744 100644
--- a/tests/test-io-channel-socket.c
+++ b/tests/test-io-channel-socket.c
@@ -25,6 +25,7 @@
 #include "socket-helpers.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
+#include "qemu/main-loop.h"
 
 
 static void test_io_channel_set_socket_bufs(QIOChannel *src,
@@ -556,6 +557,7 @@ int main(int argc, char **argv)
 bool has_ipv4, has_ipv6;
 
 module_call_init(MODULE_INIT_QOM);
+qemu_init_main_loop(_abort);
 socket_init();
 
 g_test_init(, , NULL);
-- 
2.28.0.windows.1




[PATCH v2 01/15] hw/block/nvme: Define 64 bit cqe.result

2020-09-12 Thread Dmitry Fomichev
From: Ajay Joshi 

A new write command, Zone Append, is added as a part of Zoned
Namespace Command Set. Upon successful completion of this command,
the controller returns the start LBA of the performed write operation
in cqe.result field. Therefore, the maximum size of this variable
needs to be changed from 32 to 64 bit, consuming the reserved 32 bit
field that follows the result in CQE struct. Since the existing
commands are expected to return a 32 bit LE value, two separate
variables, result32 and result64, are now kept in a union.

Signed-off-by: Ajay Joshi 
Signed-off-by: Dmitry Fomichev 
Reviewed-by: Klaus Jensen 
---
 block/nvme.c |  2 +-
 block/trace-events   |  2 +-
 hw/block/nvme.c  | 10 +-
 include/block/nvme.h |  6 --
 4 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/block/nvme.c b/block/nvme.c
index 05485fdd11..45e1a5dcd1 100644
--- a/block/nvme.c
+++ b/block/nvme.c
@@ -333,7 +333,7 @@ static inline int nvme_translate_error(const NvmeCqe *c)
 {
 uint16_t status = (le16_to_cpu(c->status) >> 1) & 0xFF;
 if (status) {
-trace_nvme_error(le32_to_cpu(c->result),
+trace_nvme_error(le64_to_cpu(c->result64),
  le16_to_cpu(c->sq_head),
  le16_to_cpu(c->sq_id),
  le16_to_cpu(c->cid),
diff --git a/block/trace-events b/block/trace-events
index e1c79a910d..55c54a18c3 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -139,7 +139,7 @@ qed_aio_write_main(void *s, void *acb, int ret, uint64_t 
offset, size_t len) "s
 # nvme.c
 nvme_kick(void *s, int queue) "s %p queue %d"
 nvme_dma_flush_queue_wait(void *s) "s %p"
-nvme_error(int cmd_specific, int sq_head, int sqid, int cid, int status) 
"cmd_specific %d sq_head %d sqid %d cid %d status 0x%x"
+nvme_error(uint64_t cmd_specific, int sq_head, int sqid, int cid, int status) 
"cmd_specific %ld sq_head %d sqid %d cid %d status 0x%x"
 nvme_process_completion(void *s, int index, int inflight) "s %p queue %d 
inflight %d"
 nvme_process_completion_queue_plugged(void *s, int index) "s %p queue %d"
 nvme_complete_command(void *s, int index, int cid) "s %p queue %d cid %d"
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 63078f6009..3a90d80694 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -524,7 +524,7 @@ static void nvme_process_aers(void *opaque)
 
 req = n->aer_reqs[n->outstanding_aers];
 
-result = (NvmeAerResult *) >cqe.result;
+result = (NvmeAerResult *) >cqe.result32;
 result->event_type = event->result.event_type;
 result->event_info = event->result.event_info;
 result->log_page = event->result.log_page;
@@ -1247,7 +1247,7 @@ static uint16_t nvme_abort(NvmeCtrl *n, NvmeRequest *req)
 {
 uint16_t sqid = le32_to_cpu(req->cmd.cdw10) & 0x;
 
-req->cqe.result = 1;
+req->cqe.result32 = 1;
 if (nvme_check_sqid(n, sqid)) {
 return NVME_INVALID_FIELD | NVME_DNR;
 }
@@ -1425,7 +1425,7 @@ defaults:
 }
 
 out:
-req->cqe.result = cpu_to_le32(result);
+req->cqe.result32 = cpu_to_le32(result);
 return NVME_SUCCESS;
 }
 
@@ -1534,8 +1534,8 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeRequest 
*req)
 ((dw11 >> 16) & 0x) + 1,
 n->params.max_ioqpairs,
 n->params.max_ioqpairs);
-req->cqe.result = cpu_to_le32((n->params.max_ioqpairs - 1) |
-  ((n->params.max_ioqpairs - 1) << 16));
+req->cqe.result32 = cpu_to_le32((n->params.max_ioqpairs - 1) |
+((n->params.max_ioqpairs - 1) << 16));
 break;
 case NVME_ASYNCHRONOUS_EVENT_CONF:
 n->features.async_config = dw11;
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 65e68a82c8..ac0ccfcb26 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -617,8 +617,10 @@ typedef struct QEMU_PACKED NvmeAerResult {
 } NvmeAerResult;
 
 typedef struct QEMU_PACKED NvmeCqe {
-uint32_tresult;
-uint32_trsvd;
+union {
+uint64_t result64;
+uint32_t result32;
+};
 uint16_tsq_head;
 uint16_tsq_id;
 uint16_tcid;
-- 
2.21.0




[PATCH v8 13/27] tests: Enable crypto tests under msys2/mingw

2020-09-12 Thread Yonggang Luo
Fixes following tests on msys2/mingw
  'test-crypto-tlscredsx509': ['crypto-tls-x509-helpers.c', 
'pkix_asn1_tab.c',
   tasn1, crypto],
  'test-crypto-tlssession': ['crypto-tls-x509-helpers.c', 
'pkix_asn1_tab.c', 'crypto-tls-psk-helpers.c',
 tasn1, crypto],
  'test-io-channel-tls': ['io-channel-helpers.c', 
'crypto-tls-x509-helpers.c', 'pkix_asn1_tab.c',
  tasn1, io, crypto]}
These tests are failure with:
ERROR test-crypto-tlscredsx509 - missing test plan
ERROR test-crypto-tlssession - missing test plan
ERROR test-io-channel-tls - missing test plan

Because on win32 those test case are all disabled in the header

Add qemu_socket_pair for cross platform support, convert file system
handling functions to glib
Add qemu_link function instead posix only link function.
Use send ad recv from qemu that convert Windows Socks error
to errno properly.

Signed-off-by: Yonggang Luo 
---
 tests/crypto-tls-x509-helpers.c  | 169 ++-
 tests/crypto-tls-x509-helpers.h  |   9 +-
 tests/test-crypto-tlscredsx509.c |  47 +
 tests/test-crypto-tlssession.c   |  68 +++--
 tests/test-io-channel-tls.c  |  51 ++
 5 files changed, 266 insertions(+), 78 deletions(-)

diff --git a/tests/crypto-tls-x509-helpers.c b/tests/crypto-tls-x509-helpers.c
index 01b3daf358..c624d8799b 100644
--- a/tests/crypto-tls-x509-helpers.c
+++ b/tests/crypto-tls-x509-helpers.c
@@ -23,6 +23,8 @@
 #include "crypto-tls-x509-helpers.h"
 #include "crypto/init.h"
 #include "qemu/sockets.h"
+#include 
+#include 
 
 #ifdef QCRYPTO_HAVE_TLS_TEST_SUPPORT
 
@@ -133,7 +135,7 @@ void test_tls_init(const char *keyfile)
 void test_tls_cleanup(const char *keyfile)
 {
 asn1_delete_structure(_asn1);
-unlink(keyfile);
+g_remove(keyfile);
 }
 
 /*
@@ -501,8 +503,171 @@ void test_tls_discard_cert(QCryptoTLSTestCertReq *req)
 req->crt = NULL;
 
 if (getenv("QEMU_TEST_DEBUG_CERTS") == NULL) {
-unlink(req->filename);
+g_remove(req->filename);
 }
 }
 
+int qemu_link(const char *exist_path1, const char *new_path2)
+{
+#ifdef _WIN32
+g_autofree gchar *current_dir = g_get_current_dir();
+g_autofree gchar *full_path = g_build_filename(current_dir, exist_path1, 
NULL);
+return CreateSymbolicLinkA(new_path2, full_path, 0 | 
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) ? 0 : -1;
+#else
+return link(exist_path1, new_path2);
+#endif
+}
+
+#ifdef _WIN32
+
+static int __stream_socketpair(struct addrinfo* addr_info, int sock[2]){
+SOCKET listener, client, server;
+int opt = 1;
+
+listener = server = client = INVALID_SOCKET;
+listener = socket(addr_info->ai_family, addr_info->ai_socktype, 
addr_info->ai_protocol);
+if (INVALID_SOCKET == listener)
+goto fail;
+
+setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,(const char*), 
sizeof(opt));
+
+if(SOCKET_ERROR == bind(listener, addr_info->ai_addr, 
addr_info->ai_addrlen))
+goto fail;
+
+if (SOCKET_ERROR == getsockname(listener, addr_info->ai_addr, 
(int*)_info->ai_addrlen))
+goto fail;
+
+if(SOCKET_ERROR == listen(listener, 5))
+goto fail;
+
+client = socket(addr_info->ai_family, addr_info->ai_socktype, 
addr_info->ai_protocol);
+
+if (INVALID_SOCKET == client)
+goto fail;
+
+if (SOCKET_ERROR == 
connect(client,addr_info->ai_addr,addr_info->ai_addrlen))
+goto fail;
+
+server = accept(listener, 0, 0);
+
+if (INVALID_SOCKET == server)
+goto fail;
+
+closesocket(listener);
+
+sock[0] = client;
+sock[1] = server;
+
+return 0;
+fail:
+if(INVALID_SOCKET!=listener)
+closesocket(listener);
+if (INVALID_SOCKET!=client)
+closesocket(client);
+return -1;
+}
+
+static int __dgram_socketpair(struct addrinfo* addr_info, int sock[2])
+{
+SOCKET client, server;
+struct addrinfo addr, *result = NULL;
+const char* address;
+int opt = 1;
+
+server = client = INVALID_SOCKET;
+
+server = socket(addr_info->ai_family, addr_info->ai_socktype, 
addr_info->ai_protocol);  
+if (INVALID_SOCKET == server)
+goto fail;
+
+setsockopt(server, SOL_SOCKET,SO_REUSEADDR, (const char*), 
sizeof(opt));
+
+if(SOCKET_ERROR == bind(server, addr_info->ai_addr, addr_info->ai_addrlen))
+goto fail;
+
+if (SOCKET_ERROR == getsockname(server, addr_info->ai_addr, 
(int*)_info->ai_addrlen))
+goto fail;
+
+client = socket(addr_info->ai_family, addr_info->ai_socktype, 
addr_info->ai_protocol); 
+if (INVALID_SOCKET == client)
+goto fail;
+
+memset(,0,sizeof(addr));
+addr.ai_family = addr_info->ai_family;
+addr.ai_socktype = addr_info->ai_socktype;
+addr.ai_protocol = addr_info->ai_protocol;
+
+if (AF_INET6==addr.ai_family)
+address = "0:0:0:0:0:0:0:1";
+else
+address = "127.0.0.1";
+
+if (getaddrinfo(address, "0", 

[PATCH v8 21/27] tests: fix test-util-sockets.c

2020-09-12 Thread Yonggang Luo
Fixes following errors:
Running test test-util-sockets
ERROR test-util-sockets - missing test plan

# Start of name tests
**
ERROR:../tests/test-util-sockets.c:93:test_socket_fd_pass_name_good: assertion 
failed (fd != -1): (-1 != -1)
Bail out! ERROR:../tests/test-util-sockets.c:93:test_socket_fd_pass_name_good: 
assertion failed (fd != -1): (-1 != -1)

First should call to qemu_init_main_loop before socket_init,
then on win32 doesn't support for SOCKET_ADDRESS_TYPE_FD socket type

Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
---
 tests/test-util-sockets.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
index af9f5c0c70..1bbb16d9b1 100644
--- a/tests/test-util-sockets.c
+++ b/tests/test-util-sockets.c
@@ -75,7 +75,7 @@ int monitor_vprintf(Monitor *mon, const char *fmt, va_list 
ap) { abort(); }
 void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) {}
 void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp) {}
 
-
+#ifndef _WIN32
 static void test_socket_fd_pass_name_good(void)
 {
 SocketAddress addr;
@@ -227,6 +227,7 @@ static void test_socket_fd_pass_num_nocli(void)
 
 g_free(addr.u.fd.str);
 }
+#endif
 
 #ifdef __linux__
 static gchar *abstract_sock_name;
@@ -321,6 +322,7 @@ int main(int argc, char **argv)
 {
 bool has_ipv4, has_ipv6;
 
+qemu_init_main_loop(_abort);
 socket_init();
 
 g_test_init(, , NULL);
@@ -340,6 +342,7 @@ int main(int argc, char **argv)
 test_fd_is_socket_bad);
 g_test_add_func("/util/socket/is-socket/good",
 test_fd_is_socket_good);
+#ifndef _WIN32
 g_test_add_func("/socket/fd-pass/name/good",
 test_socket_fd_pass_name_good);
 g_test_add_func("/socket/fd-pass/name/bad",
@@ -352,6 +355,7 @@ int main(int argc, char **argv)
 test_socket_fd_pass_num_bad);
 g_test_add_func("/socket/fd-pass/num/nocli",
 test_socket_fd_pass_num_nocli);
+#endif
 }
 
 #ifdef __linux__
-- 
2.28.0.windows.1




[PATCH v8 17/27] tests: Convert g_free to g_autofree macro in test-logging.c

2020-09-12 Thread Yonggang Luo
g_autofree are prefer than g_free when possible.

Signed-off-by: Yonggang Luo 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
---
 tests/test-logging.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tests/test-logging.c b/tests/test-logging.c
index 8a1161de1d..783fe09a27 100644
--- a/tests/test-logging.c
+++ b/tests/test-logging.c
@@ -196,7 +196,7 @@ static void rmdir_full(gchar const *root)
 
 int main(int argc, char **argv)
 {
-gchar *tmp_path = g_dir_make_tmp("qemu-test-logging.XX", NULL);
+g_autofree gchar *tmp_path = g_dir_make_tmp("qemu-test-logging.XX", 
NULL);
 int rc;
 
 g_test_init(, , NULL);
@@ -212,6 +212,5 @@ int main(int argc, char **argv)
 rc = g_test_run();
 
 rmdir_full(tmp_path);
-g_free(tmp_path);
 return rc;
 }
-- 
2.28.0.windows.1




[PATCH v8 14/27] meson: remove empty else and duplicated gio deps

2020-09-12 Thread Yonggang Luo
Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
---
 meson.build | 6 --
 1 file changed, 6 deletions(-)

diff --git a/meson.build b/meson.build
index bd84a1e777..a725b66a83 100644
--- a/meson.build
+++ b/meson.build
@@ -317,7 +317,6 @@ opengl = not_found
 if 'CONFIG_OPENGL' in config_host
   opengl = declare_dependency(compile_args: 
config_host['OPENGL_CFLAGS'].split(),
   link_args: config_host['OPENGL_LIBS'].split())
-else
 endif
 gtk = not_found
 if 'CONFIG_GTK' in config_host
@@ -344,11 +343,6 @@ if 'CONFIG_ICONV' in config_host
   iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
  link_args: config_host['ICONV_LIBS'].split())
 endif
-gio = not_found
-if 'CONFIG_GIO' in config_host
-  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
-   link_args: config_host['GIO_LIBS'].split())
-endif
 vnc = not_found
 png = not_found
 jpeg = not_found
-- 
2.28.0.windows.1




[PATCH v8 16/27] cirrus: Building freebsd in a single short

2020-09-12 Thread Yonggang Luo
This reverts commit 45f7b7b9f38f5c4d1529a37c93dedfc26a231bba
("cirrus.yml: Split FreeBSD job into two parts").

freebsd 1 hour limit not hit anymore

I think we going to a wrong direction, I think there is some tests a stall the 
test runner,
please look at
https://cirrus-ci.com/task/5110577531977728
When its running properly, the consumed time are little, but when tests running 
too long,
look at the cpu usage, the cpu usage are nearly zero. doesn't consuming time.

And look at
https://cirrus-ci.com/task/6119341601062912

If the tests running properly, the time consuming are little
We should not hide the error by split them

Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Ed Maste 
---
 .cirrus.yml | 35 ---
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/.cirrus.yml b/.cirrus.yml
index 3dd9fcff7f..690c6882e8 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1,38 +1,19 @@
 env:
   CIRRUS_CLONE_DEPTH: 1
 
-freebsd_1st_task:
+freebsd_12_task:
   freebsd_instance:
 image_family: freebsd-12-1
-cpu: 4
-memory: 4G
-  install_script: ASSUME_ALWAYS_YES=yes pkg bootstrap -f ; pkg install -y
-bash curl cyrus-sasl git glib gmake gnutls gsed
-nettle perl5 pixman pkgconf png usbredir
+cpu: 8
+memory: 8G
+  install_script:
+- ASSUME_ALWAYS_YES=yes pkg bootstrap -f ;
+- pkg install -y bash curl cyrus-sasl git glib gmake gnutls gsed 
+  nettle perl5 pixman pkgconf png usbredir
   script:
 - mkdir build
 - cd build
-- ../configure --disable-user --target-list-exclude='alpha-softmmu
-ppc64-softmmu ppc-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu
-sparc64-softmmu sparc-softmmu x86_64-softmmu i386-softmmu'
---enable-werror || { cat config.log; exit 1; }
-- gmake -j$(sysctl -n hw.ncpu)
-- gmake -j$(sysctl -n hw.ncpu) check
-
-freebsd_2nd_task:
-  freebsd_instance:
-image_family: freebsd-12-1
-cpu: 4
-memory: 4G
-  install_script: ASSUME_ALWAYS_YES=yes pkg bootstrap -f ; pkg install -y
-bash curl cyrus-sasl git glib gmake gnutls gtk3 gsed libepoxy mesa-libs
-nettle perl5 pixman pkgconf png SDL2 usbredir
-  script:
-- ./configure --enable-werror --target-list='alpha-softmmu ppc64-softmmu
-ppc-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu
-sparc64-softmmu sparc-softmmu x86_64-softmmu i386-softmmu
-sparc-bsd-user sparc64-bsd-user x86_64-bsd-user i386-bsd-user'
-|| { cat config.log; exit 1; }
+- ../configure --enable-werror || { cat config.log; exit 1; }
 - gmake -j$(sysctl -n hw.ncpu)
 - gmake -j$(sysctl -n hw.ncpu) check
 
-- 
2.28.0.windows.1




[PATCH v8 12/27] gcrypt: test_tls_psk_init should write binary file instead text file.

2020-09-12 Thread Yonggang Luo
On windows, if open file with "w", it's will automatically convert
"\n" to "\r\n" when writing to file.

Convert unlink to use g_remove.

Signed-off-by: Yonggang Luo 
---
 tests/crypto-tls-psk-helpers.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tests/crypto-tls-psk-helpers.c b/tests/crypto-tls-psk-helpers.c
index a8395477c3..5d5537 100644
--- a/tests/crypto-tls-psk-helpers.c
+++ b/tests/crypto-tls-psk-helpers.c
@@ -26,13 +26,15 @@
 #include "crypto-tls-psk-helpers.h"
 #include "qemu/sockets.h"
 
+#include 
+
 #ifdef QCRYPTO_HAVE_TLS_TEST_SUPPORT
 
 void test_tls_psk_init(const char *pskfile)
 {
 FILE *fp;
 
-fp = fopen(pskfile, "w");
+fp = fopen(pskfile, "wb");
 if (fp == NULL) {
 g_critical("Failed to create pskfile %s", pskfile);
 abort();
@@ -44,7 +46,7 @@ void test_tls_psk_init(const char *pskfile)
 
 void test_tls_psk_cleanup(const char *pskfile)
 {
-unlink(pskfile);
+g_remove(pskfile);
 }
 
 #endif /* QCRYPTO_HAVE_TLS_TEST_SUPPORT */
-- 
2.28.0.windows.1




[PATCH v8 15/27] vmstate: Fixes test-vmstate.c on msys2/mingw

2020-09-12 Thread Yonggang Luo
The vmstate are valid on win32, just need generate tmp path properly

Signed-off-by: Yonggang Luo 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
Reviewed-by: Daniel P. Berrangé 
---
 tests/test-vmstate.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c
index 1c763015d0..ac38bfcfe8 100644
--- a/tests/test-vmstate.c
+++ b/tests/test-vmstate.c
@@ -34,7 +34,6 @@
 #include "qemu/module.h"
 #include "io/channel-file.h"
 
-static char temp_file[] = "/tmp/vmst.test.XX";
 static int temp_fd;
 
 
@@ -1484,6 +1483,8 @@ static void test_tmp_struct(void)
 
 int main(int argc, char **argv)
 {
+g_autofree char *temp_file = g_strdup_printf(
+"%s/vmst.test.XX", g_get_tmp_dir());
 temp_fd = mkstemp(temp_file);
 
 module_call_init(MODULE_INIT_QOM);
-- 
2.28.0.windows.1




[PATCH v8 11/27] meson: Use -b to ignore CR vs. CR-LF issues on Windows

2020-09-12 Thread Yonggang Luo
On windows, a difference in line endings causes testsuite failures
complaining that every single line in files such as
'tests/qapi-schemadoc-good.texi' is wrong.  Fix it by adding -b to diff.

Signed-off-by: Yonggang Luo 
Reviewed-by: Eric Blake 
Reviewed-by: Daniel P. Berrangé 
---
 tests/qapi-schema/meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build
index c87d141417..f1449298b0 100644
--- a/tests/qapi-schema/meson.build
+++ b/tests/qapi-schema/meson.build
@@ -220,6 +220,6 @@ qapi_doc = custom_target('QAPI doc',
 
 # "full_path()" needed here to work around
 # https://github.com/mesonbuild/meson/issues/7585
-test('QAPI doc', diff, args: ['-u', files('doc-good.texi'), 
qapi_doc[0].full_path()],
+test('QAPI doc', diff, args: ['-b', '-u', files('doc-good.texi'), 
qapi_doc[0].full_path()],
  depends: qapi_doc,
  suite: ['qapi-schema', 'qapi-doc'])
-- 
2.28.0.windows.1




[PATCH v8 10/27] osdep: file locking functions are not available on Win32

2020-09-12 Thread Yonggang Luo
int qemu_lock_fd(int fd, int64_t start, int64_t len, bool exclusive);
int qemu_unlock_fd(int fd, int64_t start, int64_t len);
int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive);
bool qemu_has_ofd_lock(void);

Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
---
 include/qemu/osdep.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 412962d91a..e80fddd1e8 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -502,11 +502,11 @@ int qemu_close(int fd);
 int qemu_unlink(const char *name);
 #ifndef _WIN32
 int qemu_dup(int fd);
-#endif
 int qemu_lock_fd(int fd, int64_t start, int64_t len, bool exclusive);
 int qemu_unlock_fd(int fd, int64_t start, int64_t len);
 int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive);
 bool qemu_has_ofd_lock(void);
+#endif
 
 #if defined(__HAIKU__) && defined(__i386__)
 #define FMT_pid "%ld"
-- 
2.28.0.windows.1




[PATCH v8 08/27] tests: Fixes test-replication.c on msys2/mingw.

2020-09-12 Thread Yonggang Luo
On Windows there is no path like /tmp/s_local_disk.XX
Use g_get_tmp_dir instead of /tmp.

Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
---
 tests/test-replication.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/tests/test-replication.c b/tests/test-replication.c
index 9ab3666a90..e7cbd6b144 100644
--- a/tests/test-replication.c
+++ b/tests/test-replication.c
@@ -23,14 +23,14 @@
 
 /* primary */
 #define P_ID "primary-id"
-static char p_local_disk[] = "/tmp/p_local_disk.XX";
+static char *p_local_disk;
 
 /* secondary */
 #define S_ID "secondary-id"
 #define S_LOCAL_DISK_ID "secondary-local-disk-id"
-static char s_local_disk[] = "/tmp/s_local_disk.XX";
-static char s_active_disk[] = "/tmp/s_active_disk.XX";
-static char s_hidden_disk[] = "/tmp/s_hidden_disk.XX";
+static char *s_local_disk;
+static char *s_active_disk;
+static char *s_hidden_disk;
 
 /* FIXME: steal from blockdev.c */
 QemuOptsList qemu_drive_opts = {
@@ -571,6 +571,11 @@ static void setup_sigabrt_handler(void)
 int main(int argc, char **argv)
 {
 int ret;
+const char *tmpdir = g_get_tmp_dir();
+p_local_disk = g_strdup_printf("%s/p_local_disk.XX", tmpdir);
+s_local_disk = g_strdup_printf("%s/s_local_disk.XX", tmpdir);
+s_active_disk = g_strdup_printf("%s/s_active_disk.XX", tmpdir);
+s_hidden_disk = g_strdup_printf("%s/s_hidden_disk.XX", tmpdir);
 qemu_init_main_loop(_fatal);
 bdrv_init();
 
@@ -605,5 +610,10 @@ int main(int argc, char **argv)
 
 cleanup_imgs();
 
+g_free(p_local_disk);
+g_free(s_local_disk);
+g_free(s_active_disk);
+g_free(s_hidden_disk);
+
 return ret;
 }
-- 
2.28.0.windows.1




[PATCH v8 19/27] tests: fixes aio-win32 about aio_remove_fd_handler, get it consistence with aio-posix.c

2020-09-12 Thread Yonggang Luo
This is a fixes for
(C:\work\xemu\qemu\build\tests\test-aio-multithread.exe:19100): GLib-CRITICAL 
**: 23:03:24.965: g_source_remove_poll: assertion '!SOURCE_DESTROYED (source)' 
failed
ERROR test-aio-multithread - Bail out! GLib-FATAL-CRITICAL: 
g_source_remove_poll: assertion '!SOURCE_DESTROYED (source)' failed

(C:\work\xemu\qemu\build\tests\test-bdrv-drain.exe:21036): GLib-CRITICAL **: 
23:03:29.861: g_source_remove_poll: assertion '!SOURCE_DESTROYED (source)' 
failed
ERROR test-bdrv-drain - Bail out! GLib-FATAL-CRITICAL: g_source_remove_poll: 
assertion '!SOURCE_DESTROYED (source)' failed

And the idea comes from https://patchwork.kernel.org/patch/9975239/

Signed-off-by: Yonggang Luo 
---
 util/aio-win32.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/util/aio-win32.c b/util/aio-win32.c
index 953c56ab48..9899546a8a 100644
--- a/util/aio-win32.c
+++ b/util/aio-win32.c
@@ -37,6 +37,15 @@ struct AioHandler {
 
 static void aio_remove_fd_handler(AioContext *ctx, AioHandler *node)
 {
+/* If the GSource is in the process of being destroyed then
+ * g_source_remove_poll() causes an assertion failure.  Skip
+ * removal in that case, because glib cleans up its state during
+ * destruction anyway.
+ */
+if (!g_source_is_destroyed(>source)) {
+g_source_remove_poll(>source, >pfd);
+}
+
 /* If aio_poll is in progress, just mark the node as deleted */
 if (qemu_lockcnt_count(>list_lock)) {
 node->deleted = 1;
@@ -139,8 +148,6 @@ void aio_set_event_notifier(AioContext *ctx,
 /* Are we deleting the fd handler? */
 if (!io_notify) {
 if (node) {
-g_source_remove_poll(>source, >pfd);
-
 aio_remove_fd_handler(ctx, node);
 }
 } else {
-- 
2.28.0.windows.1




[PATCH v8 07/27] tests: disable /char/stdio/* tests in test-char.c on win32

2020-09-12 Thread Yonggang Luo
These tests are blocking test-char to be finished.
Disable them by using variable is_win32, so we doesn't
need macro to open it. and easy recover those function
latter.

Signed-off-by: Yonggang Luo 
---
 tests/test-char.c | 26 --
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tests/test-char.c b/tests/test-char.c
index d35cc839bc..184ddceab8 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -77,7 +77,6 @@ static void fe_event(void *opaque, QEMUChrEvent event)
 }
 }
 
-#ifdef _WIN32
 static void char_console_test_subprocess(void)
 {
 QemuOpts *opts;
@@ -102,7 +101,7 @@ static void char_console_test(void)
 g_test_trap_assert_passed();
 g_test_trap_assert_stdout("CONSOLE");
 }
-#endif
+
 static void char_stdio_test_subprocess(void)
 {
 Chardev *chr;
@@ -1448,7 +1447,11 @@ static SocketAddress unixaddr = {
 
 int main(int argc, char **argv)
 {
-bool has_ipv4, has_ipv6;
+bool has_ipv4, has_ipv6, is_win32 = false;
+
+#ifdef _WIN32
+is_win32 = true;
+#endif
 
 qemu_init_main_loop(_abort);
 socket_init();
@@ -1467,12 +1470,15 @@ int main(int argc, char **argv)
 g_test_add_func("/char/invalid", char_invalid_test);
 g_test_add_func("/char/ringbuf", char_ringbuf_test);
 g_test_add_func("/char/mux", char_mux_test);
-#ifdef _WIN32
-g_test_add_func("/char/console/subprocess", char_console_test_subprocess);
-g_test_add_func("/char/console", char_console_test);
-#endif
-g_test_add_func("/char/stdio/subprocess", char_stdio_test_subprocess);
-g_test_add_func("/char/stdio", char_stdio_test);
+if (0) {
+g_test_add_func("/char/console/subprocess", 
char_console_test_subprocess);
+g_test_add_func("/char/console", char_console_test);
+}
+
+if (!is_win32) {
+g_test_add_func("/char/stdio/subprocess", char_stdio_test_subprocess);
+g_test_add_func("/char/stdio", char_stdio_test);
+}
 #ifndef _WIN32
 g_test_add_func("/char/pipe", char_pipe_test);
 #endif
@@ -1534,7 +1540,7 @@ int main(int argc, char **argv)
 g_test_add_data_func("/char/socket/client/dupid-reconnect/" # name, \
   ##name, char_socket_client_dupid_test)
 
-if (has_ipv4) {
+if (has_ipv4 && !is_win32) {
 SOCKET_SERVER_TEST(tcp, );
 SOCKET_CLIENT_TEST(tcp, );
 g_test_add_data_func("/char/socket/server/two-clients/tcp", ,
-- 
2.28.0.windows.1




[PATCH v8 04/27] configure: Fixes ncursesw detection under msys2/mingw and enable curses

2020-09-12 Thread Yonggang Luo
The mingw pkg-config are showing following absolute path and contains : as the 
separator,
so we must not use : as path separator. and we know the command line parameter 
are not likely
contains newline, we could use newline as path command line parameter separator

-D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199506L 
-IC:/CI-Tools/msys64/mingw64/include/ncursesw:-I/usr/include/ncursesw:
-DNCURSES_WIDECHAR -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199506L -IC -pipe 
-lncursesw -lgnurx -ltre -lintl -liconv
-DNCURSES_WIDECHAR -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199506L -IC -lncursesw
-DNCURSES_WIDECHAR -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199506L -IC -lcursesw
-DNCURSES_WIDECHAR /CI-Tools/msys64/mingw64/include/ncursesw -pipe -lncursesw 
-lgnurx -ltre -lintl -liconv
-DNCURSES_WIDECHAR /CI-Tools/msys64/mingw64/include/ncursesw -lncursesw
-DNCURSES_WIDECHAR /CI-Tools/msys64/mingw64/include/ncursesw -lcursesw
-DNCURSES_WIDECHAR -I/usr/include/ncursesw -pipe -lncursesw -lgnurx -ltre 
-lintl -liconv
-DNCURSES_WIDECHAR -I/usr/include/ncursesw -lncursesw
-DNCURSES_WIDECHAR -I/usr/include/ncursesw -lcursesw

Refer to https://unix.stackexchange.com/a/103011/218958

If your file names are guaranteed not to contain newlines, you can use newlines 
as the separator. W
hen you expand the variable, first turn off globbing with set -f and set the 
list of field splitting characters
IFS to contain only a newline.

msys2/mingw lacks the POSIX-required langinfo.h.

gcc test.c -DNCURSES_WIDECHAR -I/mingw64/include/ncursesw -pipe -lncursesw 
-lgnurx -ltre -lintl -liconv
test.c:4:10: fatal error: langinfo.h: No such file or directory
4 | #include 
  |  ^~~~
compilation terminated.

So we using g_get_codeset instead of nl_langinfo(CODESET)

Signed-off-by: Yonggang Luo 
Reviewed-by: Gerd Hoffmann 
---
 configure   | 25 +++--
 ui/curses.c | 10 +-
 2 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/configure b/configure
index f4f8bc3756..b21843fdb9 100755
--- a/configure
+++ b/configure
@@ -3653,35 +3653,40 @@ if test "$iconv" = "no" ; then
 fi
 if test "$curses" != "no" ; then
   if test "$mingw32" = "yes" ; then
-curses_inc_list="$($pkg_config --cflags ncurses 2>/dev/null):"
-curses_lib_list="$($pkg_config --libs ncurses 2>/dev/null):-lpdcurses"
+curses_inc_list="$($pkg_config --cflags ncurses 2>/dev/null)
+  $($pkg_config --cflags ncursesw 2>/dev/null)"
+curses_lib_list="$($pkg_config --libs ncurses 2>/dev/null)
+  $($pkg_config --libs ncursesw 2>/dev/null)
+  -lpdcurses"
   else
-curses_inc_list="$($pkg_config --cflags ncursesw 
2>/dev/null):-I/usr/include/ncursesw:"
-curses_lib_list="$($pkg_config --libs ncursesw 
2>/dev/null):-lncursesw:-lcursesw"
+curses_inc_list="$($pkg_config --cflags ncursesw 2>/dev/null)
+  -I/usr/include/ncursesw:"
+curses_lib_list="$($pkg_config --libs ncursesw 2>/dev/null)
+  -lncursesw
+  -lcursesw"
   fi
   curses_found=no
   cat > $TMPC << EOF
 #include 
 #include 
 #include 
-#include 
 int main(void) {
-  const char *codeset;
   wchar_t wch = L'w';
   setlocale(LC_ALL, "");
   resize_term(0, 0);
   addwstr(L"wide chars\n");
   addnwstr(, 1);
   add_wch(WACS_DEGREE);
-  codeset = nl_langinfo(CODESET);
-  return codeset != 0;
+  return 0;
 }
 EOF
-  IFS=:
+  IFS='
+'   # turn off variable value expansion except for 
splitting at newlines
   for curses_inc in $curses_inc_list; do
 # Make sure we get the wide character prototypes
 curses_inc="-DNCURSES_WIDECHAR $curses_inc"
-IFS=:
+IFS='
+'   # turn off variable value expansion except for 
splitting at newlines
 for curses_lib in $curses_lib_list; do
   unset IFS
   if compile_prog "$curses_inc" "$curses_lib" ; then
diff --git a/ui/curses.c b/ui/curses.c
index a59b23a9cf..12bc682cf9 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -30,7 +30,6 @@
 #endif
 #include 
 #include 
-#include 
 #include 
 
 #include "qapi/error.h"
@@ -526,6 +525,7 @@ static void font_setup(void)
 iconv_t nativecharset_to_ucs2;
 iconv_t font_conv;
 int i;
+g_autofree gchar *local_codeset = g_get_codeset();
 
 /*
  * Control characters are normally non-printable, but VGA does have
@@ -566,14 +566,14 @@ static void font_setup(void)
   0x25bc
 };
 
-ucs2_to_nativecharset = iconv_open(nl_langinfo(CODESET), "UCS-2");
+ucs2_to_nativecharset = iconv_open(local_codeset, "UCS-2");
 if (ucs2_to_nativecharset == (iconv_t) -1) {
 fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n",
 strerror(errno));
 exit(1);
 }
 
-nativecharset_to_ucs2 = iconv_open("UCS-2", nl_langinfo(CODESET));
+nativecharset_to_ucs2 = iconv_open("UCS-2", local_codeset);
 if (nativecharset_to_ucs2 == (iconv_t) -1) {
 iconv_close(ucs2_to_nativecharset);
 fprintf(stderr, "Could not convert font glyphs to 

[PATCH v8 05/27] win32: Simplify gmtime_r detection direct base on _POSIX_THREAD_SAFE_FUNCTIONS.

2020-09-12 Thread Yonggang Luo
First, this reduce the size of configure, configure are tending to removal in 
future,
and this didn't introduce any new feature or remove any exist feature.
Second, the current localtime_r detection are conflict with ncursesw detection 
in
mingw, when ncursesw detected, it will provide the following compile flags
pkg-config --cflags ncursesw
-D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199506L 
-IC:/CI-Tools/msys64/mingw64/include/ncursesw
And the compile flag _POSIX_C_SOURCE will always cause 
_POSIX_THREAD_SAFE_FUNCTIONS to
be defined, in new version of mingw, that's will cause localtime_r to be 
defined.
But the configure script didn't provide _POSIX_C_SOURCE macro, and that's will 
result
localtime_r not detected because localtime_r are defined in forceinline manner.

And finally cause conflict between QEMU defined localtime_r
struct tm *localtime_r(const time_t *timep, struct tm *result);
with mingw defined localtime_r

```
#if defined(_POSIX_C_SOURCE) && !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
#endif

#ifdef _POSIX_THREAD_SAFE_FUNCTIONS
__forceinline struct tm *__CRTDECL localtime_r(const time_t *_Time, struct tm 
*_Tm) {
  return localtime_s(_Tm, _Time) ? NULL : _Tm;
}
__forceinline struct tm *__CRTDECL gmtime_r(const time_t *_Time, struct tm 
*_Tm) {
  return gmtime_s(_Tm, _Time) ? NULL : _Tm;
}
__forceinline char *__CRTDECL ctime_r(const time_t *_Time, char *_Str) {
  return ctime_s(_Str, 0x7fff, _Time) ? NULL : _Str;
}
__forceinline char *__CRTDECL asctime_r(const struct tm *_Tm, char * _Str) {
  return asctime_s(_Str, 0x7fff, _Tm) ? NULL : _Str;
}
#endif
```

So I suggest remove this configure script, and restrict msys2/mingw version to 
easy to maintain.
And use _POSIX_THREAD_SAFE_FUNCTIONS to guard the localtime_r and counterpart 
functions

Signed-off-by: Yonggang Luo 
---
 configure | 34 --
 include/sysemu/os-win32.h |  4 ++--
 util/oslib-win32.c|  2 +-
 3 files changed, 3 insertions(+), 37 deletions(-)

diff --git a/configure b/configure
index b21843fdb9..af86ba1db3 100755
--- a/configure
+++ b/configure
@@ -2495,37 +2495,6 @@ if test "$vhost_net" = ""; then
   test "$vhost_kernel" = "yes" && vhost_net=yes
 fi
 
-##
-# MinGW / Mingw-w64 localtime_r/gmtime_r check
-
-if test "$mingw32" = "yes"; then
-# Some versions of MinGW / Mingw-w64 lack localtime_r
-# and gmtime_r entirely.
-#
-# Some versions of Mingw-w64 define a macro for
-# localtime_r/gmtime_r.
-#
-# Some versions of Mingw-w64 will define functions
-# for localtime_r/gmtime_r, but only if you have
-# _POSIX_THREAD_SAFE_FUNCTIONS defined. For fun
-# though, unistd.h and pthread.h both define
-# that for you.
-#
-# So this #undef localtime_r and #include 
-# are not in fact redundant.
-cat > $TMPC << EOF
-#include 
-#include 
-#undef localtime_r
-int main(void) { localtime_r(NULL, NULL); return 0; }
-EOF
-if compile_prog "" "" ; then
-localtime_r="yes"
-else
-localtime_r="no"
-fi
-fi
-
 ##
 # pkg-config probe
 
@@ -7087,9 +7056,6 @@ if [ "$bsd" = "yes" ] ; then
   echo "CONFIG_BSD=y" >> $config_host_mak
 fi
 
-if test "$localtime_r" = "yes" ; then
-  echo "CONFIG_LOCALTIME_R=y" >> $config_host_mak
-fi
 if test "$qom_cast_debug" = "yes" ; then
   echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
 fi
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index d8978e28c0..3ac8a53bac 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -48,12 +48,12 @@
 #define siglongjmp(env, val) longjmp(env, val)
 
 /* Missing POSIX functions. Don't use MinGW-w64 macros. */
-#ifndef CONFIG_LOCALTIME_R
+#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
 #undef gmtime_r
 struct tm *gmtime_r(const time_t *timep, struct tm *result);
 #undef localtime_r
 struct tm *localtime_r(const time_t *timep, struct tm *result);
-#endif /* CONFIG_LOCALTIME_R */
+#endif
 
 static inline void os_setup_signal_handling(void) {}
 static inline void os_daemonize(void) {}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index c654dafd93..f2fa9a3549 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -106,7 +106,7 @@ void qemu_anon_ram_free(void *ptr, size_t size)
 }
 }
 
-#ifndef CONFIG_LOCALTIME_R
+#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
 /* FIXME: add proper locking */
 struct tm *gmtime_r(const time_t *timep, struct tm *result)
 {
-- 
2.28.0.windows.1




[PATCH v8 09/27] tests: test-replication disable /replication/secondary/* on msys2/mingw.

2020-09-12 Thread Yonggang Luo
They caused failure on msys2/mingw, that's because file-win32.c not implement
.bdrv_reopen_prepare/commit/abort yet.

This is the error message:
> $ ./tests/test-replication.exe
> # random seed: R02S3f4d1c01af2b0a046990e0235c481faf
> 1..13
> # Start of replication tests
> # Start of primary tests
> ok 1 /replication/primary/read
> ok 2 /replication/primary/write
> ok 3 /replication/primary/start
> ok 4 /replication/primary/stop
> ok 5 /replication/primary/do_checkpoint
> ok 6 /replication/primary/get_error_all
> # End of primary tests
> # Start of secondary tests
> ok 7 /replication/secondary/read
> ok 8 /replication/secondary/write
> Unexpected error in bdrv_reopen_prepare() at ../block.c:4191:
> Block format 'file' used by node '#block4287' does not support reopening
> files

Signed-off-by: Yonggang Luo 
Reviewed-by: Daniel P. Berrangé 
---
 tests/test-replication.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/tests/test-replication.c b/tests/test-replication.c
index e7cbd6b144..b067240add 100644
--- a/tests/test-replication.c
+++ b/tests/test-replication.c
@@ -392,6 +392,7 @@ static void test_secondary_write(void)
 teardown_secondary();
 }
 
+#ifndef _WIN32
 static void test_secondary_start(void)
 {
 BlockBackend *top_blk, *local_blk;
@@ -546,6 +547,7 @@ static void test_secondary_get_error_all(void)
 
 teardown_secondary();
 }
+#endif
 
 static void sigabrt_handler(int signo)
 {
@@ -597,6 +599,7 @@ int main(int argc, char **argv)
 /* Secondary */
 g_test_add_func("/replication/secondary/read",  test_secondary_read);
 g_test_add_func("/replication/secondary/write", test_secondary_write);
+#ifndef _WIN32
 g_test_add_func("/replication/secondary/start", test_secondary_start);
 g_test_add_func("/replication/secondary/stop",  test_secondary_stop);
 g_test_add_func("/replication/secondary/continuous_replication",
@@ -605,6 +608,7 @@ int main(int argc, char **argv)
 test_secondary_do_checkpoint);
 g_test_add_func("/replication/secondary/get_error_all",
 test_secondary_get_error_all);
+#endif
 
 ret = g_test_run();
 
-- 
2.28.0.windows.1




[PATCH v8 06/27] curses: Fixes curses compiling errors.

2020-09-12 Thread Yonggang Luo
This is the compiling error:
../ui/curses.c: In function 'curses_refresh':
../ui/curses.c:256:5: error: 'next_maybe_keycode' may be used uninitialized in 
this function [-Werror=maybe-uninitialized]
  256 | curses2foo(_curses2keycode, _curseskey2keycode, chr, maybe_keycode)
  | ^~
../ui/curses.c:302:32: note: 'next_maybe_keycode' was declared here
  302 | enum maybe_keycode next_maybe_keycode;
  |^~
../ui/curses.c:256:5: error: 'maybe_keycode' may be used uninitialized in this 
function [-Werror=maybe-uninitialized]
  256 | curses2foo(_curses2keycode, _curseskey2keycode, chr, maybe_keycode)
  | ^~
../ui/curses.c:265:24: note: 'maybe_keycode' was declared here
  265 | enum maybe_keycode maybe_keycode;
  |^
cc1.exe: all warnings being treated as errors

gcc version 10.2.0 (Rev1, Built by MSYS2 project)

Signed-off-by: Yonggang Luo 
Reviewed-by: Gerd Hoffmann 
Reviewed-by: Daniel P. Berrangé 
---
 ui/curses.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index 12bc682cf9..e4f9588c3e 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -262,7 +262,7 @@ static int curses2foo(const int _curses2foo[], const int 
_curseskey2foo[],
 static void curses_refresh(DisplayChangeListener *dcl)
 {
 int chr, keysym, keycode, keycode_alt;
-enum maybe_keycode maybe_keycode;
+enum maybe_keycode maybe_keycode = CURSES_KEYCODE;
 
 curses_winch_check();
 
@@ -299,7 +299,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
 
 /* alt or esc key */
 if (keycode == 1) {
-enum maybe_keycode next_maybe_keycode;
+enum maybe_keycode next_maybe_keycode = CURSES_KEYCODE;
 int nextchr = console_getch(_maybe_keycode);
 
 if (nextchr != -1) {
-- 
2.28.0.windows.1




[PATCH v8 03/27] ci: fixes msys2 build by upgrading capstone to 4.0.2

2020-09-12 Thread Yonggang Luo
The currently random version capstone have the following compiling issue:
  CC  /c/work/xemu/qemu/build/slirp/src/arp_table.o
make[1]: *** No rule to make target 
“/c/work/xemu/qemu/build/capstone/capstone.lib”。 Stop.

Subproject commit 1d230532840a37ac032c6ab80128238fc930c6c1 are the tagged 
version 4.0.2
when upgrading to this version, the folder structure of include are changed to
qemu\capstone\include
│  platform.h
│
├─capstone
│  arm.h
│  arm64.h
│  capstone.h
│  evm.h
│  m680x.h
│  m68k.h
│  mips.h
│  platform.h
│  ppc.h
│  sparc.h
│  systemz.h
│  tms320c64x.h
│  x86.h
│  xcore.h
│
└─windowsce
intrin.h
stdint.h

in capstone. so we need add extra include path 
-I${source_path}/capstone/include/capstone
for directly #include , and the exist include path should preserve, 
because
in capstone code there something like #include "capstone/capstone.h"

If only using
capstone_cflags="-I${source_path}/capstone/include/capstone"
Then will cause the following compiling error:

  CC  cs.o
cs.c:17:10: fatal error: 'capstone/capstone.h' file not found
#include 
 ^
1 error generated.

Signed-off-by: Yonggang Luo 
---
 capstone  | 2 +-
 configure | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/capstone b/capstone
index 22ead3e0bf..1d23053284 16
--- a/capstone
+++ b/capstone
@@ -1 +1 @@
-Subproject commit 22ead3e0bfdb87516656453336160e0a37b066bf
+Subproject commit 1d230532840a37ac032c6ab80128238fc930c6c1
diff --git a/configure b/configure
index 4231d56bcc..f4f8bc3756 100755
--- a/configure
+++ b/configure
@@ -5156,7 +5156,7 @@ case "$capstone" in
   LIBCAPSTONE=libcapstone.a
 fi
 capstone_libs="-Lcapstone -lcapstone"
-capstone_cflags="-I${source_path}/capstone/include"
+capstone_cflags="-I${source_path}/capstone/include 
-I${source_path}/capstone/include/capstone"
 ;;
 
   system)
-- 
2.28.0.windows.1




[PATCH v8 00/27] W32, W64 msys2/mingw patches

2020-09-12 Thread Yonggang Luo
It first introduce msys2 CI on cirrus by fixes nfs, capstone, curses and
disable partial test-char tests.
And then fixes all unit tests failure on msys2/mingw
This fixes the reviews suggested in the mailling list
All cirrus CI are passed

Maxim Levitsky (1):
  rcu: Implement drain_call_rcu

Yonggang Luo (26):
  block: Fixes nfs compiling error on msys2/mingw
  ci: fixes msys2 build by upgrading capstone to 4.0.2
  configure: Fixes ncursesw detection under msys2/mingw and enable
curses
  win32: Simplify gmtime_r detection direct base on
_POSIX_THREAD_SAFE_FUNCTIONS.
  curses: Fixes curses compiling errors.
  tests: disable /char/stdio/* tests in test-char.c on win32
  tests: Fixes test-replication.c on msys2/mingw.
  tests: test-replication disable /replication/secondary/* on
msys2/mingw.
  osdep: file locking functions are not available on Win32
  meson: Use -b to ignore CR vs. CR-LF issues on Windows
  gcrypt: test_tls_psk_init should write binary file instead text file.
  tests: Enable crypto tests under msys2/mingw
  meson: remove empty else and duplicated gio deps
  vmstate: Fixes test-vmstate.c on msys2/mingw
  cirrus: Building freebsd in a single short
  tests: Convert g_free to g_autofree macro in test-logging.c
  tests: Fixes test-io-channel-socket.c tests under msys2/mingw
  tests: fixes aio-win32 about aio_remove_fd_handler, get it consistence
with aio-posix.c
  tests: Fixes test-io-channel-file by mask only owner file state mask
bits
  tests: fix test-util-sockets.c
  tests: Fixes test-qdev-global-props.c
  rcu: fixes test-logging.c by call drain_call_rcu before rmdir_full
  ci: Enable msys2 ci in cirrus
  meson: upgrade meson for execute custom ninjatool under msys2 properly
  meson: remove --ninja option in configure.
  Revert "configure: add --ninja option"

 .cirrus.yml  |  95 -
 block/nfs.c  |  26 -
 capstone |   2 +-
 configure|  77 --
 include/qemu/osdep.h |   2 +-
 include/qemu/rcu.h   |   1 +
 include/sysemu/os-win32.h|   4 +-
 meson|   2 +-
 meson.build  |   6 --
 tests/crypto-tls-psk-helpers.c   |   6 +-
 tests/crypto-tls-x509-helpers.c  | 169 ++-
 tests/crypto-tls-x509-helpers.h  |   9 +-
 tests/qapi-schema/meson.build|   2 +-
 tests/test-char.c|  26 +++--
 tests/test-crypto-tlscredsx509.c |  47 +
 tests/test-crypto-tlssession.c   |  68 +++--
 tests/test-io-channel-file.c |  10 +-
 tests/test-io-channel-socket.c   |   2 +
 tests/test-io-channel-tls.c  |  51 ++
 tests/test-logging.c |   5 +-
 tests/test-qdev-global-props.c   |   6 +-
 tests/test-replication.c |  22 +++-
 tests/test-util-sockets.c|   6 +-
 tests/test-vmstate.c |   3 +-
 ui/curses.c  |  14 +--
 util/aio-win32.c |  11 +-
 util/oslib-win32.c   |   2 +-
 util/rcu.c   |  55 ++
 28 files changed, 514 insertions(+), 215 deletions(-)

-- 
2.28.0.windows.1




[PATCH v8 01/27] rcu: Implement drain_call_rcu

2020-09-12 Thread Yonggang Luo
From: Maxim Levitsky 

This will allow is to preserve the semantics of hmp_device_del,
that the device is deleted immediatly which was changed by previos
patch that delayed this to RCU callback

Signed-off-by: Maxim Levitsky 
Suggested-by: Stefan Hajnoczi 
Reviewed-by: Stefan Hajnoczi 
---
 include/qemu/rcu.h |  1 +
 util/rcu.c | 55 ++
 2 files changed, 56 insertions(+)

diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
index 570aa603eb..0e375ebe13 100644
--- a/include/qemu/rcu.h
+++ b/include/qemu/rcu.h
@@ -133,6 +133,7 @@ struct rcu_head {
 };
 
 extern void call_rcu1(struct rcu_head *head, RCUCBFunc *func);
+extern void drain_call_rcu(void);
 
 /* The operands of the minus operator must have the same type,
  * which must be the one that we specify in the cast.
diff --git a/util/rcu.c b/util/rcu.c
index 60a37f72c3..c4fefa9333 100644
--- a/util/rcu.c
+++ b/util/rcu.c
@@ -293,6 +293,61 @@ void call_rcu1(struct rcu_head *node, void (*func)(struct 
rcu_head *node))
 qemu_event_set(_call_ready_event);
 }
 
+
+struct rcu_drain {
+struct rcu_head rcu;
+QemuEvent drain_complete_event;
+};
+
+static void drain_rcu_callback(struct rcu_head *node)
+{
+struct rcu_drain *event = (struct rcu_drain *)node;
+qemu_event_set(>drain_complete_event);
+}
+
+/*
+ * This function ensures that all pending RCU callbacks
+ * on the current thread are done executing
+
+ * drops big qemu lock during the wait to allow RCU thread
+ * to process the callbacks
+ *
+ */
+
+void drain_call_rcu(void)
+{
+struct rcu_drain rcu_drain;
+bool locked = qemu_mutex_iothread_locked();
+
+memset(_drain, 0, sizeof(struct rcu_drain));
+qemu_event_init(_drain.drain_complete_event, false);
+
+if (locked) {
+qemu_mutex_unlock_iothread();
+}
+
+
+/*
+ * RCU callbacks are invoked in the same order as in which they
+ * are registered, thus we can be sure that when 'drain_rcu_callback'
+ * is called, all RCU callbacks that were registered on this thread
+ * prior to calling this function are completed.
+ *
+ * Note that since we have only one global queue of the RCU callbacks,
+ * we also end up waiting for most of RCU callbacks that were registered
+ * on the other threads, but this is a side effect that shoudn't be
+ * assumed.
+ */
+
+call_rcu1(_drain.rcu, drain_rcu_callback);
+qemu_event_wait(_drain.drain_complete_event);
+
+if (locked) {
+qemu_mutex_lock_iothread();
+}
+
+}
+
 void rcu_register_thread(void)
 {
 assert(rcu_reader.ctr == 0);
-- 
2.28.0.windows.1




[PATCH v8 02/27] block: Fixes nfs compiling error on msys2/mingw

2020-09-12 Thread Yonggang Luo
These compiling errors are fixed:
../block/nfs.c:27:10: fatal error: poll.h: No such file or directory
   27 | #include 
  |  ^~~~
compilation terminated.

../block/nfs.c:63:5: error: unknown type name 'blkcnt_t'
   63 | blkcnt_t st_blocks;
  | ^~~~
../block/nfs.c: In function 'nfs_client_open':
../block/nfs.c:550:27: error: 'struct _stat64' has no member named 'st_blocks'
  550 | client->st_blocks = st.st_blocks;
  |   ^
../block/nfs.c: In function 'nfs_get_allocated_file_size':
../block/nfs.c:751:41: error: 'struct _stat64' has no member named 'st_blocks'
  751 | return (task.ret < 0 ? task.ret : st.st_blocks * 512);
  | ^
../block/nfs.c: In function 'nfs_reopen_prepare':
../block/nfs.c:805:31: error: 'struct _stat64' has no member named 'st_blocks'
  805 | client->st_blocks = st.st_blocks;
  |   ^
../block/nfs.c: In function 'nfs_get_allocated_file_size':
../block/nfs.c:752:1: error: control reaches end of non-void function 
[-Werror=return-type]
  752 | }
  | ^

On msys2/mingw, there is no st_blocks in struct _stat64, so we use consistence 
st_size instead.

Signed-off-by: Yonggang Luo 
---
 block/nfs.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/block/nfs.c b/block/nfs.c
index 61a249a9fc..98b48f363b 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -24,7 +24,9 @@
 
 #include "qemu/osdep.h"
 
+#if !defined(_WIN32)
 #include 
+#endif
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
@@ -51,6 +53,12 @@
 #define QEMU_NFS_MAX_PAGECACHE_SIZE (8388608 / NFS_BLKSIZE)
 #define QEMU_NFS_MAX_DEBUG_LEVEL 2
 
+#if defined (_WIN32)
+#define nfs_stat __stat64
+#else
+#define nfs_stat stat
+#endif
+
 typedef struct NFSClient {
 struct nfs_context *context;
 struct nfsfh *fh;
@@ -58,7 +66,9 @@ typedef struct NFSClient {
 bool has_zero_init;
 AioContext *aio_context;
 QemuMutex mutex;
+#if !defined (_WIN32)
 blkcnt_t st_blocks;
+#endif
 bool cache_used;
 NFSServer *server;
 char *path;
@@ -70,7 +80,7 @@ typedef struct NFSRPC {
 int ret;
 int complete;
 QEMUIOVector *iov;
-struct stat *st;
+struct nfs_stat *st;
 Coroutine *co;
 NFSClient *client;
 } NFSRPC;
@@ -419,7 +429,7 @@ static int64_t nfs_client_open(NFSClient *client, 
BlockdevOptionsNfs *opts,
int flags, int open_flags, Error **errp)
 {
 int64_t ret = -EINVAL;
-struct stat st;
+struct nfs_stat st;
 char *file = NULL, *strp = NULL;
 
 qemu_mutex_init(>mutex);
@@ -545,7 +555,9 @@ static int64_t nfs_client_open(NFSClient *client, 
BlockdevOptionsNfs *opts,
 }
 
 ret = DIV_ROUND_UP(st.st_size, BDRV_SECTOR_SIZE);
+#if !defined (_WIN32)
 client->st_blocks = st.st_blocks;
+#endif
 client->has_zero_init = S_ISREG(st.st_mode);
 *strp = '/';
 goto out;
@@ -706,6 +718,7 @@ static int nfs_has_zero_init(BlockDriverState *bs)
 return client->has_zero_init;
 }
 
+#if !defined (_WIN32)
 /* Called (via nfs_service) with QemuMutex held.  */
 static void
 nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
@@ -729,7 +742,7 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState 
*bs)
 {
 NFSClient *client = bs->opaque;
 NFSRPC task = {0};
-struct stat st;
+struct nfs_stat st;
 
 if (bdrv_is_read_only(bs) &&
 !(bs->open_flags & BDRV_O_NOCACHE)) {
@@ -748,6 +761,7 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState 
*bs)
 
 return (task.ret < 0 ? task.ret : st.st_blocks * 512);
 }
+#endif
 
 static int coroutine_fn
 nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
@@ -778,7 +792,7 @@ static int nfs_reopen_prepare(BDRVReopenState *state,
   BlockReopenQueue *queue, Error **errp)
 {
 NFSClient *client = state->bs->opaque;
-struct stat st;
+struct nfs_stat st;
 int ret = 0;
 
 if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) {
@@ -800,7 +814,9 @@ static int nfs_reopen_prepare(BDRVReopenState *state,
nfs_get_error(client->context));
 return ret;
 }
+#if !defined (_WIN32)
 client->st_blocks = st.st_blocks;
+#endif
 }
 
 return 0;
@@ -869,7 +885,9 @@ static BlockDriver bdrv_nfs = {
 .create_opts= _create_opts,
 
 .bdrv_has_zero_init = nfs_has_zero_init,
+#if !defined (_WIN32)
 .bdrv_get_allocated_file_size   = nfs_get_allocated_file_size,
+#endif
 .bdrv_co_truncate   = nfs_file_co_truncate,
 
 .bdrv_file_open = nfs_file_open,
-- 
2.28.0.windows.1




Re: [PATCH] iotests: Allow running from different directory

2020-09-12 Thread Claudio Fontana
On 9/3/20 7:21 PM, Kevin Wolf wrote:
> Am 03.09.2020 um 14:54 hat Max Reitz geschrieben:
>> On 02.09.20 13:03, Kevin Wolf wrote:
>>> It is convenient to be able to edit the tests and run them without
>>> changing the current working directory back and forth. Instead of
>>> assuming that $PWD is the qemu-iotests build directory, derive the build
>>> directory from the executed script.
>>>
>>> This allows 'check' to find the required files even when called from
>>> another directory. The scratch directory will still be in the current
>>> working directory.
>>>
>>> Signed-off-by: Kevin Wolf 
>>> ---
>>>  tests/qemu-iotests/check | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
>>> index 3ab859ac1a..22ada6a549 100755
>>> --- a/tests/qemu-iotests/check
>>> +++ b/tests/qemu-iotests/check
>>> @@ -44,7 +44,7 @@ then
>>>  _init_error "failed to obtain source tree name from check symlink"
>>>  fi
>>>  source_iotests=$(cd "$source_iotests"; pwd) || _init_error "failed to 
>>> enter source tree"
>>> -build_iotests=$PWD
>>> +build_iotests=$(dirname "$0")
>>
>> This breaks running check from the build tree.
>> (i.e. cd $build/tests/qemu-iotests; ./check)
>>
>> The problem is that to run the test, we do cd to the source directory
>> ($source_iotests), and so $build_iotests then becomes invalid if it’s
>> just a relative path.  In my case, this leads to the following error:
>>
>> -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
>> +./common.rc: line 139: $QEMU/tests/qemu-iotests/../../qemu-img: No such
>> file or directory
> 
> Ah, my symlinks in the source tree made it work for me.
> 
>> I think this could be resolved by wrapping the $(dirname) in
>> $(realpath), i.e.
>>
>> build_iotests=$(realpath "$(dirname "$0")")
> 
> Sounds good, I'll update it in my tree.
> 
> Kevin
> 

Hello Kevin,

the committed patch in master is now (not sure where it changed):

diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 3ab859ac1a..e14a1f354d 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -44,7 +44,7 @@ then
 _init_error "failed to obtain source tree name from check symlink"
 fi
 source_iotests=$(cd "$source_iotests"; pwd) || _init_error "failed to 
enter source tree"
-build_iotests=$PWD
+build_iotests=$(readlink -f $(dirname "$0"))
 else
 # called from the source tree
 source_iotests=$PWD

-

This seems to break the MacOS build (Cirrus-ci) though:

readlink: illegal option -- f
usage: readlink [-n] [file ...]
./check: line 60: /common.env: No such file or directory
check: failed to source common.env (make sure the qemu-iotests are run from 
tests/qemu-iotests in the build tree)
gmake: *** 
[/private/var/folders/3y/l0z1x3693dl_8n0qybp4dqwhgn/T/cirrus-ci-build/tests/Makefile.include:144:
 check-block] Error 1
Exit status: 2

Ciao,

Claudio



Re: [PATCH v9 11/14] hw/arm: Wire up BMC boot flash for npcm750-evb and quanta-gsj

2020-09-12 Thread Havard Skinnemoen
On Fri, Sep 11, 2020 at 5:46 AM Philippe Mathieu-Daudé 
wrote:

>
>
> On 9/11/20 7:20 AM, Havard Skinnemoen via wrote:
> > This allows these NPCM7xx-based boards to boot from a flash image, e.g.
> > one built with OpenBMC. For example like this:
> >
> > IMAGE=${OPENBMC}/build/tmp/deploy/images/gsj/image-bmc
> > qemu-system-arm -machine quanta-gsj -nographic \
> >   -drive file=${IMAGE},if=mtd,bus=0,unit=0,format=raw,snapshot=on
> >
> > Reviewed-by: Tyrone Ting 
> > Reviewed-by: Cédric Le Goater 
> > Tested-by: Cédric Le Goater 
> > Tested-by: Philippe Mathieu-Daudé 
> > Signed-off-by: Havard Skinnemoen 
> > ---
> >  hw/arm/npcm7xx_boards.c | 20 
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
> > index b4c772d6b5..79e2e2744c 100644
> > --- a/hw/arm/npcm7xx_boards.c
> > +++ b/hw/arm/npcm7xx_boards.c
> > @@ -20,6 +20,7 @@
> >  #include "hw/arm/npcm7xx.h"
> >  #include "hw/core/cpu.h"
> >  #include "hw/loader.h"
> > +#include "hw/qdev-properties.h"
> >  #include "qapi/error.h"
> >  #include "qemu-common.h"
> >  #include "qemu/units.h"
> > @@ -55,6 +56,22 @@ static void npcm7xx_load_bootrom(MachineState
> *machine, NPCM7xxState *soc)
> >  }
> >  }
> >
> > +static void npcm7xx_connect_flash(NPCM7xxFIUState *fiu, int cs_no,
> > +  const char *flash_type, DriveInfo
> *dinfo)
> > +{
> > +DeviceState *flash;
> > +qemu_irq flash_cs;
> > +
> > +flash = qdev_new(flash_type);
> > +if (dinfo) {
> > +qdev_prop_set_drive(flash, "drive", blk_by_legacy_dinfo(dinfo));
> > +}
> > +qdev_realize_and_unref(flash, BUS(fiu->spi), _fatal);
> > +
> > +flash_cs = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0);
> > +qdev_connect_gpio_out_named(DEVICE(fiu), "cs", cs_no, flash_cs);
> > +}
> > +
> >  static void npcm7xx_connect_dram(NPCM7xxState *soc, MemoryRegion *dram)
> >  {
> >  memory_region_add_subregion(get_system_memory(), NPCM7XX_DRAM_BA,
> dram);
> > @@ -92,6 +109,7 @@ static void npcm750_evb_init(MachineState *machine)
> >  qdev_realize(DEVICE(soc), NULL, _fatal);
> >
> >  npcm7xx_load_bootrom(machine, soc);
> > +npcm7xx_connect_flash(>fiu[0], 0, "w25q256", drive_get(IF_MTD,
> 0, 0));
>
> Nitpicking: add definition for '0' magic number
> (consider as future cleanup).
>

Thanks. I've made the change, but won't send it out until this series is
merged, or I'll fold it in if I need to do another iteration for other
reasons.

>  npcm7xx_load_kernel(machine, soc);
> >  }
> >
> > @@ -104,6 +122,8 @@ static void quanta_gsj_init(MachineState *machine)
> >  qdev_realize(DEVICE(soc), NULL, _fatal);
> >
> >  npcm7xx_load_bootrom(machine, soc);
> > +npcm7xx_connect_flash(>fiu[0], 0, "mx25l25635e",
> > +  drive_get(IF_MTD, 0, 0));
>
> Reviewed-by: Philippe Mathieu-Daudé 
>
> >  npcm7xx_load_kernel(machine, soc);
> >  }
> >
> >
>


Re: [PULL 00/17] Crypto next patches

2020-09-12 Thread Peter Maydell
On Thu, 10 Sep 2020 at 11:07, Daniel P. Berrangé  wrote:
>
> The following changes since commit 9435a8b3dd35f1f926f1b9127e8a906217a5518a:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/sirius/ipxe-20200908-pull=
> -request' into staging (2020-09-08 21:21:13 +0100)
>
> are available in the Git repository at:
>
>   https://gitlab.com/berrange/qemu tags/crypt-perf-pull-request
>
> for you to fetch changes up to 1b010d9339497b081c3b8ab4f98b2a21f2cae08d:
>
>   crypto/gcrypt: Split QCryptoCipherGcrypt into subclasses (2020-09-10 11:02:=
> 23 +0100)
>
> 
> Improve performance of crypto cipher subsystem
>
> 
>

Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.2
for any user-visible changes.

-- PMM



Re: [PULL 00/18] Trivial branch for 5.2 patches

2020-09-12 Thread Peter Maydell
On Fri, 11 Sep 2020 at 20:35, Laurent Vivier  wrote:
>
> The following changes since commit 9435a8b3dd35f1f926f1b9127e8a906217a5518a:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/sirius/ipxe-20200908-pull=
> -request' into staging (2020-09-08 21:21:13 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/vivier/qemu.git tags/trivial-branch-for-5.2-pull-request
>
> for you to fetch changes up to 8821e21414468b1810f0ccf38bcbfa5c0bd1d56b:
>
>   target/i386/kvm: Add missing fallthrough comment (2020-09-11 21:25:59 +0200)
>
> 
> trivial patches pull request 20200911
>
> 


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.2
for any user-visible changes.

-- PMM



Re: [PATCH v2 0/7] hw/char/serial: Housekeeping

2020-09-12 Thread Ed Maste
On Sat, 12 Sep 2020 at 07:46,  wrote:
>
> Patchew URL: https://patchew.org/QEMU/20200912114040.918464-1-f4...@amsat.org/
>
> Hi,
>
> This series failed build test on FreeBSD host. Please find the details below.
>
> The full log is available at
> http://patchew.org/logs/20200912114040.918464-1-f4...@amsat.org/testing.FreeBSD/?type=message.

Looks like a full disk:

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
>From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20200912114040.918464-1-f4...@amsat.org
-> patchew/20200912114040.918464-1-f4...@amsat.org
error: copy-fd: write returned No space left on device
fatal: failed to copy file to
'/var/tmp/patchew-tester-tmp-b6phottt/src/.git/objects/pack/pack-7bdf4f5a855cab7e92327c9c14876dca81c24a36.pack':
No space left on device
fatal: The remote end hung up unexpectedly



Re: [PATCH 0/3] gitmodules: add qboot, meson, and vbootrom mirrors

2020-09-12 Thread Paolo Bonzini
On 09/09/20 12:16, Stefan Hajnoczi wrote:
> This patch series adds qemu.org mirrors for qboot, meson, and vbootrom.
> 
> vbootrom is not yet used by qemu.git/master so you may wish to hold off on
> applying the final patch.
> 
> Stefan Hajnoczi (3):
>   gitmodules: switch to qemu.org qboot mirror
>   gitmodules: switch to qemu.org meson mirror
>   gitmodules: add qemu.org vbootrom submodule
> 
>  .gitmodules | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 

Thanks Stefan,

I created the github mirrors too.

Paolo




Re: [PULL v2] Block layer patches

2020-09-12 Thread Peter Maydell
On Sat, 12 Sep 2020 at 13:27, Thomas Huth  wrote:
> Peter, why did this slip through your merge tests, do you still skip the
> iotests there?

I forget what the reason for them being skipped is, maybe
it's because they demand a gnu sed ?

thanks
-- PMM



Re: [PATCH v2 2/2] hw/timer/hpet: Fix DPRINTF format string

2020-09-12 Thread Dov Murik

Hi Phil,

On 10/09/2020 16:58, Philippe Mathieu-Daudé wrote:

Fix building with HPET_DEBUG enabled:

   hw/timer/hpet.c:512:73: error: format specifies type 'unsigned int' but the 
argument has type 'uint64_t' (aka 'unsigned long') [-Werror,-Wformat]
   DPRINTF("qemu: Enter hpet_ram_writel at %" PRIx64 " = %#x\n", addr, 
value);
 ~~~   ^
 %#lx
   hw/timer/hpet.c:655:21: error: format specifies type 'unsigned int' but the 
argument has type 'uint64_t' (aka 'unsigned long') [-Werror,-Wformat]
   value, s->hpet_counter);
   ^

Reviewed-by: Thomas Huth 
Signed-off-by: Dov Murik 
Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/timer/hpet.c | 9 ++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index b683f64f1d3..20bd0388740 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -495,7 +495,8 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
  HPETState *s = opaque;
  uint64_t old_val, new_val, val, index;

-DPRINTF("qemu: Enter hpet_ram_writel at %" PRIx64 " = %#x\n", addr, value);
+DPRINTF("qemu: Enter hpet_ram_writel at %#" HWADDR_PRIx " = %#"PRIx64"\n",
+addr, value);


You still use "#" in the format string; but qemu's CODING_STYLE.rst says:

//

'#' printf flag
---

Do not use printf flag '#', like '%#x'.

Rationale: there are two ways to add a '0x' prefix to printed number: 
'0x%...'

and '%#...'. For consistency the only one way should be used. Arguments for
'0x%' are:

* it is more popular
* '%#' omits the 0x for the value 0 which makes output inconsistent

//



According to that, I think the better solution would be:

DPRINTF("qemu: Enter hpet_ram_writel at 0x%" HWADDR_PRIx
" = 0x%" PRIx64 "\n", addr, value);





  index = addr;
  old_val = hpet_ram_read(opaque, addr, 4);
  new_val = value;
@@ -637,7 +638,8 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
  }
  s->hpet_counter =
  (s->hpet_counter & 0xULL) | value;
-DPRINTF("qemu: HPET counter written. ctr = %#x -> %" PRIx64 "\n",
+DPRINTF("qemu: HPET counter written. ctr = %#"
+PRIx64 " -> %#" PRIx64 "\n",


ditto.


  value, s->hpet_counter);
  break;
  case HPET_COUNTER + 4:
@@ -646,7 +648,8 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
  }
  s->hpet_counter =
  (s->hpet_counter & 0xULL) | (((uint64_t)value) << 32);
-DPRINTF("qemu: HPET counter + 4 written. ctr = %#x -> %" PRIx64 
"\n",
+DPRINTF("qemu: HPET counter + 4 written. ctr = %#"
+PRIx64 " -> %#" PRIx64 "\n",


ditto.


  value, s->hpet_counter);
  break;
  default:



-Dov



[Bug 1895399] [NEW] Docfix: add missing virtiofsd cache default 'auto'

2020-09-12 Thread Harry Coin
Public bug reported:

The usage command line for virtiofsd has:

void fuse_cmdline_help(void)
{
printf("-h   --helpprint help\n"
...
   "-o cache=cache mode. could be one of \"auto, "
   "always, none\"\n"
   "   default: auto\n"


But the default: auto info is missing from the man page.  I suggest this patch:

--- docs/tools/virtiofsd.rst2020-09-10 18:07:45.380430677 -0500
+++ /tmp/virtiofsd.rst  2020-09-12 11:48:10.440815204 -0500
@@ -106,6 +106,7 @@
   forbids the FUSE client from caching to achieve best coherency at the cost of
   performance.  ``auto`` acts similar to NFS with a 1 second metadata cache
   timeout.  ``always`` sets a long cache lifetime at the expense of coherency.
+  The default is ``auto``.
 
 Examples
 

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1895399

Title:
  Docfix: add missing virtiofsd cache default 'auto'

Status in QEMU:
  New

Bug description:
  The usage command line for virtiofsd has:

  void fuse_cmdline_help(void)
  {
  printf("-h   --helpprint help\n"
  ...
 "-o cache=cache mode. could be one of 
\"auto, "
 "always, none\"\n"
 "   default: auto\n"

  
  But the default: auto info is missing from the man page.  I suggest this 
patch:

  --- docs/tools/virtiofsd.rst2020-09-10 18:07:45.380430677 -0500
  +++ /tmp/virtiofsd.rst  2020-09-12 11:48:10.440815204 -0500
  @@ -106,6 +106,7 @@
 forbids the FUSE client from caching to achieve best coherency at the cost 
of
 performance.  ``auto`` acts similar to NFS with a 1 second metadata cache
 timeout.  ``always`` sets a long cache lifetime at the expense of 
coherency.
  +  The default is ``auto``.
   
   Examples
   

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1895399/+subscriptions



Re: [PULL v5 00/46] Next round of Meson bugfixes and cleanups

2020-09-12 Thread Philippe Mathieu-Daudé
On Tue, Sep 8, 2020 at 3:27 PM Peter Maydell  wrote:
>
> On Tue, 8 Sep 2020 at 10:45, Paolo Bonzini  wrote:
> >
> > The following changes since commit e11bd71f89649da3cff439c030d2ccac0cc914e3:
> >
> >   Merge remote-tracking branch 
> > 'remotes/huth-gitlab/tags/pull-request-2020-09-07' into staging (2020-09-07 
> > 16:51:00 +0100)
> >
> > are available in the Git repository at:
> >
> >   https://gitlab.com/bonzini/qemu.git tags/for-upstream
> >
> > for you to fetch changes up to ef6a0d6e3927464de67f70cb13abbfe67361e0c9:
> >
> >   docs: update build system documentation (2020-09-08 07:21:55 +0200)
> >
> > 
> > meson related:
> > * convert unit tests
> > * bugfixes for mtest2make
> > * miscellaneous bugfixes
> > * dead code removal and configure cleanups
> > * oss-fuzz fixes
> > * msys fixes
>
>
> Applied, thanks.

Another failure calling 'make' in my 'sanitizer' build dir:

Head of config.log:
'../configure' '--enable-trace-backends=log' '--cc=clang'
'--cxx=clang++' '--disable-user' '--extra-cflags=-ggdb'
'--enable-debug' '--enable-sanitizers' '--skip-meson'

Dependency sdl2 found: YES 2.0.12 (cached)
Found pkg-config: /usr/bin/pkg-config (1.6.3)
Run-time dependency sdl2_image found: NO (tried pkgconfig)

../meson.build:318:2: ERROR: Key OPENGL_CFLAGS is not in dict

A full log can be found at build/meson-logs/meson-log.txt

Tail of log:

Library mpathpersist found: YES
Dependency sdl2 found: YES 2.0.12 (cached)
Pkg-config binary for MachineChoice.HOST is not cached.
Pkg-config binary for MachineChoice.HOST specified from cross file,
native file, or env var as ['pkg-config']
Found pkg-config: /usr/bin/pkg-config (1.6.3)
Determining dependency 'SDL2_image' with pkg-config executable
'/usr/bin/pkg-config'
PKG_CONFIG_PATH:
Called `/usr/bin/pkg-config --modversion SDL2_image` -> 1

Run-time dependency sdl2_image found: NO (tried pkgconfig)

Re-running the 'configure' line without '--skip-meson', then 'make' again is OK.
I ran "dnf upgrade" last week but the "dnf history" doesn't show
anything related to SDL2.




Re: [PATCH 7/7] hw/char/serial: Let SerialState have an 'id' field

2020-09-12 Thread Paolo Bonzini
On 12/09/20 13:33, Philippe Mathieu-Daudé wrote:
>> I'll send a new patch for the PCI-single device:
> Bah this can simply be squashed into the previous patch.
> 

Yup, done.

Paolo




Re: [PATCH] ui/spice-input: Remove superfluous forward declaration

2020-09-12 Thread Laurent Vivier
Le 09/09/2020 à 19:11, Philippe Mathieu-Daudé a écrit :
> We only need to forward-declare kbd_push_key() and kbd_get_leds()
> which are used in kbd_interface, not kbd_leds(). Remove this
> superfluous forward declaration.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  ui/spice-input.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/ui/spice-input.c b/ui/spice-input.c
> index d5bba231c95..21990fa9962 100644
> --- a/ui/spice-input.c
> +++ b/ui/spice-input.c
> @@ -36,7 +36,6 @@ typedef struct QemuSpiceKbd {
>  
>  static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag);
>  static uint8_t kbd_get_leds(SpiceKbdInstance *sin);
> -static void kbd_leds(void *opaque, int l);
>  
>  static const SpiceKbdInterface kbd_interface = {
>  .base.type  = SPICE_INTERFACE_KEYBOARD,
> 

Reviewed-by: Laurent Vivier 



Re: Moving to C11? (was Re: Redefinition of typedefs (C11 feature))

2020-09-12 Thread Warner Losh
On Sat, Sep 12, 2020, 2:16 AM Philippe Mathieu-Daudé 
wrote:

> On 9/11/20 10:10 PM, Warner Losh wrote:
> >
> >
> > On Fri, Sep 11, 2020 at 2:07 PM Eduardo Habkost  > > wrote:
> >
> > On Fri, Sep 11, 2020 at 08:06:10PM +0100, Peter Maydell wrote:
> > > On Fri, 11 Sep 2020 at 19:49, Eduardo Habkost  > > wrote:
> > > >
> > > > I'm wondering: do our supported build host platforms all include
> > > > compilers that are new enough to let us redefine typedefs?
> > > >
> > > > The ability to redefine typedefs is a C11 feature which would be
> > > > very useful for simplifying our QOM boilerplate code.  The
> > > > feature is supported by GCC since 2011 (v4.6.0)[1], and by clang
> > > > since 2012 (v3.1)[2].
> > >
> > > In configure we mandate either GCC v4.8 or better, or
> > > clang v3.4 or better, or XCode Clang v5.1 or better
> > > (Apple uses a different version numbering setup to upstream).
> > > So you should probably double-check that that xcode clang has
> > > what you want, but it looks like we're good to go otherwise.
> >
> > Can anybody confirm if the following is accurate?
> >
> > https://gist.github.com/yamaya/2924292#file-xcode-clang-vers-L67
> > # Xcode 5.1 (5B130a)
> > Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
> > Target: x86_64-apple-darwin13.1.0
> > Thread model: posix
> >
> > If we know we have GCC 4.8+ or clang 3.4+, can we move to C11 and
> > start using -std=gnu11?
> >
> >
> > All supported branches of FreeBSD tier 1 platforms would be fine since
> > they all use clang. Most of the tier 2 ones do too, but the ports/pkg
> > system we have will install a newer compiler if need be (the ones that
> > don't are still stuck at gcc 4.2.1 for GPLv3 reasons).
>
> See the quoted message from Peter: "In configure we mandate either
> GCC v4.8 or better"... You shouldn't be able to build QEMU in ports/pkg.
>

Ah, I was grepping for gcc/clang. It specifies compiler:c11 so I missed
that it already brings in a better compiler on those weird, old platforms.

In any event, FreeBSD won't be a problem

Warner

Regards,
>
> Phil.
>


Re: [PATCH v6 0/7] hw/misc: Add LED device

2020-09-12 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200912134041.946260-1-f4...@amsat.org/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.






The full log is available at
http://patchew.org/logs/20200912134041.946260-1-f4...@amsat.org/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[PATCH v6 7/7] hw/arm/tosa: Replace fprintf() calls by LED devices

2020-09-12 Thread Philippe Mathieu-Daudé
The recently added LED device reports LED status changes with
the 'led_set_intensity' trace event. It is less invasive than
the fprintf() calls. We need however to have a binary built
with tracing support.

Reviewed-by: Luc Michel 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/arm/tosa.c  | 40 +++-
 hw/arm/Kconfig |  1 +
 2 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 2ef6c7b2883..ca998f05232 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -24,6 +24,7 @@
 #include "hw/irq.h"
 #include "hw/ssi/ssi.h"
 #include "hw/sysbus.h"
+#include "hw/misc/led.h"
 #include "exec/address-spaces.h"
 #include "qom/object.h"
 
@@ -83,26 +84,6 @@ struct TosaMiscGPIOState {
 SysBusDevice parent_obj;
 };
 
-static void tosa_gpio_leds(void *opaque, int line, int level)
-{
-switch (line) {
-case 0:
-fprintf(stderr, "blue LED %s.\n", level ? "on" : "off");
-break;
-case 1:
-fprintf(stderr, "green LED %s.\n", level ? "on" : "off");
-break;
-case 2:
-fprintf(stderr, "amber LED %s.\n", level ? "on" : "off");
-break;
-case 3:
-fprintf(stderr, "wlan LED %s.\n", level ? "on" : "off");
-break;
-default:
-g_assert_not_reached();
-}
-}
-
 static void tosa_reset(void *opaque, int line, int level)
 {
 if (level) {
@@ -114,7 +95,6 @@ static void tosa_misc_gpio_init(Object *obj)
 {
 DeviceState *dev = DEVICE(obj);
 
-qdev_init_gpio_in_named(dev, tosa_gpio_leds, "leds", 4);
 qdev_init_gpio_in_named(dev, tosa_reset, "reset", 1);
 }
 
@@ -124,6 +104,7 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
 TC6393xbState *tmio)
 {
 DeviceState *misc_gpio;
+LEDState *led[4];
 
 misc_gpio = sysbus_create_simple(TYPE_TOSA_MISC_GPIO, -1, NULL);
 
@@ -145,14 +126,23 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
 qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_JC_CF_IRQ),
 NULL);
 
+led[0] = led_create_simple(OBJECT(misc_gpio), GPIO_POLARITY_ACTIVE_HIGH,
+   LED_COLOR_BLUE, "bluetooth");
+led[1] = led_create_simple(OBJECT(misc_gpio), GPIO_POLARITY_ACTIVE_HIGH,
+   LED_COLOR_GREEN, "note");
+led[2] = led_create_simple(OBJECT(misc_gpio), GPIO_POLARITY_ACTIVE_HIGH,
+   LED_COLOR_AMBER, "charger-error");
+led[3] = led_create_simple(OBJECT(misc_gpio), GPIO_POLARITY_ACTIVE_HIGH,
+   LED_COLOR_GREEN, "wlan");
+
 qdev_connect_gpio_out(scp1, TOSA_GPIO_BT_LED,
-  qdev_get_gpio_in_named(misc_gpio, "leds", 0));
+  qdev_get_gpio_in(DEVICE(led[0]), 0));
 qdev_connect_gpio_out(scp1, TOSA_GPIO_NOTE_LED,
-  qdev_get_gpio_in_named(misc_gpio, "leds", 1));
+  qdev_get_gpio_in(DEVICE(led[1]), 0));
 qdev_connect_gpio_out(scp1, TOSA_GPIO_CHRG_ERR_LED,
-  qdev_get_gpio_in_named(misc_gpio, "leds", 2));
+  qdev_get_gpio_in(DEVICE(led[2]), 0));
 qdev_connect_gpio_out(scp1, TOSA_GPIO_WLAN_LED,
-  qdev_get_gpio_in_named(misc_gpio, "leds", 3));
+  qdev_get_gpio_in(DEVICE(led[3]), 0));
 
 qdev_connect_gpio_out(scp1, TOSA_GPIO_TC6393XB_L3V_ON, 
tc6393xb_l3v_get(tmio));
 
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 06ba1c355b1..bbcfa098ae2 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -150,6 +150,7 @@ config TOSA
 select ZAURUS  # scoop
 select MICRODRIVE
 select PXA2XX
+select LED
 
 config SPITZ
 bool
-- 
2.26.2




[PATCH v6 4/7] hw/arm/aspeed: Add the 3 front LEDs drived by the PCA9552 #1

2020-09-12 Thread Philippe Mathieu-Daudé
The Witherspoon has 3 LEDs connected to a PCA9552. Add them.
The names and reset values are taken from:
https://github.com/open-power/witherspoon-xml/blob/master/witherspoon.xml

Example booting obmc-phosphor-image:

  $ qemu-system-arm -M witherspoon-bmc -trace led_change_intensity
  1592693373.997015:led_change_intensity LED desc:'front-fault-4' color:green 
intensity 0% -> 100%
  1592693373.997632:led_change_intensity LED desc:'front-power-3' color:green 
intensity 0% -> 100%
  1592693373.998239:led_change_intensity LED desc:'front-id-5' color:green 
intensity 0% -> 100%
  1592693500.291805:led_change_intensity LED desc:'front-power-3' color:green 
intensity 100% -> 0%
  1592693500.312041:led_change_intensity LED desc:'front-power-3' color:green 
intensity 0% -> 100%
  1592693500.821254:led_change_intensity LED desc:'front-power-3' color:green 
intensity 100% -> 0%
  1592693501.331517:led_change_intensity LED desc:'front-power-3' color:green 
intensity 0% -> 100%
  1592693501.841367:led_change_intensity LED desc:'front-power-3' color:green 
intensity 100% -> 0%
  1592693502.350839:led_change_intensity LED desc:'front-power-3' color:green 
intensity 0% -> 100%
  1592693502.861134:led_change_intensity LED desc:'front-power-3' color:green 
intensity 100% -> 0%
  1592693503.371090:led_change_intensity LED desc:'front-power-3' color:green 
intensity 0% -> 100%

We notice the front-power LED starts to blink at a ~2Hz rate.

Reviewed-by: Richard Henderson 
Reviewed-by: Luc Michel 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/arm/aspeed.c | 20 
 hw/arm/Kconfig  |  1 +
 2 files changed, 21 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 8bfb1c79ddc..83e322ea983 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -20,6 +20,7 @@
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
 #include "hw/misc/tmp105.h"
+#include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
 #include "qemu/log.h"
 #include "sysemu/block-backend.h"
@@ -521,9 +522,20 @@ static void sonorapass_bmc_i2c_init(AspeedMachineState 
*bmc)
 
 static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
 {
+static const struct {
+unsigned gpio_id;
+LEDColor color;
+const char *description;
+bool gpio_polarity;
+} pca1_leds[] = {
+{13, LED_COLOR_GREEN, "front-fault-4",  GPIO_POLARITY_ACTIVE_LOW},
+{14, LED_COLOR_GREEN, "front-power-3",  GPIO_POLARITY_ACTIVE_LOW},
+{15, LED_COLOR_GREEN, "front-id-5", GPIO_POLARITY_ACTIVE_LOW},
+};
 AspeedSoCState *soc = >soc;
 uint8_t *eeprom_buf = g_malloc0(8 * 1024);
 DeviceState *dev;
+LEDState *led;
 
 /* Bus 3: TODO bmp280@77 */
 /* Bus 3: TODO max31785@52 */
@@ -534,6 +546,14 @@ static void witherspoon_bmc_i2c_init(AspeedMachineState 
*bmc)
 aspeed_i2c_get_bus(>i2c, 3),
 _fatal);
 
+for (size_t i = 0; i < ARRAY_SIZE(pca1_leds); i++) {
+led = led_create_simple(OBJECT(bmc),
+pca1_leds[i].gpio_polarity,
+pca1_leds[i].color,
+pca1_leds[i].description);
+qdev_connect_gpio_out(dev, pca1_leds[i].gpio_id,
+  qdev_get_gpio_in(DEVICE(led), 0));
+}
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4), "tmp423", 0x4c);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), "tmp423", 0x4c);
 
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index bc3a423940b..06ba1c355b1 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -394,6 +394,7 @@ config ASPEED_SOC
 select TMP105
 select TMP421
 select UNIMP
+select LED
 
 config MPS2
 bool
-- 
2.26.2




[PATCH v6 6/7] hw/misc/mps2-scc: Use the LED device

2020-09-12 Thread Philippe Mathieu-Daudé
Per the 'ARM MPS2 and MPS2+ FPGA Prototyping Boards Technical
Reference Manual' (100112_0200_07_en):

  2.1  Overview of the MPS2 and MPS2+ hardware

   The MPS2 and MPS2+ FPGA Prototyping Boards contain the
   following components and interfaces:

   * User switches and user LEDs:

 - Two green LEDs and two push buttons that connect to
   the FPGA.
 - Eight green LEDs and one 8-way dip switch that connect
   to the MCC.

Add the 8 LEDs connected to the MCC.

This replaces the 'mps2_scc_leds' trace events by the generic
'led_set_intensity' event.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 include/hw/misc/mps2-scc.h |  2 ++
 hw/misc/mps2-scc.c | 27 ---
 hw/misc/Kconfig|  1 +
 hw/misc/trace-events   |  1 -
 4 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
index 445e268b1fd..0009479ae83 100644
--- a/include/hw/misc/mps2-scc.h
+++ b/include/hw/misc/mps2-scc.h
@@ -13,6 +13,7 @@
 #define MPS2_SCC_H
 
 #include "hw/sysbus.h"
+#include "hw/misc/led.h"
 #include "qom/object.h"
 
 #define TYPE_MPS2_SCC "mps2-scc"
@@ -28,6 +29,7 @@ struct MPS2SCC {
 
 /*< public >*/
 MemoryRegion iomem;
+LEDState *led[8];
 
 uint32_t cfg0;
 uint32_t cfg1;
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
index 9d0909e7b35..ce1dfe93562 100644
--- a/hw/misc/mps2-scc.c
+++ b/hw/misc/mps2-scc.c
@@ -20,11 +20,13 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
+#include "qemu/bitops.h"
 #include "trace.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "hw/registerfields.h"
 #include "hw/misc/mps2-scc.h"
+#include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
 
 REG32(CFG0, 0)
@@ -152,18 +154,10 @@ static void mps2_scc_write(void *opaque, hwaddr offset, 
uint64_t value,
 s->cfg0 = value;
 break;
 case A_CFG1:
-/* CFG1 bits [7:0] control the board LEDs. We don't currently have
- * a mechanism for displaying this graphically, so use a trace event.
- */
-trace_mps2_scc_leds(value & 0x80 ? '*' : '.',
-value & 0x40 ? '*' : '.',
-value & 0x20 ? '*' : '.',
-value & 0x10 ? '*' : '.',
-value & 0x08 ? '*' : '.',
-value & 0x04 ? '*' : '.',
-value & 0x02 ? '*' : '.',
-value & 0x01 ? '*' : '.');
 s->cfg1 = value;
+for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
+led_set_state(s->led[i], extract32(value, i, 1));
+}
 break;
 case A_CFGDATA_OUT:
 s->cfgdata_out = value;
@@ -236,6 +230,9 @@ static void mps2_scc_reset(DeviceState *dev)
 for (i = 0; i < NUM_OSCCLK; i++) {
 s->oscclk[i] = s->oscclk_reset[i];
 }
+for (i = 0; i < ARRAY_SIZE(s->led); i++) {
+device_cold_reset(DEVICE(s->led[i]));
+}
 }
 
 static void mps2_scc_init(Object *obj)
@@ -249,6 +246,14 @@ static void mps2_scc_init(Object *obj)
 
 static void mps2_scc_realize(DeviceState *dev, Error **errp)
 {
+MPS2SCC *s = MPS2_SCC(dev);
+
+for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
+char *name = g_strdup_printf("SCC LED%zu", i);
+s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
+  LED_COLOR_GREEN, name);
+g_free(name);
+}
 }
 
 static const VMStateDescription mps2_scc_vmstate = {
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 0cecad45aad..7557a3e7b46 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -97,6 +97,7 @@ config MPS2_FPGAIO
 
 config MPS2_SCC
 bool
+select LED
 
 config TZ_MPC
 bool
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 908272e8593..97f511aa58c 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -84,7 +84,6 @@ aspeed_scu_write(uint64_t offset, unsigned size, uint32_t 
data) "To 0x%" PRIx64
 mps2_scc_read(uint64_t offset, uint64_t data, unsigned size) "MPS2 SCC read: 
offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
 mps2_scc_write(uint64_t offset, uint64_t data, unsigned size) "MPS2 SCC write: 
offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
 mps2_scc_reset(void) "MPS2 SCC: reset"
-mps2_scc_leds(char led7, char led6, char led5, char led4, char led3, char 
led2, char led1, char led0) "MPS2 SCC LEDs: %c%c%c%c%c%c%c%c"
 mps2_scc_cfg_write(unsigned function, unsigned device, uint32_t value) "MPS2 
SCC config write: function %d device %d data 0x%" PRIx32
 mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 
SCC config read: function %d device %d data 0x%" PRIx32
 
-- 
2.26.2




[PATCH v6 3/7] hw/misc/led: Emit a trace event when LED intensity has changed

2020-09-12 Thread Philippe Mathieu-Daudé
Track the LED intensity, and emit a trace event when it changes.

Reviewed-by: Richard Henderson 
Reviewed-by: Luc Michel 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/misc/led.c| 4 
 hw/misc/trace-events | 1 +
 2 files changed, 5 insertions(+)

diff --git a/hw/misc/led.c b/hw/misc/led.c
index c5fa09a613a..5266d026d0b 100644
--- a/hw/misc/led.c
+++ b/hw/misc/led.c
@@ -41,6 +41,10 @@ void led_set_intensity(LEDState *s, unsigned 
intensity_percent)
 intensity_percent = LED_INTENSITY_PERCENT_MAX;
 }
 trace_led_set_intensity(s->description, s->color, intensity_percent);
+if (intensity_percent != s->intensity_percent) {
+trace_led_change_intensity(s->description, s->color,
+   s->intensity_percent, intensity_percent);
+}
 s->intensity_percent = intensity_percent;
 }
 
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 211ff114694..5f3f6121bc9 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -217,6 +217,7 @@ grlib_apb_pnp_read(uint64_t addr, uint32_t value) "APB PnP 
read addr:0x%03"PRIx6
 
 # led.c
 led_set_intensity(const char *color, const char *desc, uint8_t 
intensity_percent) "LED desc:'%s' color:%s intensity: %u%%"
+led_change_intensity(const char *color, const char *desc, uint8_t 
old_intensity_percent, uint8_t new_intensity_percent) "LED desc:'%s' color:%s 
intensity %u%% -> %u%%"
 
 # pca9552.c
 pca955x_gpio_status(const char *description, const char *buf) "%s GPIOs 0-15 
[%s]"
-- 
2.26.2




[PATCH v6 1/7] hw/misc/led: Add a LED device

2020-09-12 Thread Philippe Mathieu-Daudé
Add a LED device which can be connected to a GPIO output.
They can also be dimmed with PWM devices. For now we do
not implement the dimmed mode, but in preparation of a
future implementation, we start using the LED intensity.

LEDs are limited to a fixed set of colors.

Reviewed-by: Luc Michel 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/misc/led.h |  87 ++
 hw/misc/led.c | 142 ++
 MAINTAINERS   |   6 ++
 hw/misc/Kconfig   |   3 +
 hw/misc/meson.build   |   1 +
 hw/misc/trace-events  |   3 +
 6 files changed, 242 insertions(+)
 create mode 100644 include/hw/misc/led.h
 create mode 100644 hw/misc/led.c

diff --git a/include/hw/misc/led.h b/include/hw/misc/led.h
new file mode 100644
index 000..286d37c75c1
--- /dev/null
+++ b/include/hw/misc/led.h
@@ -0,0 +1,87 @@
+/*
+ * QEMU single LED device
+ *
+ * Copyright (C) 2020 Philippe Mathieu-Daudé 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_MISC_LED_H
+#define HW_MISC_LED_H
+
+#include "qom/object.h"
+
+#define TYPE_LED "led"
+
+/**
+ * LEDColor: Color of a LED
+ *
+ * This set is restricted to physically available LED colors.
+ *
+ * LED colors from 'Table 1. Product performance of LUXEON Rebel Color
+ * Line' of the 'DS68 LUXEON Rebel Color Line' datasheet available at:
+ * https://www.lumileds.com/products/color-leds/luxeon-rebel-color/
+ */
+typedef enum {  /* Coarse wavelength range */
+LED_COLOR_VIOLET,   /* 425 nm */
+LED_COLOR_BLUE, /* 475 nm */
+LED_COLOR_CYAN, /* 500 nm */
+LED_COLOR_GREEN,/* 535 nm */
+LED_COLOR_AMBER,/* 590 nm */
+LED_COLOR_ORANGE,   /* 615 nm */
+LED_COLOR_RED,  /* 630 nm */
+} LEDColor;
+
+struct LEDState {
+/* Private */
+DeviceState parent_obj;
+/* Public */
+
+uint8_t intensity_percent;
+
+/* Properties */
+char *description;
+char *color;
+};
+typedef struct LEDState LEDState;
+DECLARE_INSTANCE_CHECKER(LEDState, LED, TYPE_LED)
+
+/**
+ * led_set_intensity: Set the intensity of a LED device
+ * @s: the LED object
+ * @intensity_percent: intensity as percentage in range 0 to 100.
+ */
+void led_set_intensity(LEDState *s, unsigned intensity_percent);
+
+/**
+ * led_get_intensity:
+ * @s: the LED object
+ *
+ * Returns: The LED intensity as percentage in range 0 to 100.
+ */
+unsigned led_get_intensity(LEDState *s);
+
+/**
+ * led_set_state: Set the state of a LED device
+ * @s: the LED object
+ * @is_emitting: boolean indicating whether the LED is emitting
+ *
+ * This utility is meant for LED connected to GPIO.
+ */
+void led_set_state(LEDState *s, bool is_emitting);
+
+/**
+ * led_create_simple: Create and realize a LED device
+ * @parentobj: the parent object
+ * @color: color of the LED
+ * @description: description of the LED (optional)
+ *
+ * Create the device state structure, initialize it, and
+ * drop the reference to it (the device is realized).
+ *
+ * Returns: The newly allocated and instantiated LED object.
+ */
+LEDState *led_create_simple(Object *parentobj,
+LEDColor color,
+const char *description);
+
+#endif /* HW_MISC_LED_H */
diff --git a/hw/misc/led.c b/hw/misc/led.c
new file mode 100644
index 000..1e2f49c5710
--- /dev/null
+++ b/hw/misc/led.c
@@ -0,0 +1,142 @@
+/*
+ * QEMU single LED device
+ *
+ * Copyright (C) 2020 Philippe Mathieu-Daudé 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/led.h"
+#include "trace.h"
+
+#define LED_INTENSITY_PERCENT_MAX   100
+
+static const char * const led_color_name[] = {
+[LED_COLOR_VIOLET]  = "violet",
+[LED_COLOR_BLUE]= "blue",
+[LED_COLOR_CYAN]= "cyan",
+[LED_COLOR_GREEN]   = "green",
+[LED_COLOR_AMBER]   = "amber",
+[LED_COLOR_ORANGE]  = "orange",
+[LED_COLOR_RED] = "red",
+};
+
+static bool led_color_name_is_valid(const char *color_name)
+{
+for (size_t i = 0; i < ARRAY_SIZE(led_color_name); i++) {
+if (strcmp(color_name, led_color_name[i]) == 0) {
+return true;
+}
+}
+return false;
+}
+
+void led_set_intensity(LEDState *s, unsigned intensity_percent)
+{
+if (intensity_percent > LED_INTENSITY_PERCENT_MAX) {
+intensity_percent = LED_INTENSITY_PERCENT_MAX;
+}
+trace_led_set_intensity(s->description, s->color, intensity_percent);
+s->intensity_percent = intensity_percent;
+}
+
+unsigned led_get_intensity(LEDState *s)
+{
+return s->intensity_percent;
+}
+
+void led_set_state(LEDState *s, bool is_emitting)
+{
+led_set_intensity(s, is_emitting ? LED_INTENSITY_PERCENT_MAX : 0);
+}
+
+static void led_reset(DeviceState *dev)
+{
+LEDState *s = LED(dev);
+
+led_set_state(s, false);
+}
+
+static const VMStateDescription 

[PATCH v6 5/7] hw/misc/mps2-fpgaio: Use the LED device

2020-09-12 Thread Philippe Mathieu-Daudé
Per the 'ARM MPS2 and MPS2+ FPGA Prototyping Boards Technical
Reference Manual' (100112_0200_07_en):

  2.1  Overview of the MPS2 and MPS2+ hardware

   The MPS2 and MPS2+ FPGA Prototyping Boards contain the
   following components and interfaces:

   * User switches and user LEDs:

 - Two green LEDs and two push buttons that connect to
   the FPGA.
 - Eight green LEDs and one 8-way dip switch that connect
   to the MCC.

Add the 2 LEDs connected to the FPGA.

This replaces the 'mps2_fpgaio_leds' trace events by the generic
'led_set_intensity' event.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/misc/mps2-fpgaio.h |  2 ++
 hw/misc/mps2-fpgaio.c | 23 ++-
 hw/misc/Kconfig   |  1 +
 hw/misc/trace-events  |  1 -
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
index 991f5b731e8..513e3be6f13 100644
--- a/include/hw/misc/mps2-fpgaio.h
+++ b/include/hw/misc/mps2-fpgaio.h
@@ -22,6 +22,7 @@
 #define MPS2_FPGAIO_H
 
 #include "hw/sysbus.h"
+#include "hw/misc/led.h"
 #include "qom/object.h"
 
 #define TYPE_MPS2_FPGAIO "mps2-fpgaio"
@@ -35,6 +36,7 @@ struct MPS2FPGAIO {
 
 /*< public >*/
 MemoryRegion iomem;
+LEDState *led[2];
 
 uint32_t led0;
 uint32_t prescale;
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
index 2f3fbeef348..6af0e8f837a 100644
--- a/hw/misc/mps2-fpgaio.c
+++ b/hw/misc/mps2-fpgaio.c
@@ -24,6 +24,7 @@
 #include "migration/vmstate.h"
 #include "hw/registerfields.h"
 #include "hw/misc/mps2-fpgaio.h"
+#include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
 #include "qemu/timer.h"
 
@@ -176,12 +177,9 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, 
uint64_t value,
 
 switch (offset) {
 case A_LED0:
-/* LED bits [1:0] control board LEDs. We don't currently have
- * a mechanism for displaying this graphically, so use a trace event.
- */
-trace_mps2_fpgaio_leds(value & 0x02 ? '*' : '.',
-   value & 0x01 ? '*' : '.');
 s->led0 = value & 0x3;
+led_set_state(s->led[0], value & 0x01);
+led_set_state(s->led[1], value & 0x02);
 break;
 case A_PRESCALE:
 resync_counter(s);
@@ -239,6 +237,10 @@ static void mps2_fpgaio_reset(DeviceState *dev)
 s->counter = 0;
 s->pscntr = 0;
 s->pscntr_sync_ticks = now;
+
+for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
+device_cold_reset(DEVICE(s->led[i]));
+}
 }
 
 static void mps2_fpgaio_init(Object *obj)
@@ -251,6 +253,16 @@ static void mps2_fpgaio_init(Object *obj)
 sysbus_init_mmio(sbd, >iomem);
 }
 
+static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
+{
+MPS2FPGAIO *s = MPS2_FPGAIO(dev);
+
+s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
+  LED_COLOR_GREEN, "USERLED0");
+s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
+  LED_COLOR_GREEN, "USERLED1");
+}
+
 static bool mps2_fpgaio_counters_needed(void *opaque)
 {
 /* Currently vmstate.c insists all subsections have a 'needed' function */
@@ -299,6 +311,7 @@ static void mps2_fpgaio_class_init(ObjectClass *klass, void 
*data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->vmsd = _fpgaio_vmstate;
+dc->realize = mps2_fpgaio_realize;
 dc->reset = mps2_fpgaio_reset;
 device_class_set_props(dc, mps2_fpgaio_properties);
 }
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 5c151fa3a83..0cecad45aad 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -93,6 +93,7 @@ config MIPS_ITU
 
 config MPS2_FPGAIO
 bool
+select LED
 
 config MPS2_SCC
 bool
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 5f3f6121bc9..908272e8593 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -92,7 +92,6 @@ mps2_scc_cfg_read(unsigned function, unsigned device, 
uint32_t value) "MPS2 SCC
 mps2_fpgaio_read(uint64_t offset, uint64_t data, unsigned size) "MPS2 FPGAIO 
read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
 mps2_fpgaio_write(uint64_t offset, uint64_t data, unsigned size) "MPS2 FPGAIO 
write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
 mps2_fpgaio_reset(void) "MPS2 FPGAIO: reset"
-mps2_fpgaio_leds(char led1, char led0) "MPS2 FPGAIO LEDs: %c%c"
 
 # msf2-sysreg.c
 msf2_sysreg_write(uint64_t offset, uint32_t val, uint32_t prev) "msf2-sysreg 
write: addr 0x%08" PRIx64 " data 0x%" PRIx32 " prev 0x%" PRIx32
-- 
2.26.2




[PATCH v6 0/7] hw/misc: Add LED device

2020-09-12 Thread Philippe Mathieu-Daudé
Hello,

These patches are part of the GSoC unselected 'QEMU visualizer'
project.

This series introduce a LED device that can be easily connected
to a GPIO output.

Missing review:
- Patch #2: "hw/misc/led: Allow connecting from GPIO output"

Since v5:
- Rebased on "QOM boilerplate cleanup" (use DECLARE_INSTANCE_CHECKER)
- Addressed Luc and Richard comments
- Do not use confusing "polarity-inverted" property
- Reset LEDs in MPS2 devices
- Document GpioPolarity

Since v4:
- Fixed typos (Luc)
- Removed TYPE_TOSA_MISC_GPIO qdev conversion patch (Peter)

Since v3:
- Rebased (TYPE_TOSA_MISC_GPIO)
- Rebased (Meson)
- Addressed Richard's review comments
- Improved doc/comments

Since v2:
- Rebased on PCA9552
- Model intensity to be ready for PWM use (Dave)
- Remove QMP events until we get a UI visualizer (Peter)
- Remove microbit patch (Peter)

Since v1: addressed Eric Blake review comments
- Added QMP rate limit

Next steps planned:

- PoC visualizer...
- look at using a dbus backend (elmarco)
- look at LED array/matrix such 7segments.

Regards,

Phil.

$ git backport-diff -r v6.. -u v5
Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respective=
ly

001/7:[0013] [FC] 'hw/misc/led: Add a LED device'
002/7:[0026] [FC] 'hw/misc/led: Allow connecting from GPIO output'
003/7:[] [--] 'hw/misc/led: Emit a trace event when LED intensity has cha=
nged'
004/7:[] [--] 'hw/arm/aspeed: Add the 3 front LEDs drived by the PCA9552 =
#1'
005/7:[0004] [FC] 'hw/misc/mps2-fpgaio: Use the LED device'
006/7:[0004] [FC] 'hw/misc/mps2-scc: Use the LED device'
007/7:[] [-C] 'hw/arm/tosa: Replace fprintf() calls by LED devices'

Philippe Mathieu-Daud=C3=A9 (7):
  hw/misc/led: Add a LED device
  hw/misc/led: Allow connecting from GPIO output
  hw/misc/led: Emit a trace event when LED intensity has changed
  hw/arm/aspeed: Add the 3 front LEDs drived by the PCA9552 #1
  hw/misc/mps2-fpgaio: Use the LED device
  hw/misc/mps2-scc: Use the LED device
  hw/arm/tosa: Replace fprintf() calls by LED devices

 include/hw/misc/led.h |  97 
 include/hw/misc/mps2-fpgaio.h |   2 +
 include/hw/misc/mps2-scc.h|   2 +
 include/hw/qdev-core.h|  16 
 hw/arm/aspeed.c   |  20 +
 hw/arm/tosa.c |  40 -
 hw/misc/led.c | 161 ++
 hw/misc/mps2-fpgaio.c |  23 +++--
 hw/misc/mps2-scc.c|  27 +++---
 MAINTAINERS   |   6 ++
 hw/arm/Kconfig|   2 +
 hw/misc/Kconfig   |   5 ++
 hw/misc/meson.build   |   1 +
 hw/misc/trace-events  |   6 +-
 14 files changed, 365 insertions(+), 43 deletions(-)
 create mode 100644 include/hw/misc/led.h
 create mode 100644 hw/misc/led.c

--=20
2.26.2




[PATCH v6 2/7] hw/misc/led: Allow connecting from GPIO output

2020-09-12 Thread Philippe Mathieu-Daudé
Some devices expose GPIO lines.

Add a GPIO qdev input to our LED device, so we can
connect a GPIO output using qdev_connect_gpio_out().

When used with GPIOs, the intensity can only be either
minium or maximum. This depends of the polarity of the
GPIO (which can be inverted).
Declare the GpioPolarity type to model the polarity.

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/misc/led.h  | 10 ++
 include/hw/qdev-core.h | 16 
 hw/misc/led.c  | 17 -
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/include/hw/misc/led.h b/include/hw/misc/led.h
index 286d37c75c1..aa359b87c20 100644
--- a/include/hw/misc/led.h
+++ b/include/hw/misc/led.h
@@ -9,6 +9,7 @@
 #define HW_MISC_LED_H
 
 #include "qom/object.h"
+#include "hw/qdev-core.h"
 
 #define TYPE_LED "led"
 
@@ -37,10 +38,17 @@ struct LEDState {
 /* Public */
 
 uint8_t intensity_percent;
+qemu_irq irq;
 
 /* Properties */
 char *description;
 char *color;
+/*
+ * Determines whether a GPIO is using a positive (active-high)
+ * logic (when used with GPIO, the intensity at reset is related
+ * to the GPIO polarity).
+ */
+bool gpio_active_high;
 };
 typedef struct LEDState LEDState;
 DECLARE_INSTANCE_CHECKER(LEDState, LED, TYPE_LED)
@@ -72,6 +80,7 @@ void led_set_state(LEDState *s, bool is_emitting);
 /**
  * led_create_simple: Create and realize a LED device
  * @parentobj: the parent object
+ * @gpio_polarity: GPIO polarity
  * @color: color of the LED
  * @description: description of the LED (optional)
  *
@@ -81,6 +90,7 @@ void led_set_state(LEDState *s, bool is_emitting);
  * Returns: The newly allocated and instantiated LED object.
  */
 LEDState *led_create_simple(Object *parentobj,
+GpioPolarity gpio_polarity,
 LEDColor color,
 const char *description);
 
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index e025ba9653f..ec1f1efc37b 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -423,6 +423,22 @@ void qdev_simple_device_unplug_cb(HotplugHandler 
*hotplug_dev,
 void qdev_machine_creation_done(void);
 bool qdev_machine_modified(void);
 
+/**
+ * GpioPolarity: Polarity of a GPIO line
+ *
+ * GPIO lines use either positive (active-high) logic,
+ * or negative (active-low) logic.
+ *
+ * In active-high logic (%GPIO_POLARITY_ACTIVE_HIGH), a pin is
+ * active when the voltage on the pin is high (relative to ground);
+ * whereas in active-low logic (%GPIO_POLARITY_ACTIVE_LOW), a pin
+ * is active when the voltage on the pin is low (or grounded).
+ */
+typedef enum {
+GPIO_POLARITY_ACTIVE_LOW,
+GPIO_POLARITY_ACTIVE_HIGH
+} GpioPolarity;
+
 /**
  * qdev_get_gpio_in: Get one of a device's anonymous input GPIO lines
  * @dev: Device whose GPIO we want
diff --git a/hw/misc/led.c b/hw/misc/led.c
index 1e2f49c5710..c5fa09a613a 100644
--- a/hw/misc/led.c
+++ b/hw/misc/led.c
@@ -10,6 +10,7 @@
 #include "migration/vmstate.h"
 #include "hw/qdev-properties.h"
 #include "hw/misc/led.h"
+#include "hw/irq.h"
 #include "trace.h"
 
 #define LED_INTENSITY_PERCENT_MAX   100
@@ -53,11 +54,19 @@ void led_set_state(LEDState *s, bool is_emitting)
 led_set_intensity(s, is_emitting ? LED_INTENSITY_PERCENT_MAX : 0);
 }
 
+static void led_set_state_gpio_handler(void *opaque, int line, int new_state)
+{
+LEDState *s = LED(opaque);
+
+assert(line == 0);
+led_set_state(s, !!new_state != s->gpio_active_high);
+}
+
 static void led_reset(DeviceState *dev)
 {
 LEDState *s = LED(dev);
 
-led_set_state(s, false);
+led_set_state(s, s->gpio_active_high);
 }
 
 static const VMStateDescription vmstate_led = {
@@ -84,11 +93,14 @@ static void led_realize(DeviceState *dev, Error **errp)
 if (s->description == NULL) {
 s->description = g_strdup("n/a");
 }
+
+qdev_init_gpio_in(DEVICE(s), led_set_state_gpio_handler, 1);
 }
 
 static Property led_properties[] = {
 DEFINE_PROP_STRING("color", LEDState, color),
 DEFINE_PROP_STRING("description", LEDState, description),
+DEFINE_PROP_BOOL("gpio-active-high", LEDState, gpio_active_high, true),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -119,6 +131,7 @@ static void led_register_types(void)
 type_init(led_register_types)
 
 LEDState *led_create_simple(Object *parentobj,
+GpioPolarity gpio_polarity,
 LEDColor color,
 const char *description)
 {
@@ -126,6 +139,8 @@ LEDState *led_create_simple(Object *parentobj,
 DeviceState *dev;
 
 dev = qdev_new(TYPE_LED);
+qdev_prop_set_bit(dev, "gpio-active-high",
+  gpio_polarity == GPIO_POLARITY_ACTIVE_HIGH);
 qdev_prop_set_string(dev, "color", led_color_name[color]);
 if (!description) {
 static unsigned undescribed_led_id;
-- 
2.26.2




Re: [PATCH v5 2/7] hw/misc/led: Allow connecting from GPIO output

2020-09-12 Thread Philippe Mathieu-Daudé
On 9/12/20 10:50 AM, Philippe Mathieu-Daudé wrote:
> Eduardo is already in Cc, adding Markus.
> 
> On 9/12/20 12:44 AM, Richard Henderson wrote:
>> On 9/10/20 1:54 PM, Philippe Mathieu-Daudé wrote:
>>> Some devices expose GPIO lines.
>>>
>>> Add a GPIO qdev input to our LED device, so we can
>>> connect a GPIO output using qdev_connect_gpio_out().
>>>
>>> When used with GPIOs, the intensity can only be either
>>> minium or maximum. This depends of the polarity of the
>>> GPIO (which can be inverted).
>>> Declare the GpioPolarity type to model the polarity.
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé 
>>> ---
>>>  include/hw/misc/led.h  |  8 
>>>  include/hw/qdev-core.h |  8 
>>>  hw/misc/led.c  | 17 -
>>>  3 files changed, 32 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/include/hw/misc/led.h b/include/hw/misc/led.h
>>> index f5afaa34bfb..71c9b8c59bf 100644
>>> --- a/include/hw/misc/led.h
>>> +++ b/include/hw/misc/led.h
>>> @@ -38,10 +38,16 @@ typedef struct LEDState {
>>>  /* Public */
>>>  
>>>  uint8_t intensity_percent;
>>> +qemu_irq irq;
>>>  
>>>  /* Properties */
>>>  char *description;
>>>  char *color;
>>> +/*
>>> + * When used with GPIO, the intensity at reset is related
>>> + * to the GPIO polarity.
>>> + */
>>> +bool inverted_polarity;
>>
>> Why are you not using the GpioPolarity enum that you added?
> 
> Because it is migrated...

Luc made me realize we don't need to keep the enum in the device
state, a 'is_gpio_polarity_high' boolean is enough, so I don't
need to worry about migrating the enum.

https://www.mail-archive.com/qemu-devel@nongnu.org/msg739790.html

> 
> Using DEFINE_PROP_BOOL() is simpler that adding hardware specific
> enum visitor in hw/core/qdev-properties.c (which is included in
> user-mode builds because pulled by the CPU type).
> 
> A sane cleanup would be to make get_enum(), set_enum()
> and set_default_value_enum() public (prefixed with 'qdev_')
> in include/hw/qdev-properties.h.
> 
> Out of the scope of this series, but might be worth it.
> 
> Eduardo, Markus, what do you think?

This question still stands however :)

> 
> Thanks Richard for reviewing this series!
> 
> Phil.
> 



Re: [PULL v2] Block layer patches

2020-09-12 Thread Thomas Huth
On 10/09/2020 00.09, Eric Blake wrote:
> On 9/9/20 4:55 PM, Peter Maydell wrote:
> 
>>
>> This fails 'make check' on NetBSD and OpenBSD:
>>
>> ./check: line 47: realpath: command not found
>> ./check: line 60: /common.env: No such file or directory
>> check: failed to source common.env (make sure the qemu-iotests are run
>> from tests/qemu-iotests in the build tree)
>> gmake: *** [/home/qemu/qemu-test.vcb7nz/src/tests/Makefile.include:144:
>> check-block] Error 1
> 
> BSD has 'readlink -f' (and so does coreutils on Linux), which does the
> same thing as the Linux-only realpath.

Seems like readlink -f does not work on macOS:

 https://cirrus-ci.com/task/5735398972325888?command=main#L7038

Any ideas what to use instead?

Peter, why did this slip through your merge tests, do you still skip the
iotests there?

 Thomas




[Bug 1895219] Re: qemu git -vnc fails due to missing en-us keymap

2020-09-12 Thread Darren Blaber
A work around to get vnc enabled for those that need it until this is
fixed is to manually copy from source tree pc-bios/keymaps/* to qemu-
data keymaps directory, usually installed at /usr/share/qemu/keymaps or
/usr/local/share/qemu/keymaps (default prefix).

Commit that broke the install of keymaps is either
https://github.com/qemu/qemu/commit/09db9b9db38e82acbc1fd4fa4661ac19c387380c
(commit hash 09db9b9db38e82acbc1fd4fa4661ac19c387380c)

or
https://github.com/qemu/qemu/commit/ddcf607fa3d6881cf0286a9b88a40fde265cbe37
(commit hash ddcf607fa3d6881cf0286a9b88a40fde265cbe37)

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1895219

Title:
  qemu git -vnc fails due to missing en-us keymap

Status in QEMU:
  New

Bug description:
  If trying to run qemu with -vnc :0, it will fail with:
  ./qemu-system-x86_64 -vnc :2
  qemu-system-x86_64: -vnc :2: could not read keymap file: 'en-us'

  share/keymaps is missing en-us keymap and only has sl and sv,
  confirmed previous stable versions had en-us.

  Tried with multiple targets, on arm64 and amd64

  Git commit hash: 9435a8b3dd35f1f926f1b9127e8a906217a5518a (head)

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1895219/+subscriptions



[PATCH] tests/check-block: Do not run the iotests with old versions of bash

2020-09-12 Thread Thomas Huth
macOS is shipped with a very old version of the bash (3.2), which
is currently not suitable for running the iotests anymore. Add
a check to skip the iotests in this case - if someone still wants
to run the iotests on macOS, they can install a newer version from
homebrew, for example.

Signed-off-by: Thomas Huth 
---
 tests/check-block.sh | 5 +
 1 file changed, 5 insertions(+)

diff --git a/tests/check-block.sh b/tests/check-block.sh
index 8e29c868e5..bfe1630c1e 100755
--- a/tests/check-block.sh
+++ b/tests/check-block.sh
@@ -46,6 +46,11 @@ if ! command -v bash >/dev/null 2>&1 ; then
 exit 0
 fi
 
+if bash --version | grep 'GNU bash, version [123]' > /dev/null 2>&1 ; then
+echo "bash version too old ==> Not running the qemu-iotests."
+exit 0
+fi
+
 if ! (sed --version | grep 'GNU sed') > /dev/null 2>&1 ; then
 if ! command -v gsed >/dev/null 2>&1; then
 echo "GNU sed not available ==> Not running the qemu-iotests."
-- 
2.18.2




Re: [PATCH v2 0/7] hw/char/serial: Housekeeping

2020-09-12 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200912114040.918464-1-f4...@amsat.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

N/A. Internal error while reading log file



The full log is available at
http://patchew.org/logs/20200912114040.918464-1-f4...@amsat.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH v2 0/7] hw/char/serial: Housekeeping

2020-09-12 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200912114040.918464-1-f4...@amsat.org/



Hi,

This series failed build test on FreeBSD host. Please find the details below.






The full log is available at
http://patchew.org/logs/20200912114040.918464-1-f4...@amsat.org/testing.FreeBSD/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[PATCH v2 6/7] hw/char/serial: Alias QDEV properties from generic serial object

2020-09-12 Thread Philippe Mathieu-Daudé
Instead of overwritting the properties of the generic 'state'
object, alias them.
Note we can now propagate the "baudbase" property (except on
the PCI multi-UART device).

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial-isa.c | 4 ++--
 hw/char/serial-pci.c | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 7e1b36c3f67..c0607476c22 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -118,8 +118,6 @@ static Property serial_isa_properties[] = {
 DEFINE_PROP_UINT32("index",  ISASerialState, index,   -1),
 DEFINE_PROP_UINT32("iobase",  ISASerialState, iobase,  -1),
 DEFINE_PROP_UINT32("irq",ISASerialState, isairq,  -1),
-DEFINE_PROP_CHR("chardev",   ISASerialState, state.chr),
-DEFINE_PROP_BOOL("wakeup",   ISASerialState, state.wakeup, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -140,6 +138,8 @@ static void serial_isa_initfn(Object *o)
 ISASerialState *self = ISA_SERIAL(o);
 
 object_initialize_child(o, "serial", >state, TYPE_SERIAL);
+
+qdev_alias_all_properties(DEVICE(>state), o);
 }
 
 static const TypeInfo serial_isa_info = {
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index f68948154e0..81da2783f9e 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -84,7 +84,6 @@ static const VMStateDescription vmstate_pci_serial = {
 };
 
 static Property serial_pci_properties[] = {
-DEFINE_PROP_CHR("chardev",  PCISerialState, state.chr),
 DEFINE_PROP_UINT8("prog_if",  PCISerialState, prog_if, 0x02),
 DEFINE_PROP_END_OF_LIST(),
 };
@@ -109,6 +108,8 @@ static void serial_pci_init(Object *o)
 PCISerialState *ps = PCI_SERIAL(o);
 
 object_initialize_child(o, "serial", >state, TYPE_SERIAL);
+
+qdev_alias_all_properties(DEVICE(>state), o);
 }
 
 static const TypeInfo serial_pci_info = {
-- 
2.26.2




[PATCH v2 7/7] hw/char/serial: Let SerialState have an 'id' field

2020-09-12 Thread Philippe Mathieu-Daudé
When a SoC has multiple UARTs (some configured differently),
it is hard to associate events to their UART.

To be able to distinct trace events between various instances,
add an 'id' field. Update the trace format accordingly.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/char/serial.h   | 1 +
 hw/char/serial-pci-multi.c | 1 +
 hw/char/serial.c   | 7 ---
 hw/char/trace-events   | 6 +++---
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 09845721384..a0aaa319a93 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -76,6 +76,7 @@ struct SerialState {
 uint64_t char_transmit_time;/* time to transmit a char in ticks */
 int poll_msl;
 
+uint8_t id;
 QEMUTimer *modem_status_poll;
 MemoryRegion io;
 };
diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index 2cf3e441773..53e0c6e25c0 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -105,6 +105,7 @@ static void multi_serial_pci_realize(PCIDevice *dev, Error 
**errp)
 
 for (i = 0; i < nports; i++) {
 s = pci->state + i;
+qdev_prop_set_uint8(s, "id", i);
 if (!qdev_realize(DEVICE(s), NULL, errp)) {
 multi_serial_pci_exit(dev);
 return;
diff --git a/hw/char/serial.c b/hw/char/serial.c
index ade89fadb44..e5a6b939f13 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -177,7 +177,7 @@ static void serial_update_parameters(SerialState *s)
 ssp.stop_bits = stop_bits;
 s->char_transmit_time =  (NANOSECONDS_PER_SECOND / speed) * frame_size;
 qemu_chr_fe_ioctl(>chr, CHR_IOCTL_SERIAL_SET_PARAMS, );
-trace_serial_update_parameters(speed, parity, data_bits, stop_bits);
+trace_serial_update_parameters(s->id, speed, parity, data_bits, stop_bits);
 }
 
 static void serial_update_msl(SerialState *s)
@@ -333,7 +333,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, 
uint64_t val,
 SerialState *s = opaque;
 
 assert(size == 1 && addr < 8);
-trace_serial_write(addr, val);
+trace_serial_write(s->id, addr, val);
 switch(addr) {
 default:
 case 0:
@@ -550,7 +550,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr 
addr, unsigned size)
 ret = s->scr;
 break;
 }
-trace_serial_read(addr, ret);
+trace_serial_read(s->id, addr, ret);
 return ret;
 }
 
@@ -1013,6 +1013,7 @@ static const TypeInfo serial_io_info = {
 };
 
 static Property serial_properties[] = {
+DEFINE_PROP_UINT8("id", SerialState, id, 0),
 DEFINE_PROP_CHR("chardev", SerialState, chr),
 DEFINE_PROP_UINT32("baudbase", SerialState, baudbase, 115200),
 DEFINE_PROP_BOOL("wakeup", SerialState, wakeup, false),
diff --git a/hw/char/trace-events b/hw/char/trace-events
index 609df10fed4..45b8eaab655 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -5,9 +5,9 @@ parallel_ioport_read(const char *desc, uint16_t addr, uint8_t 
value) "read [%s]
 parallel_ioport_write(const char *desc, uint16_t addr, uint8_t value) "write 
[%s] addr 0x%02x val 0x%02x"
 
 # serial.c
-serial_read(uint16_t addr, uint8_t value) "read addr 0x%02x val 0x%02x"
-serial_write(uint16_t addr, uint8_t value) "write addr 0x%02x val 0x%02x"
-serial_update_parameters(uint64_t baudrate, char parity, int data_bits, int 
stop_bits) "baudrate=%"PRIu64" parity='%c' data=%d stop=%d"
+serial_read(uint8_t id, uint8_t addr, uint8_t value) "id#%u read addr 0x%x val 
0x%02x"
+serial_write(uint8_t id, uint8_t addr, uint8_t value) "id#%u write addr 0x%x 
val 0x%02x"
+serial_update_parameters(uint8_t id, uint64_t baudrate, char parity, int 
data_bits, int stop_bits) "id#%u baudrate=%"PRIu64" parity=%c data=%d stop=%d"
 
 # virtio-serial-bus.c
 virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t 
value) "port %u, event %u, value %u"
-- 
2.26.2




[PATCH v2 5/7] hw/char/serial: Make 'wakeup' property boolean

2020-09-12 Thread Philippe Mathieu-Daudé
Make the "wakeup" property introduced in commit 9826fd597df
("suspend: make serial ports wakeup the guest") a boolean.

As we want to reuse the generic serial properties in the
ISA model (next commit), expose this property.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/char/serial.h | 2 +-
 hw/char/serial-isa.c | 2 +-
 hw/char/serial.c | 1 +
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 264f529a7f1..09845721384 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -61,7 +61,7 @@ struct SerialState {
 uint32_t baudbase;
 uint32_t tsr_retry;
 guint watch_tag;
-uint32_t wakeup;
+bool wakeup;
 
 /* Time when the last byte was successfully sent out of the tsr */
 uint64_t last_xmit_ts;
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index d4aad81a85c..7e1b36c3f67 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -119,7 +119,7 @@ static Property serial_isa_properties[] = {
 DEFINE_PROP_UINT32("iobase",  ISASerialState, iobase,  -1),
 DEFINE_PROP_UINT32("irq",ISASerialState, isairq,  -1),
 DEFINE_PROP_CHR("chardev",   ISASerialState, state.chr),
-DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
+DEFINE_PROP_BOOL("wakeup",   ISASerialState, state.wakeup, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/char/serial.c b/hw/char/serial.c
index ade4adfd526..ade89fadb44 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -1015,6 +1015,7 @@ static const TypeInfo serial_io_info = {
 static Property serial_properties[] = {
 DEFINE_PROP_CHR("chardev", SerialState, chr),
 DEFINE_PROP_UINT32("baudbase", SerialState, baudbase, 115200),
+DEFINE_PROP_BOOL("wakeup", SerialState, wakeup, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.26.2




[PATCH v2 3/7] hw/char/serial: Remove old DEBUG_SERIAL commented code

2020-09-12 Thread Philippe Mathieu-Daudé
All useful DPRINTF() calls have been converted to trace
events.  Remove a pointless one in the IOEventHandler,
and drop the DEBUG_SERIAL ifdef'ry.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index fb41337b661..1e70294f28a 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -36,8 +36,6 @@
 #include "trace.h"
 #include "hw/qdev-properties.h"
 
-//#define DEBUG_SERIAL
-
 #define UART_LCR_DLAB  0x80/* Divisor latch access bit */
 
 #define UART_IER_MSI   0x08/* Enable Modem status interrupt */
@@ -102,14 +100,6 @@
 
 #define MAX_XMIT_RETRY  4
 
-#ifdef DEBUG_SERIAL
-#define DPRINTF(fmt, ...) \
-do { fprintf(stderr, "serial: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) \
-do {} while (0)
-#endif
-
 static void serial_receive1(void *opaque, const uint8_t *buf, int size);
 static void serial_xmit(SerialState *s);
 
@@ -636,7 +626,6 @@ static void serial_receive1(void *opaque, const uint8_t 
*buf, int size)
 static void serial_event(void *opaque, QEMUChrEvent event)
 {
 SerialState *s = opaque;
-DPRINTF("event %x\n", event);
 if (event == CHR_EVENT_BREAK)
 serial_receive_break(s);
 }
-- 
2.26.2




[PATCH v2 2/7] hw/char/serial: Replace commented DPRINTF() by trace event

2020-09-12 Thread Philippe Mathieu-Daudé
Convert the old debug PRINTF() call to display the UART
baudrate to a trace event.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial.c | 4 +---
 hw/char/trace-events | 1 +
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index a855ef66ea2..fb41337b661 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -187,9 +187,7 @@ static void serial_update_parameters(SerialState *s)
 ssp.stop_bits = stop_bits;
 s->char_transmit_time =  (NANOSECONDS_PER_SECOND / speed) * frame_size;
 qemu_chr_fe_ioctl(>chr, CHR_IOCTL_SERIAL_SET_PARAMS, );
-
-DPRINTF("speed=%.2f parity=%c data=%d stop=%d\n",
-   speed, parity, data_bits, stop_bits);
+trace_serial_update_parameters(speed, parity, data_bits, stop_bits);
 }
 
 static void serial_update_msl(SerialState *s)
diff --git a/hw/char/trace-events b/hw/char/trace-events
index 2442a9f7d5f..17304bef26d 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -7,6 +7,7 @@ parallel_ioport_write(const char *desc, uint16_t addr, uint8_t 
value) "write [%s
 # serial.c
 serial_ioport_read(uint16_t addr, uint8_t value) "read addr 0x%02x val 0x%02x"
 serial_ioport_write(uint16_t addr, uint8_t value) "write addr 0x%02x val 
0x%02x"
+serial_update_parameters(uint64_t baudrate, char parity, int data_bits, int 
stop_bits) "baudrate=%"PRIu64" parity='%c' data=%d stop=%d"
 
 # virtio-serial-bus.c
 virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t 
value) "port %u, event %u, value %u"
-- 
2.26.2




[PATCH v2 1/7] hw/char/serial: Assert serial_ioport_read/write offset fits 8 bytes

2020-09-12 Thread Philippe Mathieu-Daudé
The serial device has 8 registers, each 8-bit. The MemoryRegionOps
'serial_io_ops' is initialized with max_access_size=1, and all
memory_region_init_io() callers correctly set the region size to
8 bytes:
- serial_io_realize
- serial_isa_realizefn
- serial_pci_realize
- multi_serial_pci_realize

It is safe to assert the offset argument of serial_ioport_read()
and serial_ioport_write() is always less than 8.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 23864794929..a855ef66ea2 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -344,7 +344,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, 
uint64_t val,
 {
 SerialState *s = opaque;
 
-addr &= 7;
+assert(size == 1 && addr < 8);
 trace_serial_ioport_write(addr, val);
 switch(addr) {
 default:
@@ -485,7 +485,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr 
addr, unsigned size)
 SerialState *s = opaque;
 uint32_t ret;
 
-addr &= 7;
+assert(size == 1 && addr < 8);
 switch(addr) {
 default:
 case 0:
-- 
2.26.2




[PATCH v2 0/7] hw/char/serial: Housekeeping

2020-09-12 Thread Philippe Mathieu-Daudé
Nothing very exciting, cleanups before more serious changes.

Since v1: addressed Paolo's comments
- Also alias QDev properties on the PCI device (patch 6)
- Initialize the 'id' property on the PCI multi-UART device (patch 7)

Patches 1-6 already queued by Paolo.

$ git backport-diff -r v2 -u v1
Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respective=
ly

001/7:[] [--] 'hw/char/serial: Assert serial_ioport_read/write offset fit=
s 8 bytes'
002/7:[] [--] 'hw/char/serial: Replace commented DPRINTF() by trace event'
003/7:[] [--] 'hw/char/serial: Remove old DEBUG_SERIAL commented code'
004/7:[] [--] 'hw/char/serial: Rename I/O read/write trace events'
005/7:[] [-C] 'hw/char/serial: Make 'wakeup' property boolean'
006/7:[0003] [FC] 'hw/char/serial: Alias QDEV properties from generic serial =
object'
007/7:[0001] [FC] 'hw/char/serial: Let SerialState have an 'id' field'

Paolo, can you take this #6 (instead of v1) and #7 now?

Thanks,

Phil.

Philippe Mathieu-Daud=C3=A9 (7):
  hw/char/serial: Assert serial_ioport_read/write offset fits 8 bytes
  hw/char/serial: Replace commented DPRINTF() by trace event
  hw/char/serial: Remove old DEBUG_SERIAL commented code
  hw/char/serial: Rename I/O read/write trace events
  hw/char/serial: Make 'wakeup' property boolean
  hw/char/serial: Alias QDEV properties from generic serial object
  hw/char/serial: Let SerialState have an 'id' field

 include/hw/char/serial.h   |  3 ++-
 hw/char/serial-isa.c   |  4 ++--
 hw/char/serial-pci-multi.c |  1 +
 hw/char/serial-pci.c   |  3 ++-
 hw/char/serial.c   | 25 +++--
 hw/char/trace-events   |  5 +++--
 6 files changed, 17 insertions(+), 24 deletions(-)

--=20
2.26.2




[PATCH v2 4/7] hw/char/serial: Rename I/O read/write trace events

2020-09-12 Thread Philippe Mathieu-Daudé
The serial_mm_read/write() handlers from the TYPE_SERIAL_MM device
call the serial_ioport_read/write() handlers with shifted offset.

When looking at the trace events from this MMIO device, it is
confusing to read the accesses as I/O. Simplify using generic
trace event names which make sense the various uses.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/char/serial.c | 4 ++--
 hw/char/trace-events | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 1e70294f28a..ade4adfd526 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -333,7 +333,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, 
uint64_t val,
 SerialState *s = opaque;
 
 assert(size == 1 && addr < 8);
-trace_serial_ioport_write(addr, val);
+trace_serial_write(addr, val);
 switch(addr) {
 default:
 case 0:
@@ -550,7 +550,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr 
addr, unsigned size)
 ret = s->scr;
 break;
 }
-trace_serial_ioport_read(addr, ret);
+trace_serial_read(addr, ret);
 return ret;
 }
 
diff --git a/hw/char/trace-events b/hw/char/trace-events
index 17304bef26d..609df10fed4 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -5,8 +5,8 @@ parallel_ioport_read(const char *desc, uint16_t addr, uint8_t 
value) "read [%s]
 parallel_ioport_write(const char *desc, uint16_t addr, uint8_t value) "write 
[%s] addr 0x%02x val 0x%02x"
 
 # serial.c
-serial_ioport_read(uint16_t addr, uint8_t value) "read addr 0x%02x val 0x%02x"
-serial_ioport_write(uint16_t addr, uint8_t value) "write addr 0x%02x val 
0x%02x"
+serial_read(uint16_t addr, uint8_t value) "read addr 0x%02x val 0x%02x"
+serial_write(uint16_t addr, uint8_t value) "write addr 0x%02x val 0x%02x"
 serial_update_parameters(uint64_t baudrate, char parity, int data_bits, int 
stop_bits) "baudrate=%"PRIu64" parity='%c' data=%d stop=%d"
 
 # virtio-serial-bus.c
-- 
2.26.2




Re: [PATCH 7/7] hw/char/serial: Let SerialState have an 'id' field

2020-09-12 Thread Philippe Mathieu-Daudé
On 9/12/20 1:28 PM, Philippe Mathieu-Daudé wrote:
> On 9/12/20 11:14 AM, Paolo Bonzini wrote:
>> On 07/09/20 03:55, Philippe Mathieu-Daudé wrote:
>>> When a SoC has multiple UARTs (some configured differently),
>>> it is hard to associate events to their UART.
>>>
>>> To be able to distinct trace events between various instances,
>>> add an 'id' field. Update the trace format accordingly.
>>>
>>> Reviewed-by: Richard Henderson 
>>> Signed-off-by: Philippe Mathieu-Daudé 
>>> ---
>>>  include/hw/char/serial.h | 1 +
>>>  hw/char/serial.c | 7 ---
>>>  hw/char/trace-events | 6 +++---
>>>  3 files changed, 8 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
>>> index 3d2a5b27e87..3ee2d096a85 100644
>>> --- a/include/hw/char/serial.h
>>> +++ b/include/hw/char/serial.h
>>> @@ -75,6 +75,7 @@ typedef struct SerialState {
>>>  uint64_t char_transmit_time;/* time to transmit a char in ticks */
>>>  int poll_msl;
>>>  
>>> +uint8_t id;
>>>  QEMUTimer *modem_status_poll;
>>>  MemoryRegion io;
>>>  } SerialState;
>>> diff --git a/hw/char/serial.c b/hw/char/serial.c
>>> index ade89fadb44..e5a6b939f13 100644
>>> --- a/hw/char/serial.c
>>> +++ b/hw/char/serial.c
>>> @@ -177,7 +177,7 @@ static void serial_update_parameters(SerialState *s)
>>>  ssp.stop_bits = stop_bits;
>>>  s->char_transmit_time =  (NANOSECONDS_PER_SECOND / speed) * frame_size;
>>>  qemu_chr_fe_ioctl(>chr, CHR_IOCTL_SERIAL_SET_PARAMS, );
>>> -trace_serial_update_parameters(speed, parity, data_bits, stop_bits);
>>> +trace_serial_update_parameters(s->id, speed, parity, data_bits, 
>>> stop_bits);
>>>  }
>>>  
>>>  static void serial_update_msl(SerialState *s)
>>> @@ -333,7 +333,7 @@ static void serial_ioport_write(void *opaque, hwaddr 
>>> addr, uint64_t val,
>>>  SerialState *s = opaque;
>>>  
>>>  assert(size == 1 && addr < 8);
>>> -trace_serial_write(addr, val);
>>> +trace_serial_write(s->id, addr, val);
>>>  switch(addr) {
>>>  default:
>>>  case 0:
>>> @@ -550,7 +550,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr 
>>> addr, unsigned size)
>>>  ret = s->scr;
>>>  break;
>>>  }
>>> -trace_serial_read(addr, ret);
>>> +trace_serial_read(s->id, addr, ret);
>>>  return ret;
>>>  }
>>>  
>>> @@ -1013,6 +1013,7 @@ static const TypeInfo serial_io_info = {
>>>  };
>>>  
>>>  static Property serial_properties[] = {
>>> +DEFINE_PROP_UINT8("id", SerialState, id, 0),
>>>  DEFINE_PROP_CHR("chardev", SerialState, chr),
>>>  DEFINE_PROP_UINT32("baudbase", SerialState, baudbase, 115200),
>>>  DEFINE_PROP_BOOL("wakeup", SerialState, wakeup, false),
>>> diff --git a/hw/char/trace-events b/hw/char/trace-events
>>> index cd36b63f39d..40800c9334c 100644
>>> --- a/hw/char/trace-events
>>> +++ b/hw/char/trace-events
>>> @@ -5,9 +5,9 @@ parallel_ioport_read(const char *desc, uint16_t addr, 
>>> uint8_t value) "read [%s]
>>>  parallel_ioport_write(const char *desc, uint16_t addr, uint8_t value) 
>>> "write [%s] addr 0x%02x val 0x%02x"
>>>  
>>>  # serial.c
>>> -serial_read(uint16_t addr, uint8_t value) "read addr 0x%02x val 0x%02x"
>>> -serial_write(uint16_t addr, uint8_t value) "write addr 0x%02x val 0x%02x"
>>> -serial_update_parameters(uint64_t baudrate, char parity, int data_bits, 
>>> int stop_bits) "baudrate=%"PRIu64" parity='%c' data=%d stop=%d"
>>> +serial_read(uint8_t id, uint8_t addr, uint8_t value) "id#%u read addr 0x%x 
>>> val 0x%02x"
>>> +serial_write(uint8_t id, uint8_t addr, uint8_t value) "id#%u write addr 
>>> 0x%x val 0x%02x"
>>> +serial_update_parameters(uint8_t id, uint64_t baudrate, char parity, int 
>>> data_bits, int stop_bits) "id#%u baudrate=%"PRIu64" parity=%c data=%d 
>>> stop=%d"
>>>  
>>>  # virtio-serial-bus.c
>>>  virtio_serial_send_control_event(unsigned int port, uint16_t event, 
>>> uint16_t value) "port %u, event %u, value %u"
>>>
>>
>> I'm not sure about making this one a one-off for serial.c.  You could
>> add the SerialState* too, for example.
> 
> hw/char/serial-pci-multi.c:45
> 
> Ah indeed, not sure why I only used qdev_alias_all_properties()
> on the ISA one. Probably because I don't use the other ones.
> 
> I'll send a new patch for the PCI-single device:

Bah this can simply be squashed into the previous patch.

> 
> -- >8 --
> --- a/hw/char/serial-pci.c
> +++ b/hw/char/serial-pci.c
> @@ -81,7 +81,6 @@ static const VMStateDescription vmstate_pci_serial = {
>  };
> 
>  static Property serial_pci_properties[] = {
> -DEFINE_PROP_CHR("chardev",  PCISerialState, state.chr),
>  DEFINE_PROP_UINT8("prog_if",  PCISerialState, prog_if, 0x02),
>  DEFINE_PROP_END_OF_LIST(),
>  };
> @@ -106,6 +105,8 @@ static void serial_pci_init(Object *o)
>  PCISerialState *ps = PCI_SERIAL(o);
> 
>  object_initialize_child(o, "serial", >state, TYPE_SERIAL);
> +
> +qdev_alias_all_properties(DEVICE(>state), o);
>  }
> ---



Re: [PATCH 7/7] hw/char/serial: Let SerialState have an 'id' field

2020-09-12 Thread Philippe Mathieu-Daudé
On 9/12/20 11:14 AM, Paolo Bonzini wrote:
> On 07/09/20 03:55, Philippe Mathieu-Daudé wrote:
>> When a SoC has multiple UARTs (some configured differently),
>> it is hard to associate events to their UART.
>>
>> To be able to distinct trace events between various instances,
>> add an 'id' field. Update the trace format accordingly.
>>
>> Reviewed-by: Richard Henderson 
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>  include/hw/char/serial.h | 1 +
>>  hw/char/serial.c | 7 ---
>>  hw/char/trace-events | 6 +++---
>>  3 files changed, 8 insertions(+), 6 deletions(-)
>>
>> diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
>> index 3d2a5b27e87..3ee2d096a85 100644
>> --- a/include/hw/char/serial.h
>> +++ b/include/hw/char/serial.h
>> @@ -75,6 +75,7 @@ typedef struct SerialState {
>>  uint64_t char_transmit_time;/* time to transmit a char in ticks */
>>  int poll_msl;
>>  
>> +uint8_t id;
>>  QEMUTimer *modem_status_poll;
>>  MemoryRegion io;
>>  } SerialState;
>> diff --git a/hw/char/serial.c b/hw/char/serial.c
>> index ade89fadb44..e5a6b939f13 100644
>> --- a/hw/char/serial.c
>> +++ b/hw/char/serial.c
>> @@ -177,7 +177,7 @@ static void serial_update_parameters(SerialState *s)
>>  ssp.stop_bits = stop_bits;
>>  s->char_transmit_time =  (NANOSECONDS_PER_SECOND / speed) * frame_size;
>>  qemu_chr_fe_ioctl(>chr, CHR_IOCTL_SERIAL_SET_PARAMS, );
>> -trace_serial_update_parameters(speed, parity, data_bits, stop_bits);
>> +trace_serial_update_parameters(s->id, speed, parity, data_bits, 
>> stop_bits);
>>  }
>>  
>>  static void serial_update_msl(SerialState *s)
>> @@ -333,7 +333,7 @@ static void serial_ioport_write(void *opaque, hwaddr 
>> addr, uint64_t val,
>>  SerialState *s = opaque;
>>  
>>  assert(size == 1 && addr < 8);
>> -trace_serial_write(addr, val);
>> +trace_serial_write(s->id, addr, val);
>>  switch(addr) {
>>  default:
>>  case 0:
>> @@ -550,7 +550,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr 
>> addr, unsigned size)
>>  ret = s->scr;
>>  break;
>>  }
>> -trace_serial_read(addr, ret);
>> +trace_serial_read(s->id, addr, ret);
>>  return ret;
>>  }
>>  
>> @@ -1013,6 +1013,7 @@ static const TypeInfo serial_io_info = {
>>  };
>>  
>>  static Property serial_properties[] = {
>> +DEFINE_PROP_UINT8("id", SerialState, id, 0),
>>  DEFINE_PROP_CHR("chardev", SerialState, chr),
>>  DEFINE_PROP_UINT32("baudbase", SerialState, baudbase, 115200),
>>  DEFINE_PROP_BOOL("wakeup", SerialState, wakeup, false),
>> diff --git a/hw/char/trace-events b/hw/char/trace-events
>> index cd36b63f39d..40800c9334c 100644
>> --- a/hw/char/trace-events
>> +++ b/hw/char/trace-events
>> @@ -5,9 +5,9 @@ parallel_ioport_read(const char *desc, uint16_t addr, 
>> uint8_t value) "read [%s]
>>  parallel_ioport_write(const char *desc, uint16_t addr, uint8_t value) 
>> "write [%s] addr 0x%02x val 0x%02x"
>>  
>>  # serial.c
>> -serial_read(uint16_t addr, uint8_t value) "read addr 0x%02x val 0x%02x"
>> -serial_write(uint16_t addr, uint8_t value) "write addr 0x%02x val 0x%02x"
>> -serial_update_parameters(uint64_t baudrate, char parity, int data_bits, int 
>> stop_bits) "baudrate=%"PRIu64" parity='%c' data=%d stop=%d"
>> +serial_read(uint8_t id, uint8_t addr, uint8_t value) "id#%u read addr 0x%x 
>> val 0x%02x"
>> +serial_write(uint8_t id, uint8_t addr, uint8_t value) "id#%u write addr 
>> 0x%x val 0x%02x"
>> +serial_update_parameters(uint8_t id, uint64_t baudrate, char parity, int 
>> data_bits, int stop_bits) "id#%u baudrate=%"PRIu64" parity=%c data=%d 
>> stop=%d"
>>  
>>  # virtio-serial-bus.c
>>  virtio_serial_send_control_event(unsigned int port, uint16_t event, 
>> uint16_t value) "port %u, event %u, value %u"
>>
> 
> I'm not sure about making this one a one-off for serial.c.  You could
> add the SerialState* too, for example.

hw/char/serial-pci-multi.c:45

Ah indeed, not sure why I only used qdev_alias_all_properties()
on the ISA one. Probably because I don't use the other ones.

I'll send a new patch for the PCI-single device:

-- >8 --
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -81,7 +81,6 @@ static const VMStateDescription vmstate_pci_serial = {
 };

 static Property serial_pci_properties[] = {
-DEFINE_PROP_CHR("chardev",  PCISerialState, state.chr),
 DEFINE_PROP_UINT8("prog_if",  PCISerialState, prog_if, 0x02),
 DEFINE_PROP_END_OF_LIST(),
 };
@@ -106,6 +105,8 @@ static void serial_pci_init(Object *o)
 PCISerialState *ps = PCI_SERIAL(o);

 object_initialize_child(o, "serial", >state, TYPE_SERIAL);
+
+qdev_alias_all_properties(DEVICE(>state), o);
 }
---

And amend to this one:

-- >8 --
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -105,6 +105,7 @@ static void multi_serial_pci_realize(PCIDevice *dev,
Error **errp)

 for (i = 0; i < nports; i++) {
 s = pci->state + i;
+

[PATCH v2 6/6] migration/tls: add trace points for multifd-tls

2020-09-12 Thread Chuan Zheng
add trace points for multifd-tls for debug.

Signed-off-by: Chuan Zheng 
Signed-off-by: Yan Jin 
---
 migration/multifd.c| 10 +-
 migration/trace-events |  5 +
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/migration/multifd.c b/migration/multifd.c
index 8aea4e0..0760502 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -732,7 +732,11 @@ static void multifd_tls_outgoing_handshake(QIOTask *task,
 QIOChannel *ioc = QIO_CHANNEL(qio_task_get_source(task));
 Error *err = NULL;
 
-qio_task_propagate_error(task, );
+if (qio_task_propagate_error(task, )) {
+trace_multifd_tls_outgoing_handshake_error(ioc, error_get_pretty(err));
+} else {
+trace_multifd_tls_outgoing_handshake_complete(ioc);
+}
 multifd_channel_connect(p, ioc, err);
 }
 
@@ -749,6 +753,7 @@ static void multifd_tls_channel_connect(MultiFDSendParams 
*p,
 return;
 }
 
+trace_multifd_tls_outgoing_handshake_start(ioc, tioc, hostname);
 qio_channel_set_name(QIO_CHANNEL(tioc), "multifd-tls-outgoing");
 qio_channel_tls_handshake(tioc,
   multifd_tls_outgoing_handshake,
@@ -764,6 +769,9 @@ static bool multifd_channel_connect(MultiFDSendParams *p,
 {
 MigrationState *s = p->s;
 
+trace_multifd_set_outgoing_channel(
+ioc, object_get_typename(OBJECT(ioc)), s->hostname, error);
+
 if (!error) {
 if (s->parameters.tls_creds &&
 *s->parameters.tls_creds &&
diff --git a/migration/trace-events b/migration/trace-events
index 4ab0a50..78db982 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -109,6 +109,11 @@ multifd_send_sync_main_wait(uint8_t id) "channel %d"
 multifd_send_terminate_threads(bool error) "error %d"
 multifd_send_thread_end(uint8_t id, uint64_t packets, uint64_t pages) "channel 
%d packets %" PRIu64 " pages %"  PRIu64
 multifd_send_thread_start(uint8_t id) "%d"
+multifd_tls_outgoing_handshake_start(void *ioc, void *tioc, const char 
*hostname) "ioc=%p tioc=%p hostname=%s"
+multifd_tls_outgoing_handshake_error(void *ioc, const char *err) "ioc=%p 
err=%s"
+multifd_tls_outgoing_handshake_complete(void *ioc, void) "ioc=%p"
+multifd_set_outgoing_channel(void *ioc, const char *ioctype, const char 
*hostname, void *err)  "ioc=%p ioctype=%s hostname=%s err=%p"
+
 ram_discard_range(const char *rbname, uint64_t start, size_t len) "%s: start: 
%" PRIx64 " %zx"
 ram_load_loop(const char *rbname, uint64_t addr, int flags, void *host) "%s: 
addr: 0x%" PRIx64 " flags: 0x%x host: %p"
 ram_load_postcopy_loop(uint64_t addr, int flags) "@%" PRIx64 " %x"
-- 
1.8.3.1




[PATCH v2 3/6] migration/tls: add MigrationState and tls_hostname into MultiFDSendParams

2020-09-12 Thread Chuan Zheng
MigrationState is need for tls session build and tls hostname is need
for tls handshake, add both MigrationState and tls_hostname
into MultiFDSendParams.

Signed-off-by: Chuan Zheng 
Signed-off-by: Yan Jin 
---
 migration/multifd.c | 5 +
 migration/multifd.h | 4 
 2 files changed, 9 insertions(+)

diff --git a/migration/multifd.c b/migration/multifd.c
index d044120..3e41d9e 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -543,11 +543,14 @@ void multifd_save_cleanup(void)
 
 socket_send_channel_destroy(p->c);
 p->c = NULL;
+p->s = NULL;
 qemu_mutex_destroy(>mutex);
 qemu_sem_destroy(>sem);
 qemu_sem_destroy(>sem_sync);
 g_free(p->name);
 p->name = NULL;
+g_free(p->tls_hostname);
+p->tls_hostname = NULL;
 multifd_pages_clear(p->pages);
 p->pages = NULL;
 p->packet_len = 0;
@@ -779,6 +782,8 @@ int multifd_save_setup(Error **errp)
 p->packet->magic = cpu_to_be32(MULTIFD_MAGIC);
 p->packet->version = cpu_to_be32(MULTIFD_VERSION);
 p->name = g_strdup_printf("multifdsend_%d", i);
+p->s = migrate_get_current();
+p->tls_hostname = g_strdup(p->s->hostname);
 socket_send_channel_create(multifd_new_send_channel_async, p);
 }
 
diff --git a/migration/multifd.h b/migration/multifd.h
index 448a03d..2b400e7 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -66,11 +66,15 @@ typedef struct {
 } MultiFDPages_t;
 
 typedef struct {
+/* Migration State */
+MigrationState *s;
 /* this fields are not changed once the thread is created */
 /* channel number */
 uint8_t id;
 /* channel thread name */
 char *name;
+/* tls hostname */
+char *tls_hostname;
 /* channel thread id */
 QemuThread thread;
 /* communication channel */
-- 
1.8.3.1




  1   2   >