)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"113573f2_057f7b09","updated":"2026-07-24 12:00:09.000000000","message":"This commit now doesn\u0027t include the TDX specific parts","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"671a0096_249e790a","updated":"2026-07-23 16:45:32.000000000","message":"couple of suggestions inline","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"6476d355f7e5ceb4a31616480e57b93f801a2227","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"1a8acf8d_155d9da8","updated":"2026-07-24 16:49:03.000000000","message":"For me this looks like a clean refactor. Thanks @anton.iacobaeus@canarybit.eu I think this is a nice step forward.","commit_id":"cb37f8e1223af83e16309100487b16993ac99147"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"5cf2b2aca94a0f6db6ce5e035ed785033ae086bf","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"4c7175e9_3374b191","updated":"2026-07-30 09:26:14.000000000","message":"I found out that TDX does in fact not require Stateless firmware","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"de32545e94540e782ef8416f59394de9cf04e98e","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"fc19daf5_016e08aa","in_reply_to":"13fcb3e9_733e3f77","updated":"2026-08-04 09:13:39.000000000","message":"I was under the same impression, but isn\u0027t stateless and readonly different? hw_stateless_firmware doesn\u0027t control readonly of the loader.\n\nThe instance is able to start with any value for hw_firmware_stateless, but without readonly firmware it doesn\u0027t start at all (due to apparmor on ubuntu). TDX firmware doesn\u0027t have the stateless flag like SNP does, and libvirt doesn\u0027t implicitly set it afterwards. The resulting firmware block after selection looks like this:\n\n  \u003cos firmware\u003d\u0027efi\u0027\u003e\n    \u003ctype arch\u003d\u0027x86_64\u0027 machine\u003d\u0027pc-q35-10.2\u0027\u003ehvm\u003c/type\u003e\n    \u003cfirmware\u003e\n      \u003cfeature enabled\u003d\u0027yes\u0027 name\u003d\u0027enrolled-keys\u0027/\u003e\n      \u003cfeature enabled\u003d\u0027yes\u0027 name\u003d\u0027secure-boot\u0027/\u003e\n    \u003c/firmware\u003e\n    \u003cloader readonly\u003d\u0027yes\u0027 type\u003d\u0027rom\u0027 format\u003d\u0027raw\u0027\u003e/usr/share/ovmf/OVMF.inteltdx.ms.fd\u003c/loader\u003e\n    \u003cboot dev\u003d\u0027hd\u0027/\u003e\n    \u003csmbios mode\u003d\u0027sysinfo\u0027/\u003e\n  \u003c/os\u003e\n\nadding stateless\u003d\u0027yes\u0027 doesn\u0027t affect it.","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"3f591ec3be1efef0da91bf3f55068850f98a5b34","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"01efecd0_865de7ee","in_reply_to":"13fcb3e9_733e3f77","updated":"2026-08-03 16:45:24.000000000","message":"https://review.opendev.org/c/openstack/nova/+/999249/1/nova/virt/libvirt/driver.py#7976 actually shows that we need stateless/readonly firmware.","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"da9f14684b69eb526447b59a932b2e1db3ca81c3","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"f497525b_a6eab630","in_reply_to":"4035b817_c96e2f62","updated":"2026-08-12 08:14:11.000000000","message":"That makes sense, thanks for explaining.\n\nI\u0027ll bring back the stateless check!","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"e3d0f62b67d1363a16853e0d9485cfa353609532","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"13fcb3e9_733e3f77","in_reply_to":"4c7175e9_3374b191","updated":"2026-08-03 16:19:41.000000000","message":"No it does require stateless firmware. Libvirt is able to select the appropriate firmware without explicit stateless property, but the firmware descriptor file makes it select the tdx-specific firmware which is stateless.\n\nWe discussed a similar topic for SNP and we decided to make the requirement explicit, and do not rely on that implicit selection by libvirt.","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"6e9ccc728fb5186fa773b1bb5f5e96320bf82c03","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"cc39e107_b49d175c","in_reply_to":"850e5bf5_550fa7d0","updated":"2026-08-11 14:10:43.000000000","message":"Ah, maybe I am mixing up stateless here as well, but TDX firmware doesn\u0027t have the explicit `\"mode\": \"stateless\"` that SNP firmware has:\n\n```\ncat /usr/share/qemu/firmware/60-edk2-x86_64-amdsev.json\n{\n    \"description\": \"UEFI firmware for x86_64, with SEV-ES support\",\n    \"interface-types\": [\n        \"uefi\"\n    ],\n    \"mapping\": {\n        \"device\": \"flash\",\n        \"mode\": \"stateless\",\n        \"executable\": {\n            \"filename\": \"/usr/share/ovmf/OVMF.amdsev.fd\",\n            \"format\": \"raw\"\n        }\n    },\n    ...\n}\n```\n\nDoes setting \u0027hw_firmware_stateless\u0027 do anything beyond controlling the `\u003cloader mode\u003d\u0027stateless\u0027\u003e` attribute? My understanding is that this part isn\u0027t needed for TDX since it doesn\u0027t use the `\"device\": \"flash\"`.\n\nAs far as I understand it, it doesn\u0027t change the resulting QEMU command whether `hw_firmware_stateless` is set or not for TDX. I think we can make stateless explicit anyway; I\u0027m just trying to understand what it does for TDX.","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"fba137f5d77b7bcb6f87a62f2e885f06c5554139","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"4035b817_c96e2f62","in_reply_to":"cc39e107_b49d175c","updated":"2026-08-11 18:49:27.000000000","message":"mode\u003dstateless is the legacy method to define stateless firmware. In recent versions using device\u003dmemory is equivalent.\n\n\u003e Does setting \u0027hw_firmware_stateless\u0027 do anything beyond controlling the \u003cloader mode\u003d\u0027stateless\u0027\u003e attribute?\n\nhw_firmware_stateless\u003dTrue enables os.loader.stateless\u003dtrue in libvirt, then libvirt only select firmware with mode\u003dstateless or device\u003dmemory.\n\nMy point is not really related to whether the flag is required so that libvirt can select the correct firmware. We require explicit request of stateless firmware for SEV-SNP (although it\u0027s not needed by libvirt internally) because stateful firmware has been default for UEFI and we want users to be aware of a different behavior, instead of changing it by a different flag internally.","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"d92770ae6f42c77cef47447e65b201cf465dedfc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"96d8c4a7_078fb020","in_reply_to":"f497525b_a6eab630","updated":"2026-08-13 14:57:49.000000000","message":"Thanks !","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"4a5db0caafa51cbce223ee32ab344e4d8c72ef45","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"850e5bf5_550fa7d0","in_reply_to":"fa83fcb9_79324e02","updated":"2026-08-10 16:19:27.000000000","message":"Sorry I mixed up statelss and readonly though these are different.\n\nHowever I believe my initial concern is still valid. Looking at TDX firmware file it instructs libvirt to use stateless firmware.\n\n```\n$ cat /usr/share/qemu/firmware/61-edk2-ovmf-x64-inteltdx.json \n{\n    \"description\": \"OVMF with TDX support\",\n    \"interface-types\": [\n        \"uefi\"\n    ],\n    \"mapping\": {\n        \"device\": \"memory\",\n        \"filename\": \"/usr/share/edk2/ovmf/OVMF.inteltdx.secboot.fd\"\n    },\n```\n\nLibvirt is able to select this without statleess\u003d\u0027yes\u0027 because that would be the only one with intel-tdx feature. However if it always select stateless firmware then I believe it should be explicit. (This is also same for SNP. Libvirt is able to select the correct \"stateless\" firmware, in recent distribution, without stateless)","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"569500cc315cc2c9ede62317facbc61cec463f57","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":4,"id":"fa83fcb9_79324e02","in_reply_to":"fc19daf5_016e08aa","updated":"2026-08-04 10:09:13.000000000","message":"Context for readonly:\nhttps://github.com/canonical/tdx/commit/a6216d1eeea8140f9db242d74ebc99c54071535f","commit_id":"910436857da955ba31996c7cd116b1c724bc2dc7"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"9539bdb0a3a84592d3aab9aacdfc334caf7097d3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"5d68968f_1291e037","updated":"2026-08-10 16:14:16.000000000","message":"Oh wait I forgot that I left the comment regarding stateless in this change.","commit_id":"291eb39ba15bcf428c3eeb2ee7ae2a2e9ba92d4e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dd3133e1af1c7c4ecde833b7e5bc91d81a5f0485","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"838e7d87_4721e6dc","updated":"2026-08-10 12:55:50.000000000","message":"lgtm, no questions","commit_id":"291eb39ba15bcf428c3eeb2ee7ae2a2e9ba92d4e"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"7ecc886340b01fe357f70f1cc22720dc35caabd9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"11cedd71_3c9abc12","updated":"2026-08-13 14:57:08.000000000","message":"There is one odd indentation but that\u0027s not a blocker. We can probably fix it in follow-up.","commit_id":"8457ef6437c83961643c69ac6f702ebf52d5531d"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d7b088ab43f066e10d6ef9478ee1318e04c667a3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"3d17afbe_780f3be7","updated":"2026-08-13 13:04:11.000000000","message":"make sense","commit_id":"8457ef6437c83961643c69ac6f702ebf52d5531d"}],"nova/tests/unit/virt/libvirt/test_driver.py":[{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"89d7377ccefaf51b56376b7df2e65f5b1bcc6f9d","unresolved":true,"context_lines":[{"line_number":4004,"context_line":"                                self._test_get_mem_encryption_config,"},{"line_number":4005,"context_line":"                                host_sev_enabled\u003dTrue, enc_extra_spec\u003dTrue,"},{"line_number":4006,"context_line":"                                hw_firmware_type\u003d\u0027uefi\u0027)"},{"line_number":4007,"context_line":"        mem_encryption_model \u003d fields.MemEncryptionModel.AMD_SEV"},{"line_number":4008,"context_line":"        self.assertEqual("},{"line_number":4009,"context_line":"            \"Machine type \u0027pc\u0027 is not compatible with image fake_image \""},{"line_number":4010,"context_line":"            \"(150d530b-1c57-4367-b754-1f1b5237923d): q35 type is required \""}],"source_content_type":"text/x-python","patch_set":1,"id":"27afd56d_89660f97","line":4007,"range":{"start_line":4007,"start_character":8,"end_line":4007,"end_character":28},"updated":"2026-07-23 16:45:50.000000000","message":"these changes are not actually required. If we make these we may want to use ddt to test all related mem encryption models.","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":true,"context_lines":[{"line_number":4004,"context_line":"                                self._test_get_mem_encryption_config,"},{"line_number":4005,"context_line":"                                host_sev_enabled\u003dTrue, enc_extra_spec\u003dTrue,"},{"line_number":4006,"context_line":"                                hw_firmware_type\u003d\u0027uefi\u0027)"},{"line_number":4007,"context_line":"        mem_encryption_model \u003d fields.MemEncryptionModel.AMD_SEV"},{"line_number":4008,"context_line":"        self.assertEqual("},{"line_number":4009,"context_line":"            \"Machine type \u0027pc\u0027 is not compatible with image fake_image \""},{"line_number":4010,"context_line":"            \"(150d530b-1c57-4367-b754-1f1b5237923d): q35 type is required \""}],"source_content_type":"text/x-python","patch_set":1,"id":"fe1b4d54_cf80a380","line":4007,"range":{"start_line":4007,"start_character":8,"end_line":4007,"end_character":28},"in_reply_to":"27afd56d_89660f97","updated":"2026-07-24 12:00:09.000000000","message":"This arose from moving the machine type logic to the common MemEncryptionConfig which before had specific errors with the word \"SEV\". I opted to declare the model here to have the error depend on it, rather than just specify the string. I can add the rest of the models (with ddt) if desired, or just update the string to \"amd-sev\" if preferred","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"}],"nova/tests/unit/virt/test_hardware.py":[{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"89d7377ccefaf51b56376b7df2e65f5b1bcc6f9d","unresolved":true,"context_lines":[{"line_number":5482,"context_line":"    flavor_name \u003d \u0027m1.faketiny\u0027"},{"line_number":5483,"context_line":"    image_name \u003d \u0027fakecirros\u0027"},{"line_number":5484,"context_line":"    image_id \u003d \u00277ec4448e-f3fd-44b1-b172-9a7980f0f29f\u0027"},{"line_number":5485,"context_line":"    model \u003d fields.MemEncryptionModel.AMD_SEV"},{"line_number":5486,"context_line":""},{"line_number":5487,"context_line":"    def _test_encrypted_memory_support_raises(self, enc_extra_spec,"},{"line_number":5488,"context_line":"                                              enc_image_prop, image_props,"}],"source_content_type":"text/x-python","patch_set":1,"id":"2b298ee1_c2113482","line":5485,"range":{"start_line":5485,"start_character":4,"end_line":5485,"end_character":9},"updated":"2026-07-23 16:45:50.000000000","message":"ditto. This isn\u0027t really needed unless you extend these tests to use different mem encryption models.","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":false,"context_lines":[{"line_number":5482,"context_line":"    flavor_name \u003d \u0027m1.faketiny\u0027"},{"line_number":5483,"context_line":"    image_name \u003d \u0027fakecirros\u0027"},{"line_number":5484,"context_line":"    image_id \u003d \u00277ec4448e-f3fd-44b1-b172-9a7980f0f29f\u0027"},{"line_number":5485,"context_line":"    model \u003d fields.MemEncryptionModel.AMD_SEV"},{"line_number":5486,"context_line":""},{"line_number":5487,"context_line":"    def _test_encrypted_memory_support_raises(self, enc_extra_spec,"},{"line_number":5488,"context_line":"                                              enc_image_prop, image_props,"}],"source_content_type":"text/x-python","patch_set":1,"id":"edd742e2_4e5a40f3","line":5485,"range":{"start_line":5485,"start_character":4,"end_line":5485,"end_character":9},"in_reply_to":"2b298ee1_c2113482","updated":"2026-07-24 12:00:09.000000000","message":"Acknowledged","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"}],"nova/virt/hardware.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":true,"context_lines":[{"line_number":73,"context_line":"        emsg \u003d _("},{"line_number":74,"context_line":"            \"Memory encryption is requested by %(requesters)s but the image \""},{"line_number":75,"context_line":"            \"metadata doesn\u0027t have the \u0027hw_firmware_type\u0027 property set to \""},{"line_number":76,"context_line":"            \"\u0027uefi\u0027\""},{"line_number":77,"context_line":"        )"},{"line_number":78,"context_line":"        data \u003d {\u0027requesters\u0027: \" and \".join(requesters)}"},{"line_number":79,"context_line":"        raise exception.FlavorImageConflict(emsg % data)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9da11574_beeffa8a","line":76,"updated":"2026-07-23 16:45:32.000000000","message":"It is true that both Intel and AMD case we need uefi. I\u0027m wondering if ARM CC will need it or not. Guess we can assume ARM will follow the lead here. So I\u0027m OK to move this logic to MemEncryptionConfig","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":true,"context_lines":[{"line_number":73,"context_line":"        emsg \u003d _("},{"line_number":74,"context_line":"            \"Memory encryption is requested by %(requesters)s but the image \""},{"line_number":75,"context_line":"            \"metadata doesn\u0027t have the \u0027hw_firmware_type\u0027 property set to \""},{"line_number":76,"context_line":"            \"\u0027uefi\u0027\""},{"line_number":77,"context_line":"        )"},{"line_number":78,"context_line":"        data \u003d {\u0027requesters\u0027: \" and \".join(requesters)}"},{"line_number":79,"context_line":"        raise exception.FlavorImageConflict(emsg % data)"}],"source_content_type":"text/x-python","patch_set":1,"id":"e67bfc41_6e83563f","line":76,"in_reply_to":"9da11574_beeffa8a","updated":"2026-07-24 12:00:09.000000000","message":"This is now generic","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":35307,"name":"Taketani Ryo","email":"taketani.ryo@fujitsu.com","username":"r-taketn0517"},"change_message_id":"e596d645d007394ebd3f184bb5edc9957f887f41","unresolved":true,"context_lines":[{"line_number":73,"context_line":"        emsg \u003d _("},{"line_number":74,"context_line":"            \"Memory encryption is requested by %(requesters)s but the image \""},{"line_number":75,"context_line":"            \"metadata doesn\u0027t have the \u0027hw_firmware_type\u0027 property set to \""},{"line_number":76,"context_line":"            \"\u0027uefi\u0027\""},{"line_number":77,"context_line":"        )"},{"line_number":78,"context_line":"        data \u003d {\u0027requesters\u0027: \" and \".join(requesters)}"},{"line_number":79,"context_line":"        raise exception.FlavorImageConflict(emsg % data)"}],"source_content_type":"text/x-python","patch_set":1,"id":"068f941b_56bd4887","line":76,"in_reply_to":"e67bfc41_6e83563f","updated":"2026-07-28 05:46:58.000000000","message":"\u003e It is true that both Intel and AMD case we need uefi. I\u0027m wondering if ARM CC will need it or not. Guess we can assume ARM will follow the lead here. So I\u0027m OK to move this logic to MemEncryptionConfig\n\n@gibizer@gmail.com @anton.iacobaeus@canarybit.eu\n\nOn Arm, `hw_firmware_type` is optional because UEFI is selected by default when it is omitted. Therefore, this check would reject images where `hw_firmware_type` is omitted.\n\nI\u0027d like to point out that this generic implementation does not fit Arm\u0027s existing behavior. If Arm CCA is implemented based on this abstraction, it will likely require architecture-specific handling, for example by overriding `_check_firmware_type()`.","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":true,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def _check_machine_type(self, image_meta: \u0027objects.ImageMeta\u0027,"},{"line_number":82,"context_line":"                            machine_type: str | None) -\u003e None:"},{"line_number":83,"context_line":"        # NOTE(aspiers): As explained in the SEV spec, SEV needs a q35"},{"line_number":84,"context_line":"        # machine type in order to bind all the virtio devices to the PCIe"},{"line_number":85,"context_line":"        # bridge so that they use virtio 1.0 and not virtio 0.9, since"},{"line_number":86,"context_line":"        # QEMU\u0027s iommu_platform feature was added in virtio 1.0 only:"},{"line_number":87,"context_line":"        #"},{"line_number":88,"context_line":"        # http://specs.openstack.org/openstack/nova-specs/specs/train/approved/amd-sev-libvirt-support.html"},{"line_number":89,"context_line":"        #"},{"line_number":90,"context_line":"        # So if the image explicitly requests a machine type which is not"},{"line_number":91,"context_line":"        # in the q35 family, raise an exception."},{"line_number":92,"context_line":"        #"},{"line_number":93,"context_line":"        # This check can be triggered both at API-level, at which point we"},{"line_number":94,"context_line":"        # can\u0027t check here what value of CONF.libvirt.hw_machine_type may"},{"line_number":95,"context_line":"        # have been configured on the compute node, and by the libvirt"},{"line_number":96,"context_line":"        # driver, in which case the driver can check that config option"},{"line_number":97,"context_line":"        # and will pass the machine_type parameter."},{"line_number":98,"context_line":"        mach_type \u003d machine_type or image_meta.properties.get("},{"line_number":99,"context_line":"            \u0027hw_machine_type\u0027)"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"08a80900_da4c98cb","line":97,"range":{"start_line":83,"start_character":2,"end_line":97,"end_character":51},"updated":"2026-07-23 16:45:32.000000000","message":"I think this needs to be generalized now not to (or not to only) talk about AMD-SEV as this is now in the generic MemEncryptionConfig","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":true,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def _check_machine_type(self, image_meta: \u0027objects.ImageMeta\u0027,"},{"line_number":82,"context_line":"                            machine_type: str | None) -\u003e None:"},{"line_number":83,"context_line":"        # NOTE(aspiers): As explained in the SEV spec, SEV needs a q35"},{"line_number":84,"context_line":"        # machine type in order to bind all the virtio devices to the PCIe"},{"line_number":85,"context_line":"        # bridge so that they use virtio 1.0 and not virtio 0.9, since"},{"line_number":86,"context_line":"        # QEMU\u0027s iommu_platform feature was added in virtio 1.0 only:"},{"line_number":87,"context_line":"        #"},{"line_number":88,"context_line":"        # http://specs.openstack.org/openstack/nova-specs/specs/train/approved/amd-sev-libvirt-support.html"},{"line_number":89,"context_line":"        #"},{"line_number":90,"context_line":"        # So if the image explicitly requests a machine type which is not"},{"line_number":91,"context_line":"        # in the q35 family, raise an exception."},{"line_number":92,"context_line":"        #"},{"line_number":93,"context_line":"        # This check can be triggered both at API-level, at which point we"},{"line_number":94,"context_line":"        # can\u0027t check here what value of CONF.libvirt.hw_machine_type may"},{"line_number":95,"context_line":"        # have been configured on the compute node, and by the libvirt"},{"line_number":96,"context_line":"        # driver, in which case the driver can check that config option"},{"line_number":97,"context_line":"        # and will pass the machine_type parameter."},{"line_number":98,"context_line":"        mach_type \u003d machine_type or image_meta.properties.get("},{"line_number":99,"context_line":"            \u0027hw_machine_type\u0027)"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"711d37d1_b842a508","line":97,"range":{"start_line":83,"start_character":2,"end_line":97,"end_character":51},"in_reply_to":"08a80900_da4c98cb","updated":"2026-07-24 12:00:09.000000000","message":"Agreed! I dropped the Note marker and made it into an example instead, let me know if we still want it as a Note.","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c6b35fcb3f418380f5d10487dafc42e812576b63","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def _check_machine_type(self, image_meta: \u0027objects.ImageMeta\u0027,"},{"line_number":82,"context_line":"                            machine_type: str | None) -\u003e None:"},{"line_number":83,"context_line":"        # NOTE(aspiers): As explained in the SEV spec, SEV needs a q35"},{"line_number":84,"context_line":"        # machine type in order to bind all the virtio devices to the PCIe"},{"line_number":85,"context_line":"        # bridge so that they use virtio 1.0 and not virtio 0.9, since"},{"line_number":86,"context_line":"        # QEMU\u0027s iommu_platform feature was added in virtio 1.0 only:"},{"line_number":87,"context_line":"        #"},{"line_number":88,"context_line":"        # http://specs.openstack.org/openstack/nova-specs/specs/train/approved/amd-sev-libvirt-support.html"},{"line_number":89,"context_line":"        #"},{"line_number":90,"context_line":"        # So if the image explicitly requests a machine type which is not"},{"line_number":91,"context_line":"        # in the q35 family, raise an exception."},{"line_number":92,"context_line":"        #"},{"line_number":93,"context_line":"        # This check can be triggered both at API-level, at which point we"},{"line_number":94,"context_line":"        # can\u0027t check here what value of CONF.libvirt.hw_machine_type may"},{"line_number":95,"context_line":"        # have been configured on the compute node, and by the libvirt"},{"line_number":96,"context_line":"        # driver, in which case the driver can check that config option"},{"line_number":97,"context_line":"        # and will pass the machine_type parameter."},{"line_number":98,"context_line":"        mach_type \u003d machine_type or image_meta.properties.get("},{"line_number":99,"context_line":"            \u0027hw_machine_type\u0027)"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"bc208cb8_7389f089","line":97,"range":{"start_line":83,"start_character":2,"end_line":97,"end_character":51},"in_reply_to":"711d37d1_b842a508","updated":"2026-08-07 12:50:36.000000000","message":"Done","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":true,"context_lines":[{"line_number":99,"context_line":"            \u0027hw_machine_type\u0027)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        # If hw_machine_type is not specified on the image and is not"},{"line_number":102,"context_line":"        # configured correctly on SEV compute nodes, then a separate check"},{"line_number":103,"context_line":"        # in the driver will catch that and potentially retry on other"},{"line_number":104,"context_line":"        # compute nodes."},{"line_number":105,"context_line":"        if mach_type is None:"}],"source_content_type":"text/x-python","patch_set":1,"id":"e9b0f824_7fbbd62b","line":102,"updated":"2026-07-23 16:45:32.000000000","message":"ditto SEV","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":false,"context_lines":[{"line_number":99,"context_line":"            \u0027hw_machine_type\u0027)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"        # If hw_machine_type is not specified on the image and is not"},{"line_number":102,"context_line":"        # configured correctly on SEV compute nodes, then a separate check"},{"line_number":103,"context_line":"        # in the driver will catch that and potentially retry on other"},{"line_number":104,"context_line":"        # compute nodes."},{"line_number":105,"context_line":"        if mach_type is None:"}],"source_content_type":"text/x-python","patch_set":1,"id":"0056e138_a2ca1071","line":102,"in_reply_to":"e9b0f824_7fbbd62b","updated":"2026-07-24 12:00:09.000000000","message":"Acknowledged","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":true,"context_lines":[{"line_number":114,"context_line":"        image_id \u003d (image_meta.id if \u0027id\u0027 in image_meta else \u0027\u003cno-id\u003e\u0027)"},{"line_number":115,"context_line":"        # Could be something like pc-q35-2.11 if a specific version of the"},{"line_number":116,"context_line":"        # machine type is required, so do substring matching."},{"line_number":117,"context_line":"        if \u0027q35\u0027 not in mach_type:"},{"line_number":118,"context_line":"            raise exception.InvalidMachineType("},{"line_number":119,"context_line":"                mtype\u003dmach_type,"},{"line_number":120,"context_line":"                image_id\u003dimage_id, image_name\u003dimage_name,"}],"source_content_type":"text/x-python","patch_set":1,"id":"9c39eb54_2d4e724c","line":117,"updated":"2026-07-23 16:45:32.000000000","message":"This is a problem. I\u0027m pretty sure ARM does not use q35 machine type.\nCan we make the check generic and moved to the base class but let the children classes declare the supported machine type that is then used in the generic check?\n\nmaybe the same pattern is good for the firmware type as well.","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":true,"context_lines":[{"line_number":114,"context_line":"        image_id \u003d (image_meta.id if \u0027id\u0027 in image_meta else \u0027\u003cno-id\u003e\u0027)"},{"line_number":115,"context_line":"        # Could be something like pc-q35-2.11 if a specific version of the"},{"line_number":116,"context_line":"        # machine type is required, so do substring matching."},{"line_number":117,"context_line":"        if \u0027q35\u0027 not in mach_type:"},{"line_number":118,"context_line":"            raise exception.InvalidMachineType("},{"line_number":119,"context_line":"                mtype\u003dmach_type,"},{"line_number":120,"context_line":"                image_id\u003dimage_id, image_name\u003dimage_name,"}],"source_content_type":"text/x-python","patch_set":1,"id":"faf958e9_63a902b7","line":117,"in_reply_to":"9c39eb54_2d4e724c","updated":"2026-07-24 12:00:09.000000000","message":"Now also generic. I haven\u0027t entirely looked into what ARM CCA requires, but if it is just some other machine type it should be covered. I opted to not support None as a valid entry, which would mean any machine type. This generic interface really only makes it possible to declare one family of machine type, which for now is enough to do the job :)","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c6b35fcb3f418380f5d10487dafc42e812576b63","unresolved":false,"context_lines":[{"line_number":114,"context_line":"        image_id \u003d (image_meta.id if \u0027id\u0027 in image_meta else \u0027\u003cno-id\u003e\u0027)"},{"line_number":115,"context_line":"        # Could be something like pc-q35-2.11 if a specific version of the"},{"line_number":116,"context_line":"        # machine type is required, so do substring matching."},{"line_number":117,"context_line":"        if \u0027q35\u0027 not in mach_type:"},{"line_number":118,"context_line":"            raise exception.InvalidMachineType("},{"line_number":119,"context_line":"                mtype\u003dmach_type,"},{"line_number":120,"context_line":"                image_id\u003dimage_id, image_name\u003dimage_name,"}],"source_content_type":"text/x-python","patch_set":1,"id":"9ee33fc4_a5372ba1","line":117,"in_reply_to":"faf958e9_63a902b7","updated":"2026-08-07 12:50:36.000000000","message":"Done","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":true,"context_lines":[{"line_number":124,"context_line":"    def check_constraints(self, image_meta: \u0027objects.ImageMeta\u0027,"},{"line_number":125,"context_line":"                          machine_type: str | None,"},{"line_number":126,"context_line":"                          requesters: list[str]) -\u003e None:"},{"line_number":127,"context_line":"        pass"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    def __eq__(self, other) -\u003e bool:"},{"line_number":130,"context_line":"        if not isinstance(other, MemEncryptionConfig):"}],"source_content_type":"text/x-python","patch_set":1,"id":"34aeb0cb_97c11ac0","line":127,"updated":"2026-07-23 16:45:32.000000000","message":"if we have firmware type and machine type checks now moved to the base class I guess it would make sense to call them here in the base class too.","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    def check_constraints(self, image_meta: \u0027objects.ImageMeta\u0027,"},{"line_number":125,"context_line":"                          machine_type: str | None,"},{"line_number":126,"context_line":"                          requesters: list[str]) -\u003e None:"},{"line_number":127,"context_line":"        pass"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    def __eq__(self, other) -\u003e bool:"},{"line_number":130,"context_line":"        if not isinstance(other, MemEncryptionConfig):"}],"source_content_type":"text/x-python","patch_set":1,"id":"c6484899_b3f1845d","line":127,"in_reply_to":"34aeb0cb_97c11ac0","updated":"2026-07-24 12:00:09.000000000","message":"Acknowledged","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":true,"context_lines":[{"line_number":143,"context_line":"            fields.MemEncryptionModel.AMD_SEV: MemEncryptionConfigSev,"},{"line_number":144,"context_line":"            fields.MemEncryptionModel.AMD_SEV_ES: MemEncryptionConfigSevEs,"},{"line_number":145,"context_line":"            fields.MemEncryptionModel.AMD_SEV_SNP: MemEncryptionConfigSevSnp,"},{"line_number":146,"context_line":"            fields.MemEncryptionModel.INTEL_TDX: MemEncryptionConfigTDX,"},{"line_number":147,"context_line":"        }"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        if model not in model2cls:"}],"source_content_type":"text/x-python","patch_set":1,"id":"1277f2d1_8c475143","line":146,"updated":"2026-07-23 16:45:32.000000000","message":"OK this is the main addition here. Maybe it would be cleaner to have two commits. One that is a pure refactoring and one that adds the TDX changes to this logic.","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":true,"context_lines":[{"line_number":143,"context_line":"            fields.MemEncryptionModel.AMD_SEV: MemEncryptionConfigSev,"},{"line_number":144,"context_line":"            fields.MemEncryptionModel.AMD_SEV_ES: MemEncryptionConfigSevEs,"},{"line_number":145,"context_line":"            fields.MemEncryptionModel.AMD_SEV_SNP: MemEncryptionConfigSevSnp,"},{"line_number":146,"context_line":"            fields.MemEncryptionModel.INTEL_TDX: MemEncryptionConfigTDX,"},{"line_number":147,"context_line":"        }"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        if model not in model2cls:"}],"source_content_type":"text/x-python","patch_set":1,"id":"6b4473ef_675ddbee","line":146,"in_reply_to":"1277f2d1_8c475143","updated":"2026-07-24 12:00:09.000000000","message":"Done, this is now the first commit without the TDX changes.\n\nSee the TDX changes here:\nhttps://review.opendev.org/c/openstack/nova/+/998608/1","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"c6b35fcb3f418380f5d10487dafc42e812576b63","unresolved":false,"context_lines":[{"line_number":143,"context_line":"            fields.MemEncryptionModel.AMD_SEV: MemEncryptionConfigSev,"},{"line_number":144,"context_line":"            fields.MemEncryptionModel.AMD_SEV_ES: MemEncryptionConfigSevEs,"},{"line_number":145,"context_line":"            fields.MemEncryptionModel.AMD_SEV_SNP: MemEncryptionConfigSevSnp,"},{"line_number":146,"context_line":"            fields.MemEncryptionModel.INTEL_TDX: MemEncryptionConfigTDX,"},{"line_number":147,"context_line":"        }"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"        if model not in model2cls:"}],"source_content_type":"text/x-python","patch_set":1,"id":"b8308495_6533e1d0","line":146,"in_reply_to":"6b4473ef_675ddbee","updated":"2026-08-07 12:50:36.000000000","message":"Done","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":true,"context_lines":[{"line_number":173,"context_line":"                          machine_type: str | None,"},{"line_number":174,"context_line":"                          requesters: list[str]) -\u003e None:"},{"line_number":175,"context_line":"        self._check_firmware_type(image_meta, requesters)"},{"line_number":176,"context_line":"        self._check_machine_type(image_meta, machine_type)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"class MemEncryptionConfigSevEs(MemEncryptionConfigSev):"}],"source_content_type":"text/x-python","patch_set":1,"id":"f3adb1b9_d7b2af8a","line":176,"updated":"2026-07-23 16:45:32.000000000","message":"these calls can be moved to the base class now I assume","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                          machine_type: str | None,"},{"line_number":174,"context_line":"                          requesters: list[str]) -\u003e None:"},{"line_number":175,"context_line":"        self._check_firmware_type(image_meta, requesters)"},{"line_number":176,"context_line":"        self._check_machine_type(image_meta, machine_type)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"class MemEncryptionConfigSevEs(MemEncryptionConfigSev):"}],"source_content_type":"text/x-python","patch_set":1,"id":"a004e989_734c6b2e","line":176,"in_reply_to":"f3adb1b9_d7b2af8a","updated":"2026-07-24 12:00:09.000000000","message":"Indeed!","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"da668f1eb3acdd3a039a0b971dc89fe3f672886f","unresolved":true,"context_lines":[{"line_number":232,"context_line":"        self._check_firmware_type(image_meta, requesters)"},{"line_number":233,"context_line":"        self._check_machine_type(image_meta, machine_type)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"        if not get_stateless_firmware_constraint(image_meta):"},{"line_number":236,"context_line":"            emsg \u003d _("},{"line_number":237,"context_line":"                \"The %s memory encryption model requires stateless firmware \""},{"line_number":238,"context_line":"                \"but the image metadata doesn\u0027t have \""}],"source_content_type":"text/x-python","patch_set":1,"id":"a4ce1aa7_035a7f53","line":235,"updated":"2026-07-23 16:45:32.000000000","message":"this could be deduplicated across SNP by having  generic check function in the base class and just calling it in SNP and TDX case.","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":false,"context_lines":[{"line_number":232,"context_line":"        self._check_firmware_type(image_meta, requesters)"},{"line_number":233,"context_line":"        self._check_machine_type(image_meta, machine_type)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"        if not get_stateless_firmware_constraint(image_meta):"},{"line_number":236,"context_line":"            emsg \u003d _("},{"line_number":237,"context_line":"                \"The %s memory encryption model requires stateless firmware \""},{"line_number":238,"context_line":"                \"but the image metadata doesn\u0027t have \""}],"source_content_type":"text/x-python","patch_set":1,"id":"79849876_5c5f0e84","line":235,"in_reply_to":"a4ce1aa7_035a7f53","updated":"2026-07-24 12:00:09.000000000","message":"Acknowledged","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"89d7377ccefaf51b56376b7df2e65f5b1bcc6f9d","unresolved":true,"context_lines":[{"line_number":231,"context_line":"                          requesters: list[str]) -\u003e None:"},{"line_number":232,"context_line":"        self._check_firmware_type(image_meta, requesters)"},{"line_number":233,"context_line":"        self._check_machine_type(image_meta, machine_type)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"        if not get_stateless_firmware_constraint(image_meta):"},{"line_number":236,"context_line":"            emsg \u003d _("},{"line_number":237,"context_line":"                \"The %s memory encryption model requires stateless firmware \""},{"line_number":238,"context_line":"                \"but the image metadata doesn\u0027t have \""},{"line_number":239,"context_line":"                \"the \u0027hw_firmware_stateless\u0027 property set to True\""},{"line_number":240,"context_line":"            )"},{"line_number":241,"context_line":"            raise exception.StatelessFirmwareRequired(emsg % self.model)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"def get_vcpu_pin_set():"}],"source_content_type":"text/x-python","patch_set":1,"id":"8cda2e67_80ee6686","line":241,"range":{"start_line":234,"start_character":1,"end_line":241,"end_character":72},"updated":"2026-07-23 16:45:50.000000000","message":"I think usage of stateless firmware would become common for multiple memory encryption. Can we add a common method like _requires_stateless_firwmare_constrait and use it in both TDX and SEV-SNP ?","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"e6f07ddc21055bcb0fda58888dba98d73aae723c","unresolved":false,"context_lines":[{"line_number":231,"context_line":"                          requesters: list[str]) -\u003e None:"},{"line_number":232,"context_line":"        self._check_firmware_type(image_meta, requesters)"},{"line_number":233,"context_line":"        self._check_machine_type(image_meta, machine_type)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"        if not get_stateless_firmware_constraint(image_meta):"},{"line_number":236,"context_line":"            emsg \u003d _("},{"line_number":237,"context_line":"                \"The %s memory encryption model requires stateless firmware \""},{"line_number":238,"context_line":"                \"but the image metadata doesn\u0027t have \""},{"line_number":239,"context_line":"                \"the \u0027hw_firmware_stateless\u0027 property set to True\""},{"line_number":240,"context_line":"            )"},{"line_number":241,"context_line":"            raise exception.StatelessFirmwareRequired(emsg % self.model)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"def get_vcpu_pin_set():"}],"source_content_type":"text/x-python","patch_set":1,"id":"4e6c7992_3af13c13","line":241,"range":{"start_line":234,"start_character":1,"end_line":241,"end_character":72},"in_reply_to":"6a86f553_2ada1032","updated":"2026-07-27 12:15:53.000000000","message":"Done","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":38744,"name":"Anton Iacobaeus","display_name":"antia","email":"anton.iacobaeus@canarybit.eu","username":"antia","status":"Canary Bit"},"change_message_id":"a3826761c7d9faeb2d5fdd04ab0d5b45bb23fe63","unresolved":true,"context_lines":[{"line_number":231,"context_line":"                          requesters: list[str]) -\u003e None:"},{"line_number":232,"context_line":"        self._check_firmware_type(image_meta, requesters)"},{"line_number":233,"context_line":"        self._check_machine_type(image_meta, machine_type)"},{"line_number":234,"context_line":""},{"line_number":235,"context_line":"        if not get_stateless_firmware_constraint(image_meta):"},{"line_number":236,"context_line":"            emsg \u003d _("},{"line_number":237,"context_line":"                \"The %s memory encryption model requires stateless firmware \""},{"line_number":238,"context_line":"                \"but the image metadata doesn\u0027t have \""},{"line_number":239,"context_line":"                \"the \u0027hw_firmware_stateless\u0027 property set to True\""},{"line_number":240,"context_line":"            )"},{"line_number":241,"context_line":"            raise exception.StatelessFirmwareRequired(emsg % self.model)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"def get_vcpu_pin_set():"}],"source_content_type":"text/x-python","patch_set":1,"id":"6a86f553_2ada1032","line":241,"range":{"start_line":234,"start_character":1,"end_line":241,"end_character":72},"in_reply_to":"8cda2e67_80ee6686","updated":"2026-07-24 12:00:09.000000000","message":"Yes agreed!","commit_id":"f3ccffacbb1b17efb988a99fce45bab92a27148b"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"0b28fd0d0c104d8cb9dacdd4e2b52921e8225567","unresolved":false,"context_lines":[{"line_number":167,"context_line":"            fields.MemEncryptionModel.AMD_SEV: MemEncryptionConfigSev,"},{"line_number":168,"context_line":"            fields.MemEncryptionModel.AMD_SEV_ES: MemEncryptionConfigSevEs,"},{"line_number":169,"context_line":"            fields.MemEncryptionModel.AMD_SEV_SNP: MemEncryptionConfigSevSnp,"},{"line_number":170,"context_line":"            fields.MemEncryptionModel.INTEL_TDX: MemEncryptionConfigTDX,"},{"line_number":171,"context_line":"        }"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"        if model not in model2cls:"}],"source_content_type":"text/x-python","patch_set":2,"id":"90a72ad5_51f9eff1","line":170,"updated":"2026-07-24 14:29:33.000000000","message":"pep8: F821 undefined name \u0027MemEncryptionConfigTDX\u0027","commit_id":"bc6824e90d2ab2ba9f19425e46432d476ee41db3"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"e6f07ddc21055bcb0fda58888dba98d73aae723c","unresolved":true,"context_lines":[{"line_number":144,"context_line":"                reason\u003d_(\"%s type is required for %s to work\") %"},{"line_number":145,"context_line":"                    (required, self.model))"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    def check_constraints(self, image_meta: \u0027objects.ImageMeta\u0027,"},{"line_number":148,"context_line":"                          machine_type: str | None,"},{"line_number":149,"context_line":"                          requesters: list[str]) -\u003e None:"},{"line_number":150,"context_line":"        self._check_firmware_type(image_meta, requesters)"}],"source_content_type":"text/x-python","patch_set":3,"id":"a531ff90_4bde7e2e","line":147,"range":{"start_line":147,"start_character":8,"end_line":147,"end_character":25},"updated":"2026-07-27 12:15:53.000000000","message":"We could add a new require_stateless_firmware property and call _check_stateless_firmware if the flag is true, so that we can simplify check_constraints in children but that\u0027s not so prioritized that we block this change.","commit_id":"cb37f8e1223af83e16309100487b16993ac99147"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"7ecc886340b01fe357f70f1cc22720dc35caabd9","unresolved":true,"context_lines":[{"line_number":139,"context_line":"                image_id\u003dimage_id, image_name\u003dimage_name,"},{"line_number":140,"context_line":"                reason\u003d_(\"%s type is required for %s to work\") %"},{"line_number":141,"context_line":"                    (required, self.model))"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"    def _check_stateless_firmware("},{"line_number":144,"context_line":"    self, image_meta: \u0027objects.ImageMeta\u0027) -\u003e None:"},{"line_number":145,"context_line":"        if not self.needs_stateless_firmware:"},{"line_number":146,"context_line":"            return"},{"line_number":147,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"ed584c63_eb3db7c6","line":144,"range":{"start_line":142,"start_character":1,"end_line":144,"end_character":51},"updated":"2026-08-13 14:57:08.000000000","message":"```suggestion\n\n    def _check_stateless_firmware(\n        self, image_meta: \u0027objects.ImageMeta\u0027\n    ) -\u003e None:\n```","commit_id":"8457ef6437c83961643c69ac6f702ebf52d5531d"}]}
