Combine 1 tablespoon garam masala, 1 teaspoon salt, ½ teaspoon cumin, ½ teaspoon coriander, and ½ teaspoon pepper in a 1-gallon zipper-lock bag. Toss the spices around to combine. Add lamb and shake to coat. Add 1 cup yogurt, seal bag, and massage meat to coat. Transfer bag to refrigerator and marinate for 1 hour or up to overnight.
Heat 2 tablespoons oil in a 12-inch sauté pan over medium. Add 1 sliced onion and remaining 1 teaspoon salt; cook until softened and starting to brown, 8–10 minutes, stirring occasionally.
Reduce heat to medium-low and add 4 chopped cloves garlic, 1 minced serrano, and 1 tablespoon grated ginger; cook stirring frequently until onions are softened and golden brown, about 7 minutes.
Stir in remaining 1 tablespoon garam masala, remaining 1 teaspoon cumin, and ½ teaspoon cardamom; cook 1 minute.
Add 1 (28-ounce) can tomatoes with juices, crushing them with your hands as you add them (or use your kitchen shears to cut them in the can). Bring sauce to a boil, reduce heat, and simmer, stirring frequently and scraping up browned bits from bottom of pan, until thickened and deepened in color, 15–20 minutes.
Stir in 1 (14 ounce) can coconut milk and simmer until thickened, 5–7 minutes.
Meanwhile, heat oven to broil (high) with rack set in upper middle position Line a rimmed baking sheet with foil and set a wire rack inside sheet. Arrange lamb on rack in a single layer (don’t scrape marinade off). Broil lamb until starting to char, 10–12 minutes.
Add lamb to sauce, and simmer, stirring occasionally, until lamb is cooked through, about 8 minutes. Serve with rice, cilantro, and naan if desired.