Skip to content

Commit 212ab69

Browse files
authored
Merge pull request #2778 from lindig/CP-18860
CP 18860 - Restrict setting memory limits for Bromium VMs * The memory configuration is checked explicitly before VM.start * A check is integrated into xapi_vm_memory_constraints * There is no check as part of vm_lifecycle which was the original approach to implement the check.
2 parents 0a000d2 + c0fe510 commit 212ab69

File tree

4 files changed

+50
-20
lines changed

4 files changed

+50
-20
lines changed

ocaml/idl/datamodel.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,8 @@ let _ =
511511
~doc:"You attempted an operation which would have resulted in duplicate keys in the database." ();
512512
error Api_errors.location_not_unique ["SR"; "location"]
513513
~doc:"A VDI with the specified location already exists within the SR" ();
514+
error Api_errors.memory_constraint_violation ["constraint"]
515+
~doc:"The dynamic memory range does not satisfy the following constraint." ();
514516

515517
(* Session errors *)
516518
error Api_errors.session_authentication_failed []

ocaml/xapi/xapi_vm_lifecycle.ml

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -279,18 +279,28 @@ let check_protection_policy ~vmr ~op ~ref_str =
279279
* If the VM_metrics object does not exist, it implies the VM is not
280280
* running - in which case we use the current values from the database.
281281
**)
282-
let is_mobile ~__context vm strict =
283-
let metrics = Db.VM.get_metrics ~__context ~self:vm in
282+
283+
let nomigrate ~__context vm metrics =
284284
try
285-
let nomigrate = Db.VM_metrics.get_nomigrate ~__context ~self:metrics in
286-
let nested_virt = Db.VM_metrics.get_nested_virt ~__context ~self:metrics in
287-
(not nomigrate && not nested_virt) || not strict
285+
Db.VM_metrics.get_nomigrate ~__context ~self:metrics
288286
with _ ->
289-
(* No VM_metrics *)
290-
let not_true platformdata key =
291-
not @@ Vm_platform.is_true ~key ~platformdata ~default:false in
292-
let platform = Db.VM.get_platform ~__context ~self:vm in
293-
(not_true platform "nomigrate" && not_true platform "nested-virt") || not strict
287+
let platformdata = Db.VM.get_platform ~__context ~self:vm in
288+
let key = "nomigrate" in
289+
Vm_platform.is_true ~key ~platformdata ~default:false
290+
291+
let nested_virt ~__context vm metrics =
292+
try
293+
Db.VM_metrics.get_nested_virt ~__context ~self:metrics
294+
with _ ->
295+
let platformdata = Db.VM.get_platform ~__context ~self:vm in
296+
let key = "nested-virt" in
297+
Vm_platform.is_true ~key ~platformdata ~default:false
298+
299+
let is_mobile ~__context vm strict =
300+
let metrics = Db.VM.get_metrics ~__context ~self:vm in
301+
(not @@ nomigrate ~__context vm metrics
302+
&& not @@ nested_virt ~__context vm metrics)
303+
|| not strict
294304

295305

296306
(** Take an internal VM record and a proposed operation. Return None iff the operation

ocaml/xapi/xapi_vm_memory_constraints.ml

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,34 @@ module Vm_memory_constraints : T = struct
5151

5252
include Vm_memory_constraints.Vm_memory_constraints
5353

54+
let nested_virt ~__context vm =
55+
let metrics = Db.VM.get_metrics ~__context ~self:vm in
56+
Xapi_vm_lifecycle.nested_virt ~__context vm metrics
57+
58+
let order_constraint =
59+
"Memory limits must satisfy: \
60+
static_min ≤ dynamic_min ≤ dynamic_max ≤ static_max"
61+
let equality_constraint =
62+
"Memory limits must satisfy: \
63+
static_min ≤ dynamic_min = dynamic_max = static_max"
64+
5465
let assert_valid ~constraints =
5566
if not (are_valid ~constraints)
5667
then raise (Api_errors.Server_error (
57-
Api_errors.memory_constraint_violation,
58-
["Memory limits must satisfy: \
59-
static_min ≤ dynamic_min ≤ dynamic_max ≤ static_max"]))
68+
Api_errors.memory_constraint_violation, [order_constraint]))
6069

6170
let assert_valid_and_pinned_at_static_max ~constraints =
6271
if not (are_valid_and_pinned_at_static_max ~constraints)
6372
then raise (Api_errors.Server_error (
64-
Api_errors.memory_constraint_violation,
65-
["Memory limits must satisfy: \
66-
static_min ≤ dynamic_min = dynamic_max = static_max"]))
73+
Api_errors.memory_constraint_violation, [equality_constraint]))
6774

6875
let assert_valid_for_current_context ~__context ~vm ~constraints =
6976
let is_control_domain = Db.VM.get_is_control_domain ~__context ~self:vm in
70-
(if Pool_features.is_enabled ~__context Features.DMC && not is_control_domain
71-
then assert_valid
72-
else assert_valid_and_pinned_at_static_max)
73-
~constraints
77+
if Pool_features.is_enabled ~__context Features.DMC
78+
&& not is_control_domain
79+
&& not (nested_virt ~__context vm)
80+
then assert_valid ~constraints
81+
else assert_valid_and_pinned_at_static_max ~constraints
7482

7583
let extract ~vm_record =
7684
{

ocaml/xapi/xapi_xenops.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,16 @@ module MD = struct
708708
(* CA-55754: temporarily disable msitranslate when GPU is passed through. *)
709709
let pci_msitranslate =
710710
if vm.API.vM_VGPUs <> [] then false else pci_msitranslate in
711+
712+
(* CP-18860: check memory limits if using nested_virt *)
713+
if Vm_platform.is_true ~key:"nested-virt" ~platformdata ~default:false
714+
then
715+
begin
716+
let module C = Xapi_vm_memory_constraints.Vm_memory_constraints in
717+
let c = C.get ~__context ~vm_ref:vmref in
718+
C.assert_valid_and_pinned_at_static_max c
719+
end;
720+
711721
{
712722
id = vm.API.vM_uuid;
713723
name = vm.API.vM_name_label;

0 commit comments

Comments
 (0)