@@ -65,10 +65,9 @@ static
65
65
SpaprMachineStateNestedGuest * spapr_get_nested_guest (SpaprMachineState * spapr ,
66
66
target_ulong guestid )
67
67
{
68
- SpaprMachineStateNestedGuest * guest ;
69
-
70
- guest = g_hash_table_lookup (spapr -> nested .guests , GINT_TO_POINTER (guestid ));
71
- return guest ;
68
+ return spapr -> nested .guests ?
69
+ g_hash_table_lookup (spapr -> nested .guests ,
70
+ GINT_TO_POINTER (guestid )) : NULL ;
72
71
}
73
72
74
73
bool spapr_get_pate_nested_papr (SpaprMachineState * spapr , PowerPCCPU * cpu ,
@@ -594,26 +593,37 @@ static bool spapr_nested_vcpu_check(SpaprMachineStateNestedGuest *guest,
594
593
return false;
595
594
}
596
595
597
- static void * get_vcpu_state_ptr (SpaprMachineStateNestedGuest * guest ,
598
- target_ulong vcpuid )
596
+ static void * get_vcpu_state_ptr (SpaprMachineState * spapr ,
597
+ SpaprMachineStateNestedGuest * guest ,
598
+ target_ulong vcpuid )
599
599
{
600
600
assert (spapr_nested_vcpu_check (guest , vcpuid , false));
601
601
return & guest -> vcpus [vcpuid ].state ;
602
602
}
603
603
604
- static void * get_vcpu_ptr (SpaprMachineStateNestedGuest * guest ,
605
- target_ulong vcpuid )
604
+ static void * get_vcpu_ptr (SpaprMachineState * spapr ,
605
+ SpaprMachineStateNestedGuest * guest ,
606
+ target_ulong vcpuid )
606
607
{
607
608
assert (spapr_nested_vcpu_check (guest , vcpuid , false));
608
609
return & guest -> vcpus [vcpuid ];
609
610
}
610
611
611
- static void * get_guest_ptr (SpaprMachineStateNestedGuest * guest ,
612
+ static void * get_guest_ptr (SpaprMachineState * spapr ,
613
+ SpaprMachineStateNestedGuest * guest ,
612
614
target_ulong vcpuid )
613
615
{
614
616
return guest ; /* for GSBE_NESTED */
615
617
}
616
618
619
+ static void * get_machine_ptr (SpaprMachineState * spapr ,
620
+ SpaprMachineStateNestedGuest * guest ,
621
+ target_ulong vcpuid )
622
+ {
623
+ /* ignore guest and vcpuid for this */
624
+ return & spapr -> nested ;
625
+ }
626
+
617
627
/*
618
628
* set=1 means the L1 is trying to set some state
619
629
* set=0 means the L1 is trying to get some state
@@ -1013,7 +1023,15 @@ struct guest_state_element_type guest_state_element_types[] = {
1013
1023
GSBE_NESTED_VCPU (GSB_VCPU_OUT_BUFFER , 0x10 , runbufout , copy_state_runbuf ),
1014
1024
GSBE_NESTED_VCPU (GSB_VCPU_OUT_BUF_MIN_SZ , 0x8 , runbufout , out_buf_min_size ),
1015
1025
GSBE_NESTED_VCPU (GSB_VCPU_HDEC_EXPIRY_TB , 0x8 , hdecr_expiry_tb ,
1016
- copy_state_hdecr )
1026
+ copy_state_hdecr ),
1027
+ GSBE_NESTED_MACHINE_DW (GSB_L0_GUEST_HEAP_INUSE , l0_guest_heap_inuse ),
1028
+ GSBE_NESTED_MACHINE_DW (GSB_L0_GUEST_HEAP_MAX , l0_guest_heap_max ),
1029
+ GSBE_NESTED_MACHINE_DW (GSB_L0_GUEST_PGTABLE_SIZE_INUSE ,
1030
+ l0_guest_pgtable_size_inuse ),
1031
+ GSBE_NESTED_MACHINE_DW (GSB_L0_GUEST_PGTABLE_SIZE_MAX ,
1032
+ l0_guest_pgtable_size_max ),
1033
+ GSBE_NESTED_MACHINE_DW (GSB_L0_GUEST_PGTABLE_RECLAIMED ,
1034
+ l0_guest_pgtable_reclaimed ),
1017
1035
};
1018
1036
1019
1037
void spapr_nested_gsb_init (void )
@@ -1031,8 +1049,13 @@ void spapr_nested_gsb_init(void)
1031
1049
else if (type -> id >= GSB_VCPU_IN_BUFFER )
1032
1050
/* 0x0c00 - 0xf000 Thread + RW */
1033
1051
type -> flags = 0 ;
1052
+ else if (type -> id >= GSB_L0_GUEST_HEAP_INUSE )
1053
+
1054
+ /*0x0800 - 0x0804 Hostwide Counters + RO */
1055
+ type -> flags = GUEST_STATE_ELEMENT_TYPE_FLAG_HOST_WIDE |
1056
+ GUEST_STATE_ELEMENT_TYPE_FLAG_READ_ONLY ;
1034
1057
else if (type -> id >= GSB_VCPU_LPVR )
1035
- /* 0x0003 - 0x0bff Guest + RW */
1058
+ /* 0x0003 - 0x07ff Guest + RW */
1036
1059
type -> flags = GUEST_STATE_ELEMENT_TYPE_FLAG_GUEST_WIDE ;
1037
1060
else if (type -> id >= GSB_HV_VCPU_STATE_SIZE )
1038
1061
/* 0x0001 - 0x0002 Guest + RO */
@@ -1139,18 +1162,26 @@ static bool guest_state_request_check(struct guest_state_request *gsr)
1139
1162
return false;
1140
1163
}
1141
1164
1142
- if (type -> flags & GUEST_STATE_ELEMENT_TYPE_FLAG_GUEST_WIDE ) {
1165
+ if (type -> flags & GUEST_STATE_ELEMENT_TYPE_FLAG_HOST_WIDE ) {
1166
+ /* Hostwide elements cant be clubbed with other types */
1167
+ if (!(gsr -> flags & GUEST_STATE_REQUEST_HOST_WIDE )) {
1168
+ qemu_log_mask (LOG_GUEST_ERROR , "trying to get/set a host wide "
1169
+ "Element ID:%04x.\n" , id );
1170
+ return false;
1171
+ }
1172
+ } else if (type -> flags & GUEST_STATE_ELEMENT_TYPE_FLAG_GUEST_WIDE ) {
1143
1173
/* guest wide element type */
1144
1174
if (!(gsr -> flags & GUEST_STATE_REQUEST_GUEST_WIDE )) {
1145
- qemu_log_mask (LOG_GUEST_ERROR , "trying to set a guest wide "
1175
+ qemu_log_mask (LOG_GUEST_ERROR , "trying to get/ set a guest wide "
1146
1176
"Element ID:%04x.\n" , id );
1147
1177
return false;
1148
1178
}
1149
1179
} else {
1150
1180
/* thread wide element type */
1151
- if (gsr -> flags & GUEST_STATE_REQUEST_GUEST_WIDE ) {
1152
- qemu_log_mask (LOG_GUEST_ERROR , "trying to set a thread wide "
1153
- "Element ID:%04x.\n" , id );
1181
+ if (gsr -> flags & (GUEST_STATE_REQUEST_GUEST_WIDE |
1182
+ GUEST_STATE_REQUEST_HOST_WIDE )) {
1183
+ qemu_log_mask (LOG_GUEST_ERROR , "trying to get/set a thread wide"
1184
+ " Element ID:%04x.\n" , id );
1154
1185
return false;
1155
1186
}
1156
1187
}
@@ -1419,7 +1450,8 @@ static target_ulong h_guest_create_vcpu(PowerPCCPU *cpu,
1419
1450
return H_SUCCESS ;
1420
1451
}
1421
1452
1422
- static target_ulong getset_state (SpaprMachineStateNestedGuest * guest ,
1453
+ static target_ulong getset_state (SpaprMachineState * spapr ,
1454
+ SpaprMachineStateNestedGuest * guest ,
1423
1455
uint64_t vcpuid ,
1424
1456
struct guest_state_request * gsr )
1425
1457
{
@@ -1452,7 +1484,7 @@ static target_ulong getset_state(SpaprMachineStateNestedGuest *guest,
1452
1484
1453
1485
/* Get pointer to guest data to get/set */
1454
1486
if (type -> location && type -> copy ) {
1455
- ptr = type -> location (guest , vcpuid );
1487
+ ptr = type -> location (spapr , guest , vcpuid );
1456
1488
assert (ptr );
1457
1489
if (!~(type -> mask ) && is_gsr_invalid (gsr , element , type )) {
1458
1490
return H_INVALID_ELEMENT_VALUE ;
@@ -1469,6 +1501,7 @@ static target_ulong getset_state(SpaprMachineStateNestedGuest *guest,
1469
1501
}
1470
1502
1471
1503
static target_ulong map_and_getset_state (PowerPCCPU * cpu ,
1504
+ SpaprMachineState * spapr ,
1472
1505
SpaprMachineStateNestedGuest * guest ,
1473
1506
uint64_t vcpuid ,
1474
1507
struct guest_state_request * gsr )
@@ -1492,7 +1525,7 @@ static target_ulong map_and_getset_state(PowerPCCPU *cpu,
1492
1525
goto out1 ;
1493
1526
}
1494
1527
1495
- rc = getset_state (guest , vcpuid , gsr );
1528
+ rc = getset_state (spapr , guest , vcpuid , gsr );
1496
1529
1497
1530
out1 :
1498
1531
address_space_unmap (CPU (cpu )-> as , gsr -> gsb , len , is_write , len );
@@ -1510,27 +1543,46 @@ static target_ulong h_guest_getset_state(PowerPCCPU *cpu,
1510
1543
target_ulong buf = args [3 ];
1511
1544
target_ulong buflen = args [4 ];
1512
1545
struct guest_state_request gsr ;
1513
- SpaprMachineStateNestedGuest * guest ;
1546
+ SpaprMachineStateNestedGuest * guest = NULL ;
1514
1547
1515
- guest = spapr_get_nested_guest (spapr , lpid );
1516
- if (!guest ) {
1517
- return H_P2 ;
1518
- }
1519
1548
gsr .buf = buf ;
1520
1549
assert (buflen <= GSB_MAX_BUF_SIZE );
1521
1550
gsr .len = buflen ;
1522
1551
gsr .flags = 0 ;
1523
- if (flags & H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE ) {
1552
+
1553
+ /* Works for both get/set state */
1554
+ if ((flags & H_GUEST_GET_STATE_FLAGS_GUEST_WIDE ) ||
1555
+ (flags & H_GUEST_SET_STATE_FLAGS_GUEST_WIDE )) {
1524
1556
gsr .flags |= GUEST_STATE_REQUEST_GUEST_WIDE ;
1525
1557
}
1526
- if (flags & ~H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE ) {
1527
- return H_PARAMETER ; /* flag not supported yet */
1528
- }
1529
1558
1530
1559
if (set ) {
1560
+ if (flags & ~H_GUEST_SET_STATE_FLAGS_MASK ) {
1561
+ return H_PARAMETER ;
1562
+ }
1531
1563
gsr .flags |= GUEST_STATE_REQUEST_SET ;
1564
+ } else {
1565
+ /*
1566
+ * No reserved fields to be set in flags nor both
1567
+ * GUEST/HOST wide bits
1568
+ */
1569
+ if ((flags & ~H_GUEST_GET_STATE_FLAGS_MASK ) ||
1570
+ (flags == H_GUEST_GET_STATE_FLAGS_MASK )) {
1571
+ return H_PARAMETER ;
1572
+ }
1573
+
1574
+ if (flags & H_GUEST_GET_STATE_FLAGS_HOST_WIDE ) {
1575
+ gsr .flags |= GUEST_STATE_REQUEST_HOST_WIDE ;
1576
+ }
1577
+ }
1578
+
1579
+ if (!(gsr .flags & GUEST_STATE_REQUEST_HOST_WIDE )) {
1580
+ guest = spapr_get_nested_guest (spapr , lpid );
1581
+ if (!guest ) {
1582
+ return H_P2 ;
1583
+ }
1532
1584
}
1533
- return map_and_getset_state (cpu , guest , vcpuid , & gsr );
1585
+ return map_and_getset_state (cpu , spapr , guest , vcpuid , & gsr );
1534
1586
}
1535
1587
1536
1588
static target_ulong h_guest_set_state (PowerPCCPU * cpu ,
@@ -1641,7 +1693,8 @@ static int get_exit_ids(uint64_t srr0, uint16_t ids[16])
1641
1693
return nr ;
1642
1694
}
1643
1695
1644
- static void exit_process_output_buffer (PowerPCCPU * cpu ,
1696
+ static void exit_process_output_buffer (SpaprMachineState * spapr ,
1697
+ PowerPCCPU * cpu ,
1645
1698
SpaprMachineStateNestedGuest * guest ,
1646
1699
target_ulong vcpuid ,
1647
1700
target_ulong * r3 )
@@ -1679,7 +1732,7 @@ static void exit_process_output_buffer(PowerPCCPU *cpu,
1679
1732
gsr .gsb = gsb ;
1680
1733
gsr .len = VCPU_OUT_BUF_MIN_SZ ;
1681
1734
gsr .flags = 0 ; /* get + never guest wide */
1682
- getset_state (guest , vcpuid , & gsr );
1735
+ getset_state (spapr , guest , vcpuid , & gsr );
1683
1736
1684
1737
address_space_unmap (CPU (cpu )-> as , gsb , len , true, len );
1685
1738
return ;
@@ -1705,7 +1758,7 @@ void spapr_exit_nested_papr(SpaprMachineState *spapr, PowerPCCPU *cpu, int excp)
1705
1758
1706
1759
exit_nested_store_l2 (cpu , excp , vcpu );
1707
1760
/* do the output buffer for run_vcpu*/
1708
- exit_process_output_buffer (cpu , guest , vcpuid , & r3_return );
1761
+ exit_process_output_buffer (spapr , cpu , guest , vcpuid , & r3_return );
1709
1762
1710
1763
assert (env -> spr [SPR_LPIDR ] != 0 );
1711
1764
nested_load_state (cpu , spapr_cpu -> nested_host_state );
@@ -1820,7 +1873,7 @@ static target_ulong h_guest_run_vcpu(PowerPCCPU *cpu,
1820
1873
gsr .buf = vcpu -> runbufin .addr ;
1821
1874
gsr .len = vcpu -> runbufin .size ;
1822
1875
gsr .flags = GUEST_STATE_REQUEST_SET ; /* Thread wide + writing */
1823
- rc = map_and_getset_state (cpu , guest , vcpuid , & gsr );
1876
+ rc = map_and_getset_state (cpu , spapr , guest , vcpuid , & gsr );
1824
1877
if (rc == H_SUCCESS ) {
1825
1878
nested_papr_run_vcpu (cpu , lpid , vcpu );
1826
1879
} else {
0 commit comments