On Fri, Feb 21, 2020 at 05:42:01PM +0100, David Hildenbrand wrote:

[...]

> @@ -3160,7 +3160,13 @@ static int ram_load_postcopy(QEMUFile *f)
>                  break;
>              }
>  
> -            if (!offset_in_ramblock(block, addr)) {
> +            /*
> +             * Relying on used_length is racy and can result in false 
> positives.
> +             * We might place pages beyond used_length in case RAM was shrunk
> +             * while in postcopy, which is fine - trying to place via
> +             * UFFDIO_COPY/UFFDIO_ZEROPAGE will never segfault.
> +             */
> +            if (!block->host || addr >= block->postcopy_length) {

I'm thinking whether we can even avoid the -ENOENT failure of
UFFDIO_COPY.  With the postcopy_length you introduced, I think it's
the case when addr >= used_length && addr < postcopy_length, right?
Can we skip those?

Thanks,

>                  error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
>                  ret = -EINVAL;
>                  break;
> @@ -3757,6 +3763,7 @@ static void ram_mig_ram_block_resized(RAMBlockNotifier 
> *n, void *host,
>                               rb->idstr);
>              }
>          }
> +        rb->postcopy_length = new_size;
>          break;
>      case POSTCOPY_INCOMING_NONE:
>      case POSTCOPY_INCOMING_RUNNING:
> -- 
> 2.24.1
> 

-- 
Peter Xu


Reply via email to