21
21
#include <linux/bitmap.h>
22
22
#include <linux/lockdep.h>
23
23
24
+ #include <acpi/acpi_numa.h>
25
+
24
26
enum virtio_mem_mb_state {
25
27
/* Unplugged, not added to Linux. Can be reused later. */
26
28
VIRTIO_MEM_MB_STATE_UNUSED = 0 ,
@@ -72,6 +74,8 @@ struct virtio_mem {
72
74
73
75
/* The device block size (for communicating with the device). */
74
76
uint32_t device_block_size ;
77
+ /* The translated node id. NUMA_NO_NODE in case not specified. */
78
+ int nid ;
75
79
/* Physical start address of the memory region. */
76
80
uint64_t addr ;
77
81
/* Maximum region size in bytes. */
@@ -389,7 +393,10 @@ static int virtio_mem_sb_bitmap_prepare_next_mb(struct virtio_mem *vm)
389
393
static int virtio_mem_mb_add (struct virtio_mem * vm , unsigned long mb_id )
390
394
{
391
395
const uint64_t addr = virtio_mem_mb_id_to_phys (mb_id );
392
- int nid = memory_add_physaddr_to_nid (addr );
396
+ int nid = vm -> nid ;
397
+
398
+ if (nid == NUMA_NO_NODE )
399
+ nid = memory_add_physaddr_to_nid (addr );
393
400
394
401
dev_dbg (& vm -> vdev -> dev , "adding memory block: %lu\n" , mb_id );
395
402
return add_memory (nid , addr , memory_block_size_bytes ());
@@ -407,7 +414,10 @@ static int virtio_mem_mb_add(struct virtio_mem *vm, unsigned long mb_id)
407
414
static int virtio_mem_mb_remove (struct virtio_mem * vm , unsigned long mb_id )
408
415
{
409
416
const uint64_t addr = virtio_mem_mb_id_to_phys (mb_id );
410
- int nid = memory_add_physaddr_to_nid (addr );
417
+ int nid = vm -> nid ;
418
+
419
+ if (nid == NUMA_NO_NODE )
420
+ nid = memory_add_physaddr_to_nid (addr );
411
421
412
422
dev_dbg (& vm -> vdev -> dev , "removing memory block: %lu\n" , mb_id );
413
423
return remove_memory (nid , addr , memory_block_size_bytes ());
@@ -426,6 +436,17 @@ static void virtio_mem_retry(struct virtio_mem *vm)
426
436
spin_unlock_irqrestore (& vm -> removal_lock , flags );
427
437
}
428
438
439
+ static int virtio_mem_translate_node_id (struct virtio_mem * vm , uint16_t node_id )
440
+ {
441
+ int node = NUMA_NO_NODE ;
442
+
443
+ #if defined(CONFIG_ACPI_NUMA )
444
+ if (virtio_has_feature (vm -> vdev , VIRTIO_MEM_F_ACPI_PXM ))
445
+ node = pxm_to_node (node_id );
446
+ #endif
447
+ return node ;
448
+ }
449
+
429
450
/*
430
451
* Test if a virtio-mem device overlaps with the given range. Can be called
431
452
* from (notifier) callbacks lockless.
@@ -1267,6 +1288,7 @@ static bool virtio_mem_any_memory_present(unsigned long start,
1267
1288
static int virtio_mem_init (struct virtio_mem * vm )
1268
1289
{
1269
1290
const uint64_t phys_limit = 1UL << MAX_PHYSMEM_BITS ;
1291
+ uint16_t node_id ;
1270
1292
1271
1293
if (!vm -> vdev -> config -> get ) {
1272
1294
dev_err (& vm -> vdev -> dev , "config access disabled\n" );
@@ -1287,6 +1309,9 @@ static int virtio_mem_init(struct virtio_mem *vm)
1287
1309
& vm -> plugged_size );
1288
1310
virtio_cread (vm -> vdev , struct virtio_mem_config , block_size ,
1289
1311
& vm -> device_block_size );
1312
+ virtio_cread (vm -> vdev , struct virtio_mem_config , node_id ,
1313
+ & node_id );
1314
+ vm -> nid = virtio_mem_translate_node_id (vm , node_id );
1290
1315
virtio_cread (vm -> vdev , struct virtio_mem_config , addr , & vm -> addr );
1291
1316
virtio_cread (vm -> vdev , struct virtio_mem_config , region_size ,
1292
1317
& vm -> region_size );
@@ -1365,6 +1390,8 @@ static int virtio_mem_init(struct virtio_mem *vm)
1365
1390
memory_block_size_bytes ());
1366
1391
dev_info (& vm -> vdev -> dev , "subblock size: 0x%x" ,
1367
1392
vm -> subblock_size );
1393
+ if (vm -> nid != NUMA_NO_NODE )
1394
+ dev_info (& vm -> vdev -> dev , "nid: %d" , vm -> nid );
1368
1395
1369
1396
return 0 ;
1370
1397
}
@@ -1508,12 +1535,20 @@ static int virtio_mem_restore(struct virtio_device *vdev)
1508
1535
}
1509
1536
#endif
1510
1537
1538
+ static unsigned int virtio_mem_features [] = {
1539
+ #if defined(CONFIG_NUMA ) && defined(CONFIG_ACPI_NUMA )
1540
+ VIRTIO_MEM_F_ACPI_PXM ,
1541
+ #endif
1542
+ };
1543
+
1511
1544
static struct virtio_device_id virtio_mem_id_table [] = {
1512
1545
{ VIRTIO_ID_MEM , VIRTIO_DEV_ANY_ID },
1513
1546
{ 0 },
1514
1547
};
1515
1548
1516
1549
static struct virtio_driver virtio_mem_driver = {
1550
+ .feature_table = virtio_mem_features ,
1551
+ .feature_table_size = ARRAY_SIZE (virtio_mem_features ),
1517
1552
.driver .name = KBUILD_MODNAME ,
1518
1553
.driver .owner = THIS_MODULE ,
1519
1554
.id_table = virtio_mem_id_table ,
0 commit comments